跳转至

通道与路由

OpenClaw 将回复路由回消息来源的通道。模型不会选择通道;路由是确定性的,并由主机配置控制。在默认 DM 作用域下,来自每个通道的直接消息都会汇聚到代理的主会话。

关键术语

  • 通道:通道插件,例如 discord、googlechat、imessage、irc、line、signal、slack、telegram 或 whatsapp。webchat 是内部 WebChat UI 通道,不是可配置的外发通道。
  • AccountId:每个通道的账户实例(如果支持)。
  • 可选的通道默认账户:channels.<channel>.defaultAccount 选择当外发路径未指定 accountId 时使用哪个账户。
  • 在多账户设置中,当配置了两个或更多账户时,请设置显式默认值(defaultAccount 或名为 default 的账户)。否则,回退路由可能会选择第一个规范化账户 ID。
  • AgentId:隔离的工作区 + 会话存储(“大脑”)。
  • SessionKey:用于存储上下文并控制并发性的桶键。

外发目标前缀

显式外发目标可以包含提供商前缀,例如 telegram:123 或 tg:123。核心仅在所选通道为 last 或无法解析时,并且仅当已加载的插件声明了该前缀时,才将该前缀视为通道选择提示。如果调用方已经选择了显式通道,则提供商前缀必须与该通道匹配;跨通道组合(例如将 WhatsApp 投递到 telegram:123)会在插件特定的目标规范化之前失败。

目标类型和服务前缀,例如 channel:<id>、user:<id>、room:<id>、thread:<id>、imessage:<handle> 和 sms:<number>,保留在所选通道的语法内部。它们本身不会选择提供商。

报告失败、抑制或演练的插件发送回执不会更改对话中存储的路由和投递转录。已确认的部分发送可以建立路由,但请求的内容不会被镜像为已完全投递。

会话键形状(示例)

直接消息默认会折叠到代理的主会话:

  • agent:<agentId>:main(例如:agent:main:main)

session.dmScope 控制 DM 折叠:main(默认)共享一个主会话,而 per-peer、per-channel-peer 和 per-account-channel-peer 将 DM 保留在独立会话中。路由绑定可以通过 bindings[].session.dmScope 为其匹配的对端覆盖作用域。

即使直接消息对话历史与主会话共享,沙箱和工具策略也会为外部 DM 使用派生的每账户直接聊天运行时键,以便通道来源的消息不被视为本地主会话运行。

在默认 session.groupScope: "per-group" 下,群组和通道按通道保持隔离:

  • 群组:agent:<agentId>:<channel>:group:<id>
  • 通道/房间:agent:<agentId>:<channel>:channel:<id>

设置 session.groupScope: "main" 可将所有非直接对端路由到代理的主会话,或对选定房间使用 bindings[].session.groupScope。绑定覆盖优先于全局值。这只会更改共享上下文;提及门控和回复仍使用来源群组或通道。

线程:

  • Slack/Discord 线程会在基础键后追加 :thread:<threadId>。
  • Telegram 论坛主题会在群组键中嵌入 :topic:<topicId>。

示例:

  • agent:main:telegram:group:-1001234567890:topic:42
  • agent:main:discord:channel:123456:thread:987654

主 DM 路由固定

当 session.dmScope 为 main 时,直接消息可能共享一个主会话。为防止会话的 lastRoute 被非所有者 DM 覆盖,当以下所有条件都为真时,OpenClaw 会从 allowFrom 推断一个固定的所有者:

  • allowFrom 恰好有一个非通配符条目。
  • 该条目可以规范化为该通道的具体发送者 ID。
  • 入站 DM 发送者不匹配该固定所有者。

在这种不匹配情况下,OpenClaw 仍会记录入站会话元数据,但会跳过更新主会话 lastRoute。

受保护的入站记录

通道插件可以将入站会话记录标记为 createIfMissing: false,当受保护路径不得创建新的 OpenClaw 会话时。在该模式下,OpenClaw 可以更新现有会话的元数据和 lastRoute,但不会仅因为观察到一条消息就创建仅路由的会话条目。

路由规则(如何选择一个代理)

