多智能体路由
在一个 Gateway 进程中运行多个_隔离的_agent,每个 agent 都有自己的工作区、状态目录(agentDir)和基于 SQLite 的会话历史,以及多个渠道账户(例如两个 WhatsApp 号码)。入站消息通过绑定路由到正确的 agent。
agent 是完整的按人设划分的作用域:工作区文件、认证配置文件、模型注册表和会话存储。绑定将渠道账户(Slack 工作区、WhatsApp 号码等)映射到其中一个 agent。
如需包含账户和对话示例的聚焦配置指南,请参阅 Agent 绑定。
什么是单个 agent¶
每个 agent 都有自己的:
- 工作区:文件、
AGENTS.md/SOUL.md/USER.md、本地笔记、人设规则。 - 状态目录(
agentDir):认证配置文件、模型注册表、每个 agent 的配置。 - 会话存储:
<agentDir>/openclaw-agent.sqlite中的聊天历史和路由状态。
认证配置文件是每个 agent 独立的,从 <agentDir>/openclaw-agent.sqlite 读取。使用默认布局时,解析为:
Note
sessions_history 是更安全的跨会话回忆路径:它返回有界、脱敏的视图,而不是原始转录转储。它会剥离思考块签名、工具结果负载细节、<relevant-memories> 脚手架、工具调用 XML 标签(<tool_call>、<function_call> 及其复数/降级形式)以及 MiniMax 工具调用 XML,然后按字节大小截断并限制输出。
Warning
切勿跨 agent 复用 agentDir——这会导致认证/会话状态冲突。当次要 agent 的本地 OAuth 凭据过期或其刷新失败时,OpenClaw 会读取到默认/主 agent 对同一 profile id 的凭据,并采用其中时间最新的令牌,而不会将刷新令牌复制到次要 agent 的存储中。如果你想要完全独立的 OAuth 账户,请从该 agent 登录。如果手动复制凭据,只复制可移植的静态 api_key 或 token 配置文件——OAuth 刷新材料默认不可移植(copyToAgents 可以显式将某个 profile 纳入复制范围)。
技能从每个 agent 的工作区以及诸如 ~/.openclaw/skills 之类的共享根目录加载,然后按生效的 agent 技能允许列表进行过滤。使用 agents.defaults.skills 作为共享基线,使用 agents.entries.*.skills 进行每个 agent 的替换(显式条目替换默认值,而不是合并)。请参阅 技能:每个 agent 与共享 和 技能:agent 允许列表。
插件自有存储遵循该插件的配置;添加第二个 agent 不会自动拆分每个全局插件存储。例如,当人设不得共享整合后的 wiki 知识时,请配置 每个 agent 的 Memory Wiki 存储库。
Note
工作区说明: 每个 agent 的工作区是默认 cwd,而不是硬性沙箱。相对路径在工作区内解析,但绝对路径可以到达主机的其他位置,除非启用了沙箱。请参阅 沙箱。
路径¶
| 项目 | 默认值 | 覆盖 |
|---|---|---|
| 配置 | ~/.openclaw/openclaw.json |
OPENCLAW_CONFIG_PATH |
| 状态目录 | ~/.openclaw |
OPENCLAW_STATE_DIR |
| 默认 agent 的工作区 | <stateDir>/workspace(命名 profile 为 ~/.openclaw-<profile>/workspace) |
agents.entries.*.workspace,然后是 agents.defaults.workspace,或 OPENCLAW_WORKSPACE_DIR |
| 其他 agent 的工作区 | <stateDir>/workspace-<agentId>(设置时为 <agents.defaults.workspace>/<agentId>) |
agents.entries.*.workspace |
| Agent 目录 | ~/.openclaw/agents/<agentId>/agent |
agents.entries.*.agentDir |
| 会话和转录 | <agentDir>/openclaw-agent.sqlite |
agents.entries.*.agentDir |
| 旧版/归档会话产物 | ~/.openclaw/agents/<agentId>/sessions |
— |
单 agent 模式(默认)¶
如果你没有配置任何内容,OpenClaw 会运行一个 agent:
agentId默认为main。- 主会话键为
agent:main:main。 - 工作区默认为
<stateDir>/workspace(默认安装为~/.openclaw/workspace,命名 profile 为~/.openclaw-<profile>/workspace)。 - 状态默认为
~/.openclaw/agents/main/agent。
Agent 辅助工具¶
添加一个新的隔离 agent:
标志:--role <role>、--workspace <dir>、--model <id>、--agent-dir <dir>、--bind <channel[:accountId]>(可重复)、--non-interactive(除非提供了 role,否则需要 --workspace)。
添加 bindings 以路由入站消息(向导会提议为你完成此操作),然后验证:
在 Control UI 中,位于 /agents 的 Agents 页面显示 Agent 列表、当前工作状态和最近的聊天预览,Open chat 可打开每个 agent 的主会话。使用 Manage agents 在 /settings/agents 配置 Agent 列表。
设置 → Agents 会在 Gateway 发布新目录时更新模型选项。刷新选项会保留您已选择的模型、回退选项和身份草稿。如果读取失败,编辑器会显示错误并保留之前的选项,直到后续更新成功。模型和回退选项的编辑保持正常的自动保存行为。
代理溯源¶
OpenClaw 记录每个已配置代理的创建方式:CLI、引导流程和 Gateway 请求使用 operator;系统代理请求时使用 agent;Claw 安装添加时使用 claw。代理创建的条目还会保留请求代理的 id。已配置的代理可以通过其 openclaw 工具请求 OpenClaw 创建另一个代理。系统代理记录输入的操作,向操作员显示请求代理的 id,并且仅在操作员批准后创建代理。使用以下命令查看当前的创建层级:
已删除的创建者仍作为历史溯源保留。如果创建者不再位于已配置的名册中,其子代理将出现在树的根节点。
团队预设¶
通过书面角色契约和定向委派创建一个小型团队:
openclaw agents team create --non-interactive
openclaw agent --agent coordinator --message "Research the options and draft a recommendation."
该预设会创建一名幕僚长(coordinator)、研究员、撰稿人和审核人,每个角色都有独立的工作区和完整的身份。幕僚长仍是人类的主要联系人:它发现匹配的专家、分配有边界的工作、检查他们的产出,并报告一致的结果。专家将产出和证据返回给协调员,不再进一步委派。他们的操作程序位于 AGENTS.md 中,因此也适用于未加载 SOUL.md 或 IDENTITY.md 的派生会话。
内置角色是 Claw 源,共享可移植的 CLAW.md 身份格式、SOUL.md 正文和声明的工作区文件。agents add --role <role> 加载其中一个源。启用实验性 Claws 界面后,源码检出中对应的源路径为 openclaw claws add docs/reference/templates/roles/<role>;请遵循 Claw 预览与同意流程。
您还可以从 Control UI 创建幕僚长或完整团队:在侧边栏或 Agents 主页选择 新建代理,然后在管理员聊天中选择角色或小团队推荐。创建过程使用相同的角色模板,并等待您的批准。
相关的代理级委派配置片段如下:
```json5 validate=false { agents: { entries: { coordinator: { subagents: { allowAgents: ["researcher", "writer", "reviewer"], delegationMode: "prefer", }, }, researcher: { subagents: { allowAgents: [] } }, writer: { subagents: { allowAgents: [] } }, reviewer: { subagents: { allowAgents: [] } }, }, }, }
`"prefer"` 引导协调员委派合适的工作;这是提示词引导,而非调度器。`allowAgents` 控制显式的派生目标。该预设保持 `agents.defaults.subagents` 和 `tools.*` 不变,因此现有的工具可用性和访问策略仍然适用。角色指令要求在进行外部发送、发布、购买、删除或生产变更之前获得人工批准。这些委派设置仍作为配置中的团队连接保留。一旦独立的 Claw 配置文件支持落地,角色 Claws 将携带这些设置。
协调员是一个显式目标。团队创建仅在 `agents.defaults.systemAgent.agentId` 未设置时才将其设置为协调员;现有所有者会被保留并报告。在显式代理组中,这也指定了支持默认代理选择的操作的默认值。显式目标和[路由绑定](agent-bindings.md)优先。
使用 `--prefix <p>` 为所有团队 id 添加命名空间,使用 `--coordinator <id>` 重命名协调员,使用 `--workspace-root <dir>` 为独立工作区选择父目录。创建前会检查所有 id 的冲突。有关标志和示例,请参阅 [`agents team create`](../cli/agents.md#agents-team-create),或在[引导流程](../start/wizard.md#choose-one-agent-or-a-team)中使用团队选项。
## 快速开始 {#quick-start}
**1. 创建每个代理的工作区**
```bash
openclaw agents add coding
openclaw agents add social
每个代理都有自己的工作区,包含 SOUL.md、AGENTS.md 和可选的 USER.md,以及专用的 agentDir 和会话存储。默认情况下,这些代理文件位于 ~/.openclaw/agents/<agentId> 下。
2. 创建频道账户
在您偏好的频道上为每个代理创建一个账户:
- Discord:每个代理一个机器人,启用 Message Content Intent,复制每个令牌。
- Telegram:通过 BotFather 为每个代理创建一个机器人,复制每个令牌。
- WhatsApp:每个账户关联一个手机号码。
查看频道指南:Discord、Telegram、WhatsApp。
3. 添加代理、账户和绑定
在 agents.entries 下添加代理,在 channels.<channel>.accounts 下添加频道账户,并使用 bindings 将它们连接起来(示例见下文)。
4. 重启并验证
多代理、多角色¶
每个已配置的 agentId 都是核心代理状态的独立角色边界:
- 每个频道使用不同的账户(按
accountId)。 - 不同的个性(每个代理的
AGENTS.md/SOUL.md)。 - 独立的认证和会话,跨代理会话访问默认开启,由
tools.agentToAgent管理。使用tools.sessions.visibility收窄会话可见性,使用tools.agentToAgent.allow限制代理对,或设置tools.agentToAgent.enabled: false以阻止普通的跨代理访问。请求者拥有的原生子代理和 ACP 子会话在tree或all可见性下仍可访问;如需严格隔离,请使用独立的网关。
这允许多个人共享同一个 Gateway,同时保持核心代理状态相互隔离。
每个代理的 Memory Wiki 库¶
Memory Wiki 默认使用一个全局库。若要将支持代理的编译知识与营销代理的编译知识分开,请将
plugins.entries.memory-wiki.config.vault.scope 设置为 agent:
{
plugins: {
entries: {
"memory-wiki": {
enabled: true,
config: {
vault: {
scope: "agent",
path: "~/.openclaw/wiki",
},
},
},
},
},
}
配置的路径是父目录。OpenClaw 会追加规范化后的代理 id,生成诸如 ~/.openclaw/wiki/support 和
~/.openclaw/wiki/marketing 的路径。当配置了多个代理时,代理范围的 CLI 和 Gateway 操作需要
显式指定代理。有关桥接过滤、迁移和信任边界详情,请参阅
Memory Wiki 每个代理的库。
跨代理记忆搜索¶
QMD 跨代理搜索路径已在 v2026.8.1 中随 QMD 后端其余部分一起移除。内置记忆不会搜索
其他代理的转录语料库;每个代理只搜索其自身配置的记忆以及符合条件的同代理会话来源。当同一
参考资料需要被多个代理索引时,请将有意共享的
Markdown 放入显式共享的 memory.search.extraPaths 目录。有关完整
升级路径,请参阅 从 QMD 迁移。
一个 WhatsApp 号码,多个人(DM 拆分)¶
通过匹配发送者 E.164(+15551234567)和 peer.kind: "direct",可以将不同的 WhatsApp DM 路由到 一个 WhatsApp 账户上的不同代理。回复仍然来自同一个 WhatsApp 号码——没有按代理区分的发送者身份。
Note
直接聊天默认会折叠到代理的主会话键,因此真正的隔离需要每个人对应一个代理。
{
agents: {
entries: {
alex: { default: true, workspace: "~/.openclaw/workspace-alex" },
mia: { workspace: "~/.openclaw/workspace-mia" },
},
},
bindings: [
{
agentId: "alex",
match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551230001" } },
},
{
agentId: "mia",
match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551230002" } },
},
],
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551230001", "+15551230002"],
},
},
}
DM 访问控制(配对/允许列表)按 WhatsApp 账户全局生效,而不是按代理生效。对于共享群组,请将群组绑定到一个代理,或使用 广播群组。
路由规则¶
绑定是确定性的,并且最具体的规则获胜。有关完整的层级顺序(精确 peer、父级 peer、peer 通配符、guild+roles、guild、team、account、channel、默认代理),请参阅 频道路由。这里值得强调几条规则:
- 如果同一层级中有多个绑定匹配,则配置顺序中的第一个获胜。
- 如果一个绑定设置了多个匹配字段(例如
peer+guildId),则所有指定字段都必须匹配(AND语义)。 - 省略
accountId的绑定只匹配默认账户,而不是每个账户。使用accountId: "*"作为整个频道的回退,或使用accountId: "<name>"针对单个账户。再次添加带有显式账户 id 的相同绑定时,会升级现有的仅频道绑定,而不是重复它。
对于现有的多代理配置,openclaw doctor --fix 会将遗留的环境默认路由物化为整个频道的绑定,以及显式的 heartbeat、Custodian 和 Talk 目标。单代理配置保持不变。
对于直接在主配置文件中定义的多代理名册,如果没有遗留的
default: true 标记,Doctor 会为键控的 agents.entries 和旧版 agents.list 名册都添加
agents.ownership: "explicit",包括使用
--fix --non-interactive 时。现有绑定和按表面的所有者保持不变。最后已知良好恢复会在验证并恢复直接编写的无标记名册之前应用相同的所有权标记。
Doctor 永远不会将更窄的会话绑定提升为整个账户的所有权。
它不会从其他账户或频道借用所有权,不会在冲突的所有者之间进行选择,也不会分配其他无主表面。
在遗留 agents.list 迁移期间,未绑定账户会保留其历史首代理回退作为显式账户绑定,即使更窄的会话路由指定了其他代理也是如此。Doctor
会连同所有权标记一起记录该绑定。update-channel 迁移和手动 Doctor 都需要原始名册;如果不可用,Doctor 会报告
该原因并保持绑定不变。所有者仍未解决的账户会报告所需的绑定,并保持阻塞状态,不会尝试自动重启;其他账户和 Gateway 继续提供服务。
在迁移没有默认标记的遗留 agents.list 名册时,Doctor
还会将第一个代理继承的工作区固定到 agents.entries.<id>.workspace。其自定义指令
和历史 memory/ 笔记仍保留在原始目录中。显式工作区保持权威。如果之前的升级已经留下了两个经过编辑的工作区,请选择预期的按代理工作区,并从备份中核对其内容;Doctor 不会合并目录。
多个账户 / 电话号码¶
支持多个账户的频道(例如 WhatsApp)使用 accountId 来标识每个登录。每个 accountId 路由到其自己的代理,因此一台服务器可以托管多个电话号码而不会混淆会话。
设置 channels.<channel>.defaultAccount 以选择在省略 accountId 时使用的账户。未设置时,OpenClaw 会回退到 default(如果存在),否则回退到第一个已配置的账户 id(按排序)。
支持多个账户的频道:discord、feishu、googlechat、imessage、irc、line、mattermost、matrix、nextcloud-talk、nostr、signal、slack、telegram、whatsapp、zalo、zalouser。
概念¶
agentId:一个“大脑”(工作区、每个代理的认证、每个代理的会话存储)。accountId:一个渠道账号实例(例如 WhatsApp 账号personal与biz)。binding:根据(channel, accountId, peer)将入站消息路由到某个agentId,并可选地根据 guild/team ID 进行路由。- 直接聊天默认折叠为
agent:<agentId>:main(即每个代理的 主会话)。
平台示例¶
每个代理一个 Discord 机器人
每个 Discord 机器人账号对应一个唯一的 accountId。将每个账号绑定到一个代理,并为每个机器人保留独立的允许列表。
{
agents: {
entries: {
main: { default: true, workspace: "~/.openclaw/workspace-main" },
coding: { workspace: "~/.openclaw/workspace-coding" },
},
},
bindings: [
{ agentId: "main", match: { channel: "discord", accountId: "default" } },
{ agentId: "coding", match: { channel: "discord", accountId: "coding" } },
],
channels: {
discord: {
groupPolicy: "allowlist",
accounts: {
default: {
token: "DISCORD_BOT_TOKEN_MAIN",
guilds: {
"123456789012345678": {
channels: {
"222222222222222222": { enabled: true, requireMention: false },
},
},
},
},
coding: {
token: "DISCORD_BOT_TOKEN_CODING",
guilds: {
"123456789012345678": {
channels: {
"333333333333333333": { enabled: true, requireMention: false },
},
},
},
},
},
},
},
}
- 将每个机器人邀请到 guild,并启用 Message Content Intent。
- 令牌位于
channels.discord.accounts.<id>.token(默认账号可以使用DISCORD_BOT_TOKEN)。
每个代理一个 Telegram 机器人
{
agents: {
entries: {
main: { default: true, workspace: "~/.openclaw/workspace-main" },
alerts: { workspace: "~/.openclaw/workspace-alerts" },
},
},
bindings: [
{ agentId: "main", match: { channel: "telegram", accountId: "default" } },
{ agentId: "alerts", match: { channel: "telegram", accountId: "alerts" } },
],
channels: {
telegram: {
accounts: {
default: {
botToken: "123456:ABC...",
dmPolicy: "pairing",
},
alerts: {
botToken: "987654:XYZ...",
dmPolicy: "allowlist",
allowFrom: ["tg:123456789"],
},
},
},
},
}
- 使用 BotFather 为每个代理创建一个机器人,并复制每个令牌。
- 令牌位于
channels.telegram.accounts.<id>.botToken(默认账号可以使用TELEGRAM_BOT_TOKEN)。 - 如果同一个 Telegram 群组中有多个机器人,请邀请每个机器人,并提及需要回复的机器人。
- 为每个群组机器人禁用 BotFather 隐私模式(
/setprivacy-> 禁用),然后移除并重新添加机器人,以便 Telegram 应用该设置。 - 使用
channels.telegram.groups允许群组,或者仅在受信任的群组部署中使用groupPolicy: "open"。 - 将发送者用户 ID 放入
groupAllowFrom。群组 ID 和超级群组 ID 应放在channels.telegram.groups中,而不是groupAllowFrom。 - 按
accountId绑定,使每个机器人路由到其对应的代理。
每个代理一个 WhatsApp 号码
在启动网关之前,先关联每个账号:
openclaw channels login --channel whatsapp --account personal
openclaw channels login --channel whatsapp --account biz
~/.openclaw/openclaw.json(JSON5):
{
agents: {
entries: {
home: {
default: true,
name: "Home",
workspace: "~/.openclaw/workspace-home",
agentDir: "~/.openclaw/agents/home/agent",
},
work: {
name: "Work",
workspace: "~/.openclaw/workspace-work",
agentDir: "~/.openclaw/agents/work/agent",
},
},
},
// Deterministic routing: first match wins (most-specific first).
bindings: [
{ agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
{ agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },
// Optional per-peer override (example: send a specific group to work agent).
{
agentId: "work",
match: {
channel: "whatsapp",
accountId: "personal",
peer: { kind: "group", id: "1203630...@g.us" },
},
},
],
// On by default. Omitted/empty `allow` permits every agent pair;
// list requester and target ids to restrict access, or set enabled: false to turn it off.
tools: {
agentToAgent: {
allow: ["home", "work"],
},
},
channels: {
whatsapp: {
accounts: {
personal: {
// Optional override. Default: ~/.openclaw/credentials/whatsapp/personal
// authDir: "~/.openclaw/credentials/whatsapp/personal",
},
biz: {
// Optional override. Default: ~/.openclaw/credentials/whatsapp/biz
// authDir: "~/.openclaw/credentials/whatsapp/biz",
},
},
},
},
}
常见模式¶
按渠道拆分:将 WhatsApp 路由到一个快速的日常代理,将 Telegram 路由到一个 Opus 代理。
{
agents: {
entries: {
chat: {
default: true,
name: "Everyday",
workspace: "~/.openclaw/workspace-chat",
model: "anthropic/claude-sonnet-4-6",
},
opus: {
name: "Deep Work",
workspace: "~/.openclaw/workspace-opus",
model: "anthropic/claude-opus-4-6",
},
},
},
bindings: [
{ agentId: "chat", match: { channel: "whatsapp", accountId: "*" } },
{ agentId: "opus", match: { channel: "telegram", accountId: "*" } },
],
}
这些示例使用 accountId: "*",以便后续添加账户时绑定仍然有效。若要将单个私信/群组路由到 Opus,同时让其余消息保持使用 chat,请为该对等方添加一个 match.peer 绑定——对等方匹配始终优先于整个渠道的规则。
让 WhatsApp 继续使用快速代理,但将一个私信路由到 Opus:
{
agents: {
entries: {
chat: {
default: true,
name: "Everyday",
workspace: "~/.openclaw/workspace-chat",
model: "anthropic/claude-sonnet-4-6",
},
opus: {
name: "Deep Work",
workspace: "~/.openclaw/workspace-opus",
model: "anthropic/claude-opus-4-6",
},
},
},
bindings: [
{
agentId: "opus",
match: { channel: "whatsapp", accountId: "*", peer: { kind: "direct", id: "+15551234567" } },
},
{ agentId: "chat", match: { channel: "whatsapp", accountId: "*" } },
],
}
对等方绑定始终优先,因此请将其放在整个渠道规则之上。
将一个专用的家庭代理绑定到单个 WhatsApp 群组,并启用提及门控和更严格的工具策略:
{
agents: {
entries: {
family: {
default: true,
name: "Family",
workspace: "~/.openclaw/workspace-family",
identity: { name: "Family Bot" },
groupChat: {
mentionPatterns: ["@family", "@familybot", "@Family Bot"],
},
sandbox: {
mode: "all",
scope: "agent",
},
tools: {
allow: [
"exec",
"read",
"sessions_list",
"sessions_history",
"sessions_send",
"sessions_spawn",
"session_status",
],
deny: ["write", "edit", "apply_patch", "browser", "canvas", "nodes", "cron"],
},
},
},
},
bindings: [
{
agentId: "family",
match: {
channel: "whatsapp",
peer: { kind: "group", id: "120363999999999999@g.us" },
},
},
],
}
工具允许/拒绝列表是工具,而不是技能。如果某个技能需要运行二进制文件,请确保已允许 exec,并且该二进制文件存在于沙箱中。若要实施更严格的门控,请设置 agents.entries.*.groupChat.mentionPatterns,并针对该渠道保持启用群组允许列表。
每个代理的沙箱和工具配置¶
每个代理都可以拥有自己的沙箱和工具限制:
{
agents: {
entries: {
personal: {
default: true,
workspace: "~/.openclaw/workspace-personal",
sandbox: {
mode: "off", // No sandbox for personal agent
},
// No tool restrictions - all tools available
},
family: {
workspace: "~/.openclaw/workspace-family",
sandbox: {
mode: "all", // Always sandboxed
scope: "agent", // One container per agent
docker: {
// Optional one-time setup after container creation
setupCommand: "apt-get update && apt-get install -y git curl",
},
},
tools: {
allow: ["read"], // Only read tool
deny: ["exec", "write", "edit", "apply_patch"], // Deny others
},
},
},
},
}
Note
setupCommand 位于 sandbox.docker 下,并在容器创建时运行一次。当解析后的作用域为 "shared" 时,每个代理的 sandbox.docker.* 覆盖会被忽略。
这将为你提供:
- 安全隔离:为不受信任的代理限制工具。
- 资源控制:对特定代理进行沙箱隔离,同时让其他代理保留在主机上。
- 灵活策略:为每个代理设置不同的权限。
Note
tools.elevated 同时具有全局门控(tools.elevated.enabled/allowFrom)和每个代理的门控(agents.entries.*.tools.elevated.enabled/allowFrom)。每个代理的门控只能在全局门控的基础上进一步限制——两者都必须允许某个发送者,提权命令才能运行。对于群组定向,请使用 agents.entries.*.groupChat.mentionPatterns,以便 @提及 能够准确映射到目标代理。
有关详细示例,请参阅多代理沙箱和工具。
相关¶
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw