多渠道多 Agent 系统如何设计消息路由,OpenClaw 的匹配优先级是什么?
未标记
考查重点:身份绑定与路由优先级。把渠道、账号、用户或群组映射到目标 Agent,说明多条规则同时命中时如何决策,并结合 OpenClaw 的规则顺序展开
本题目录
参考答案
OpenClawTypeScript
核心回答
多渠道多 Agent 系统需要分开解决三件事:谁处理、使用哪段会话、回复发到哪里。渠道适配器先提供渠道、接入账号、聊天对象、组织和线程等身份信息;路由层按确定的优先级选 Agent;会话层生成上下文标识;投递层保留回复的渠道、账号、目标和线程。入口身份应来自可信的渠道上下文,不能让模型生成的参数决定用户身份。
OpenClaw 使用 TypeScript 和 Node.js 构建 Gateway,连接消息渠道与 Agent 执行层。普通入站路由由配置规则决定,选出一个 Agent,再确定其工作区和会话。它的匹配顺序是:精确聊天对象 → 父聊天对象 → 聊天对象通配 → Guild 与角色 → Guild → Team → 账号 → 渠道 → 可确定的兜底 Agent。同一级按配置顺序选第一个满足条件的规则。
这类规则路由与按问题内容选择专家可以同时存在:渠道绑定先确定负责这段对话的 Agent,选中的 Agent 内部再决定是否委派任务。普通渠道路由本身不要求模型判断,也不意味着把消息广播给所有 Agent。
实际匹配优先级
解析前先规范化渠道名和 accountId,只取当前渠道、当前账号及账号通配规则作为候选。这里的账号是接入平台的机器人或账号实例,发送消息的人则属于聊天对象身份,两者不能混用。
当前共享路由解析器按以下顺序检查:
- 精确聊天对象:匹配
peer.kind与peer.id,例如指定某个私聊用户、群或频道。 - 父聊天对象:当前对象未命中时,使用渠道提供的
parentPeer查找绑定,让线程可以继承父频道的 Agent。 - 聊天对象通配:匹配指定对象类型的
peer.id: "*",例如该账号下所有私聊。 - Guild 与角色:匹配
guildId,并要求发送者的角色 ID 与配置的roles至少有一个相同,常用于Discord。 - Guild:匹配所在服务器的
guildId。 - Team:匹配
teamId,例如Slack工作区。 - 账号:当前渠道下的具体
accountId绑定。 - 渠道:该渠道中
accountId: "*"的绑定,覆盖任意账号。 - 兜底 Agent:使用调用方明确给出的所属 Agent,或配置中可以唯一确定的所属 Agent;多 Agent 场景无法确定时,需要补绑定或指定 Agent,不会任取名册第一项。
优先级先于配置顺序,配置顺序解决同级冲突。 一个精确对象规则即使排在账号规则后面,也仍先检查;两个同级规则都能命中时,则由先出现的规则获胜,而不是按字段数量临时计算“更具体”。
复合条件仍然全部有效。绑定同时写了 peer、guildId、teamId 或 roles,不能只满足其中一个就命中;父对象继承阶段也继续检查组织与角色条件。角色匹配使用平台提供的角色 ID,不是看到消息里提到某个角色就转发。
还有一个容易配错的地方:省略 accountId 表示默认账号,显式写 "*" 才覆盖任意账号。入站账号和配置账号使用同一套归一化规则,例如 " WORK " 会按 work 参与匹配。
Session key 决定上下文范围
选定 Agent 后,还要确定消息进入哪段历史。SessionKey 用于持久化上下文和控制会话并发,不能简单固定为“渠道加用户”。OpenClaw 的私聊作用域由 session.dmScope 或命中绑定中的覆盖配置决定:
main:默认值,进入该 Agent 的主会话,形如agent:<agentId>:main。per-peer:按聊天对象区分,可跨渠道共享同一对象的会话。per-channel-peer:按渠道与聊天对象区分。per-account-channel-peer:进一步包含接入账号,适合同一渠道存在多个账号的情况。
session.identityLinks 可以把已配置的跨渠道身份映射为统一对象标识,在非 main 的私聊模式中参与生成会话标识。是否最终合并,还取决于所选作用域是否继续包含渠道与账号;它不是自动识别人,也不是授权机制。
群或频道默认使用 per-group 范围,线程或话题由渠道继续补充标识;配置也可以将选定群组并入主会话。因此私聊默认并不按用户隔离,多人接入时需要明确选择合适的范围。会话划分解决上下文共享问题,入口授权和工具执行权限还要分别控制。
路由目标与回复投递目标分开
agentId 和 SessionKey 决定在哪里执行、读写哪段上下文;回复的 channel、accountId、to 和 threadId 决定发给谁。同一个主会话可能承接多个渠道的输入,但本轮回复仍应使用对应来源的投递坐标,不能从共享主会话推导出唯一收件人。
OpenClaw 会结合当前 OriginatingChannel、OriginatingTo、账号和线程解析回复路由;内部事件或符合条件的 sessions_send 交接可以继承已保存的外部投递信息。普通交互不能任意借用旧的外部目标,当前显式路线与已保存路线不同,也不应继承旧房间的描述信息。选中 Agent、获得执行准入、生成回复和确认投递,是不同阶段。
用冲突场景验证路由
例如在同一个 Discord 账号 work 下,分别配置:频道 C17 交给 reviewer,服务器 G1 交给 support,整个账号兜底交给 general。
G1中来自C17的消息命中精确对象,交给reviewer。C17的子线程没有自己的绑定时,渠道提供父对象信息,可继承reviewer;线程自身有精确绑定时,精确绑定优先。G1的其他频道交给support,其他服务器中未命中的消息再落到账号规则。- 另一账号的消息不能误用仅属于
work的规则;两条同级规则重叠时,应检查配置顺序。
还应覆盖跨账号相同聊天对象、角色不符、私聊作用域切换,以及当前回复来源与历史投递路线不同的情况。检查路由结果中的 matchedBy、agentId 和 SessionKey,再单独核对投递坐标,可以区分“选错 Agent”和“回复发错地方”。
对应教程
- 《LangGraph 多智能体与 A2A》:回看路由、主管调度和控制权交接的区别;这里进一步展开渠道身份绑定、会话作用域和回复投递。
参考资料
- 国内:zero2Agent:OpenClaw 的应用层与运行时分工:参考其对网关、消息渠道、会话和 Agent 执行层的区分,建立多渠道路由的整体职责。
- 国内:zero2Agent:Agent Loop 与事件桥接:借鉴执行事件由上层渠道消费的分工,说明选定 Agent 执行与把结果返回渠道应分别处理。
- 国内:zero2Agent:多 Agent 与多渠道路由:参考统一渠道入口与会话路由的组织方式,具体匹配顺序及私聊默认范围以本文所引实现为依据。
- 国内:JavaGuide:多 Agent 协作系统设计:参考规则路由、动态委派和交接的区别,说明渠道先选择负责对话的 Agent,内部仍可继续分工。
- 国外:OpenClaw:Channel routing:依据普通消息的九级匹配顺序、复合条件与账号规则,解释冲突决策和执行路由、回复路线的区别。
- 国外:OpenClaw:Session management:依据私聊作用域和跨渠道身份关联的语义,解释默认共享主会话与可配置会话划分。
- 国外:OpenClaw:路由实现、候选规则索引、会话标识与回复目标解析:对应优先级、同级配置顺序、会话作用域与条件式投递继承的具体实现。