OpenClaw 多 Agent 与专家分线:一个网关跑几个人格,消息怎么路由到对的那个
一个网关里想跑两个”人格”,是很自然的需求:一个管日常闲聊和家里的事,一个专门接代码活;或者一家人共用一台服务器,各自的聊天记录别串到一起。OpenClaw 支持这么干,但真动手配的时候,麻烦通常不在”怎么多建一个 agent”,而在两件事上——消息进来了到底会被路由给谁,以及哪些状态其实压根没分开。
第二件事尤其容易翻车:很多人默认”新建一个 agent = 一套全新的隔离环境”,然后发现 skills 是共享根目录加载的、插件存储没跟着拆、WhatsApp 的 DM 白名单是账号级而不是 agent 级。官方文档在这几处都单独写了提示。
还有一个更隐蔽的预期偏差:以为多开几个 agent 就能并行干活、互不拖累。OpenClaw 官方专门写了一篇《Parallel specialist lanes》,开头一句话就把这个幻觉打掉了——把并行当成稀缺资源的设计问题,而不是”多几个 agent”。下面按官方文档的口径,把这两篇讲的机制串起来。
一个 agent 的边界,具体包含哪三块
文档里对”agent”的定义是完整的每人格作用域:工作区文件、鉴权档案、模型注册表、会话存储。拆开来是三块:
- 工作区(Workspace):文件、
AGENTS.md/SOUL.md/USER.md、本地笔记、人格规则。 - 状态目录(
agentDir):鉴权档案、模型注册表、按 agent 的配置。 - 会话存储:聊天历史与路由状态,落在
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite。
而 binding(绑定) 是另一个概念:它把一个渠道账号(一个 Slack 工作区、一个 WhatsApp 号码等)映射到其中某个 agent。agent 是”脑子”,binding 是”这条消息该进哪个脑子”。
有一点必须先说清楚,因为它决定了你对隔离度的预期:文档明确写了,每个 agent 的工作区是默认 cwd,不是硬沙箱。相对路径会落在工作区里,但绝对路径在没开沙箱的情况下能够到主机上的其它位置。真要做隔离,得走沙箱那条线,参见 沙箱、工具策略与提权的边界。
默认就是单 agent,路径长这样
什么都不配的时候,OpenClaw 跑的是一个 agent:agentId 默认 main,会话键形如 agent:main:<mainKey>(默认 mainKey 是 main),工作区在 <stateDir>/workspace(命名 profile 则是 ~/.openclaw-<profile>/workspace),状态目录在 ~/.openclaw/agents/main/agent。
多 agent 之后各条路径的默认值与覆盖方式,官方给了一张表:
| 项 | 默认位置 | 覆盖方式 |
|---|---|---|
| 配置文件 | ~/.openclaw/openclaw.json | OPENCLAW_CONFIG_PATH |
| 状态根目录 | ~/.openclaw | OPENCLAW_STATE_DIR |
| 默认 agent 工作区 | <stateDir>/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 |
| 会话与转录 | ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite | 无 |
| 旧版/归档会话产物 | ~/.openclaw/agents/<agentId>/sessions | 无 |
后两行没有覆盖项,意味着会话库的位置是跟着 agentDir 走的——这也是下一节那条警告的根源。
加一个 agent:命令、绑定、验证
新增一个隔离 agent 用这条:
openclaw agents add work
可用的标志:--workspace <dir>、--model <id>、--agent-dir <dir>、--bind <channel[:accountId]>(可重复)、--non-interactive(用它就必须同时给 --workspace)。
加完 agent 还要加 bindings 才能把入站消息路由过去(向导会主动问你要不要顺手配),然后验证:
openclaw agents list --bindings
官方给的快速上手是四步:先各建一个工作区;再按渠道各开一个账号(Discord 一个 agent 一个 bot 并打开 Message Content Intent,Telegram 用 BotFather 一个 agent 一个 bot,WhatsApp 每个账号各自登录,例如 openclaw channels login --channel whatsapp --account work);然后在配置里写 agents.entries、channels.<channel>.accounts 和 bindings 三段;最后 openclaw gateway restart 加上 agents list --bindings、channels status --probe 验证。
另外 OpenClaw 会记录每个 agent 是怎么被创建的:CLI、引导流程和网关请求记为 operator,系统 agent 请求创建的记为 agent,Claw 安装带进来的记为 claw;agent 创建的条目还会保留发起方的 agent id,用 openclaw agents list --tree 能看创建层级。一个已配置的 agent 确实可以通过自己的 openclaw 工具请求再建一个 agent,但系统 agent 会把它登记成一条有类型的操作、把发起方 agent id 展示给操作者,要操作者批准之后才真的创建。
路由规则:确定性、最具体的赢
绑定的匹配是确定性的,最具体的那条胜出。完整的层级顺序在渠道路由文档里:精确 peer、父级 peer、peer 通配、guild+角色、guild、team、账号、渠道、默认 agent。多 Agent 文档特意拎出来三条最容易被坑的:
- 同一层级里有多条命中,配置里靠前的那条赢。所以 peer 级的特例规则要写在渠道级兜底规则上面。
- 一条绑定里写了多个匹配字段(比如
peer加guildId),是 AND 语义,所有写明的字段都得匹配。 - 省略
accountId的绑定只匹配默认账号,不是匹配所有账号。要全渠道兜底得写accountId: "*",要指定账号就写accountId: "<name>"。另外,把同一条绑定带上明确的账号 id 再加一次,是升级原来那条仅渠道级的绑定,而不是复制出一条新的。
第三条最容易误解:以为按渠道绑了就全覆盖,结果新加的第二个账号消息全落到默认 agent。官方示例里,凡是希望”以后加账号还能继续生效”的绑定都写了 accountId: "*"。
对已有的多 agent 配置,openclaw doctor --fix 会把遗留的隐式默认路由固化成显式的渠道级绑定,外加明确的 heartbeat、Custodian 和 Talk 目标;单 agent 配置不受影响。
支持多账号的渠道,文档列的是:discord、feishu、googlechat、imessage、irc、line、mattermost、matrix、nextcloud-talk、nostr、signal、slack、telegram、whatsapp、zalo、zalouser。channels.<channel>.defaultAccount 决定省略 accountId 时用哪个账号,不设的话先回退到名为 default 的账号,没有就取排序后的第一个账号 id。
想把这套路由和会话键的关系理清楚,配合看 会话模型:主会话、附着与状态 会顺一些。
agentDir 绝对不要跨 agent 复用
这是文档里级别最高的一条警告:复用 agentDir 会导致鉴权与会话状态冲撞。
更麻烦的是它的失败方式不是直接报错。文档写明:当次级 agent 本地的 OAuth 凭据过期、刷新又失败时,OpenClaw 会读穿到默认/主 agent 同一个 profile id 的凭据,并采用其中最新的那个 token,同时不会把 refresh token 复制进次级 agent 自己的存储。也就是说,你以为两个 agent 用的是两个账号,实际可能悄悄共用了同一份授权。
想要真正独立的 OAuth 账号,只有一条路:从那个 agent 自己登录一次。如果非要手工搬凭据,只能搬可移植的静态 api_key 或 token 类型的 profile;OAuth 的刷新材料默认不可移植,除非用 copyToAgents 显式把某个 profile 放行。
顺带一提跨会话读历史的口子:sessions_history 是更安全的那条路径,它返回的是有界、经过脱敏的视图,而不是原始转录的整包倾倒——思考块签名、工具结果载荷细节、<relevant-memories> 脚手架和各类工具调用 XML 标签都会被剥掉,输出还按字节大小做截断和上限控制。
哪些东西默认没跟着拆开
这一节是本文最值得抄下来的部分。新建 agent 不会自动把下面这些东西一并隔离:
Skills:从每个 agent 的工作区加载,再叠加 ~/.openclaw/skills 这类共享根目录,然后按该 agent 生效的 skill 允许列表过滤。agents.defaults.skills 是共享基线,agents.entries.*.skills 是按 agent 的替换——显式条目替换默认值,不做合并。这个”替换而非合并”的语义如果没注意,很容易配出一个技能比预期少的 agent。
插件存储:跟着各插件自己的配置走。加第二个 agent 并不会自动把每个全局插件的存储都切开。文档举的例子是 Memory Wiki:默认是一个全局仓库,如果不希望客服 agent 和市场 agent 共享编译过的知识,得把 plugins.entries.memory-wiki.config.vault.scope 设成 agent:
{
plugins: {
entries: {
"memory-wiki": {
enabled: true,
config: {
vault: {
scope: "agent",
path: "~/.openclaw/wiki",
},
},
},
},
},
}
这里的 path 是父目录,OpenClaw 会在后面追加规范化后的 agent id,得到 ~/.openclaw/wiki/support、~/.openclaw/wiki/marketing 这样的路径。另外,配了多个 agent 之后,按 agent 作用域的 CLI 和网关操作都必须显式指定是哪个 agent。
跨 agent 记忆搜索:QMD 的跨 agent 搜索路径已经被移除了。内置记忆不会去搜另一个 agent 的转录语料,每个 agent 只搜自己配置的记忆和同 agent 内可用的会话来源。确实想让多个 agent 共享同一批参考资料,就把这些 Markdown 放进一个显式的共享目录,配到 memory.search.extraPaths 里。
渠道侧的访问控制:以 WhatsApp 为例,DM 的访问控制(配对/白名单)是每个 WhatsApp 账号全局生效的,不是按 agent 的。而且用一个 WhatsApp 号码给不同人分流时(用 peer.kind: "direct" 匹配发送方的 E.164 号码),回复仍然是从同一个号码发出去的——没有按 agent 的发送方身份。文档还补了一句:直聊默认会收敛到该 agent 的主会话键,所以真正的隔离要求一人一个 agent。共享群组要么整个绑到一个 agent,要么走广播群那套。
多开 agent 不等于更快:官方怎么定义”专家分线”
《Parallel specialist lanes》这篇的立场很明确:一条专家分线只有在减少对真实瓶颈的争抢时才提升吞吐。文档列的瓶颈有五个:
| 瓶颈 | 说明 |
|---|---|
| 会话锁 | 同一会话同一时刻只应有一次运行在改动它 |
| 全局模型容量 | 所有可见的聊天运行仍然共用供应商的额度限制 |
| 工具容量 | shell、浏览器、网络、仓库类工作可能比模型这一轮还慢 |
| 上下文预算 | 长转录会让之后每一轮都更慢、更不聚焦 |
| 归属含糊 | 多个 agent 干同一件事就是在浪费容量 |
OpenClaw 本身已经做了两件事:按会话串行化运行,以及通过命令队列限制全局并行度。分线是加在这之上的策略——谁拥有哪块活、什么留在聊天里、什么变成后台任务。队列这层的机制见 队列、插话与重试。
官方推荐的落地顺序是三阶段,而且明确说了不要倒着来。
第一阶段:分线契约 + 重活转后台。 给每条分线在它的工作区和系统提示里写一份成文契约,包含五项:这条线负责什么(Purpose)、哪些活不该自己接而该转出去(Non-goals)、聊天预算(快问快答留在聊天里,长任务先简短确认再丢到后台子 agent 或任务里跑)、交接规则(不归自己就说清该去哪条线,并给一份紧凑的交接摘要)、工具风险规则(用能干成这件事的最小工具面)。文档评价这是最便宜的一个阶段,也解决了大部分堵塞:一个编码任务不会再把研究那条线拖成糖浆,每个聊天的上下文也各自干净。
第二阶段:优先级与并发控制。 按各条线的业务价值去调队列和模型容量:
{
agents: {
defaults: {
maxConcurrent: 4,
subagents: { maxConcurrent: 8, delegationMode: "prefer" },
},
},
messages: {
queue: {
mode: "collect",
cap: 20,
drop: "summarize",
},
},
}
配套的策略是:直聊/个人聊天和生产运维类 agent 走高优先级;系统忙的时候,把研究、起草、批量编码挪到后台任务。
第三阶段:协调者 / 交通管制。 等多条分线都跑起来之后再加一个小的协调者:跟踪各线在跑的任务和归属、发现跨群的重复请求、在分线之间转交接摘要、只把阻塞项、已完成结果和必须人来拍板的决定浮上来。文档对这一阶段的警告很直白——不要从这里开始,没有分线契约的协调者只是在协调混乱。
官方还给了一份最小契约模板,可以直接放进分线工作区:
# Lane contract
## Owns
- <job this lane is responsible for>
## Does not own
- <work to hand off>
## Chat budget
- Answer quick questions directly.
- For multi-step, slow, or tool-heavy work: acknowledge briefly, spawn/background
the work, then return the result when complete.
## Handoff
If another lane owns the request, reply with:
- target lane
- objective
- relevant context
- exact next action
## Tool posture
Use the smallest tool surface that can complete the task. Avoid broad shell or
network work unless this lane explicitly owns it.
每个 agent 可以有自己的沙箱和工具策略
多 agent 的另一个正经用途是给不同信任级别的人格配不同权限。官方示例里,个人 agent 用 sandbox.mode: "off" 且不加工具限制;给家人用的 agent 则 sandbox.mode: "all"、scope: "agent"(一个 agent 一个容器),工具上 allow: ["read"]、deny: ["exec", "write", "edit", "apply_patch"]。
几个细节值得记:setupCommand 挂在 sandbox.docker 下面,只在容器创建时跑一次;当解析出来的 scope 是 "shared" 时,按 agent 的 sandbox.docker.* 覆盖会被忽略。tools.elevated 有全局闸门(tools.elevated.enabled / allowFrom)和按 agent 的闸门(agents.entries.*.tools.elevated.enabled / allowFrom)两层,按 agent 的那层只能进一步收紧全局的,两层都放行某个发送方,提权命令才跑得起来。还有一个概念区分:allow/deny 列的是工具,不是 skills;某个 skill 要跑一个二进制,前提是 exec 被允许且这个二进制在沙箱里存在。
群里点名某个 agent 用 agents.entries.*.groupChat.mentionPatterns 配 @ 模式。另外 agent 之间互发消息(tools.agentToAgent)默认是关的,要用得显式打开并配允许列表。
整体分层见 OpenClaw 架构总览。
什么时候别上多 agent,以及还有哪些没解决
按文档的事实往回推,有几种情况多 agent 帮不上忙甚至添乱:
- 只是想让活跑得更快。会话锁和全局模型容量摆在那儿,多开 agent 不会变出额度。文档的原话是把并行当稀缺资源问题,先做分线契约把重活挪后台,比多开 agent 收益大得多。
- 只是想给两个人分聊天记录,但用的是同一个 WhatsApp 号。直聊默认收敛到该 agent 的主会话键,DM 白名单又是账号级的,回复也没有独立发送方身份。
- 指望新建 agent 自动隔离一切。skills 走共享根目录加显式替换语义、插件存储跟插件配置走、Memory Wiki 默认是全局单仓,都要单独配。
- 想让两个 agent 共享同一个 OAuth 登录省事。读穿主 agent 凭据这条路径存在,但它是失效兜底,不是给你当共享方案用的。
还有几处是文档明确说”没有”的:跨 agent 的记忆/转录搜索被移除了,共享只能靠显式的 memory.search.extraPaths 目录;agentDir 的复用也没有任何自动修复手段。至于协调者具体怎么实现,官方给的是模式描述和职责清单,没有现成组件。
配置前先把一件事想清楚:你要的是人格分离(不同 AGENTS.md、不同记忆、不同账号),还是权限分离(不同沙箱、不同工具面),还是吞吐分离(别互相堵)。这三个诉求在 OpenClaw 里对应的是完全不同的配置块,混在一起配,最后往往是每一项都做了一半。
延伸阅读
- 从头读起:OpenClaw 架构总览:网关、Agent、渠道、节点、插件五层各管什么,出问题该往哪查
- 本专题共 40 篇,完整分组目录见专题页
- OpenClaw 多用户模式与 USER.md 用户模型:共用一个 agent 时谁能看到谁的会话
- OpenClaw 模型供应商怎么接、挂了怎么自动转移:从 provider/model 到 fallback 链
本文依据 OpenClaw 官方仓库(github.com/openclaw/openclaw)docs/ 下的官方文档整理,核对日 2026-08-17。
我们没有安装或运行过 OpenClaw,因此不涉及界面外观、操作手感与实测耗时的任何描述;
文中的默认值、命令与配置项均为文档口径,不构成对实际运行结果的保证。
该项目迭代很快,请以仓库最新内容为准。接入即时通讯平台前,请自行确认所在平台的规则与合规要求。