AI 程式設計教程中文版
從原理到實戰

07 · 多 Agent:什麼時候拆、怎麼協作

解釋 OpenClaw 多 Agent 的真實邊界:獨立 workspace、agentDir、sessions、bindings、sub-agents 和 delegate 場景。

上一章講單個 Agent 的 workspace。本篇擴充套件到多個 Agent。

先給結論:

OpenClaw 的多 Agent 不是“多個聊天名字”,而是在一個 Gateway 中執行多個隔離的 per-persona scope:每個 Agent 可以有自己的 workspace、agentDir、session store、模型、工具策略和渠道繫結。

拆分 Agent 之前,先問一句:你需要隔離什麼?如果答不上來,就先不要拆。

1. 官方語境裡,一個 Agent 是什麼

官方 Multi-Agent Routing 文件把 Agent 定義成 full per-persona scope。

一個 Agent 包含三層範圍:Workspace 放 AGENTS.mdSOUL.mdUSER.md、local notes、persona rules;State directory 也就是 agentDir,儲存 auth profiles、model registry、per-agent config;Session store 位於 ~/.openclaw/agents/<agentId>/sessions,儲存 chat history 和 routing state。

flowchart TD
  A[Gateway] --> B[agent: main]
  A --> C[agent: coding]
  A --> D[agent: support]

  B --> B1[workspace-main]
  B --> B2[agentDir main]
  B --> B3[sessions main]

  C --> C1[workspace-coding]
  C --> C2[agentDir coding]
  C --> C3[sessions coding]

  D --> D1[workspace-support]
  D --> D2[agentDir support]
  D --> D3[sessions support]

預設什麼都不配時,OpenClaw 只有一個 agent:

  • agentId 預設是 main
  • sessions keyed as agent:main:<mainKey>
  • workspace 預設 ~/.openclaw/workspace
  • state 預設 ~/.openclaw/agents/main/agent

多 Agent 是在這個基礎上增加多個 agents.list[] 條目和 bindings。

2. 什麼時候應該拆 Agent

不要為了架構好看而拆。OpenClaw 多 Agent 的核心價值是隔離和路由,不是裝飾。

可以用這五個訊號判斷:

  • Persona 不同:一個偏工程,一個偏客服,一個偏家庭助手,聲音和邊界不同。
  • Workspace/Memory 需要隔離:技術 notes、個人偏好、客戶資料不能混在一個 workspace。
  • Channel/account identity 不同:不同 WhatsApp 號、Telegram bot、Discord bot 需要繫結不同 Agent。
  • Model/tool/sandbox 策略不同:一個 Agent 可寫檔案跑命令,另一個只能讀和發訊息。
  • 組織授權邊界不同:delegate 需要自己的身份、憑據和顯式組織許可權。

不建議拆的情況:

  • 只是想把任務分類得更“專業”。
  • 所有 Agent 用同一個 workspace、同一個模型、同一套工具許可權。
  • 只是為了讓聊天入口變多。
  • 還沒有穩定的 routing 規則。

拆 Agent 會增加配置、除錯和許可權審計成本。只有隔離收益大於複雜度時才值得。

多 Agent 的理由不是“看起來專業”,而是 workspace、記憶、憑據、模型、工具或渠道邊界真的需要隔離。

3. 新建 Agent 的實際路徑

官方提供 agent wizard:

openclaw agents add work

常見流程:

  1. 建立 Agent workspace。
  2. 建立或配置 channel account。
  3. agents.list 加 agent 定義。
  4. bindings 加入 inbound routing。
  5. 重啟 Gateway 並驗證。

驗證命令:

openclaw gateway restart
openclaw agents list --bindings
openclaw channels status --probe

一個最小概念配置:

{
  "agents": {
    "list": [
      {
        "id": "chat",
        "name": "Everyday",
        "workspace": "~/.openclaw/workspace-chat",
        "model": "anthropic/claude-sonnet-4-6"
      },
      {
        "id": "deep",
        "name": "Deep Work",
        "workspace": "~/.openclaw/workspace-deep",
        "model": "anthropic/claude-opus-4-6"
      }
    ]
  },
  "bindings": [
    { "agentId": "chat", "match": { "channel": "whatsapp" } },
    { "agentId": "deep", "match": { "channel": "telegram" } }
  ]
}

這裡不是讓模型判斷訊息歸誰,而是 host configuration 決定路由。

4. Bindings 是確定性路由

官方 Channel Routing 文件說:The model does not choose a channel; routing is deterministic and controlled by the host configuration。

Inbound message 只會 pick one agent,規則從具體到寬泛:

優先順序匹配方式
1Exact peer match,peer.kind + peer.id
2Parent peer match,thread inheritance
3Discord guildId + roles
4Discord guildId
5Slack teamId
6Channel accountId
7Channel match,任意賬號時可用 accountId: "*"
8Default agent,agents.list[].default,否則 first list entry,最後 fallback main

如果一個 binding 寫了多個 match fields,例如 peer + guildId,所有欄位都必須匹配。

