OpenClaw 路由与处理层 - 守门人与调度员

4 阅读5分钟

路由与处理层 (Routing & Processing Layer)

文档版本:2026.3.4  最后更新:2026-03-04

openclaw版本:v2026.2.25

封面

1. 层概述

职责: 对渠道层传入的消息进行安全检查、授权验证、账号解析及代理路由分发

定位: 渠道接入层与 AI 代理层之间的"守门人"与"调度员"

核心特性:

  • 6 级路由绑定(全局 → 频道 → 账号 → 角色 → 群组 → 用户)
  • 白名单(AllowFrom)安全模型
  • 配对(Pairing)一次性授权
  • DM 群组访问策略决策
  • 全链路安全审计日志

2. 主要组件

2.1 路由解析器 (Route Resolver)

路径: src/routing/resolve-route.ts

职责: 根据消息来源(渠道 + 账号)和配置文件中的绑定规则,解析出对应的目标 Agent 实例及其 Session Key。

关键类型与函数:

符号说明
resolveAgentRoute(input)核心路由解析入口,返回 ResolvedAgentRoute
ResolveAgentRouteInput路由解析输入:channelId, accountId, guildId, roleIds 等
ResolvedAgentRoute解析结果:agentId, sessionKey, bindingScope
buildEvaluatedBindingsIndex构建已求值绑定索引(带 LRU 缓存)
BindingScope绑定作用域枚举:global / channel / account / role / group / user
RoutePeerKind路由对等方类型:dm / group / guild

绑定层级(从低优先级到高优先级):

6级路由绑定层级

global  →  channel  →  account  →  role  →  groupuser

匹配越具体优先级越高;命中最高优先级绑定,路由到对应 Agent。

