一个 Agent 能帮你写一个函数,不代表它能帮你交付一个功能;能交付一个功能,不代表它能可靠地交付整个系统。

上一篇《模型不是关键,Harness 才是》讲了单 Agent 场景下的 Harness 最佳实践——怎么写 AGENTS.md、怎么省 Token、怎么设计记忆系统。

但当你面对的真实任务是这样的:

一个 Agent 就不够了。你需要一群 Agent 协作

问题来了:从 1 个 Agent 到 N 个 Agent,你的 Harness 要怎么变?

这篇文章用 6 个维度做对比——通信方式、验证机制、身份设计、状态管理、错误恢复、进化机制——每个维度告诉你单 Agent 怎么做,多 Agent 为什么必须换打法。

image


为什么不能直接「一个 Agent 干所有事」

先说结论:不是模型不够聪明,是上下文装不下,约束管不住。

单 Agent 的根本限制在于 context window 是独占资源。一个 Agent 要同时记住需求约定、架构规范、历史教训、当前任务状态、工具定义——还没开始干活,context 已经被基础设施占掉了一半。

更致命的是约束漂移。你在项目开头告诉 Agent「所有时间字段必须用 UTC 存储」「API 路由必须按 /m//s/ 约定字母」——到了第 30 轮对话,它可能已经在某个新文件里用了本地时间、自创了一个 /manage/ 路由。这不是 Agent 故意偷懒,而是 context window 越长,早期信息的权重就越低。你说的规则没有被覆盖,只是被「稀释」了。

多 Agent 不是为了炫技,而是为了把一个装不下的上下文拆成多个装得下的上下文,每个 Agent 专注一个领域,约束更少但更刚性。


维度一:通信方式——从「对话」到「文件」

单 Agent 怎么做

所有信息在 context window 里流转——prompt + memory + tool results。你跟 Agent 的对话历史就是全部上下文。

优点:简单直接,信息无损。 缺点:上下文越跑越臃肿,越往后信息越多越杂,关键约束容易被淹没。

多 Agent 怎么做

Agent 之间靠文件传递信息,不靠对话历史。

具体来说:协调者 Agent(Orchestrator)把任务指令、需求澄清结果、状态追踪信息写成文件,传递给下游子专家 Agent。每个 Agent 独立读写文件,下游 Agent 用的时候去读文件,不需要知道上游 Agent 的完整对话历史。

协调者 Agent
  │
  ├─写入→ task_instruction.md(任务指令)
  ├─写入→ requirement_clarification.md(需求澄清结果)
  ├─写入→ state_trace.md(状态追踪)
  │
  ▼
子专家 Agent A(需求拆解)
  │ 读取上游文件 → 工作 → 写入产出文件
  ▼
子专家 Agent B(方案设计)
  │ 读取上游文件 → 工作 → 写入产出文件
  ▼
子专家 Agent C(SQL 开发)
  │ 读取上游文件 → 工作 → 写入产出文件
  ▼
子专家 Agent D(测试验证)

为什么必须这样?

核心转变:单 Agent 的上下文是「记忆」,多 Agent 的上下文是「契约」。 记忆会模糊,契约不会。


维度二:验证机制——从「自检」到「分离」

单 Agent 怎么做

同一个 Agent 写完代码后自己检查。上一篇讲过的五层自我修复 Harness 里的 Hooks、CI、test、lint 都属于这一类——在 Agent 循环外部用确定性工具做验证。

优点:工具链成熟(PostToolUse hook、Stop hook、CI pipeline)。 缺点:Agent 对自己生成的内容有认知盲区——它几乎都觉得自己写的「挺好的」。

多 Agent 怎么做

写东西的人和判断「写得行不行」的人必须是两个不同的角色

生成者(Generator)          评估者(Evaluator)
┌──────────────┐           ┌──────────────┐
│  子专家 Agent  │  ──产出──▶ │  审查 Agent    │
│  写代码/方案   │           │  用独立标准检查 │
│  自带生成逻辑  │           │  不受生成者影响 │
└──────────────┘           └──────────────┘

为什么必须分离?

问题出在 LLM 的底层机制:生成文本和评估文本用的是同一套模型参数,这让 Agent 天然倾向于认为自己产出的是合理的——它没有「跳出来看」的能力。就像让一个学生自己批改自己的考卷,满分几乎是必然结果。