flowchart TD
  A[Inbound message] --> B{Exact peer?}
  B -- Yes --> R[Matched agent]
  B -- No --> C{Thread parent?}
  C -- Yes --> R
  C -- No --> D{Guild roles?}
  D -- Yes --> R
  D -- No --> E{Account?}
  E -- Yes --> R
  E -- No --> F{Channel fallback?}
  F -- Yes --> R
  F -- No --> G[Default agent]

確定性路由的好處是可預測、可審計。錯了就改 binding,不需要猜模型為什麼把訊息分錯。

Routing 是配置問題,不是模型判斷問題。訊息進錯 Agent 時,先查 bindings,不要先調 prompt。

5. Session key 也跟 Agent 繫結

Channel Routing 文件給出的 session key 形態:

場景Session key
DM 預設摺疊到 main sessionagent:<agentId>:<mainKey>
Groupagent:<agentId>:<channel>:group:<id>
Channel/roomagent:<agentId>:<channel>:channel:<id>
Slack/Discord threadbase key 後追加 :thread:threadId
Telegram forum topicgroup key 內包含 :topic:topicId

例子:

agent:main:telegram:group:-1001234567890:topic:42
agent:main:discord:channel:123456:thread:987654

這解釋了兩個現象:

  • 同一頻道不同 group/channel/thread 可以隔離上下文。
  • 同一使用者發給不同 Agent,會進入不同 Agent 的 session store。

WebChat 會 attach 到選中的 Agent,並預設使用該 Agent 的 main session,所以它能從一個地方看這個 Agent 的跨渠道 context。

6. 多賬號和單賬號多人的邊界

Channels 支援 accountId 時,一個 Gateway 可以託管多個賬號。

例子:兩個 WhatsApp 號可以讓每個 accountId 繫結一個 Agent;兩個 Telegram bot 可以讓每個 bot account 繫結一個 Agent;一個 WhatsApp 號給多個人時,用 peer.kind: "direct" 加 E.164 sender 路由不同 DM。

需要注意:一個 WhatsApp 號拆給多人時,回覆仍然來自同一個號碼,不會產生 per-agent sender identity。真正強身份隔離,最好是不同 channel account 或不同 delegate identity。

7. Broadcast group 是例外:同一 peer 跑多個 Agent

通常 inbound routing picks one agent。

但 Broadcast groups 可以讓同一個 peer 同時跑多個 Agent,前提是 OpenClaw 本來就會回覆,比如 WhatsApp group 經過 mention/activation gating 後。

概念配置:

{
  "broadcast": {
    "strategy": "parallel",
    "[email protected]": ["alfred", "logger"]
  }
}

這不是預設路由。它適合需要並行記錄、監督或多人格響應的特殊場景。普通業務先用單 agent binding。

8. 每個 Agent 可以有自己的模型和工具邊界

多 Agent 的實際價值之一,是把模型和許可權按職責拆開。

例如:

  • personal:host 上執行,工具許可權較寬。
  • family/support:sandbox mode: "all",只允許 read/message,拒絕 write/edit/browser/cron。
  • coding:coding profile + browser/exec/process。
  • archive:低成本模型 + 只讀工具。

官方示例裡,每個 agent 可設定自己的 sandboxtools.allow / tools.deny。注意兩個細節:

  • Tool allow/deny list 是 tools,不是 skills。
  • 如果 skill 需要執行 binary,仍要確保 exec 允許且 binary 在 sandbox 裡存在。

tools.elevated 是 global and sender-based,不是 per-agent 配置。需要 per-agent 邊界時,用 agents.list[].tools deny exec 或限制工具集。

9. Auth profiles 和 agentDir 不要混用

每個 Agent 都有自己的 agentDir

~/.openclaw/agents/<agentId>/agent

Auth profiles 位於:

~/.openclaw/agents/<agentId>/agent/auth-profiles.json

硬規則:

  • 不要在多個 Agent 之間複用同一個 agentDir,會導致 auth/session collisions。
  • 如果需要獨立 OAuth 賬號,應從該 Agent 登入。
  • 如果手工複製憑據,只複製可攜帶的靜態 api_keytoken profiles。
  • 對 sub-agent 來說,auth 按 agent id 解析;主 Agent profiles 可能作為 fallback,Agent profiles 衝突時覆蓋 main profiles。

所以不要把多 Agent auth 理解成天然互不影響。更準確的是:狀態目錄按 Agent 分開,但 fallback 和手工複製策略要按官方規則審計。

10. Cross-agent memory search 要顯式配置

預設隔離不代表永遠不能共享。

如果一個 Agent 需要搜尋另一個 Agent 的 QMD session transcripts,可以配置 agents.list[].memorySearch.qmd.extraCollections。只有所有 Agent 都該繼承同一組共享 transcript collections 時,才放到 agents.defaults.memorySearch.qmd.extraCollections

原則:

  • 預設隔離。
  • 明確共享。
  • 路徑、collection name 和適用 Agent 都寫清楚。

跨 Agent 召回要謹慎,因為它會打破原本的記憶邊界。

