iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
AI Engineering

30天拆Agent:從Repo看設計系列 第 12 篇

Day 12|拆開 Claude Commerce Agents:一個 Agent 到底由哪些模組組成?

  • 分享至 

  • xImage
  •  

前面幾天看 Codex 時,比較常從 Agent Runtime 往內拆:Thread 怎麼保存、Turn 怎麼跑、Tool 怎麼執行、Sandbox 怎麼限制,以及 Memory 怎麼留下來。

接下來想換一個角度。

如果今天真的要開始做一個 Agent Product,例如:

用 Claude 做一個可以查商品、操作購物車,甚至讓內部人員調整價格與庫存的 Agent。

程式到底應該怎麼拆?

Anthropic 的 commerce-agents 很適合拿來看這件事。

Repo 裡主要示範兩種 Agent:

Customer
   v
Shopping Agent


Merchant Staff
   v
Merchant Agent

Shopping Agent 面向消費者,處理商品搜尋、購物車、訂單與政策。

Merchant Agent 面向內部人員,處理業績、商品、庫存、價格與 Campaign。

這個 Repo 真正值得看的是:

當 Agent 開始操作企業系統,一個 Agent Application 到底應該拆成哪些部分?

這篇先把 Repo 與 Agent Core 拆開。

下一篇再深入 Tool、Executor、Gate 與 Backend 為什麼要刻意分開。


1. 先用一張圖看懂整個 Repo

架構可以先縮成四層:

Web / LINE / Slack
        v
    Host / API
        v
      Runtime
        v
     Role Core
        v
      Backend
        v
 Business System

對應到 Repo,大致是:

commerce-agents/
|
+-- commerce-common/
|
+-- shopping-agent/
|   +-- core/
|   +-- skills/
|   +-- runtime-messages-api/
|   +-- runtime-agent-sdk/
|   +-- managed-agents/
|
+-- merchant-agent/
|   +-- core/
|   +-- skills/
|   +-- runtime-messages-api/
|   +-- runtime-agent-sdk/
|   +-- managed-agents/
|
+-- examples/

先記住三個核心概念就好:

層級 負責什麼
commerce-common Shopping、Merchant 都會使用的共用 Agent 機制
Role Core 定義這個 Agent 的 Domain 與能力
Runtime 決定 Agent Loop 怎麼執行

最外面的 Host / UI,才決定使用者從 Web、LINE 還是 Slack 進來。

換句話說:

Role Core 決定「這是什麼 Agent」,Runtime 決定「它怎麼跑」。


2. Shopping 和 Merchant:長得很像,但不是同一個 Agent

Shopping Core 裡可以看到:

backend.py
config.py
prompt.py
types.py
tools/
executor.py
gates.py
grounding.py
serialization.py
fencing.py
memory.py

Merchant Core 也幾乎有同樣的結構。

第一次看到,很容易產生一個疑問:

它們是不是其實是同一個 Agent,只是換不同 Skill?

不是。

比較接近下面這種關係:

模組 Shopping Merchant
types.py Product、Cart Listing、Change
backend.py Storefront Backend Merchant Backend
tools/ Search、Cart Metrics、Pricing
gates.py 購物車安全限制 Change、Approval
prompt.py Customer Role Operator Role

檔案負責的責任相似,但裡面的 Domain Logic 不同。

例如 Shopping 的 types.py 可能定義:

class Product(BaseModel):
    product_id: str
    title: str
    price: float
    in_stock: bool = True

Merchant 則可能是:

class Listing(BaseModel):
    listing_id: str
    title: str
    status: str
    price: float
    stock: int

兩邊都叫 types.py,但描述的是不同的 Business World。

也就是 相同的組織方式,不同的 Agent 邏輯。


3. Role Core 其實只是在回答四個問題

看到十幾個 .py,很容易覺得:

做一個 Agent 要寫這麼多 Module?

但把它們重新分組後,其實只是在回答四個問題。

問題 主要模組
Agent 認得什麼? types.py、backend.py
Claude 可以做什麼? tools/、prompt.py、skills/
Action 怎麼安全執行? executor.py、gates.py、grounding.py
哪些機制可以重用或調整? config.py、serialization.py、fencing.py、memory.py

接下來逐組看就會簡單很多。


3.1 Agent 認得什麼?-- types.py + backend.py

types.py 回答的是:

這個 Agent 的世界裡有哪些 Business Object?

Shopping 可能有:

  • Product
  • Cart
  • Order
  • Policy

Merchant 則可能有:

  • Listing
  • MetricSeries
  • InventoryAlert
  • Campaign
  • StagedChange

