返回文章索引
AI辅助研发15 分钟阅读

我给 OpenClaw 搭了一支 1+10 的多智能体团队

从一个全能助手到 1 个 Chief、10 个专家:完整复盘 OpenClaw 的模型分工、路由、MCP、权限、记忆、部署、踩坑与验收。

在今年的 PL 第一公里大会上,林博讲解了一个自己基于多智能体的团队管理经验。一开始我不以为意,过了几个月之后,自己细细品味,才恍然大悟其中精髓。

当时我的第一反应很朴素:模型已经足够强了,把需要的工具都接上,一个 Agent 不就能把事情做完吗?为什么还要分主控、专家、协作流程,弄得像一个真正的团队?

后来我真的把 OpenClaw 用进投资研究、无线技术、服务器运维、写作、旅行和日常事务里,问题慢慢暴露出来。一个“全能助手”当然什么都能碰,但它也因此什么都混在一起:专业判断、工具权限、长期记忆、对外回复,全部挤在同一个上下文里。能力越多,噪声越多;工具越全,权限边界越模糊。

这时我才明白,林博那次分享的重点根本不是“多开几个 Agent”,而是像管理团队一样管理智能体:谁是统一入口,谁负责专业判断,谁有权使用什么工具,工作怎么交接,出了问题由谁兜底。

于是我把原来的 OpenClaw 改造成了一套 1 + 10 的多智能体系统。

OpenClaw 1+10 多智能体架构

单体助手用久了,问题开始出现

我最初的思路,是不断给主 Agent 增加能力:股票数据、天气、地图、服务器诊断、写作、图片生成、知识整理……看上去越来越强,实际使用却越来越像让一个人同时做前台、研究员、运维工程师、设计师和秘书。

这种模式有三个明显问题。

第一,职责会漂。它上一秒还在分析股票,下一秒就去改文案,同一个上下文里的语气、判断标准和记忆很容易互相污染。

第二,权限会膨胀。投资研究需要行情数据,旅行需要航班和地图,运维需要主机状态。但如果这些工具都挂在一个 Agent 身上,那么每次普通聊天都背着一整套不必要的能力。

第三,出了问题很难说清责任。是模型判断错了,工具数据错了,路由错了,还是权限配置错了?单体 Agent 往往只能给出一句笼统的“调用失败”。

所以这次我先画组织架构图,再决定每个 Agent 应该保留什么能力。

一位 Chief,十位专家

整套系统只有一个正式入口:main。我在微信里发出的所有任务,先到 main;最终能直接回复我的,也只有 main

它下面有十个专家:

Agent职责
investmentA 股研究、市场复盘、风险分析
work无线通信、系统仿真、版本研发,只处理公开或已脱敏材料
opsOpenClaw、VPS、代码和 DevOps 只读诊断
image封面、结构图、视觉资产
writer博客、汇报、演讲和中文表达
consultant战略、职业、管理和复杂决策
knowledgeMarkdown、知识分类和长期沉淀
life天气、待办、提醒和本地生活
travel航班、地图、路线和旅行计划
shopping商品研究、比价和购买建议

main 的工作不是假装精通所有领域。它负责识别意图、判断敏感级别、选择专家、删掉不该外传的信息、检查专家证据,再把结果整理成一条最终答复。

专家也不是“小号 main”。它们没有微信入口,不能主动给我发消息,不能继续生成下一层 Agent,更不能跑任意 Shell。每个专家做完后,只能按统一的 Handoff 格式把结论交还给 main

这套关系其实很像真实团队:负责人不必把所有活都抢过来做,专家也不该绕过负责人各说各话。我最后给它定下的规则很简单——入口统一、职责清楚、交付格式一致。

模型之间没有上下级,Agent 之间才有

很多人看到多智能体,第一反应是“是不是用了十一个不同模型”。其实不是。

我的配置里主要用了两类模型:

  • GPT-5.6 Luna:负责主控、写作、知识、生活、旅行、购物和视觉类岗位;
  • GPT-5.6 Sol:负责投资、无线技术、运维分析和复杂咨询这些需要更深推理的岗位;
  • 图片生成单独使用 gpt-image-2

