Esc
输入关键词开始搜索
Agent

harness design long running apps.md

原文:Harness Design for Long-Running Application Development 作者:Prithvi Rajasekaran(Anthropic Labs 团队) 发布日期:2026 年 3 月 24 日


一、文章定位:Anthropic Agent 工程系列的第四篇

要理解这篇文章的分量,必须先把它放在 Anthropic 整个 Agent 工程系列中来看。这个系列构成了一条清晰的技术演进线:

  1. Effective Context Engineering for AI Agents(2025.09)——解决”Agent 的上下文应该放什么、怎么管理”这个基础问题
  2. Building Effective Agents(2025)——Agent 设计的总纲领,提出”找到最简单的可行方案,只在需要时增加复杂度”这个核心原则
  3. Effective Harnesses for Long-Running Agents(2025.11)——初版 Harness,用 Initializer Agent + Coding Agent + Context Reset 解决跨上下文窗口的长时工作
  4. 本文(2026.03)——在前作基础上引入 GAN 灵感的 Generator-Evaluator 结构,演进为三 Agent 架构,并展示了随模型升级(Sonnet 4.5 → Opus 4.5 → Opus 4.6)如何系统性地简化 Harness

每一篇都建立在前一篇的发现之上,而本文是目前为止最完整的一篇——它不仅提出了新架构,还回溯了整条技术路径,展示了每个设计决策的原因、权衡和演进。


二、起点:前作的成就与天花板

2.1 前作做了什么

在 2025 年 11 月的前作中,Justin Young 等人描述了一个两部分方案:

  • Initializer Agent:第一个会话使用专门的 prompt,让模型搭建初始环境——init.sh 脚本、claude-progress.txt 进度文件、初始 git commit。最关键的是,它会基于用户 prompt 生成一个结构化的 feature list(JSON 格式,200+ 个 feature),每个都标记为 passes: false
  • Coding Agent:后续每个会话的 Agent 遵循固定流程——先 pwd 确认目录 → 读 git log 和 progress 文件恢复状态 → 从 feature list 挑最高优先级的未完成 feature → 实现 → 用 Puppeteer MCP 做端到端测试 → 写 git commit 和 progress update → 交班。

前作解决了四个核心失败模式:

失败模式解决方案
Agent 一口气尝试做完整个项目Feature list 强制逐个功能实现
Agent 过早宣布项目完成Feature list 中有明确的 passes: false 标记
Agent 留下一团乱麻(bug + 无文档)每个会话结束时必须 git commit + 写 progress update
Agent 标记功能完成但没有真正测试强制使用浏览器自动化工具做端到端测试

2.2 前作碰到的天花板

前作在结尾坦承了一个关键的未解决问题:

“是否一个通用的单 coding agent 在所有上下文中表现最好,还是多 agent 架构能通过专门化实现更好的性能?专门化的 agent——如测试 agent、QA agent、代码清理 agent——似乎可以在软件开发生命周期的子任务上做得更好。”

本文正是对这个问题的直接回答:是的,多 Agent 架构能做得更好,而且好很多。

同时,前作还有两个未显式提到但从描述中可以推断的限制:

  1. 需要用户提供详细的产品规格——Initializer Agent 只是将规格分解为 feature list,不能自己扩展规格的范围
  2. 没有解决”审美质量”问题——对于前端设计这类主观任务,即使 feature 全部 pass,视觉质量仍可能平庸

本文同时解决了这两个问题。


三、两大失败模式的深入分析

3.1 失败模式一:上下文退化与 Context Anxiety

作者在本文中对上下文管理问题进行了比前作更精确的概念化。他区分了两个不同但相关的现象:

上下文退化(Context Degradation):随着上下文窗口填满,模型对较早信息的把握逐渐模糊,输出的连贯性下降。这是一个渐进的过程,所有使用长上下文的场景都会遇到。

Context Anxiety(上下文焦虑):某些模型在”认为”自己接近上下文限制时,会主动开始收尾工作——即使实际上还有大量工作未完成。这不是因为真的没有上下文空间了,而是模型习得的一种行为模式:它在训练中学到了”上下文快用完了应该收尾”,于是在推理时过早触发这个行为。

作者对两种缓解方案的分析是文章的一个重要技术贡献:

Compaction(对话压缩)

  • 做法:将对话历史的早期部分进行摘要压缩,让 Agent 在缩短的历史上继续工作
  • 优点:保持连续性,同一个 Agent 继续工作,无需交接
  • 缺点:不能解决 Context Anxiety。因为 Agent 虽然上下文变短了,但它”记得”自己已经工作了很久。压缩后的摘要本身就暗示了大量的历史工作,模型仍然会觉得”快到头了应该收尾”
  • 本质:Compaction 解决的是信息衰减问题,但不解决行为模式问题

