深入理解 OpenClaw 技术架构与实现原理(三):多 Agent 路由实战
编者按:本系列从源码层面深入剖析 OpenClaw 的技术架构。第一篇讲了 Gateway 架构,第二篇讲了 Agent 循环,这一篇我们进入实战:多 Agent 路由配置。
前两篇我们说了:
第一篇:Gateway 是"AI 网关",单进程接管所有聊天 第二篇:Agent 是"大脑",循环思考 + 工具调用
但有个关键问题没讲:
如果你有多个 Agent,消息怎么知道该发给谁?
👉 工作消息 → 工作 Agent 👉 家庭消息 → 家庭 Agent 👉 股票问题 → 投资 Agent 👉 编程问题 → 编码 Agent
这篇文章,我们深入:
👉 多 Agent 路由系统
一、先搞清楚:为什么需要多 Agent?
问一个问题:
👉 一个 Agent 不够用吗?
理论上,一个 Agent 可以处理所有事情
但实际使用中,你会遇到这些问题:
问题 1:人格分裂
用户 A:帮我写个严肃的工作报告用户 B:讲个笑话听听同一个 Agent 要在"严肃"和"搞笑"之间切换
👉 容易混乱
问题 2:权限冲突
工作 Agent:需要访问公司代码库家庭 Agent:只需要查天气、聊聊天放在一起,权限不好控制
👉 安全隐患
问题 3:记忆污染
工作对话:讨论项目进度家庭对话:讨论周末去哪玩混在一起,记忆会乱
👉 上下文污染
所以答案是:
👉 多个 Agent,各司其职
二、路由系统:消息怎么找到对的 Agent?
OpenClaw 的做法:
👉 绑定(Binding)系统
绑定是什么?
简单说,就是一套"如果...就..."规则:
{ "bindings": [ { // 如果是 WhatsApp 工作号的消息 "match": { "channel": "whatsapp", "accountId": "work" }, // 就发给 work 这个 Agent "agentId": "work" }, { // 如果是 WhatsApp 个人号的消息 "match": { "channel": "whatsapp", "accountId": "personal" }, // 就发给 home 这个 Agent "agentId": "home" } ]}听起来很简单?
但这里有几个关键设计点
三、路由优先级:哪条规则说了算?
先问一个问题:
如果你有 10 条绑定规则,一条消息匹配了其中 3 条
👉 听谁的?
OpenClaw 的答案:
👉 最具体者优先(Most Specific Wins)
优先级从高到低:
1. peer 匹配(精确的 DM/群组/通道 ID) ↓2. parentPeer 匹配(线程继承) ↓3. guildId + roles(Discord 角色路由) ↓4. guildId(Discord 服务器) ↓5. teamId(Slack) ↓6. accountId 匹配 ↓7. 通道级匹配(accountId: "*") ↓8. 回退到默认 Agent举个例子:
{ "bindings": [ // 规则 1:特定群组 → work Agent { "agentId": "work", "match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "120363xxx@g.us" // 具体群组 ID } } }, // 规则 2:所有 WhatsApp 工作号 → work Agent { "agentId": "work", "match": { "channel": "whatsapp", "accountId": "work" } }, // 规则 3:所有 WhatsApp 消息 → home Agent(兜底) { "agentId": "home", "match": { "channel": "whatsapp" } } ]}消息路由过程:
消息:来自 WhatsApp 工作号的某个群组匹配检查:1. 规则 1:peer 匹配? → 是这个群组 → ✅ 匹配!2. 规则 2:accountId 匹配? → 是 work → ✅ 匹配3. 规则 3:channel 匹配? → 是 WhatsApp → ✅ 匹配结果:规则 1 优先级最高(peer 匹配)→ 路由到 work Agent关键设计点:
👉 peer 匹配 > accountId 匹配 > channel 匹配
四、实战配置:从简单到复杂
场景 1:单通道,单 Agent
最简单的情况:
{ "agents": { "list": [ { "id": "main", "workspace": "~/.openclaw/workspace" } ] }, "bindings": [ { "agentId": "main", "match": { "channel": "whatsapp" } } ]}场景 2:单通道,多账户,多 Agent
一个 WhatsApp,两个号,两个 Agent:
{ "agents": { "list": [ { "id": "home", "workspace": "~/.openclaw/workspace-home" }, { "id": "work", "workspace": "~/.openclaw/workspace-work" } ] }, "bindings": [ { "agentId": "home", "match": { "channel": "whatsapp", "accountId": "personal" } }, { "agentId": "work", "match": { "channel": "whatsapp", "accountId": "biz" } } ]}场景 3:多通道,多 Agent
WhatsApp 和 Telegram,不同 Agent:
{ "agents": { "list": [ { "id": "chat", "name": "日常聊天", "workspace": "~/.openclaw/workspace-chat" }, { "id": "deep", "name": "深度工作", "workspace": "~/.openclaw/workspace-deep" } ] }, "bindings": [ { "agentId": "chat", "match": { "channel": "whatsapp" } }, { "agentId": "deep", "match": { "channel": "telegram" } } ]}场景 4:同通道,特定用户路由
大部分消息给 chat Agent,特定用户给 deep Agent:
{ "agents": { "list": [ { "id": "chat", "workspace": "~/.openclaw/workspace-chat" }, { "id": "deep", "workspace": "~/.openclaw/workspace-deep" } ] }, "bindings": [ // 特定用户 → deep Agent(优先级高) { "agentId": "deep", "match": { "channel": "whatsapp", "peer": { "kind": "direct", "id": "+8613800138000" } } }, // 其他用户 → chat Agent(兜底) { "agentId": "chat", "match": { "channel": "whatsapp" } } ]}场景 5:群组专属 Agent
家庭群、工作群、朋友群,分别路由:
{ "agents": { "list": [ { "id": "family", "name": "家庭助手" }, { "id": "work", "name": "工作助手" }, { "id": "social", "name": "社交助手" } ] }, "bindings": [ { "agentId": "family", "match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "120363family@g.us" } } }, { "agentId": "work", "match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "120363work@g.us" } } }, { "agentId": "social", "match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "120363friends@g.us" } } } ]}五、Discord 特殊场景:角色路由
Discord 有个特殊能力:
👉 按用户角色路由
配置示例:
{ "agents": { "list": [ { "id": "admin-bot", "name": "管理员助手" }, { "id": "member-bot", "name": "会员助手" } ] }, "bindings": [ // 管理员角色 → admin-bot { "agentId": "admin-bot", "match": { "channel": "discord", "guildId": "123456789", "roles": ["admin-role-id"] } }, // 普通会员 → member-bot { "agentId": "member-bot", "match": { "channel": "discord", "guildId": "123456789" } } ]}这意味着:
管理员问问题 → 获得更详细的答案 普通会员问问题 → 标准答案 完全隔离,互不干扰
六、账户管理:一个平台多个号
先登录多个账户:
# 登录 WhatsApp 个人号openclaw channels login --channel whatsapp --account personal# 登录 WhatsApp 工作号openclaw channels login --channel whatsapp --account biz# 登录 Telegram 个人号openclaw channels login --channel telegram --account personal# 登录 Telegram 工作号openclaw channels login --channel telegram --account work配置示例:
{ "channels": { "whatsapp": { "accounts": { "personal": { // 个人号配置 }, "biz": { // 工作号配置 } } }, "telegram": { "accounts": { "personal": { botToken: "123456:ABC..." }, "work": { botToken: "987654:XYZ..." } } } }}关键点:
每个账户有独立的认证凭据 每个账户可以绑定不同的 Agent 完全隔离,互不干扰
七、默认 Agent:兜底规则
如果一条消息没匹配任何绑定怎么办?
答案:
👉 回退到默认 Agent
设置默认 Agent:
{ "agents": { "list": [ { "id": "main", "default": true, // ← 标记为默认 "workspace": "~/.openclaw/workspace" }, { "id": "special", "workspace": "~/.openclaw/workspace-special" } ] }}或者:
👉 如果没有显式标记,第一个 Agent 就是默认
八、哈巴狗模式:实战案例
这就是一个典型的多 Agent 协作系统
哈巴狗的工作方式:
1. 用户发消息 → 哈巴狗主代理(Binding 路由)2. 哈巴狗分析任务类型3. 动态 spawn 子代理执行(sessions_spawn)4. 子代理返回结果5. 哈巴狗汇总 → 回复用户子代理类型:
这其实是:
👉 两层路由系统
第一层:消息 → 主代理(Binding 路由,静态配置) 第二层:主代理 → 子代理(动态分派,运行时决定)
关键区别:
Binding 路由 = 配置驱动
在 openclaw.json 中配置 消息进来时自动匹配 静态、预定义
动态分派 = 逻辑驱动
主代理分析任务后决定 使用 sessions_spawn 工具 动态、按需创建
九、路由性能:有没有瓶颈?
先问一个问题:
👉 路由判断会不会很慢?
答案:
👉 不会,因为设计很简单
路由过程:
消息进来 ↓遍历 bindings 数组 ↓检查 match 条件 ↓找到第一个匹配 → 返回 agentId ↓没找到 → 返回默认 Agent时间复杂度:
👉 O(n),n 是 bindings 数量
实际使用中:
一般配置 5-10 条 bindings 每条检查是简单的字段比较 总耗时 < 1ms
所以:
👉 路由不是瓶颈
真正的瓶颈在:
模型 API 调用 工具执行 网络延迟
十、常见问题与陷阱
10.1 规则顺序错了
错误示例:
{ "bindings": [ // 规则 1:所有 WhatsApp → home Agent { "agentId": "home", "match": { "channel": "whatsapp" } }, // 规则 2:特定群组 → work Agent(永远不会生效!) { "agentId": "work", "match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "xxx@g.us" } } } ]}问题:
👉 规则 1 已经匹配了所有 WhatsApp 消息
👉 规则 2 永远不会被检查
正确做法:
{ "bindings": [ // 具体规则放前面 { "agentId": "work", "match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "xxx@g.us" } } }, // 通用规则放后面 { "agentId": "home", "match": { "channel": "whatsapp" } } ]}10.2 忘记配置默认 Agent
问题:
如果消息没匹配任何绑定,又没默认 Agent
👉 消息会丢失
解决:
{ "agents": { "list": [ { "id": "main", "default": true // ← 一定要设 } ] }}10.3 账户 ID 搞混
问题:
{ "bindings": [ { "agentId": "work", "match": { "channel": "whatsapp", "accountId": "personal" // ← 写错了! } } ]}解决:
先列出所有账户:
openclaw channels status确认 accountId 后再配置
十一、调试技巧
11.1 查看当前路由配置
openclaw agents list --bindings输出:
Agent: home - Binding: whatsapp → personalAgent: work - Binding: whatsapp → biz - Binding: whatsapp → group:120363xxx@g.us11.2 测试路由(示意)
⚠️ 注:以下为示意命令,实际可使用日志观察路由结果
# 查看 Gateway 日志,观察路由决策openclaw gateway logs --grep "routing"输出示例:
[ROUTING] Matched binding #2 → agent: home[ROUTING] Channel: whatsapp, Account: personal → agent: home11.3 查看日志
# 实时查看 Gateway 日志openclaw gateway logs --follow# 过滤路由相关日志openclaw gateway logs --grep "routing"十二、架构总结:一张图看懂
┌─────────────────────────────────────────────────────────┐│ Incoming Message ││ (WhatsApp/Telegram/...) │└────────────────────────┬────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────┐│ Binding Router ││ ││ ┌──────────────────────────────────────────────────┐ ││ │ 1. peer match (highest priority) │ ││ │ 2. parentPeer match │ ││ │ 3. guildId + roles │ ││ │ 4. guildId │ ││ │ 5. teamId │ ││ │ 6. accountId match │ ││ │ 7. channel match │ ││ │ 8. default agent (fallback) │ ││ └──────────────────────────────────────────────────┘ │└────────────────────────┬────────────────────────────────┘ │ ▼┌─────────────────────────────────────────────────────────┐│ Target Agent ││ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ││ │ home │ │ work │ │ special │ ││ └─────────────┘ └─────────────┘ └─────────────┘ │└─────────────────────────────────────────────────────────┘十三、关键设计哲学
13.1 显式优于隐式
👉 所有路由规则都要明明白白写出来
不靠猜测,不靠魔法 配置即文档
13.2 具体优先
👉 最具体的规则优先级最高
peer > accountId > channel
这是最符合直觉的设计
13.3 兜底必须存在
👉 永远要有默认 Agent
防止消息丢失 防止配置错误导致服务中断
13.4 隔离是默认
👉 每个 Agent 完全隔离
不同的 workspace 不同的记忆 不同的工具权限
十四、但问题也很明显
14.1 配置复杂度
Agent 越多,配置越复杂
10 个 Agent → 可能 20+ 条 bindings
👉 容易出错
14.2 调试成本
路由错了,消息就丢了
排查需要:
检查配置 查看日志 模拟测试
👉 耗时
14.3 动态路由不支持
目前路由规则是静态配置
不支持:
基于消息内容路由 基于时间路由 基于用户行为学习
👉 未来可能的改进方向
十五、总结
这一篇我们深入了多 Agent 路由系统:
核心思想就一个:
👉 路由是"声明式"的,不是"编程式"的
你只需要告诉系统:
什么消息 → 哪个 Agent
不需要写代码 不需要搞逻辑
配置即文档 文档即配置
十六、下一篇预告
《深入理解 OpenClaw 技术架构与实现原理(四):记忆系统与技能架构》
我们将深入探讨:
短期记忆 vs 长期记忆的设计哲学 记忆压缩算法 技能系统的扩展机制 ClawHub 技能生态
参考资料:
OpenClaw 官方文档:https://docs.openclaw.ai[1] 多 Agent 路由:https://docs.openclaw.ai/concepts/multi-agent[2] 绑定配置:https://docs.openclaw.ai/gateway/configuration[3] 会话管理:https://docs.openclaw.ai/concepts/session[4]
本文基于 OpenClaw v2026.3.8 版本编写
(完)
引用链接
[1]https://docs.openclaw.ai
[2]https://docs.openclaw.ai/concepts/multi-agent
[3]https://docs.openclaw.ai/gateway/configuration
[4]https://docs.openclaw.ai/concepts/session
夜雨聆风