OpenClaw 多 Agent 协同的技术原理:从消息路由到任务委派
深入解析 OpenClaw 如何实现多个 AI Agent 的协同工作,包括消息路由、Session 隔离、子任务委派和跨 Agent 通信机制。
为什么需要多 Agent?
单个 AI Agent 的能力边界是有限的。当你需要:
- 不同的 Agent 负责不同的专业领域(编码助手 vs 日程管家)
- 多人共用一个 Gateway,但各自有独立的 Agent
- 让 Agent 把复杂任务拆解后委派给子 Agent 并行处理
这时候,多 Agent 架构就变得必要了。
OpenClaw 的多 Agent 架构
┌─────────────────────────────────────────────────────────┐
│ Gateway │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Channel │ │ Channel │ │ Channel │ │ Channel │ │
│ │Telegram │ │ Feishu │ │ Discord │ │ IRC │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ └────────────┴─────┬──────┴────────────┘ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Router │ ← Mappings 配置 │
│ └──────┬──────┘ │
│ │ │
│ ┌──────────────────┼──────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Agent A │ │ Agent B │ │ Agent C │ │
│ │ (主助手) │ │ (专家) │ │ (Coder) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────┘
核心组件:
- Gateway:唯一的消息枢纽,管理所有 Channel 连接
- Router:根据
mappings配置决定消息发给哪个 Agent - Agent:独立的 AI 实体,有自己的人格、记忆和工具权限
消息路由:Mappings 机制
当一条消息从 Telegram 进入 Gateway,Router 需要决定把它交给哪个 Agent。这通过 mappings 配置实现:
{
"mappings": [
{
"agentId": "assistant",
"match": {
"channel": "telegram",
"accountId": "my_assistant_bot"
}
},
{
"agentId": "coder",
"match": {
"channel": "telegram",
"accountId": "my_coder_bot"
}
}
]
}
路由逻辑:
- 消息进入 Gateway,携带
channel(telegram)和accountId(bot 的账号标识) - Router 遍历
mappings,找到第一个匹配的规则 - 将消息路由到对应的 Agent
这意味着:路由规则非常灵活。你可以让一个 Bot 的私聊消息路由到 Agent A,群组消息路由到 Agent B;也可以让多个 Bot 都路由到同一个 Agent。关键在于 match 条件的设计。
Session 隔离:每个对话独立
Agent 处理消息时,需要维护对话的上下文。OpenClaw 使用 Session 来实现这一点:
Session Key = agent:{agentId}:{sessionType}:{identifier}
示例:
- agent:assistant:main # 主助手 的主 Session
- agent:assistant:telegram:group:-100123 # 主助手 在某个群组的 Session
- agent:coder:subagent:task-abc # Coder 的一个子任务 Session
关键设计:
- 每个 Agent 有独立的 Session 池,互不干扰
- 群组和私聊分开,避免上下文混淆
- 子任务使用 isolated Session,不污染主对话
子 Agent 委派:sessions_spawn
当一个任务太复杂,主 Agent 可以 spawn 一个子 Agent 来处理:
// 主 Agent 调用
sessions_spawn({
task: "分析这个 PR 的代码变更,找出潜在问题",
mode: "run",
sessionTarget: "isolated",
model: "claude-sonnet-4",
timeoutSeconds: 300
})
mode 参数取值:
| 值 | 说明 | 使用场景 |
|---|---|---|
run | 一次性任务,执行完即销毁 | 代码分析、数据处理、一次性查询 |
session | 持久会话,保持对话历史 | 需要多轮交互的复杂任务、长期运行的助手 |
sessionTarget 参数取值:
| 值 | 说明 | 使用场景 |
|---|---|---|
isolated | 独立上下文,与主 Session 完全隔离 | 子任务处理、避免污染主对话、并行执行 |
main | 复用主 Session(仅限 default agent) | 需要访问主对话上下文的场景 |
组合示例:
// 场景1:一次性代码审查(最常用)
sessions_spawn({ mode: "run", sessionTarget: "isolated" })
// 场景2:持久的编码助手(保持上下文)
sessions_spawn({ mode: "session", sessionTarget: "isolated", thread: true })
// 场景3:需要主对话上下文的任务
sessions_spawn({ mode: "run", sessionTarget: "main" }) // 仅 default agent
执行流程:
- Gateway 创建一个 isolated Session(独立上下文)
- 子 Agent 在隔离环境中执行任务
- 完成后,结果通过
subagent_announce返回给主 Agent - 主 Agent 可以选择将结果转发给用户
这种模式的优势:
- 并行处理:多个子任务可以同时执行
- 隔离失败:子任务崩溃不影响主 Session
- 资源控制:可以给子任务设置不同的 model 和 timeout
跨 Agent 通信:sessions_send
有时候,Agent A 需要主动给 Agent B 发消息(而不是委派任务):
// Agent A 给 Agent B 发消息
sessions_send({
sessionKey: "agent:agentB:main",
message: "用户刚才问了关于日程的问题,你来回答一下"
})
这适用于:
- 专业领域转发:用户问了编码问题,日程 Agent 转发给 Coder Agent
- 协作场景:多个 Agent 配合完成一个复杂任务
- 通知机制:一个 Agent 完成任务后通知另一个 Agent
实战案例:PR Review 流水线
假设我们要实现一个自动化 PR Review 系统:
用户: "帮我 review 一下这个 PR"
│
▼
┌─────────┐
│ 主助手 │ ← 主 Agent,接收用户请求
│ (协调者) │
└────┬────┘
│ spawn 3 个子任务
├────────────────────────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 代码分析 │ │ 安全扫描 │ │ 性能评估 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└───────────────┴──────────────────┘
│
▼
汇总结果,回复用户
代码流程:
// 1. 并行 spawn 三个子任务
const [codeReview, securityScan, perfCheck] = await Promise.all([
sessions_spawn({ task: "分析代码质量", mode: "run" }),
sessions_spawn({ task: "扫描安全漏洞", mode: "run" }),
sessions_spawn({ task: "评估性能影响", mode: "run" })
]);
// 2. 汇总结果
const summary = synthesize(codeReview, securityScan, perfCheck);
// 3. 回复用户
reply(summary);
注意事项
1. Session 上下文大小
每个 Session 都有 token 限制。如果对话历史太长,需要:
- 使用
/clear清空历史 - 开启
compaction自动压缩 - 将长任务拆分到子 Session
2. 子任务的模型选择
不是所有任务都需要最强的模型:
sessions_spawn({
task: "简单的格式检查",
model: "claude-haiku", // 便宜快速
})
sessions_spawn({
task: "复杂的架构分析",
model: "claude-opus", // 深度推理
})
3. 避免循环调用
Agent A spawn Agent B,Agent B 又 spawn Agent A —— 这会导致无限循环。设计时要明确各 Agent 的职责边界。
总结
OpenClaw 的多 Agent 架构核心是:
| 组件 | 职责 |
|---|---|
| Mappings | 消息路由,决定谁处理 |
| Session | 上下文隔离,各司其职 |
| sessions_spawn | 任务委派,并行执行 |
| sessions_send | 跨 Agent 通信 |
这套机制让你可以:
- 运行多个专业化的 Agent
- 将复杂任务拆解并行处理
- 在 Agent 之间建立协作流程
📚 延伸阅读:
- OpenClaw 官方文档:docs.openclaw.ai
- GitHub 仓库:github.com/openclaw/op…
我是赛博养成日志,专注 AI Agent 使用实践。关注我,一起探索 AI 时代的新玩法。