Context Reset(上下文重置)

  • 做法:完全清空上下文窗口,启动一个全新的 Agent 实例,通过结构化的交接文件(handoff artifact)将前一个 Agent 的状态和下一步计划传递给新 Agent
  • 优点:彻底消除 Context Anxiety——新 Agent 从全新的空白状态开始,没有”我已经工作很久了”的认知负担
  • 缺点:增加了编排复杂度(需要编排多个 Agent 实例的生命周期)、token 开销(交接文件本身消耗 token)、延迟(每次 Reset 都有启动开销)
  • 额外要求:交接文件必须包含足够的状态信息,让新 Agent 能够干净地接手工作。这本身就是一个需要精心设计的问题

实测结论:在 Sonnet 4.5 上,Context Anxiety 严重到 Compaction 单独使用不够,Context Reset 成为 Harness 的必要组件。但到了 Opus 4.5,这个行为基本消失了,所以作者完全去掉了 Context Reset,回归了单会话 + 自动 Compaction。再到 Opus 4.6,由于长上下文检索能力的进一步提升,模型可以在单个连续会话中运行超过 2 小时而不失去连贯性。

深层启示:Context Anxiety 是一个模型行为问题,不是架构问题。它是训练过程的副产物,随着训练方法的改进可以被直接消除。这意味着为解决它而引入的 Harness 复杂度是”暂时的桥梁”,而非”永久的架构需求”。作者后续”每个组件都是对模型能力边界的假设”这一原则,正是从这个具体经验中提炼出来的。

3.2 失败模式二:自我评估失效

这是本文的核心发现之一。作者观察到一个一致的现象:当 Agent 被要求评估自己刚刚完成的工作时,它会系统性地高估质量

这不是偶发现象,而是 LLM 的一个结构性倾向。作者将其分解为两个层面:

主观任务上的表现:对于设计这类没有二元对错的任务,Agent 在评价自己的设计时会”自信地夸赞”——即使在人类观察者看来,输出明显是平庸的模板拼凑。不存在像”测试通过/失败”这样的客观检查来纠正它。

即使在有可验证结果的任务上:作者特别指出,这个问题不限于主观任务。即使在有对错标准的编码任务中,Agent 也会在执行过程中表现出”判断力不足”——比如忽略明显的 bug、对 stub 实现表示满意、看到运行不报错就认为一切正常。

为什么分离 Generator 和 Evaluator 有效?

作者的解释非常精妙:分离本身不会自动消除 LLM 对 LLM 输出的宽容倾向——评估者仍然是一个 LLM,天然倾向于对 LLM 生成的内容手下留情。但关键在于:

“调优一个独立的评估者使其变得苛刻,远比让一个生成者对自己的工作变得挑剔容易得多。”

这里的工程直觉是:让一个 Agent 既做事又批评自己做的事,是在要求它执行两个矛盾的任务——它刚刚花了大量的推理努力来产出这个结果,现在你要它否定自己的努力。这在认知上是困难的。而一个独立的评估者没有这种”沉没成本”心理,它从全新的视角看到一个成品,可以更客观地评判。

而且,一旦这种外部反馈存在,生成者就有了具体的、可操作的目标去迭代——不再是模糊的”做得更好”,而是”评估者在这三个维度给了你低分,具体原因是 X、Y、Z”。


四、前端设计实验:把主观判断工程化

4.1 问题的本质

在没有任何干预的情况下,Claude 在前端设计上的默认表现是:技术上正确、功能上可用,但视觉上乏味。它会倾向于安全的、可预测的布局——可以称之为”AI 设计泔水(AI slop)“:白色卡片 + 紫色渐变 + 无个性的排版。

这个问题的根源在于,LLM 在训练中看到了大量的”正确但平庸”的网页设计,它习得的”安全策略”就是复制这些常见模式。要让它跳出这个安全区,需要外部压力。

4.2 两个关键洞察

作者在这里提出了两个驱动整个 Harness 设计的核心洞察:

洞察一:主观判断可以被分解为可评分的标准

“这个设计美不美?“这个问题太模糊,LLM 无法一致地回答。但”这个设计是否遵循了我们定义的好设计原则?“给了 Claude 一个可以具体评分的东西。

这是一种将品味工程化的方法——你不能教会模型什么是”美”,但你可以定义一套标准,让模型按照这套标准给出一致的评判。