跨 Agent memory search 是顯式打破隔離邊界。配置前要說明誰能搜誰、為什麼搜、搜到什麼算合規。

11. Sub-agents 不是多 Agent 路由

多 Agent routing 是多個長期 persona 並存。

Sub-agents 是從一次現有 Agent run 派生出的 background agent runs。

官方 Sub-agents 文件定義:

  • sub-agent 執行在自己的 session:agent:<agentId>:subagent:<uuid>
  • 完成後 announce result 回 requester chat channel。
  • 每個 sub-agent run 是 background task。
  • 主要目標是並行 research、long task、slow tool work,不阻塞 main run。
  • 預設隔離,session 分離,可選 sandbox。
  • sub-agent 預設不拿 session tools,減少誤用面。
flowchart TD
  A[Main agent run] --> B[sessions_spawn]
  B --> C[Sub-agent session]
  C --> D[Work in background]
  D --> E[Announce result]
  E --> F[Requester chat channel]

使用場景:

需求用 Multi-agent routing用 Sub-agent
長期不同人格和 workspace
不同渠道固定路由
臨時並行研究
慢工具任務不阻塞主 run
可持續 thread-bound 子會話一般不用可用 thread: true + mode: "session"

Sub-agent 有自己的 context 和 token usage。重任務可以配置更便宜的 subagent model,讓 main agent 保持高質量模型。

12. Sub-agent 的 context 模式

官方當前區分兩種 context:isolated 適合新研究、獨立實現、慢工具任務、能用 task text 說清楚的工作,會建立乾淨 child transcript,也是預設模式;fork 適合依賴當前 conversation、歷史工具結果或細微上下文的任務,會把 requester transcript 分支到 child session。

fork 不應該成為偷懶替代品。能寫清楚 task,就用 isolated。

13. Delegate 是組織場景

Delegate architecture 把個人助手模式擴充套件到組織部署。

官方定義的 delegate:

  • 有自己的 identity,例如 email、display name、calendar。
  • acts on behalf of one or more humans,但 never impersonates a human。
  • 使用組織 identity provider 授予的 explicit permissions。
  • 遵守 AGENTS.md 裡的 standing orders。

它解決兩個問題:Accountability 上,訊息清楚來自 delegate,不冒充人;Scope control 上,identity provider 控制能訪問什麼,獨立於 OpenClaw tool policy。

組織場景裡,正確順序是:

  1. 先建立 isolated delegate agent。
  2. 先 harden:tool restrictions、sandbox、hard blocks、audit trail。
  3. 再授予身份提供商許可權。
  4. 從最低 capability tier 開始,逐步升級。

不要先給憑據再補安全邊界。

14. 常見誤解

常見誤解可以按這組邊界校正:

  • 多 Agent 不是多個名字。每個 Agent 是 workspace + agentDir + sessions 的完整 scope。
  • 路由不應該讓 AI 判斷。OpenClaw routing 是 deterministic binding。
  • peer binding 和 channel binding 不是簡單看配置順序。先按優先順序層級,peer 更具體;同層再看 config order。
  • 多 Agent 成本不是固定乘以 N。成本取決於實際 runs、context、工具呼叫和模型。
  • Sub-agent 不是第二個長期 Agent。Sub-agent 是 background run,不是長期 persona routing。
  • agentDir 不能複用。複用會導致 auth/session collisions。
  • Delegate 不能冒充人。Delegate 有自己身份,只能 on behalf of,不 impersonate。

15. 給 Agent 的實踐任務

把下面任務交給你的 OpenClaw Agent:

请审查当前多 Agent 配置:
1. 读取 agents.list,列出每个 agentId、workspace、agentDir、model、sandbox、tools.allow/deny。
2. 读取 bindings,按 routing 优先级解释每类 inbound message 会进入哪个 Agent。
3. 检查是否有多个 Agent 复用 agentDir 或 workspace。
4. 检查是否有 peer-specific binding 被 channel-wide binding 遮蔽。
5. 检查 subagents.allowAgents、subagent model、maxConcurrent、runTimeoutSeconds 是否符合用途。
6. 给出哪些 Agent 应该合并、哪些应该拆开的理由。

重點看它是否按隔離邊界分析,而不是隻給“可以最佳化配置”的泛泛建議。

16. 本章自檢

讀完這一篇,你應該能回答:

  1. OpenClaw 裡的一個 Agent 包含哪些 scope?
  2. 為什麼不要複用 agentDir
  3. Bindings 的路由優先順序是什麼?
  4. agentIdaccountIdbindingsessionKey 分別是什麼?
  5. Broadcast group 和普通 routing 有什麼區別?
  6. Multi-agent routing 和 sub-agent spawn 有什麼區別?
  7. Delegate 為什麼不能 impersonate human?

能回答這些問題,再進入時間維度,就能理解為什麼 session、heartbeat、cron、sub-agent completion 都是在“同一個 Gateway 多個執行單元”上疊加出來的。

17. 接下來去哪

18. 官方資料

本頁目錄