分离之后,评估者用独立的、预设的标准检查,不受生成者推理过程的影响。这比「让 Agent 自己反思一下」可靠得多。

可靠性比能力上限更值钱。 一个能力 80 分但行为可预测的 Agent,比一个能力 95 分但偶尔失控的 Agent 更适合生产环境——因为你敢给它权限。

单 Agent 用户能借鉴什么

即使你只用一个 Agent,也可以用 Stop hook 做完成验证——让一个独立进程(不是 Agent 本身)检查产出是否满足预设条件。这本质上就是 Generator-Evaluator 分离的简化版。


维度三:身份设计——从「一份文件」到「一支团队」

单 Agent 怎么做

一份 AGENTS.md 定义所有行为——规则、约束、知识、流程全在一个文件里。上一篇讲过,这份文件应该控制在 60 行以内,太多 Agent 会「选择性遵守」。

多 Agent 怎么做

身份设计变成了组织架构设计

首先,架构选型是 Orchestrator + Specialist

协调者身上叠了 6 个显式定义的角色身份

角色 做什么
分派 根据任务类型决定调用哪个子专家
确认 信息不足时向用户追问
复查 用独立标准检查子专家产出
放行 通过硬性门禁检查才继续下一步
通报 向用户汇报进展和结果
容错 判断该重试、回退还是终止

其次,每个 Agent 的规则体系采用三层金字塔

层级 内容 信号强度
顶层:超级红线 违反即严重事故,数量极少 最强,Agent 必须绝对遵守
中间层:错误记录 历史教训总结 中等,系统进化的燃料
底层:操作规则 知识库检索流程、产出模板、错误处理标准 最弱,太多会选择性遵守

为什么要分层?

规则的效力跟它的数量成反比。当所有规则都写得一样严厉,Agent 要么全部忽略,要么过度保守——它分不清哪些是真正的底线,哪些只是建议。

分层的本质是给规则标优先级。红线是「违反即停」的硬约束,操作规则是「尽量遵守」的软建议。标清楚优先级,Agent 才知道什么时候可以灵活、什么时候必须刹车。

单 Agent 用户能借鉴什么

你的 AGENTS.md 也应该分层:


维度四:状态管理——从「无状态」到「状态机」

单 Agent 怎么做

Session 断了就重来。上一篇讲过的 CLAUDE.md + MEMORY.md 是最接近「状态」的东西,但它们是被动的——Agent 不主动追踪「我现在在流程的哪一步」。

多 Agent 怎么做

定义 12 个明确状态枚举,从「需求接收」到「完成」覆盖全流程的每一个节点:

需求接收 → 需求澄清 → 需求确认 → 方案设计 → 方案评审 →
方案确认 → 开发中 → 开发完成 → 测试中 → 测试通过 →
上线检查 → 完成

每个任务维护一份状态追踪文件。任意时刻终止流程,下次恢复时先读这份文件,几秒钟就能回到断点,不需要重跑任何已完成的步骤。

每个阶段结束时,还会强制压缩成固定格式的 Checkpoint,追加到状态文件里:

阶段:API 设计完成
传递给前端开发 Agent 的关键信息:
  - 端点:POST /api/articles
  - 认证:需要 cookie token
  - 时间字段:UTC(ISO 8601 格式)
待关注事项:图片上传接口尚未就绪

这个 Checkpoint 格式有多重要?

它不是给人看的总结,是给下一个 Agent 看的契约。下一个 Agent 启动时读这个文件,就能知道:上游做了什么决定、传了什么信息、有什么需要注意的——不需要读完整的对话历史。

单 Agent 用户能借鉴什么

在 Claude Code 里,你可以用 exec-plans/ 目录 + checkpoint 文件做类似的事:

这比依赖 Agent 的「记忆」可靠得多。


维度五:错误恢复——从「重试」到「分级回退」

单 Agent 怎么做

错了就改改再试。上一篇讲过每次失败分三类处理:旧错复发→写 CLAUDE.md;机器可判断的错误→写成 hook/lint/test;任务流程不稳定→写成 Skill/workflow。

多 Agent 怎么做

三档故障分级,每档有明确的处理方式:

