来源:互联网 更新时间:2026-06-09 07:13
上节课我们梳理了通道的概念——OpenClaw 能够接收来自不同平台的消息,统一封装成 InboundMessage 格式,再交给 run_agent_turn 去调用 Agent。今天聊路由。简单说,路由就是给消息找个对口的 Agent:不同来源、不同层级的消息,该由谁响应?有了路由表,这件事就清晰了。
核心单位叫
tier 从小到大的顺序依次检查——越具体的规则越优先。
@dataclass
class Binding:
agent_id: str
tier: int # 1-5, 越小越具体
match_key: str # "peer_id" | "guild_id" | "account_id" | "channel" | "default"
match_value: str # 例如 "telegram:12345", "discord", "*"
priority: int = 0 # 同层内, 越大越优先
参数含义很直观:agent_id 目标 Agent 的唯一 ID;tier 表示匹配层级,从 1 到 5,数值越小越优先;match_key 指定按什么字段匹配(peer_id、channel、default、guild_id、account_id);match_value 是具体匹配值;priority 在同层内决定谁的优先级更高。
举个例子,看下面这组绑定:
bt = BindingTable()
bt.add(Binding(agent_id="luna", tier=5, match_key="default", match_value="*"))
bt.add(Binding(agent_id="sage", tier=4, match_key="channel", match_value="telegram"))
bt.add(Binding(agent_id="sage", tier=1, match_key="peer_id",
match_value="discord:admin-001", priority=10))
它们的匹配逻辑是这样的:
luna 被设为 tier=5 的默认兜底——如果前 1~4 层都没有命中,那就由 luna 响应。sage 的 tier=4 规则匹配 channel 为 telegram——只要消息来自 Telegram,且没有更具体的 1~3 层规则,就由 sage 处理。sage 还有一条 tier=1 规则,专门匹配用户 ID 为 discord:admin-001 的消息——这是最具体的层级,一旦命中,直接使用 sage。解析的过程就是按 tier 从小到大遍历 BindingTable,第一个匹配的就是最终结果。具体实现如下:
def resolve(self, channel: str = "", account_id: str = "",
guild_id: str = "", peer_id: str = "") -> tuple[str | None, Binding | None]:
"""遍历第1-5层, 第一个匹配的获胜。返回 (agent_id, matched_binding)。"""
for b in self._bindings:
if b.tier == 1 and b.match_key == "peer_id":
if ":" in b.match_value:
if b.match_value == f"{channel}:{peer_id}":
return b.agent_id, b
elif b.match_value == peer_id:
return b.agent_id, b
elif b.tier == 2 and b.match_key == "guild_id" and b.match_value == guild_id:
return b.agent_id, b
elif b.tier == 3 and b.match_key == "account_id" and b.match_value == account_id:
return b.agent_id, b
elif b.tier == 4 and b.match_key == "channel" and b.match_value == channel:
return b.agent_id, b
elif b.tier == 5 and b.match_key == "default":
return b.agent_id, b
return None, None
可以看到,tier 1 是 peer 级匹配(最具体),tier 2 是 guild 级,tier 3 是 account 级,tier 4 是 channel 级,tier 5 是默认兜底。整个流程像漏斗一样,从最精确到最泛化。
通过 dm_scope 参数,就能控制私聊会话的隔离粒度。说白了,就是决定不同用户、不同通道的聊天历史是否共享——粒度越细,越能实现“互不干扰”。
底层逻辑是:根据 dm_scope 构建不同的 session key,生成对应的 session.json 文件,序列化后发给 LLM。
# ---------------------------------------------------------------------------
# 会话键构建
# ---------------------------------------------------------------------------
# dm_scope 控制私聊隔离粒度:
# main -> agent:{id}:main
# per-peer -> agent:{id}:direct:{peer}
# per-channel-peer -> agent:{id}:{ch}:direct:{peer}
# per-account-channel-peer -> agent:{id}:{ch}:{acc}:direct:{peer}
def build_session_key(agent_id: str, channel: str = "", account_id: str = "",
peer_id: str = "", dm_scope: str = "per-peer") -> str:
aid = normalize_agent_id(agent_id)
ch = (channel or "unknown").strip().lower()
acc = (account_id or "default").strip().lower()
pid = (peer_id or "").strip().lower()
if dm_scope == "per-account-channel-peer" and pid:
return f"agent:{aid}:{ch}:{acc}:direct:{pid}"
if dm_scope == "per-channel-peer" and pid:
return f"agent:{aid}:{ch}:direct:{pid}"
if dm_scope == "per-peer" and pid:
return f"agent:{aid}:direct:{pid}"
return f"agent:{aid}:main"
从代码可以直观看到:main 是所有用户共享一个对话;per-peer 是按私聊对象隔离;per-channel-peer 则把通道也纳入区分;per-account-channel-peer 粒度最细,连账号都考虑进去了。
下面这张流程图梳理了整个消息处理链路。入口有两个:CLI 和 WebSocket 客户端。消息进来后,如果指定了 force_agent,就直接用那个 Agent 响应该消息;否则进入路由表解析——通过 BindingTable 找到匹配的 Agent,再用 build_session_key 生成会话键,决定不同用户/通道的消息是否共享同一段历史记录。

以上就是路由的核心逻辑。配合上节课的通道概念,你已经能理解 OpenClaw 如何根据消息来源灵活调度不同的 Agent 了——既支持细粒度的私聊隔离,也能用默认 Agent 兜底,整个设计相当精炼。
下饭影视APP下载安装指南
和平精英如何做到压枪稳-和平精英怎样才能压枪稳
《Off Campus》第二季官宣:这对CP还在,但不再是主角
下载浏览器app下载安装选择推荐
免费影视剧APP推荐
儿子穿新中式现身大会堂 马斯克罕见用中文回应:他正在学习普通话
Elysium Above 履云录官网在哪下载 最新官方下载安装地址
抖音最火沙雕男生网名(精选100个)
网络热词聊污是什么意思
名单曝光!库克、马斯克等将随团到访中国 黄仁勋不在其中
短剧《情绪超市》剧情介绍
短视频软件推荐
免费看电影的软件推荐
SpaceX狂揽AI人才,马斯克亲自面试且不看简历背景
KuCoin基本面分析
金铲铲之战s17六暗星卡莎阵容玩法构筑指南
苹果macOS 27将优化界面设计并测试AI驱动的Safari标签页自动分组功能
网石18禁MMO《RAVEN2:渡鸦》大型更新推出全新职业“军阀”
HBO 奇幻剧《龙之家族》第三季定档 6 月 22 日,最终预告片曝光喉道海战
洛克王国世界S2赛季狂欢怪谈介绍
手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc