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.md、SOUL.md、USER.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常見流程:
- 建立 Agent workspace。
- 建立或配置 channel account。
- 在
agents.list加 agent 定義。 - 在
bindings加入 inbound routing。 - 重啟 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,規則從具體到寬泛:
| 優先順序 | 匹配方式 |
|---|---|
| 1 | Exact peer match,peer.kind + peer.id |
| 2 | Parent peer match,thread inheritance |
| 3 | Discord guildId + roles |
| 4 | Discord guildId |
| 5 | Slack teamId |
| 6 | Channel accountId |
| 7 | Channel match,任意賬號時可用 accountId: "*" |
| 8 | Default 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 session | agent:<agentId>:<mainKey> |
| Group | agent:<agentId>:<channel>:group:<id> |
| Channel/room | agent:<agentId>:<channel>:channel:<id> |
| Slack/Discord thread | base key 後追加 :thread:threadId |
| Telegram forum topic | group 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:sandboxmode: "all",只允許 read/message,拒絕 write/edit/browser/cron。coding:coding profile + browser/exec/process。archive:低成本模型 + 只讀工具。
官方示例裡,每個 agent 可設定自己的 sandbox 和 tools.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>/agentAuth profiles 位於:
~/.openclaw/agents/<agentId>/agent/auth-profiles.json硬規則:
- 不要在多個 Agent 之間複用同一個
agentDir,會導致 auth/session collisions。 - 如果需要獨立 OAuth 賬號,應從該 Agent 登入。
- 如果手工複製憑據,只複製可攜帶的靜態
api_key或tokenprofiles。 - 對 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。
組織場景裡,正確順序是:
- 先建立 isolated delegate agent。
- 先 harden:tool restrictions、sandbox、hard blocks、audit trail。
- 再授予身份提供商許可權。
- 從最低 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. 本章自檢
讀完這一篇,你應該能回答:
- OpenClaw 裡的一個 Agent 包含哪些 scope?
- 為什麼不要複用
agentDir? - Bindings 的路由優先順序是什麼?
agentId、accountId、binding、sessionKey分別是什麼?- Broadcast group 和普通 routing 有什麼區別?
- Multi-agent routing 和 sub-agent spawn 有什麼區別?
- Delegate 為什麼不能 impersonate human?
能回答這些問題,再進入時間維度,就能理解為什麼 session、heartbeat、cron、sub-agent completion 都是在“同一個 Gateway 多個執行單元”上疊加出來的。
17. 接下來去哪
08 · Session 與 Heartbeat
繼續看 session、heartbeat、cron 和 hook 如何給 Agent 接入時間維度。
06 · Workspace
回到單個 Agent 的 workspace 邊界,對照多 Agent 為什麼要拆 scope。
官方教程:Agents
對照官方 Agents 頁繼續核對 agentId、workspace、agentDir 和工具邊界。