洞察二:将生成和评分分离,可以创建一个驱动质量提升的反馈循环

这直接借鉴了 GAN 的核心思想——生成器和判别器的对抗推动两者共同进步。但和真正的 GAN 不同,这里不涉及梯度反向传播和权重更新,而是通过 prompt 和文本反馈来实现。

4.3 四维评分标准的详细拆解

这四个标准的设计不是随意的,每个都有明确的意图和权重考量:

1. Design Quality(设计质量)

  • 问的问题:设计是否感觉是一个连贯的整体,而非拼凑的零件?
  • 什么算好:颜色、排版、布局、意象和其他细节组合在一起,创造出独特的氛围和身份(mood and identity)
  • 关键词:“连贯整体”(coherent whole)vs “零件集合”(collection of parts)——这个区分非常精准。很多 AI 生成的页面,每个组件单独看都没问题,但放在一起缺乏统一的设计语言
  • 权重:高(刻意提升)

2. Originality(原创性)

  • 问的问题:是否有自主的设计决策的证据?
  • 什么算差:模板布局、库默认值、AI 生成模式。未修改的库存组件。典型的 AI 生成标志——紫色渐变覆盖在白色卡片上
  • 关键词:“一个人类设计师应该能认出刻意的创造性选择”——这是一个非常高的标准,它要求输出不仅要避免模板感,还要让专业人士认可其中有设计思考
  • 权重:高(刻意提升)
  • 注意:这个标准直接将”AI 泔水”列为扣分项,是一种对 LLM 生成内容固有弱点的精确打击

3. Craft(工艺)

  • 问的问题:技术执行质量如何?
  • 检查项:排版层级、间距一致性、色彩和谐、对比度
  • 性质:能力检查(competence check),不是创意检查(creativity check)
  • 权重:正常——因为 Claude 在这方面默认表现就不错,大多数合理的实现在此项自然达标。失败意味着基本功崩溃
  • 言下之意:如果你在这里都拿不到分,说明其他维度也不用看了

4. Functionality(功能性)

  • 问的问题:独立于美学的可用性
  • 检查项:用户能否理解界面功能、找到主要操作、完成任务而不需要猜测
  • 权重:正常——同样是 Claude 的默认强项

权重策略的哲学:作者刻意将 Design Quality 和 Originality 的权重调高。逻辑是:Claude 已经天然擅长 Craft 和 Functionality(技术能力和可用性自然而然就好),但在 Design Quality 和 Originality 上经常输出平庸的结果。通过加重这两个维度,强制推动模型承担更多美学风险。

这实际上是一种对 LLM 能力分布的精确补偿——哪里弱就在那里加权,而不是均匀地要求所有维度。

4.4 评估者的校准方法

作者使用了 few-shot examples + 详细分数分解 来校准评估者。这确保了:

  1. 评估者的判断与作者本人的偏好对齐
  2. 减少了跨迭代的分数漂移(score drift)

这个细节很关键——没有校准的评估者会随着输入的不同而漂移标准。Few-shot 锚定了评估者的基准线。

4.5 技术实现细节

底层框架Claude Agent SDK——Anthropic 官方的 Agent 编排 SDK,保持了编排的简洁性。

评估者的工具:Playwright MCP——这让评估者不是看截图打分,而是实际操作运行中的页面。在实践中,评估者会自己导航页面、截屏、仔细研究实现,然后才产出评估。

这比静态截图分析有效得多。一个页面可能截图上看着没问题,但实际交互时会暴露布局在特定视口下的问题、hover 效果的缺失、滚动行为的异常等。

生成者的输出:HTML/CSS/JS 前端(基于用户 prompt)

迭代策略:每轮评估后,生成者要做一个战略决策——如果分数趋势向好,就沿当前方向继续精炼;如果方向不行,就彻底转向一种完全不同的美学(pivot)。

这个 pivot 机制非常重要。如果没有它,生成者可能会在一个错误方向上反复打补丁,越改越差。明确允许甚至鼓励推翻重来,是创造性突破的前提。

4.6 迭代运行的参数与观察

迭代次数:每次生成运行 5-15 轮迭代

单轮耗时:因为评估者在实际导航页面(而不是看静态截图),每轮需要真实的 wall-clock time

总运行时间:全量运行最长可达 4 小时

观察到的迭代模式

模式一:分数总体上随迭代改善,但不是线性的。 后期实现整体上更好,但作者多次发现自己更喜欢某个中间迭代而非最终轮。这说明”质量”是多维的,某些维度的改善可能伴随其他维度的退步。

模式二:实现复杂度随迭代递增。 生成者在评估者的反馈推动下,会尝试越来越有野心的方案。这是一个双刃剑——更复杂的实现可能更令人印象深刻,但也更容易出 bug。

模式三:即使第一轮(无评估者反馈),有评分标准的输出就已明显优于完全无 prompt 的基线。 这个发现意义重大——它说明评分标准的文本本身就在 prompt 中起到了引导作用,即使还没有评估者的反馈。标准中的语言和概念塑造了生成者的”审美意识”。

模式四:标准中的措辞会以出乎意料的方式塑造输出。 作者提到,在标准中包含”最好的设计是博物馆品质的”这样的短语,推动了设计向特定的视觉收敛。这暗示了一个深层机制——评分标准不仅是评分工具,它本身就是一种隐性的 prompt engineering,直接影响了生成者的输出特征。

4.7 荷兰艺术博物馆案例

这是文章中最引人注目的单一案例。

前9轮:生成器产出了一个干净的深色主题博物馆落地页。视觉上精致,但在作者的预期范围内——你看到一个黑色背景、白色文字、漂亮图片的页面,会觉得”嗯,不错”,但不会惊讶。

第10轮:生成器彻底推翻了方案。它将网站重新构想为一个空间体验

  • 一个用 CSS 透视渲染的 3D 房间
  • 格子地板
  • 画作以自由位置挂在墙上
  • 门廊导航在画廊房间之间切换,取代传统的滚动或点击导航

作者评价:这是他之前从未从单轮生成中见过的创造性飞跃

这个案例的深层含义是:评估者驱动的迭代+允许 pivot 的机制,可以让 LLM 突破”安全区”,产生真正出人意料的创意输出。第10轮的 pivot 发生,恰恰是因为前9轮的分数虽然在改善但可能遇到了瓶颈,触发了生成者选择”彻底换方向”的策略分支。如果没有这个机制,它可能只会在深色主题落地页的框框里小修小补。


五、全栈编码:三 Agent 架构的完整设计

5.1 从前作到本文的架构演进

维度前作(2025.11)本文 V1(Opus 4.5)本文 V2(Opus 4.6)
Agent 数量2(Initializer + Coder)3(Planner + Generator + Evaluator)3(但 Evaluator 简化)
上下文管理Context Reset(必需)单会话 + 自动 Compaction单会话 + 自动 Compaction
工作分解Feature list + 逐个实现Sprint 分解 + Sprint Contract无 Sprint,自由构建
质量保证Agent 自测(Puppeteer)独立 Evaluator 逐 Sprint 评估独立 Evaluator 仅在最后 pass
规格来源用户提供详细规格Planner 自动扩展Planner 自动扩展
模型Sonnet 4.5Opus 4.5Opus 4.6

5.2 三个 Agent 的详细设计

Planner(规划者)

解决的问题:前作要求用户提供详细的产品规格。这在实际使用中是一个巨大的摩擦——大多数用户只有一个模糊的想法,不会写产品文档。

设计

  • 输入:1-4 句话的简单 prompt
  • 输出:完整的产品规格说明书
  • 被指示要”雄心勃勃”——这是一个有意的设计选择。如果 Planner 保守,生成的产品范围就会有限,最终产品也会单薄。鼓励它大胆设想可以产出更丰富的产品。
  • 聚焦产品上下文和高层技术设计,而非细粒度实现细节

这最后一点的理由值得深入理解。作者的推理是:如果 Planner 试图在前期指定细粒度的技术细节,而某些细节是错误的,那么这些错误会级联到下游的实现中。更聪明的做法是约束 Agent 的可交付成果(deliverables),让它们自己在工作中找到实现路径。

类比:这就像一个好的产品经理——你告诉工程师”用户应该能做 X、Y、Z”(What),而不是”你应该用 React + Redux,在 useEffect 里调 API”(How)。

额外指令:作者还要求 Planner 在规格中寻找机会织入 AI 功能。这是一个巧妙的元级操作——让 AI 在规划产品时主动思考”这个产品的哪些地方可以用 AI 来增强”。

实例:在 RetroForge 游戏制作器的规格中,Planner 不仅规划了核心编辑器,还自主增加了 AI 辅助精灵生成器和 AI 辅助关卡设计器。这些功能在用户原始的一句话 prompt 中完全没有提到。

更细的实例:附录中展示了 Planner 为 RetroForge 生成的产品规格(部分)。它包含了完整的项目概述、目标用户画像、以及详细到 User Story 级别的功能规格。比如”项目仪表板与管理”功能就包含了 5 个 User Story 和完整的数据模型定义(项目元数据、画布设置、瓷砖大小配置、调色板选择等)。这不是一个粗略的大纲——这是一份真正可以拿去开发的产品文档。

