目标不是做一个更炫的多 Agent 图,而是让 Claude 能在无人持续干预的情况下, 把一个真实应用从一句 Prompt 推进到可用项目。为此,Harness 必须先解决长程项目里会反复出现的跑偏、漏做和自评过宽。
这篇文章的主线是:为了让 Agent 自动完成一个完整项目, 先用 Planner 把含糊 Prompt 扩成 feature list,再让 Generator 和挑剔的 Evaluator 围绕每个 feature 反复协商、实现、测试和修复。
Generator/Evaluator 的价值来自两个失败事实:长程任务会失去连贯性,模型又很容易宽容地通过自己的半成品。 外部 QA、硬阈值和可测试契约,才把“看起来完成”推向“真的能用”。
原文讨论的 Harness,不是为了让输出看起来更复杂,而是为了让模型从一句模糊需求出发, 在几个小时的无人干预中持续推进,最后交付一个功能真的可用的完整应用。
这篇文章的起点是一个产品工程问题:用户只给 1-4 句话, Claude 要自己补全产品规格、拆出 feature、实现应用、发现问题、再修到可用。 如果只把它理解成“Generator 和 Evaluator 互相发消息”,就会丢掉最重要的设计目的。
所以叙事应该先问:一个长程项目为什么不能靠单 Agent 一路写到底? 然后再看 Harness 里的每个部件分别补哪个缺口。 Planner 补规格,Generator 补实现,Evaluator 补外部判断和真实使用验证。
过去的长任务 Harness 已经在用「初始化 Agent + 编码 Agent + 结构化交接」, 但在复杂任务上,Agent 仍然会跑偏。把这件事拆开来看,能分成两个截然不同的问题。
这部分是理解全文的地基。作者并不是一开始就想做复杂的多 Agent 系统, 而是先从失败日志里拆出了两个反复出现的问题:长上下文下的连贯性下降,以及模型对自己产出的过度宽容。
第一个问题偏工程编排:什么时候该重置上下文,怎样交接状态。 第二个问题偏判断力:即使任务有测试,模型也可能因为自我评估太松而把半成品当成完成品。 后文的 Planner、Generator、Evaluator 都是在回应这些具体失败,而不是为了架构复杂而复杂。
真正的结构不是两个 Agent 空转互评,而是先把项目边界固定下来: Planner 把需求扩成 feature list;随后每个 feature 都经历“契约 → 实现 → QA → 修复”的闭环。
这套 Harness 的关键,是把“完成一个应用”拆成两个层级。 第一层是全局规划:Planner 不写实现细节,而是把一句话需求变成有野心但仍然高层的产品规格和 feature list。 第二层是局部闭环:Generator 每次只拿一个 feature,先和 Evaluator 谈清楚怎样算完成,再开始写代码。
Evaluator 的职责也不是“事后写几句评价”,而是像用户一样打开真实应用, 点击 UI、调用 API、检查数据库状态,并用硬阈值决定当前 feature 是否通过。 不通过时,反馈回到 Generator,下一轮围绕同一个 feature 修复。
提出 sprint contract,说明要做什么、怎样验证,然后实现当前 feature。
先审核 contract,再用 Playwright MCP 操作真实应用;未达标就返回具体 Bug。
上一节是总图;这一节拆开看每个角色为什么存在,以及 contract 为什么要发生在写代码之前。
这套设计的关键不是把任务平均分给三个 Agent,而是让每个 Agent 避开不适合自己的判断。 Planner 不决定底层实现;Generator 不独自裁决质量;Evaluator 不写主要代码,而是把“是否真的可用”拉回到外部证据上。
这里最值得注意的是 Sprint 契约。 产品规格刻意保持高层,避免过早钉死实现细节;但真正写代码之前, Generator 和 Evaluator 要先把“这一步怎样算完成”谈清楚。 这一步把抽象需求翻译成了可测试行为。
Prompt:「做一个 2D 复古游戏制作器,包含关卡编辑器、精灵编辑器、实体行为系统,以及可试玩的测试模式。」
Harness 跑的成本是单跑的 20 倍以上 —— 但输出质量的差距是肉眼可见的。
这组对比是全文最有说服力的部分:单 Agent 版本看起来接近完成, 但一旦真实使用,核心玩法链路就断了。完整 Harness 贵很多、慢很多, 但它把同一句简单 Prompt 扩成了更完整的产品,并且让关键路径真的可用。
所以这里的结论不是“多花钱就一定更好”,而是当任务处在模型单跑能力边缘时, Planner 和 Evaluator 会把输出从“表面完整”推向“实际可操作”。
Evaluator 报出的问题具体到不需要额外排查就能直接动手修 —— 指出代码位置、函数名、错误的路由顺序。开箱即用的 Claude 其实是个糟糕的 QA (会主动给自己台阶下,把真问题说成不大要紧),需要好几轮对 QA Prompt 的调教才达到能用的水平。
这些 Bug 例子应该直接露出来,因为它们证明 Evaluator 不是在写泛泛而谈的建议。 好的 QA 反馈要能落到具体行为、具体代码路径、具体失败条件上,Generator 才能在下一轮真正修复。
fillRectangle 函数已经存在,但没有在 mouseUp 上正确触发。
LevelEditor.tsx:892 处的 Delete 键处理同时要求 selection 和
selectedEntityId 都被设置,但点选一个实体时只会设 selectedEntityId。
条件应改成 selection || (selectedEntityId && activeLayer === 'entity')。
PUT /frames/reorder 路由定义在了 /{frame_id} 之后。
FastAPI 把 'reorder' 当成了 frame_id 整数去解析,
直接返回 422: "unable to parse string as an integer."
第一版 Harness 笨重、慢、贵。后续的「瘦身」一半是常识,一半是更深一层的原则: Harness 里的每个部件,本质上都在编码一个关于「模型自己做不到什么」的假设 —— 模型一变强,这些假设就可能立刻过时。
后半篇的重点是“删东西”。作者不是把三 Agent Harness 当成最终形态, 而是随着 Opus 4.6 的能力变化,重新检查哪些组件还在承重。 Sprint 切分从必要约束变成了可以移除的开销,Evaluator 也从每个 Sprint 都评估,变成最后集中评估。
这让文章的观点更细:Harness 不是越复杂越先进。 它应该随着模型能力移动,只在模型当前还不可靠的边界上增加外部结构。
| Agent / 阶段 | 用时 | 成本 |
|---|---|---|
| Planner | 4.7 min | $0.46 |
| Build · 第 1 轮 | 2 hr 7 min | $71.08 |
| QA · 第 1 轮 | 8.8 min | $3.24 |
| Build · 第 2 轮 | 1 hr 2 min | $36.89 |
| QA · 第 2 轮 | 6.8 min | $3.09 |
| Build · 第 3 轮 | 10.9 min | $5.88 |
| QA · 第 3 轮 | 9.6 min | $4.06 |
| V3 Harness 总计 | 3 hr 50 min | $124.70 |
模型变强时,套在它外面的脚手架往往会变得不那么重要。 但反过来:模型越强,越有空间去搭一些超出它原生能力之外的复杂 Harness。
最后的结论可以压成一句工程判断: 先用真实模型在真实任务上读 trace,再决定要给模型外面加什么结构。 如果一个组件不能解释清楚它补的是哪个能力缺口,就应该被怀疑。