模型只是能力底座,真正的上下级关系来自 OpenClaw 里的路由、工具权限和消息边界。main 用 Luna,并不代表它“比 Sol 更强”;它更像一个懂得分派任务、校验结果和承担最终责任的 Chief。

所有 Agent 都固定自己的主模型,并把自动 fallback 设为空:

model: {
  primary: "openai/gpt-5.6-luna",
  fallbacks: [],
},
models: {
  "openai/gpt-5.6-luna": {
    agentRuntime: { id: "openclaw" },
  },
},

我以前会觉得“有 fallback 总比没有好”。真正做审计时我才发现,模型一旦静默切换,输出风格、推理行为和兼容性也会随之变化,出了问题很难还原当时到底用了哪套能力。现在如果主模型不可用,我宁愿让失败被看见,再由 main 决定重试或降级。

一条消息在系统里怎么走

不是每个问题都需要专家。寒暄、系统介绍、简单解释和已有结果的短总结,main 直接回答。只有当任务需要实时数据、专业判断、专属工具、独立记忆或长篇产物时,它才委派。

从用户问题到单次最终回复

比如我说:“帮我分析一只股票最近的走势,再写成一段适合发给朋友看的说明。”

这条任务会被拆成两段:

用户
  → main 判断敏感级别并删去无关信息
  → investment 查询数据、给出证据和风险
  → main 校验 Handoff
  → writer 只接收经过整理的事实
  → main 终审
  → 用户只收到一条最终回复

这里有两个我刻意坚持的约束:一轮最多两个专家;专家之间不直接互相调用。需要更多角色时,由 main 分阶段串联。这样做没有“十个 Agent 一起开会”那么热闹,但资源可控,责任链也更清楚。

专家的返回不是随意写一段话,而是遵守同一个交接协议:

{
  "task_id": "task-001",
  "task": "分析某公司的公开财务数据",
  "agent": "investment",
  "status": "complete",
  "conclusion": "收入增长,但现金流质量仍需观察",
  "confidence": "medium",
  "key_findings": [],
  "evidence": [
    {
      "source": "公司公告,2026-08-11",
      "fact": "报告期营业收入同比增长"
    }
  ],
  "risks": [],
  "unknowns": [],
  "recommended_action": [],
  "needs_other_agent": {
    "required": false,
    "suggested_agent": null,
    "reason": null
  },
  "artifacts": [],
  "sensitivity": "public"
}

这份 Schema 很像工作中的交付模板。它不保证结论永远正确,却能强迫系统把“结论、证据、风险、未知项”分开,避免一句很自信的话掩盖事实缺口。

我后来才分清 Skill、MCP 和 Memory

搭建过程中,我花了不少时间才真正分清三件容易混在一起的东西。

Skill 是做事方法。 它告诉 Agent 应该遵循什么流程、注意什么边界,但不代表 Agent 自动获得了某项权限。

MCP 是把外部工具和数据服务接进来的协议层。 股票行情、地图、航班和商品搜索通过这一层提供给相应专家,但不会因此变成所有 Agent 的公共能力。

Memory 是长期仍然成立的事实和偏好。 它不该变成聊天流水仓库,更不能存 Token、邮件正文、实时价格或工作秘密。

最初,我把 MCP 服务都放在全局配置里,以为再用工具白名单限制可见性就够了。后来通过运行时检查发现,“Agent 看不到工具”不等于底层服务没有被初始化。某些运行路径会先加载全局 MCP,再做工具过滤。这不仅扩大了权限面,也会在小型服务器上制造额外进程和内存压力。

最终我把七个 MCP 服务移出全局配置,按需要分装到五个专家的 workspace:

investment  → 股票研究数据
ops         → 固定只读诊断
life        → 最小天气/地点能力
travel      → 地图、航班、地理检索
shopping    → 商品检索
main        → 不加载业务 MCP

每套服务只放进获授权专家的工作区,普通运行账号不能修改启动定义。测试时,我不只看工具列表,还会新开一个 main 会话,确认它没有启动业务 MCP;专家任务结束后,再检查相关子进程是否已经回收。