Generator(生成者)

角色:代码实现者,按 Sprint 逐个功能实现。

技术栈:React + Vite + FastAPI + SQLite(后期升级为 PostgreSQL)

工作模式(V1,Opus 4.5):

  1. 从规格中按优先级挑选一个功能
  2. 与 Evaluator 协商 Sprint Contract
  3. 实现该功能
  4. 自评
  5. 交给 Evaluator QA
  6. 根据 Evaluator 反馈修复问题
  7. 进入下一个 Sprint

版本控制:有 git,这让 Generator 可以 revert 错误的代码变更,恢复到已知的良好状态

自评环节:在交给 Evaluator 之前,Generator 先自评。这不是替代外部评估,而是在外部评估之前先过滤掉明显的问题,减少 Evaluator 的负担。

Evaluator(评估者)

角色:独立的 QA Agent,用用户视角测试运行中的应用。

工具:Playwright MCP——让它可以像用户一样点击、导航、输入、截屏。

评估维度(从前端实验改编,适配全栈场景):

  • Product Depth(产品深度)
  • Functionality(功能性)
  • Visual Design(视觉设计)
  • Code Quality(代码质量)

评分机制:每个维度有硬性阈值,任何一个维度低于阈值,Sprint 就失败(FAIL),Generator 获得详细的失败反馈。

测试范围:UI 功能、API 端点、数据库状态——全方位的端到端测试。

5.3 Sprint Contract 机制详解

Sprint Contract 是本文的一个重要创新。它的完整工作流是:

  1. Generator 提出:我打算在这个 Sprint 中构建 X,成功标准是 Y1、Y2、Y3…
  2. Evaluator 审查:审查提案是否合理——Generator 是否在构建正确的东西?成功标准是否可测试?是否遗漏了重要方面?
  3. 两者迭代:如果 Evaluator 有异议,Generator 修改提案,直到双方达成一致
  4. 达成一致后:Generator 按照合同开始编码,Evaluator 将使用合同中的成功标准来测试最终输出

为什么需要这个机制?产品规格是故意写得高层次的(避免细节错误级联),但 Evaluator 需要具体的、可测试的行为来判定通过/失败。Sprint Contract 就是这个桥梁。

合同的粒度:文章提到,Sprint 3(关卡编辑器)的合同就有 27 个测试标准。这不是泛泛的”关卡编辑器应该能工作”,而是像”矩形填充工具应允许点击拖动来用选定瓷砖填充矩形区域”这样具体的行为描述。

5.4 Agent 间通信:基于文件

Agent 之间的通信通过文件系统进行——一个 Agent 写一个文件,另一个 Agent 读取并回应(要么在同一个文件中回应,要么写一个新文件让前一个 Agent 读取)。

这个看似低技术的选择有深刻的优势:

  • 可审计:所有通信都以文件形式持久化,事后可以完整回溯
  • 可重启:如果某个 Agent 崩溃,从文件恢复状态
  • 可调试:人类可以直接打开文件阅读理解 Agent 之间的对话
  • 无并发问题:Agent 是串行执行的,一个写完另一个读
  • 与 git 自然集成:文件变更可以被 git track,形成通信的版本历史
  • 对 LLM 友好:读写文件是 LLM Agent 最基本的操作,不需要复杂的消息传递协议

六、实测对比:Solo vs Full Harness

6.1 测试 prompt

Create a 2D retro game maker with features including a level editor, 
sprite editor, entity behaviors, and a playable test mode.

6.2 数据对比

维度Solo(单 Agent)Full Harness(三 Agent)
时间20 分钟6 小时
成本$9$200
成本倍率1x22x
功能范围基本编辑器 + 播放模式16 个功能、10 个 Sprint

6.3 Solo 的具体问题

作者逐一描述了 Solo 运行的每个问题:

  1. 布局浪费空间:固定高度的面板留下了大量空白视口
  2. 工作流僵硬:试图填充关卡时,系统提示需要先创建精灵和实体,但 UI 中没有任何引导告诉你应该按这个顺序操作
  3. 核心功能坏了:实体出现在屏幕上,但不响应任何输入。作者挖掘代码后发现,实体定义和游戏运行时之间的连线是断的(wiring was broken),而且表面上看不出哪里出了问题

最后这一点最致命——不是某个可见的错误,而是两个系统之间的集成断裂,只有深入代码才能发现。这正是单 Agent 自评的盲点——它写了两个系统,各自可能单独”看起来没问题”,但它没有从端到端的视角验证它们是否真正连通。

6.4 Full Harness 的表现

  1. Planner 的规格扩展:一句话 prompt → 16 个功能、10 个 Sprint。包含精灵动画系统、行为模板、音效音乐、AI 辅助精灵生成器和关卡设计器、游戏导出和分享链接。远远超出用户 prompt 的原始范围
  2. Planner 读取了 frontend design skill:它用这个 Skill 为应用创建了一套视觉设计语言(visual design language),作为规格的一部分。这确保了整个应用有一致的视觉身份
  3. 布局改善:Canvas 使用全视口,面板尺寸合理,界面有一致的视觉身份
  4. 精灵编辑器更丰富:更干净的工具调色板、更好的颜色选择器、更可用的缩放控件
  5. AI 功能集成:内置 Claude 集成,可以通过 prompt 生成游戏的不同部分——显著加速了工作流
  6. 核心功能可用:能够实际移动角色、游玩关卡

仍然存在的问题

  • 工作流仍然不够直观——仍然需要用户自己摸索出”先创建精灵和实体再填充关卡”的顺序。作者认为这是模型产品直觉的缺陷,而非 Harness 能解决的问题,但也指出这是 Harness 可以进一步优化的方向
  • 物理引擎有粗糙之处——角色跳上平台会与平台重叠
  • AI 生成的关卡有局限——有一堵跳不过去的大墙

6.5 Evaluator 抓到的真实 Bug 案例

文章给出了三个具体的 bug 案例,每个都值得仔细分析:

Bug 1:矩形填充工具

  • 合同标准:矩形填充工具应允许点击拖动来用选定瓷砖填充矩形区域
  • Evaluator 发现:工具只在拖动的起始和结束点放置瓷砖,而不是填充整个区域。fillRectangle 函数存在但在 mouseUp 时没有被正确触发
  • 分析:这是一个经典的”函数存在但未被正确调用”的集成 bug。Generator 写了填充函数,也写了鼠标事件处理,但没有正确连接两者

Bug 2:实体删除

  • 合同标准:用户可以选择并删除已放置的实体生成点
  • Evaluator 发现LevelEditor.tsx:892 行的 Delete 键处理需要同时设置 selectionselectedEntityId,但点击实体只设置了 selectedEntityId。条件应该是 selection || (selectedEntityId && activeLayer === 'entity')
  • 分析:这是一个逻辑条件错误。Evaluator 不仅发现了 bug,还精确到了文件名、行号、并给出了正确的修复条件。这个级别的诊断精度意味着 Generator 可以直接去修复,不需要额外的调查

Bug 3:动画帧重排序 API

  • 合同标准:用户可以通过 API 重新排列动画帧
  • Evaluator 发现PUT /frames/reorder 路由定义在 /{frame_id} 路由之后。FastAPI 将 ‘reorder’ 字符串匹配为 frame_id 的整数参数,返回 422:“unable to parse string as an integer”
  • 分析:这是一个 FastAPI 路由顺序问题——路径参数和具名路径的优先级冲突。这种 bug 在代码审查中很容易被人类发现,但 Agent 自测时往往不会去测试这种特定的路由组合

这三个 bug 的共同特点是:它们都不是通过看代码就能发现的,而是通过实际操作运行中的应用才暴露的。 这正是使用 Playwright MCP 进行端到端测试的价值所在。


七、调优 Evaluator 的血泪史

这个部分是全文最有实操价值的段落之一。

7.1 开箱即用的 Claude 是个糟糕的 QA Agent

作者坦承:

“Out of the box, Claude is a poor QA agent.”

具体表现:

  • 识别出了合理的问题 → 然后说服自己这些问题”不是什么大问题” → 批准工作
  • 倾向于表面测试(happy path),而非探测边界情况
  • 更微妙的 bug 经常溜过去

7.2 调优循环

调优方法是一个经典的人在回路(human-in-the-loop)迭代过程:

  1. 运行 Harness
  2. 阅读 Evaluator 的完整日志
  3. 找到 Evaluator 的判断与自己判断不一致的地方
  4. 分析不一致的原因——是太宽容?测试不够深入?遗漏了某类问题?
  5. 更新 QA 的 prompt 来解决这些具体问题
  6. 重新运行
  7. 重复多轮

关键点:这不是一次性的 prompt 工程。作者说”花了好几轮这样的开发循环,Evaluator 才开始以我认为合理的方式评分。“

7.3 调优后仍然存在的局限

即使经过多轮调优,Harness 的输出仍然显示了模型 QA 能力的边界:

  • 小的布局问题
  • 某些交互在某些地方仍感觉不直观
  • 更深层嵌套的功能中仍有未被发现的 bug——评估者没有足够深入地测试

作者的判断:仍然有更多的验证空间可以通过进一步调优来捕获。 但与 Solo 相比——核心功能根本不工作——提升已经是显而易见的了。


八、Harness 简化方法论

8.1 核心原则

“Harness 中的每个组件都编码了一个关于模型不能独立完成什么的假设,这些假设值得压力测试——既因为它们可能是错误的,也因为它们可能随着模型改进而迅速过时。”

这是本文最重要的方法论贡献之一。它将 Harness 设计从”构建一个系统”提升到了”管理一组假设”。每个组件不是”功能”,而是”假设的外化”。当假设不再成立时,对应的组件就应该被移除。

8.2 简化的方法论:逐个组件消融

作者的第一次尝试是激进地大幅削减 Harness 并尝试一些新创意,但无法复现原始版本的性能。而且变得很难判断哪些部分真正承载了性能贡献。

基于这个教训,他转向了更系统的方法:每次只移除一个组件,观察它对最终结果的影响。这本质上是一种消融实验(ablation study)——机器学习研究中常用的方法,但这里应用在了 Harness 工程中。

8.3 Opus 4.6 带来的简化动力

Opus 4.6 的发布公告中提到的改进——更仔细的规划、更持久的 agentic 任务执行、更可靠的大代码库操作、更好的代码审查和调试能力、长上下文检索的大幅提升——恰好对应了 Harness 原本试图补充的每一项能力。

这给了作者强有力的理由去测试:这些组件是否仍然必要?

8.4 移除 Sprint 分解

结果:Sprint 结构可以完全去掉。Opus 4.6 原生能够处理不分解的长任务。

保留 Planner 的原因:没有 Planner,Generator 会范围不足(under-scope)——给定原始 prompt,它会直接开始构建而不先规格化工作,最终产品的功能不如有 Planner 时丰富。

Evaluator 的调整:从逐 Sprint 评估变为仅在最后做一次 pass。

8.5 Evaluator 价值的相对性

这是一个非常微妙的分析:

在 Opus 4.5 上,构建任务处于 Generator 能力的边缘——Solo 表现不佳,Evaluator 在整个构建过程中都能捕获有意义的问题。

在 Opus 4.6 上,模型的原始能力提升了,这个边界向外移动了。以前需要 Evaluator 检查才能正确实现的任务,现在在 Generator 的能力范围内了,Evaluator 对这些任务变成了不必要的开销。但对于仍然处于 Generator 能力边缘的那些部分,Evaluator 继续提供真实的提升。

“Evaluator 不是一个固定的 yes-or-no 决策。它在任务超出当前模型能可靠独立完成的范围时,才值得花成本。”

推论:随着每个新模型的发布,你应该重新评估 Evaluator 对你的特定任务是否仍然有价值。

8.6 新增的 AI 功能构建能力

在结构简化的同时,作者还增加了 prompt 来改善 Harness 在每个应用中构建 AI 功能的方式——具体来说,让 Generator 构建一个能够通过工具驱动应用功能的完整 Agent。

这需要”真正的迭代”(real iteration),因为相关知识足够新,Claude 的训练数据覆盖稀薄。但经过足够的调优,Generator 能够正确地构建 Agent。


九、简化后的 DAW 实测

9.1 测试 prompt

Build a fully featured DAW in the browser using the Web Audio API.

9.2 详细成本分解

Agent 与阶段时间成本
Planner4.7 分钟$0.46
Build(第1轮)2 小时 7 分钟$71.08
QA(第1轮)8.8 分钟$3.24
Build(第2轮)1 小时 2 分钟$36.89
QA(第2轮)6.8 分钟$3.09
Build(第3轮)10.9 分钟$5.88
QA(第3轮)9.6 分钟$4.06
总计3 小时 50 分钟$124.70

值得注意的数据

  • Planner 只花了 4.7 分钟和 $0.46——这是整个 Harness 中 ROI 最高的组件
  • Build 第1轮连续运行了 2 小时 7 分钟而不失连贯——在 Opus 4.5 上不可能
  • QA 每轮 ~8 分钟,成本 ~$3——相对于 Build 的成本,是非常高效的质量保障
  • Build 从第1轮的 2 小时缩减到第3轮的 11 分钟——因为大部分功能已经在前两轮实现,第3轮只是修复 QA 发现的问题

9.3 QA 的具体反馈

第1轮 QA 反馈

“这是一个强大的应用,设计保真度出色,AI Agent 扎实,后端良好。主要失败点是功能完整性——虽然应用看起来令人印象深刻且 AI 集成运作良好,但几个核心 DAW 功能只有展示没有交互深度:片段无法在时间线上被拖动/移动,没有乐器 UI 面板(合成器旋钮、鼓垫),没有视觉效果编辑器(EQ 曲线、压缩器表)。这些不是边缘情况——它们是让 DAW 可用的核心交互,而且规格中明确要求了它们。”

这段 QA 反馈展示了一个经过校准的 Evaluator 的判断力:

  • 先给出正面肯定(设计好、AI 集成好、后端好)
  • 然后精准定位核心失败点(功能完整性)
  • 区分了”展示性功能”和”可交互功能”——这是一个很专业的产品判断
  • 明确指出这些不是边缘情况而是核心需求
  • 引用了规格文档作为判断依据

第2轮 QA 反馈

“剩余缺口:

  • 音频录制仍然是 stub-only(按钮切换但没有麦克风捕获)
  • 片段按边缘拖动调整大小和片段分割未实现
  • 效果可视化是数字滑块,不是图形化的(没有 EQ 曲线)”

到第2轮,反馈变得更具体——从”几个核心功能缺失”到精确列出哪些具体功能仍然是 stub 或未实现。

9.4 最终产品评估

最终的 DAW 应用包含:

  • 工作的编曲视图(arrangement view)
  • 混音器(mixer)
  • 走带控制(transport)
  • 全部运行在浏览器中
  • 内置 AI Agent,可以通过 prompt 驱动应用功能

作者通过 prompt 让 AI Agent 从头到尾制作了一段简短的歌曲:设置速度和调号 → 铺设旋律 → 构建鼓轨 → 调整混音器电平 → 添加混响。

坦诚的局限

  • 距离专业音乐制作程序还很远
  • AI Agent 的作曲能力明显需要大量改进
  • Claude 不能实际”听到”声音,这使得 QA 反馈循环在音乐品味方面不够有效——这是一个有趣的模态限制

十、总结:面向未来的方法论

10.1 三条核心教训

作者在结尾提炼了三条可以带到未来工作中的教训:

教训一:始终实验、阅读 trace、调优

  • 与你正在构建的模型进行实验
  • 在真实问题上阅读它的 trace(运行日志)
  • 调优它的表现以达到你期望的结果
  • 这是一个持续的过程,不是一次性的

教训二:任务分解和专门化 Agent 有时能带来额外空间

  • 对于更复杂的任务,将任务分解并为每个方面应用专门化的 Agent,有时能释放出额外的性能空间
  • 注意”有时”——这不是一个普遍规则,而是取决于任务是否处于模型的能力边界

教训三:新模型到来时,重新审视 Harness

  • 剥离不再承载性能贡献的组件
  • 添加新组件以实现之前不可能的更大能力
  • 这是一个持续的迭代循环

10.2 最深层的洞察

“随着模型改进,有趣的 Harness 组合空间不会缩小。它会移动,AI 工程师的有趣工作是不断找到下一个新组合。”

这句话是全文的精华。它意味着:

  • AI 工程不会因为模型变强而变得无聊或没有必要
  • 相反,每次模型升级都打开了新的 Harness 设计空间
  • 你以前因为模型能力不足而做不到的事,现在可以尝试了
  • 这需要持续的探索和创新,而不是一劳永逸的架构

附录:关键引用与数据索引

关键数据点

  • Solo run:20 分钟、$9、核心功能坏
  • Full Harness V1(Opus 4.5):6 小时、$200、16 功能 10 Sprint
  • Full Harness V2(Opus 4.6):3 小时 50 分钟、$124.70、3 轮 Build+QA
  • 前端实验:5-15 轮迭代、最长 4 小时
  • Sprint 3 合同标准数:27 个
  • Evaluator 批准率(Agent 自身的权限审批数据):用户实际批准 93% 的权限提示

关键技术选型

组件技术
Agent 编排Claude Agent SDK
端到端测试Playwright MCP
前端React + Vite
后端FastAPI
数据库SQLite → PostgreSQL
版本控制git
Agent 间通信文件系统

模型能力演进对 Harness 的影响

模型需要 Context Reset需要 Sprint 分解需要逐 Sprint Evaluator连续工作时长
Sonnet 4.5是(Context Anxiety 严重)短(受 anxiety 限制)
Opus 4.5否(Anxiety 基本消失)中等
Opus 4.6否(仅最后一次 pass)2+ 小时

相关文章链接

目录