OpenClaw 的频道路由(Channel Routing)决定了每条消息如何被分配到正确的 Agent,以及回复如何原路返回到消息来源频道。理解路由机制是构建复杂多 Agent 系统的基础。
核心设计:确定性路由
OpenClaw 的路由是确定性的——不是 AI 决定回复到哪个频道,而是由配置规则精确控制:
回复总是发回消息来源的频道。模型不参与频道选择,路由由主机配置决定。
关键概念
| 术语 | 说明 |
|---|---|
| Channel | 频道标识符:telegram、whatsapp、discord、slack 等 |
| AccountId | 同一频道的多账号实例(当支持时) |
| AgentId | 独立的工作区 + 会话存储(「大脑」单元) |
| SessionKey | 存储上下文和控制并发的桶键(bucket key) |
Session Key 结构
会话键决定了对话上下文的存储和共享方式:
DM(私信)
agent:<agentId>:<mainKey>
默认:agent:main:main(所有 DM 合并到一个主会话)
群组
agent:<agentId>:<channel>:group:<id>
示例:agent:main:whatsapp:group:120363403215116621@g.us
频道/房间
agent:<agentId>:<channel>:channel:<id>
线程
- Slack/Discord:在基础 key 后追加
:thread:<threadId> - Telegram 话题:在群组 key 中嵌入
:topic:<topicId>
完整示例:
agent:main:telegram:group:-1001234567890:topic:42
agent:main:discord:channel:123456:thread:987654
agent:main:slack:channel:C123456:thread:1704067200.123456
路由优先级规则
当一条消息到达时,OpenClaw 按以下优先级选择 Agent(从高到低):
| 优先级 | 匹配条件 |
|---|---|
| 1 | 精确 Peer 匹配(peer.kind + peer.id) |
| 2 | 父级 Peer 匹配(线程继承) |
| 3 | 服务器 + 角色匹配(Discord guildId + roles) |
| 4 | 服务器匹配(Discord guildId) |
| 5 | 工作区匹配(Slack teamId) |
| 6 | 账号匹配(accountId 精确) |
| 7 | 频道匹配(任意账号,accountId: "*") |
| 8 | 默认 Agent(agents.list[].default,或第一个,或 main) |
重要:bindings 中包含多个匹配字段(peer、guildId、teamId、roles)时,所有字段都必须同时匹配才生效。
绑定配置(bindings)
基础配置
{
"agents": {
"list": [
{
"id": "support",
"name": "Support Agent",
"workspace": "~/.openclaw/workspace-support"
},
{
"id": "main",
"name": "Main Agent",
"default": true
}
]
},
"bindings": [
{
"match": { "channel": "slack", "teamId": "T123456" },
"agentId": "support"
},
{
"match": {
"channel": "telegram",
"peer": { "kind": "group", "id": "-100123456789" }
},
"agentId": "support"
}
]
}Discord 角色绑定
{
"bindings": [
{
"match": {
"channel": "discord",
"guildId": "1234567890",
"roles": ["管理员", "超级用户"]
},
"agentId": "admin-agent"
},
{
"match": {
"channel": "discord",
"guildId": "1234567890"
},
"agentId": "general-agent"
}
]
}多账号路由
{
"bindings": [
{
"match": { "channel": "telegram", "accountId": "bot1" },
"agentId": "sales"
},
{
"match": { "channel": "telegram", "accountId": "bot2" },
"agentId": "support"
}
]
}DM 路由固定(dmScope)
当 session.dmScope 为 main 时,所有 DM 共享一个主会话。为防止非主人 DM 覆盖主会话的 lastRoute(回复路径),OpenClaw 会自动推断固定主人:
触发条件(同时满足):
allowFrom中只有一个非通配符条目- 该条目可以解析为具体发送者 ID
- 当前 DM 发送者与固定主人不匹配
在这种情况下,OpenClaw 仍然记录入站会话元数据,但跳过更新主会话 lastRoute,避免回复路径被陌生人 DM 覆盖。
WebChat 行为
WebChat 附加到当前选定的 Agent,默认使用该 Agent 的主会话。这使得 WebChat 可以查看该 Agent 跨频道的完整对话历史——所有频道的上下文都汇聚在同一个视图中。
回复上下文
所有入站回复(reply)消息统一包含:
ReplyToId:被回复消息的 IDReplyToBody:被回复消息的内容ReplyToSender:被回复消息的发送者
被引用内容以 [Replying to ...] 块追加到消息正文末尾,跨所有频道行为一致。
会话存储位置
~/.openclaw/agents/<agentId>/sessions/sessions.json
JSONL 格式的对话记录与 sessions.json 并排存储。可通过 session.store 配置和 {agentId} 模板变量自定义路径:
{
"session": {
"store": "/data/openclaw/agents/{agentId}/sessions/sessions.json"
}
}原文:Channel Routing - OpenClaw | 来源:OpenClaw 官方文档