我实际怎么配

整个过程不是直接改一份大配置,而是按“先盘点、再备份、后变更”的顺序推进。

第一步:盘点现状

我先把当前 Agent、入口绑定、Cron、Skill、MCP、模型认证、Memory 目录和主机资源都列出来。尤其要确认原来的 main workspace 在哪里,因为直接换目录会让已有身份、记忆和会话脱链。

openclaw config validate --json
openclaw agents list --json
openclaw agents bindings --json
openclaw mcp status --json
openclaw gateway status --json

第二步:先建回滚锚点

配置文件、主工作区、Agent 目录、定时任务和 systemd 单元分别备份,目录权限收紧,并生成校验和。任何一步出问题,都要能恢复到变更前,而不是靠记忆手工改回去。

第三步:建立独立身份和目录

十个专家分别拥有独立 workspaceagentDir。这里不能共用 agentDir,否则认证、会话和状态可能互相覆盖。

state/
├── workspace/                  # 原 main,保留
├── workspaces/
│   ├── investment/
│   ├── work/
│   ├── ops/
│   └── ...
├── agents/<id>/agent/
└── shared/                     # 仅非敏感协作规则

第四步:固定模型、权限和并发

main 可以调用十个白名单专家,专家的 allowAgents 为空。所有 Agent 禁止任意 Shell、进程和 elevated 权限,文件工具限制在自己的 workspace。

agents: {
  defaults: {
    maxConcurrent: 2,
    subagents: {
      maxConcurrent: 2,
      maxSpawnDepth: 1,
      maxChildrenPerAgent: 2,
      requireAgentId: true,
    },
  },
},
cron: { maxConcurrentRuns: 1 },
tools: {
  elevated: { enabled: false },
  exec: { host: "gateway", mode: "deny" },
  fs: { workspaceOnly: true },
},

这段只是全局底线;每个 Agent 还有自己单独的工具白名单和拒绝表,完整配置放在仓库里。

第五步:让 main 保持“薄”

main 只做路由、脱敏、串联和终审,不直接拥有股票、航班、商品或运维 MCP。专业能力越少,入口越容易守住。

它的委派规则也写得很死:每次 sessions_spawn 必须显式传入专家 agentId;只要最终答案依赖专家,就先 sessions_yield 等待;同一个用户请求只产生一条最终答复。

第六步:先 dry-run,再逐项上线

OpenClaw 的 Agent 列表是数组,合并补丁时可能整段替换,所以我每次都先做 dry-run,并检查配置引用和 Schema:

openclaw config patch \
  --file ./config/openclaw.multi-agent.example.json5 \
  --dry-run --json
 
openclaw config validate --json

上线后也不一次并发探测全部 MCP。小机器上最稳妥的做法,是逐个服务串行检查:

openclaw mcp probe <server-name> --json

每次探测前后都看内存和残留进程,确认回收后再测下一个。

几个真正让我长记性的坑

1. “回答了两次”,其实不是两个 Agent 在抢话

我在微信里问了一句系统介绍,先收到 main 的正常回答,紧接着又出现一个带 Sub-agent 字样的灰色气泡。第一眼看上去,就是主控回答一次,子 Agent 又回答一次。

审计会话后才发现,那一轮根本没有成功创建子会话。main 调用 sessions_spawn 时漏了必填的 agentId,工具返回 forbidden,微信又把失败的工具进度卡显示给了用户。卡片里的 cleanup delete failed 也不是删除失败,只是参数 cleanup=delete 和状态 failed 被界面拼在了一起。

最后我做了四件事:关闭微信工具进度卡外显、抑制原始工具错误、把 delegationMode 从容易主动委派的 prefer 调成更克制的 suggest,并强化 main 的显式 agentId + yield + 单次汇总 规则。

这件事提醒我:所谓“多智能体重复回复”,不一定是路由问题,也可能只是内部工具状态泄漏到了用户界面。诊断时必须看真实会话和投递事件,不能凭截图猜。

2. Tushare 不是“积分不够”这么简单