缓存策略:

  • resolvedRouteCacheByCfg — 按配置哈希缓存路由结果(上限 MAX_RESOLVED_ROUTE_CACHE_KEYS
  • evaluatedBindingsCacheByCfg — 缓存已求值绑定索引

2.2 账号查找 (Account Lookup)

路径: src/routing/account-lookup.ts, src/routing/account-id.ts

职责: 将平台原始账号标识(如WhatsApp JID)规范化为系统内部 accountId,并查找 AllowFrom 条目。

核心函数:

函数说明
resolveAccountEntry解析账号条目,处理遗留格式兼容
normalizeId规范化账号 ID(去除多余前缀/后缀)

2.3 安全配对系统 (Pairing System)

路径: src/pairing/

职责: 通过一次性配对码实现陌生用户的安全授权入驻,避免将凭证硬编码到配置中。

关键文件:

文件说明
pairing-store.tsAllowFrom 状态读写、配对请求管理
pairing-challenge.ts配对挑战/验证逻辑
pairing-messages.ts配对流程的用户提示消息
setup-code.ts一次性设置码生成与验证

配对流程:

配对流程示意图

用户发送 /pair <code>
      ↓
pairing-challenge 验证 code 有效性及未过期
      ↓
approveChannelPairingCode() 写入 AllowFrom 状态
      ↓
用户加入白名单,后续消息正常路由

关键常量:

  • PAIRING_CODE_LENGTH = 6 位
  • PAIRING_PENDING_TTL_MS — 请求过期时限
  • PAIRING_PENDING_MAX — 同时待确认请求上限

2.4 白名单管理 (AllowFrom / Allowlist)

路径: src/pairing/pairing-store.ts, src/security/dm-policy-shared.ts

职责: 维护每个渠道的"允许接入"账号列表(AllowFrom),决定哪些账号的消息会被处理。

数据结构:

interface AllowFromStore {
  allowFrom: AllowFromEntry[]   // 白名单条目列表
  pairingRequests: PairingRequest[]
}

interface PairingChannel {
  id: string          // 渠道 ID
  allowFrom: string[] // 允许的账号列表
}

AllowFrom 状态文件: ~/.openclaw/credentials/<channelId>/allow-from.json

关键操作:

函数说明
readChannelAllowFromStore异步读取渠道白名单
readChannelAllowFromStoreSync同步读取(启动时使用)
updateChannelAllowFromStore更新渠道白名单(带文件锁)
addChannelAllowFromStoreEntry新增白名单条目
removeChannelAllowFromStoreEntry移除白名单条目

2.5 DM 访问策略 (DM Policy)

路径: src/security/dm-policy-shared.ts

职责: 决定群组(group/guild)中的私信(DM)消息是否允许访问 AI Agent。

决策流程:

DM 访问策略决策流程

resolveDmGroupAccessDecision(params)
  ↓
resolveDmGroupAccessWithCommandGate  →  检查是否已发送过指令消息
  ↓
resolveDmGroupAccessWithLists        →  检查 AllowFrom 白名单
  ↓
DmGroupAccessDecision { allowed: boolean; reason: DmGroupAccessReasonCode }

DmGroupAccessReasonCode 枚举值(部分):

  • PINNED_MAIN_DM_OWNER — 固定主账号持有人
  • ALLOW_FROM_MATCH — 白名单命中
  • COMMAND_SENT — 已发送命令
  • NOT_ALLOWED — 未授权

2.6 安全审计 (Security Audit)

路径: src/security/audit.ts, src/security/audit-channel.ts

职责: 对所有安全相关事件(消息接入、配对、工具调用等)进行结构化审计日志记录。

关键函数:

函数说明
auditChannelAccess审计渠道消息接入事件
auditToolPolicy审计工具策略决策
auditFs审计文件系统访问

审计级别: 继承主日志系统(trace/debug/info/warn/error)


2.7 Session Key 管理

路径: src/routing/session-key.ts, src/sessions/session-key-utils.ts

职责: 为每次路由结果生成稳定、唯一的 Session Key,用于后续 Agent 会话查找与续接。

Session Key 构成:

{agentId}:{channelId}:{accountId}[:{threadId}]
  • 同一 (agent, channel, account) 三元组复用同一 Session
  • 可选 threadId 支持多线程隔离(如 Discord 线程)

3. 对外提供的接口

路由层作为内部模块,不直接暴露 HTTP/WebSocket 接口。对上层(Agent 层)提供以下编程接口:

接口说明
resolveAgentRoute(input)核心路由解析,返回 agentId + sessionKey
readChannelAllowFromStore(channelId)读取白名单状态
resolveDmGroupAccessDecision(params)DM 访问决策
approveChannelPairingCode(channelId, code)审批配对码
upsertChannelPairingRequest(channelId, req)提交配对申请

4. 与其他层的交互

4.1 上游(渠道接入层 → 路由层)

ChannelLayer 接收消息
      ↓
提取 { channelId, accountId, guildId, roleIds, text }
      ↓
调用 resolveAgentRoute() 获取目标 agentId 和 sessionKey

4.2 下游(路由层 → Agent 层)

路由层输出 { agentId, sessionKey, bindingScope }
      ↓
Agent 层使用 sessionKey 查找/建立对话上下文
      ↓
将消息派发到对应的 Pi Agent 实例

4.3 与 Gateway 控制平面的交互

  • 路由层读取 Gateway 的配置(agents[].bindings)构建绑定索引
  • 配置热重载时自动清除绑定缓存
  • 审计日志写入 Gateway 事件总线

路由层与上下游交互架构


5. 关键代码路径

src/routing/
├─ resolve-route.ts     # 核心路由解析(6级绑定 + LRU缓存)
├─ account-lookup.ts    # 账号条目查找
├─ account-id.ts        # 账号 ID 规范化
├─ session-key.ts       # Session Key 生成规则
├─ bindings.ts          # 绑定配置类型定义
└─ default-account-warnings.ts  # 默认账号配置警告

src/pairing/
├─ pairing-store.ts     # AllowFrom 状态持久化(文件锁)
├─ pairing-challenge.ts # 配对码验证逻辑
├─ pairing-messages.ts  # 用户提示文本
└─ setup-code.ts        # 一次性设置码生成

src/security/
├─ audit.ts             # 安全审计主模块
├─ audit-channel.ts     # 渠道访问审计
├─ dm-policy-shared.ts  # DM 群组访问策略决策
├─ dangerous-config-flags.ts  # 危险配置项检测
└─ external-content.ts  # 外部内容安全过滤

6. 技术实现

6.1 核心技术

  • 语言: TypeScript (ESM)
  • 文件锁: proper-lockfile — 确保并发写入安全
  • 缓存: 基于 Map 的 LRU 缓存(按配置哈希分区)
  • ID 规范化: 正则归一化各平台账号标识

6.2 设计模式

  • 策略模式: DmGroupAccessDecision 封装多条件决策逻辑
  • 缓存优先: 路由解析结果缓存,避免每条消息重新计算绑定索引
  • 不可变决策: 路由解析为纯函数,输入相同配置必定输出相同结果

6.3 安全设计

  • 默认拒绝: 未在 AllowFrom 中的账号,消息静默丢弃(不回复)
  • 过期清理: 配对请求自动按 TTL 过期,防止配对码滥用
  • 文件锁: AllowFrom 状态写入使用文件锁,防止并发写入损坏

6.4 配置示例

# openclaw.config.json5 中的绑定配置
agents:
  - id: "my-agent"
    bindings:
      - channel: "feishu"           # 渠道级绑定
      - channel: "discord"
        account: "123456789"          # 账号级绑定
      - channel: "slack"
        guild: "T0XXXXXXX"
        roles: ["admin", "member"]    # 角色级绑定