5.2 会话路由源码分析

生成模型:Claude Opus 4.6 (anthropic/claude-opus-4-6) Token 消耗:输入 ~250,000 tokens,输出 ~18,000 tokens(本章合计)


当一条消息从通道到达 Gateway 时,系统需要回答两个问题:交给哪个 Agent?放入哪个会话? 这就是会话路由的核心职责。本节将逐文件分析路由系统的源码实现。

5.2.1 路由绑定(Bindings)

路由绑定(Binding)是用户在配置文件中定义的规则,用于将特定的通道/账户/对等方映射到特定的 Agent。src/routing/bindings.ts 提供了绑定查询的基础设施。

// src/routing/bindings.ts
import type { OpenClawConfig } from "../config/config.js";
import type { AgentBinding } from "../config/types.agents.js";

export function listBindings(cfg: OpenClawConfig): AgentBinding[] {
  return Array.isArray(cfg.bindings) ? cfg.bindings : [];
}

一个典型的绑定配置如下:

// config.json5
{
  "bindings": [
    {
      "agentId": "work-assistant",
      "match": {
        "channel": "slack",
        "accountId": "company-workspace"
      }
    },
    {
      "agentId": "personal",
      "match": {
        "channel": "telegram",
        "peer": { "kind": "dm", "id": "12345" }
      }
    }
  ]
}

这表示:来自 Slack 公司工作区的消息交给 work-assistant Agent,来自 Telegram 用户 12345 的私聊交给 personal Agent。

listBoundAccountIds() 函数提取某个通道下所有被绑定的账户 ID:

buildChannelAccountBindings() 构建一个嵌套的 Map<channel, Map<agentId, accountId[]>> 结构,方便后续快速查找:

5.2.2 路由解析(Resolve Route)

src/routing/resolve-route.ts 是路由系统的核心——resolveAgentRoute() 函数接收消息的来源信息,返回应该使用的 Agent ID 和会话键。

输入与输出类型

matchedBy 字段记录了路由匹配的原因,这对调试非常有价值。

匹配优先级

resolveAgentRoute() 按照从具体到宽泛的优先级尝试匹配:

衍生解释:这种从具体到宽泛的匹配优先级在路由系统中非常常见。类似于 nginx 的 location 匹配规则——精确匹配 > 前缀匹配 > 正则匹配 > 默认。OpenClaw 的路由也遵循同样的原则:peer 绑定 > guild 绑定 > account 绑定 > channel 绑定 > 默认。

5.2.3 会话键生成

路由解析的最终产物是会话键。buildAgentSessionKey() 函数根据路由结果生成适当的会话键:

线程会话键

对于 Slack 线程、Discord 帖子等场景,resolveThreadSessionKeys() 在基础会话键后追加 :thread:<threadId>

5.2.4 键映射规则

让我们用具体示例总结不同消息类型产生的会话键:

直接消息(DM)

群组消息

群组消息不受 dmScope 影响,始终包含通道和群组 ID:

Cron 会话

定时任务使用特殊的键格式:

线程会话

线程在基础键上追加线程标识:


本节小结

会话路由是 OpenClaw 消息处理流水线中的关键一环:

  1. 绑定系统:通过配置文件将通道/账户/对等方映射到特定的 Agent

  2. 优先级匹配:从具体(peer)到宽泛(default)的 7 级匹配优先级

  3. 灵活的键生成:根据 dmScopeidentityLinks 和消息类型生成唯一的会话键

  4. 线程继承:线程消息继承父消息的路由绑定,保证同一线程的所有消息路由到同一个 Agent

路由系统的设计使得 OpenClaw 能够在一个 Gateway 实例中同时服务多个 Agent、多个通道、多种消息类型,而每条消息都能被准确地路由到正确的位置。

Last updated