有了這些資料結構後,下一個問題是:

這個 Agent 可以從公司系統取得什麼?

這就是 backend.py 的工作。

例如 Shopping:

class StorefrontBackend(ABC):

    async def search_products(...):
        ...

    async def get_cart(...):
        ...

注意,這裡沒有真的去查 PostgreSQL。

因為它不是 Backend Implementation,而是 Backend Contract。

它只是在說:

Shopping Agent 要正常工作,你的系統至少要提供這些能力。

至於後面實際接的是 Shopify、SAP、PostgreSQL 或 REST API,Agent Core 不需要知道。


3.2 Claude 可以做什麼?-- tools/ + Prompt + Skill

Backend 裡存在:

search_products(...)

不代表 Claude 自動知道這個 Function。

還需要 Tool Contract 告訴 Model:

{
    "name": "search_products",
    "description": "Search the catalog...",
    "input_schema": {
        ...
    }
}

所以 Backend 和 Tool 可以用一句話區分:

回答的問題
Backend 系統真的可以做什麼?
Tool Claude 知道自己可以做什麼?

而 prompt.py、Skill 則補上行為規則。

例如:

  • 你現在扮演什麼角色?
  • 哪些原則大部分 Turn 都適用?
  • 什麼情況應該使用 Tool?
  • 哪些事情屬於 Multi-step Procedure?

因此不是所有規則都塞進 System Prompt。

不同規則會放在不同位置。


3.3 Action 怎麼執行?-- Executor + Gate + Grounding

Claude 決定呼叫:

search_products

之後,真正接手的是 executor.py。

例如:

def handlers(self):
    return {
        "search_products": self._search_products,
        "get_cart": self._get_cart,
        "add_to_cart": self._add_to_cart,
    }

Executor 的工作可以簡化成:

Model Tool Call
      v
   Executor
      v
    Backend
      v
Business System

但它不只是 Function Mapping。

中間還可能處理:

  • 輸入解析
  • Session State
  • Gate
  • Error handling
  • Serialization
  • UI Event

其中 gates.py 特別值得注意。

例如加入購物車前,可以真的用 Code 驗證:

  • 這個商品曾經被搜尋到嗎?
  • Size / Color 是否選完整?
  • 數量是否超過限制?

這和只在 Prompt 裡寫:

請不要亂填 product_id。

完全不同。

前者是 Runtime 真的會阻止 Action 執行。


Gate 和 Grounding 有什麼不同?

兩者很容易混在一起。

可以直接記:

Gate:現在能不能做?

Grounding:回答以前是不是一定要先查?

例如使用者問:

我的訂單什麼時候到?

這不一定是危險 Action,所以 Gate 未必有事。

但 Runtime 不能只靠之前聊天內容回答,而應該先取得最新的:

get_order_status

這就是 Grounding。

所以:

Gate
-> 保護 Action

Grounding
-> 保護回答依據

3.4 哪些東西可以重用?-- Adapter + Config

剩下的幾個檔案通常比較薄。

serialization.py

它負責決定:

Backend 回來的資料,哪些真的需要給 Model?

例如 Backend Object 可能還包含:

  • database_row_id
  • internal_user_key
  • fraud_score

這些資訊不一定需要暴露給 Claude。

因此 Serialization 會整理成適合 Model 使用的 Payload。


memory.py

Role-specific 的 memory.py 比較像是在定義:

這個 Role 值得留下什麼?

例如 Shopping 可能保留:

  • 尺寸偏好
  • 預算
  • 商品偏好

Merchant 可能保留:

  • 營運目標
  • 價格底線
  • 工作方式

而真正的 Memory Store、Retention 等共用機制,主要放在 commerce-common。


config.py

Config 也很容易被誤解。

它不是:

用 Config 寫出一個新的 Agent。

比較像:

調整一個已經存在的 Role。

例如:

ShoppingAgentConfig(
    enable_cart=False,
    enable_orders=False,
)

可以把既有 Capability 關掉。

適合 Config 的通常是:

  • Model
  • Memory 開關
  • Capability 開關
  • 數值限制
  • Approval 行為
  • Grounding 參數

但如果想增加:

quote_flight_change

Config 就幫不上忙。

因為這已經不是「調整 Shopping Agent」,而是 新增 Domain Capability。


4. 用 add_to_cart 一次把整個 Core 串起來

前面看了很多模組名稱。

現在直接用一個 Action 串一次。

假設使用者說:

把剛剛第二個商品加進購物車。

整條流程大致是:

User
 v
Prompt / Skill
 v
Tool Contract
 v
Executor
 v
Gate
 v
