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 和工具边界。