普通路由为每条入站消息选择一个代理:

  1. 精确对端匹配(带有 peer.kind + peer.id 的 bindings)。
  2. 父对端匹配(线程继承)。
  3. 对端通配符匹配(对某种对端类型使用 peer.id: "*")。
  4. 公会 + 角色匹配(Discord),通过 guildId + roles。
  5. 公会匹配(Discord),通过 guildId。
  6. 团队匹配(Slack),通过 teamId。
  7. 账户匹配(通道上的 accountId)。
  8. 通道匹配(该通道上的任何账户,accountId: "*")。
  9. 回退所有者:由调用方提供的所有者,否则是唯一的已配置代理或保留的遗留所有者。多个代理且没有所有者时需要匹配的绑定;路由不会选择第一个名单位。

原始遗留默认标记以及没有代理名册的原始配置中的 main 回退仍受支持以保持兼容。

当绑定包含多个匹配字段(peer、guildId、teamId、roles)时,所有提供的字段都必须匹配,该绑定才会生效。

匹配的代理决定使用哪个工作区和会话存储。

广播组(运行多个代理)

代理组线程使用顶层 broadcast 配置,为一条被接受的入站消息运行多个代理。带限定的 "<channel>:<peerId>" 键优先于未带限定的 WhatsApp 对端键。普通路由仍提供对话路由;协调器为该通道、账户、对端和线程中的每个参与者提供其自己的代理会话。

{
  broadcast: {
    strategy: "parallel",
    "telegram:-100123": {
      agents: ["reviewer", "writer"],
      maxRounds: 2,
      maxTurns: 4,
    },
    "slack:C0123": ["support", "reviewer"],
    "120363403215116621@g.us": ["alfred", "baerbel"],
  },
}

合格条目默认采用显式提及选择、一轮,以及每个已配置智能体一个回合。maxTurns 限制的是所有轮次中启动的参与者运行次数,而不是平台上的实际消息数。旧版 WhatsApp 数组仍保留向所有列出智能体的单遍扇出。

频道允许列表仍然适用。在 Discord、Slack 和 Telegram 中,显式提及任何合格参与者即可满足房间的提及门控。已配置的 ACP 绑定仍保持独占,并绕过群线程扇出。

有关选择、延续资格、预算和参与者标签,请参阅广播组。控制界面尚未提供专用的团队线程会话。

配置概览

  • agents.entries:命名智能体定义(工作区、模型等)。
  • bindings:将入站频道/账户/对端映射到智能体。

示例:

{
  agents: {
    entries: {
      support: {
        default: true,
        name: "Support",
        workspace: "~/.openclaw/workspace-support",
      },
    },
  },
  bindings: [
    { match: { channel: "slack", teamId: "T123" }, agentId: "support" },
    {
      match: { channel: "slack", peer: { kind: "channel", id: "C0123TEAM" } },
      agentId: "support",
      session: { groupScope: "main" },
    },
  ],
}

会话存储

运行时会话行和转录内容位于状态目录(默认 ~/.openclaw)下每个智能体的 SQLite 数据库中:

  • ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite

旧版安装可能在 ~/.openclaw/agents/<agentId>/sessions/ 下具有旧版转录 JSONL 文件和 sessions.json 行存储。要将该历史记录导入 SQLite,请停止 Gateway,备份其状态,并在重启前运行 openclaw doctor --fix。Gateway 启动时不会导入旧版会话文件:如果发现旧版存储,它会拒绝就绪并打印当前活动配置的 Doctor 命令。使用 openclaw doctor --session-sqlite inspect --session-sqlite-all-agents 以及 Doctor 迁移序列进行检查 和验证。

session.store 支持 {agentId} 模板。运行时,旧版存储路径会选择其对应的 SQLite 数据库;JSON 文件本身只是迁移输入或显式的离线维护目标。

Gateway 会话发现可以包括默认 agents/ 根目录下的磁盘存储,以及使用 agents/<agentId>/sessions/sessions.json 布局的模板化 session.store 根目录。它会识别对应的 agent/openclaw-agent.sqlite 数据库,而不要求存在旧版 sessions.json 文件。发现的存储文件必须是已解析智能体根目录内的常规文件;符号链接存储文件和根目录外的路径将被忽略。

ACP 会话发现会读取 SQLite ACP 元数据,并将其与对应的会话条目关联。

WebChat 行为

WebChat 会附加到所选智能体,并默认使用该智能体的主会话。因此,WebChat 让你可以在一个地方查看该智能体的跨频道上下文。

回复上下文

入站回复包括:

  • 在可用时,包括 ReplyToId、ReplyToBody 和 ReplyToSender。
  • 引用上下文会作为 [Replying to ...] 块追加到 Body。

这在所有频道中保持一致。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw