上一篇拆完 commerce-agents 的 Shopping Agent 後,這篇不再繼續拆每一個 Agent module,而是回答兩個問題:
Tool 定義好之後,怎麼真正掛到 Agent 上?
以及:
同一套 Shopping Agent,如何提供三種runtime的方式,跟claude溝通 Messages API、Agent SDK、Managed Agents?
commerce-common:Tool 的共用執行底座有哪些 Shopping Tool,是由 Shopping Core 定義。
例如:
shopping-agent/core/shopping_agent/tools/registry.py
這裡定義了:
search_products
get_product_details
get_cart
add_to_cart
get_orders
search_policies
...
並依 ShoppingAgentConfig 決定這次 Deployment 真正開放哪些 Tool。
例如:
enable_cart = True
其中 Shopping Core 大致可以看成:
Shopping Core
│
├── tools/registry.py
│ └── Tool 名稱、description、input schema
│
├── gates.py
│ └── 寫入操作前的限制
│
└── executor.py
└── Tool 最後對應哪個 Backend method
而 commerce-common 處理的是 Shopping Agent、Merchant Agent,以及不同 Runtime 都會重複遇到的共用問題:
commerce-common/commerce_common/
├── config.py
├── execution.py
├── fencing.py
├── memory.py
├── presentation.py
├── agent_sdk.py
└── mcp_server.py
官方 README 也把這一層定位成 config、fencing、memory、presentation、executor frame、events 等共用能力。
例如 Model 想呼叫:
add_to_cart
整條路徑可以簡化成:
tools/registry.py
(shopping-agent/core/shopping_agent/tools/registry.py)
│
│ 這次 Agent 可以看到哪些 Tool
▼
commerce_common/execution.py
(shopping-agent/core/shopping_agent/executor.py)
│
│ 這個 Tool 是否允許被執行
▼
ShoppingToolExecutor
│
▼
StorefrontBackend
(shopping-agent/core/shopping_agent/backend.py)
│
▼
企業商品 / 購物車 / 訂單 API
這比只在 System Prompt 裡寫:
請不要呼叫沒有權限的工具。
可靠得多。
到了 Agent SDK Runtime,原本的 Shopping Tool 仍然繼續使用。
Adapter 在:
shopping-agent/runtime-agent-sdk/
└── shopping_agent_sdk/
└── shopping_tools.py
它做的事情是把 Shopping Core 已經定義好的 Tool contract,轉成 Agent SDK 可以使用的 MCP Tool。
所以:
Shopping Core Tool
│
▼
Agent SDK Adapter
shopping_tools.py
│
▼
MCP Tool
│
▼
ShoppingToolExecutor
│
▼
StorefrontBackend
這也是這個 Repo 很重要的一個設計:
Business Tool 定義一次,再由不同 Runtime Adapter 接出去。
這個 Repo 把安全拆成不同層:
User Identity
→ 這次是誰在操作?
Tool Permission
→ 這個 Agent 能不能呼叫這個 Tool?
MCP Exposure
→ 這台 MCP Server 能不能直接被外部連線?
其中 User Identity 與正式的 Authentication 的模組開發,主要仍然是 Host / Deployment 要負責。
以 Shopping Agent 為例,如果前端是 LINE:
LINE User
↓
FastAPI 驗證 LINE userId
↓
建立 Session
{
session_id: "abc123",
customer_id: "C001"
}
↓
後續請求只帶 session_id
↓
Backend 從 Session 取得 customer_id
這樣 Tool 就不需要接受:
get_orders(user_id="C001")
因為 user_id 如果是 Tool argument,就可能由 Model 產生或修改。
比較安全的做法是:
Host 先確認使用者身份,再把身份綁到 Session;Backend 只相信 Session 裡的身份。
Session 的參考實作可以看:
examples/demo_common/sessions.py
examples/demo_common/storefront.py
MCP Server 的共用安全檢查在:
commerce-common/commerce_common/mcp_server.py
Reference MCP Server 預設偏向只接受本機連線。
也就是開發環境比較接近:
Agent
↓
localhost MCP
↓
Backend
如果正式部署成 Remote MCP,不應只是把 Port 開到 Internet:
Internet
↓
MCP Server
↓
Backend
比較合理的架構是:
Internet
↓
Gateway
├─ Authentication
├─ Authorization
├─ Rate Limit
└─ Audit
↓
MCP Server
↓
Backend
所以 commerce-common/commerce_common/mcp_server.py 提供的比較像是:
避免 Reference MCP Server 不小心直接對外暴露的安全護欄。
三種 Runtime 是同一套:
Shopping Core
├── Config
├── Prompt
├── Skills
├── Tool Contracts
├── Gates
├── Executor
└── Backend
可以選擇三種執行方式:
Shopping Core
│
┌────────────┼────────────┐
▼ ▼ ▼
Messages API Agent SDK Managed Agents
真正的差別只有一個核心問題:
誰負責 Agent Loop、Session、Tool Registration 和 Permission?
下面全部使用同一個案例。
使用者說:
我要找兩人用、8000 元以下的輕量帳篷。
Messages API 是三種做法裡,最接近一般 Backend Application 的方式。
主要程式位置:
shopping-agent/runtime-messages-api/
└── shopping_agent_runtime/
└── orchestrator.py
Runtime 會建立一個 ShoppingAgent:
agent = ShoppingAgent(
backend=my_backend,
config=my_config,
skills_dir=my_skills,
memory_store=my_memory,
client=anthropic_client,
)
這幾個主要參數分別對應:
| 參數 | 用途 | 主要程式位置 |
|---|---|---|
backend |
商品、購物車、訂單真正去哪裡執行 | shopping-agent/core/shopping_agent/backend.py |
config |
Model、Brand、Cart、Orders 等能力設定 | shopping-agent/core/shopping_agent/config.py |
skills_dir |
Agent 工作 SOP | shopping-agent/core/ 相關 Skill 載入邏輯 |
memory_store |
長期記憶 | commerce-common/commerce_common/memory.py |
client |
Claude API Client | runtime-messages-api/.../orchestrator.py |
真正跑一輪時,再傳:
agent.stream_turn(
messages, # Conversation History
session, # 現在是哪個 User / Session
state, # 這個 Agent Session 已經做過哪些事情
)
這條路裡,Application 自己負責很多事情:
Webhook
Session
History
Agent Loop
Tool Dispatch
Streaming
Retry
Logging
UI
如果公司本來已經有:
FastAPI
Redis
Database
Session Service
API Gateway
現在只是想:
在既有 Backend 裡加入一個 Agent。
那 Messages API 最直覺。
可以把它理解成:
我的 Application 本來就存在,Agent 只是其中一個能力。
第二種做法是 Agent SDK。
最大的差別是:
Agent Loop 不再自己寫。
主要組裝位置:
shopping-agent/runtime-agent-sdk/
└── shopping_agent_sdk/
├── agent.py
└── shopping_tools.py
主要入口在:
shopping-agent/runtime-agent-sdk/
shopping_agent_sdk/agent.py
這裡透過 make_options() 組 Runtime:
options, toolset = make_options(
backend=my_backend,
config=my_config,
session_id="user-123-session-1",
user_id="user-123",
max_turns=16,
skills_dir=my_skills,
)
也就是:
Shopping Core
│
▼
make_options()
│
▼
ClaudeAgentOptions
│
▼
Claude Agent SDK
這裡最特別的是 MCP。
Adapter 在:
shopping-agent/runtime-agent-sdk/
└── shopping_agent_sdk/
└── shopping_tools.py
原本 Shopping Core 的:
search_products
會被轉成 Agent SDK 看到的:
mcp__storefront__search_products
但這裡通常不是另外架一台遠端 MCP Server。
而是:
Claude Agent SDK
│
▼
in-process MCP
│
▼
ShoppingToolExecutor
│
▼
StorefrontBackend
也就是 Tool 與 Agent 可以跑在同一個 Process 裡。
如果想做的是:
一個 Container
=
一個能自己工作的 Agent Worker
例如:
Research Agent
Coding Agent
Operation Agent
Background Worker
Agent SDK 會比自己管理 Messages API Loop 更省事。
可以簡單區分成:
Messages API:把 Agent 放進既有 Application。
Agent SDK:Application 本身就是一個 Agent。
第三種做法再往前一步。
這次:
連 Agent Runtime 都不一定跑在自己的 Server。
Agent Definition 在:
shopping-agent/managed-agents/
└── shopping-agent/
└── agent.yaml
原本 Python 裡面的:
Model
System Prompt
Skills
Tools
現在改成 Manifest:
agent.yaml
│
├── Model
├── Prompt
├── Skills
├── MCP Server
└── Tool Permission
這就是 Managed Agent 的 Agent Definition。
這次 MCP 真的是 Remote MCP。
agent.yaml 裡會設定:
mcp_servers:
- type: url
name: storefront
url: ${STOREFRONT_MCP_URL}
所以實際架構是:
Managed Agent
│
│ HTTPS / MCP
▼
Storefront MCP Server
│
▼
ShoppingToolExecutor
│
▼
StorefrontBackend
│
▼
Company API
例如:
search_products
→ always_allow
add_to_cart
→ always_ask
設定位置:
shopping-agent/managed-agents/
shopping-agent/agent.yaml
所以查商品可以直接執行:
search_products
但修改購物車:
add_to_cart
Runtime 可以先停下來要求確認。
如果不想自己維護:
Agent Process
Agent Loop
Session Runtime
Tool Loop
Permission Pause
只想保留:
Company MCP
Business API
Credential
UI
那 Managed Agents 就比較接近平台化方案。
| Messages API | Agent SDK | Managed Agents | |
|---|---|---|---|
| Agent Loop | 自己管理 | SDK 管 | Platform 管 |
| Agent 怎麼組 | ShoppingAgent(...) |
ClaudeAgentOptions |
agent.yaml |
| Tool 接法 | tools[] |
in-process MCP | Remote MCP |
| Session | Application 管 | Application / SDK | Platform Session |
| Backend | Application Server | Agent Process | MCP Server 後方 |
| Credential | Application 管 | Runtime Environment | Vault / MCP |
| 最適合 | 既有 Web / LINE Backend | Container Agent / Worker | Hosted Agent Platform |