级别 场景 处理方式
可重试 知识库检索失败、API 超时 自动重试 1-2 次,异常自愈
需回退 方案设计不通过、代码测试不通过 退回上一个稳定存档点,重新调用
必须中止 需求理解根本性偏差、依赖安装失败 停下来,坦诚告知用户

关键是第二档:回退到稳定存档点

单 Agent 出错时,最坏的情况是重头开始。但多 Agent 系统里,前面的步骤可能是几个小时的工作(需求澄清、方案设计、多个 Agent 协作)。如果第 4 步测试不通过,你不能让前面 3 步全部白做。

有了状态机 + checkpoint,你可以:

  1. 检测到测试不通过
  2. 找到上一个通过的存档点(比如「方案确认」状态)
  3. 退回那个状态,重新执行「开发中」
  4. 不动「需求澄清」和「方案设计」的产出

这就是状态机 + 文件驱动的威力——错误可以被隔离在局部,不会全局回滚

单 Agent 用户能借鉴什么

在 Claude Code 里,你可以通过 git commit + exec-plans 实现类似的效果:


维度六:进化机制——从「个人记忆」到「组织学习」

单 Agent 怎么做

踩坑→写进 CLAUDE.md。上一篇讲过,AGENTS.md 文件里的每一行规则,背后都对应着 Agent 曾经犯过的一个错。但这是个人记忆——只有这个项目的这个 Agent 知道。

多 Agent 怎么做

踩坑变成三级驱动的组织学习

  1. 实时记录:用户指出「你做错了」的下一秒就必须落库
  2. 自动加载:所有 Agent 启动时强制加载历史教训文件
  3. 行为约束迭代:反复出现的错误自动升级为超级红线

区别在于:单 Agent 的经验只存在于一个 CLAUDE.md 里,而多 Agent 的经验进入了一个共享知识库,所有 Agent 都受益。

踩过的坑必须变成系统的一部分——一条 CI 检查、一个 lint 规则、一个 hook 脚本。 只要它还只存在于 prompt 或记忆里,就一定会再犯。

单 Agent 用户能借鉴什么

如果你有多个项目,可以维护一个全局的 ~/.claude/CLAUDE.md(用户级记忆),把跨项目的通用教训放进去。每个项目的 ./CLAUDE.md 只放项目特定的规则。这就是上一篇讲过的六层级记忆架构——全局规则、项目规则、个人规则各司其职。


速查表:单 Agent vs 多 Agent Harness 对比

维度 单 Agent 多 Agent
通信 context window 内传递(记忆) spec 文件传递(契约)
验证 自检 + 外部工具(Hook/CI) Generator + Evaluator 分离
身份 一份 AGENTS.md Orchestrator(6 角色)+ 多个 Specialist
状态 无状态(断了重来) 12 状态枚举 + checkpoint
恢复 重试(最坏重头开始) 三级分级(重试/回退存档点/中止)
进化 踩坑→写 CLAUDE.md(个人记忆) 踩坑→共享知识库(组织学习)

什么时候该从单 Agent 升级到多 Agent

不是所有任务都需要多 Agent。判断标准很简单:

如果一个 Agent 能在单次 session 里完成,并且中间不需要切换知识领域——用单 Agent。

以下任何一个信号出现,就该考虑多 Agent:

杀鸡不用宰牛刀。 对于常规任务,单个 Agent 循环往往够了。多 Agent 的复杂性只有在它解决的问题比它引入的问题多的时候才值得。


总结

从 1 个 Agent 到 N 个 Agent,不是简单地把一个 Agent 复制 N 份。你的 Harness 要完成 6 个根本转变:

  1. 通信:从对话记忆变成文件契约
  2. 验证:从自检变成角色分离
  3. 身份:从一份文件变成一支团队
  4. 状态:从无状态变成状态机
  5. 恢复:从重试变成分级回退
  6. 进化:从个人记忆变成组织学习

每个转变背后都是同一个原则:把依赖 Agent「自觉性」的东西,变成依赖系统「结构」的东西。

Agent 不会自主学习进化。如果你不把这些知识写进系统结构里,它第一百次犯的错会和第一次一模一样——不管它是一个 Agent 还是一百个 Agent。

Harness Engineering 的本质从来不是让 Agent 更聪明,而是让系统更可靠。 从单 Agent 到多 Agent,你解决的不是「能力问题」,而是「规模化之后的可靠性问题」。

← 返回文章列表