Backend
 v
Business System
 v
Serialization
 v
Model / UI

Claude 先知道自己有:

add_to_cart(product_id, quantity)

接著 Executor 接到 Tool Call:

async def _add_to_cart(...):
    return await gated_add_to_cart(...)

Gate 先確認:

  1. Product 真的曾經出現過嗎?
  2. Size / Color 是否已經選好?
  3. Quantity 是否合法?

全部通過後,才真正執行:

await backend.add_to_cart(...)

Backend 再操作真正的 Commerce System。

這也解釋了 Anthropic 為什麼沒有把所有邏輯都塞進:

def add_to_cart():
    validate()
    update_db()
    return result

因為這幾層負責的事情並不一樣。


5. 如果改成航空改票 Agent,要重寫多少?

回到一開始最實際的問題:

如果我要自己做航空改票 Agent,是不是所有 .py 都要重寫?

答案是:不用。

新的 Domain 可以先不要想檔案,而是先定義 Agent 要負責哪些能力。

例如航空改票:

查 Reservation
搜尋替代航班
查 Ticket Rule
取得改票 Estimate
Stage Change
Apply Change

確定這些事情之後,才會自然產生需要的 Module:

問題 對應模組
需要哪些資料? types.py
公司提供哪些 API? backend.py
Claude 可以呼叫什麼? tools/
Tool 怎麼執行? executor.py
哪些 Action 一定要擋? gates.py
哪些問題一定要先重新查資料? grounding.py

例如 Domain Model 可能變成:

class Reservation(BaseModel):
    reservation_id: str
    traveler_name: str


class FlightOption(BaseModel):
    flight_id: str
    departure: datetime
    arrival: datetime


class ChangeEstimate(BaseModel):
    estimate_id: str
    price_difference: float
    change_fee: float

Backend Contract 則可能是:

class FlightChangeBackend(ABC):

    async def get_reservation(...):
        ...

    async def search_flights(...):
        ...

    async def estimate_change(...):
        ...

    async def apply_change(...):
        ...

真正 Implementation 再去接:

  • Amadeus
  • Sabre
  • Reservation API
  • Pricing Engine
  • Ticketing System

而 Gate 也會換成航空業自己的規則:

  • Reservation 屬於這位旅客嗎?
  • Flight Option 真的查過嗎?
  • Estimate 過期了嗎?
  • Ticket Rule 允許嗎?
  • 使用者真的確認了嗎?

因此從 Shopping 換成航空改票 Agent,並不是:

換一個 Prompt 或 Skill。

而是需要重新定義 Domain Logic。

但底下很多 Infrastructure 不用重新發明,例如:

  • Execution framework
  • Memory infrastructure
  • Skill loading
  • Grounding framework
  • Presentation
  • Streaming
  • Fencing

這些仍然可以沿用 commerce-common 的設計。

所以比較精確的說法是:

新的 Role Agent 要重新定義 Domain Logic,但不需要重新發明整套 Agent Runtime。


6. Role Core 和 Runtime 也被刻意分開

最後還有一個 Repo 層級的重要設計。

同一套 Role Core 可以搭配三種 Runtime:

Messages API
Claude Agent SDK
Managed Agents

但這裡不要理解成:

同一個 ShoppingAgent Python Object 原封不動插到三個地方。

比較準確的是:

同一套 Role Core,有不同的 Runtime Adapter。

共同保留的是:

Role Core
+-- Config
+-- Prompt / Skills
+-- Tools
+-- Executor
+-- Gates
+-- Backend Contract

下面再接不同 Runtime:

                    Role Core
          +-----------------------+
          | Config                |
          | Prompt / Skills       |
          | Tools                 |
          | Executor              |
          | Gates                 |
          | Backend Contract      |
          +-----------------------+
               |       |       |
               v       v       v
           Messages   Agent   Managed
             API       SDK     Agents

差別主要在:

Agent Loop 由誰負責。

而 Runtime 再往外,才是 Host Application。

例如換成 LINE:

LINE
 v
Webhook / FastAPI
 v
Runtime
 v
Role Core
 v
Backend

因此這兩組概念不要混在一起:

回答的問題
Messages API / Agent SDK / Managed Agents Agent 怎麼執行?
Web / LINE / Slack 使用者從哪裡進來?

Host Application 才是兩者之間的接點。


References


上一篇
Day 11|用 Codex 做長期 Agent:Memory 要怎麼設定、調整與多人隔離?
下一篇
Day 13|Tool 怎麼接進 Agent?從 `commerce-common` 到三種 Runtime
系列文
30天拆Agent:從Repo看設計 共 13 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言