投资 Agent 原计划接入 Tushare。审计后发现,问题远不止账户积分:所用 Skill 来自第三方,旧版 SDK 会通过明文 HTTP 发送凭据,而且凭据曾被放进全局环境,扩大到了不相关的 Agent 和进程。

我没有为了“功能列表好看”强行把它修到能跑,而是把状态明确标成 DORMANT:禁用 Skill、撤掉全局凭据、按已暴露处理并要求服务端轮换。投资研究先走已经验收通过的 mx-ds 数据路径。

这可能是整个项目里最重要的一次取舍:能用,不等于应该用。

3. 十一个 Agent,不等于十一份并发

这是一台资源有限的小型 VPS。验收时我曾把多个模型测试、远程检查和 MCP 探测叠在一起,结果直接触发了主机 OOM。

最后的配置非常克制:Agent 总并发 2、子 Agent 并发 2、最大深度 1、单任务最多两个子 Agent、Cron 并发 1。需要更多专家就排队,MCP 验收全部串行。

从那以后,我宁可让任务排队慢一点,也不再拿整台机器的稳定性赌并发。

4. Sandbox 不能为了打勾而提权

Docker 镜像已经准备好,但 OpenClaw 的服务账号不能安全访问 Docker socket。最省事的办法,是把它加入 Docker 管理组;可这几乎等于给了接近 root 的主机控制权。

我最终选择承认 Docker Sandbox 仍然是 DEGRADED,继续用 exec deny、workspaceOnly、独立目录、窄工具和 MCP 分域做逻辑隔离。标签不好看没关系,边界不能自欺欺人。

5. 运维 Agent 不能拿到“看起来只读”的通用命令

命令白名单如果只限制可执行文件路径,并不能限制参数。允许 systemctl status 的同时,很可能也等于放开 systemctl restart

因此 ops 最后没有任意 Shell,只拿到五个固定、无参数、只读的诊断动作。需要修改、重启、发布时,仍然走独立授权和回滚流程。

我怎么证明它真的能用

我不再把“配置校验通过”当作上线完成。最终验收至少包括:

  • 11/11 Agent 启动与固定模型检查;
  • 20/20 路由用例;
  • 十类越权负向测试;
  • Prompt Injection 代表测试;
  • 七个 MCP 的协议和实际业务调用;
  • main 无业务 MCP、无任意 Shell;
  • 原有 15 条 Cron 完整保留;
  • 双专家协作后只由 main 输出一条最终消息;
  • 微信单次投递事件的 resultCount=1
  • 回滚备份、权限和校验和验证。

我也保留了三个不那么好看的状态:Docker Sandbox 是 DEGRADED,Tushare 是 DORMANT,真人微信完整入站在最终复测前是 PENDING-HUMAN

以前做个人项目,我很容易把“差不多能跑”写成“已经完成”。这次反而是这些明确的状态,让整套系统更可信。

多智能体的五层安全边界

做完以后,我重新理解了“管理”

回头看,这次最有价值的不是多了十个 Agent,而是我给这支团队留下了几条很朴素的规矩:负责人保留必要控制权,专家只做职责内的事;信息只传完成任务所需的部分;交付要说明证据、风险和不知道的地方;能力不等于授权;出问题先留现场,上线前先想好怎么退回去。

我原来以为,多智能体的重点是“多”。现在我更愿意说,它的重点是“组织”。

做到这些以后,我才敢把它接进每天都用的微信入口,而不只是留在测试窗口里演示。

完整的脱敏配置、Prompt、Handoff Schema、命令和验收清单,我整理在独立仓库:openclaw-multi-agent-team

本文著作权归作者所有;未经许可请勿全文转载。

如果这篇文章对你有帮助,可以给它点个赞。

Connect

持续跟踪通信仿真、AI 辅助研发与技术管理

如果你也关注系统仿真、AI for RAN、研发效能和团队管理,欢迎通过邮件交流具体问题和实践经验。

也欢迎围绕仿真平台、AI Coding 落地、技术团队管理等主题交流具体问题和实践经验。

Next Reading

优先推荐标签或分类相关的文章;没有足够相关内容时,补充最新文章。