Claude Code 为什么强?从“不断线”到“不自嗨”,Anthropic 两篇文章讲透 Harness Engineering 方法论
引言
最近我在继续学习 Harness Engineering。此前我已经围绕 OpenAI 的工程技术:在智能体优先的世界中利用 Codex | OpenAI写过一篇博客从“AI 写代码”到“为 AI 设计工程系统”:OpenAI《Harness engineering: leveraging Codex in an agent-first world》-CSDN博客,那篇文章给我的核心启发是:在 agent-first 的软件工程里,工程师的工作不再只是直接写代码,而是设计一个让智能体可以稳定工作的环境。
这个环境包括什么?包括代码仓库结构、文档体系、执行计划、质量标准、测试、CI、工具接口、上下文管理,以及一系列让智能体能够“看见、理解、执行、验证”的外部工件。OpenAI 在文章中明确提出,情境管理是智能体面对大型复杂任务时的最大挑战之一,因此不要给 Codex 一本庞大的说明书,而要给它一张可导航的地图;代码仓库中的结构化文档、执行计划和决策日志,才是智能体真正能够使用的记录系统。
Anthropic 最近关于 Harness Engineering 的两篇文章,则从另一个角度把这个问题讲得更细。他们不是从一个大型代码库或组织流程出发,而是从“如何让一个 Agent 长时间独立完成复杂应用开发”这个更实验化的问题出发。
这两篇文章分别是:
第一篇是Effective harnesses for long-running agents \ Anthropic(Published Nov 26, 2025)。它讨论的是:当一个 Agent 要工作数小时,甚至跨越多个上下文窗口时,如何避免它忘记进度、重复劳动、误判完成,或者把项目留在一个半坏不坏的状态中。文章给出的方案是 initializer agent 与 coding agent 的两段式结构,通过 feature_list.json、claude-progress.txt、git history、init.sh 等工件,让每个新的 session 都能接上前一个 session 的工作。
第二篇是Harness design for long-running application development \ Anthropic(Published Mar 24, 2026)。它站在第一篇的基础上继续推进:如果 Agent 已经能持续工作,那么下一步的问题就是,如何让它持续做得更好?如何让它不仅完成任务,而且有更好的产品判断、更好的前端审美、更强的 QA 能力?这篇文章引入了 planner、generator、evaluator 的多智能体结构,并用类似 generator/evaluator 的反馈循环来提升前端设计和全栈应用开发质量。
因此,这两篇文章不能割裂地读。第一篇解决的是 continuity,也就是长任务如何不断线;第二篇解决的是 quality,也就是不断线之后如何持续提升质量。
更准确地说:
第一篇把 Harness Engineering 从“提示词”推进到“跨上下文的状态管理”;第二篇则把它从“状态管理”继续推进到“多角色协作与外部评价”。
这也是本文的主线。
第一章:Harness Engineering 不是 Prompt Engineering
在正式逐段解读 Anthropic 的两篇文章之前,需要先澄清一个概念:Harness Engineering 不是 Prompt Engineering 的换皮版本。
Prompt Engineering 关注的是:我应该如何向模型表达任务?
Harness Engineering 关注的是:我应该如何设计一个环境,让模型能够持续、可靠、可验证地完成任务?
这两个问题有交集,但不是同一个层级。
一个 prompt 可以要求模型“请一步一步完成这个项目”。但当项目复杂到需要多个小时、多个 session、多个上下文窗口时,单靠这句话并不能解决问题。模型会忘记之前做了什么,会重复做已经完成的工作,会误以为任务已经完成,会在没有端到端测试的情况下把功能标记为通过,也会在上下文压力下匆忙收尾。
这正是 Anthropic 第一篇文章的出发点。文章开头指出,随着 AI agents 能力增强,开发者开始要求它们处理需要数小时甚至数天的复杂任务;但这些任务往往无法在一个 context window 内完成,而每个新的 session 又天然没有前一轮的记忆。Anthropic 用“轮班工程师”的比喻来描述这个问题:每个新工程师上岗时都不知道上一班发生了什么,那么整个项目自然很难稳定推进。
这句话其实点出了 Harness Engineering 的第一性问题:
Agent 的上下文窗口不是可靠记忆。
可靠记忆必须被外部化。
所谓外部化,就是把那些原本存在于聊天历史、人类脑中、临时对话、隐性经验里的信息,转化成 agent 每次启动都能读取、理解和使用的工件。
在 Anthropic 第一篇文章中,这些工件包括:
-
feature_list.json -
claude-progress.txt -
init.sh -
git commit history
-
端到端测试步骤
-
browser automation 结果
在 OpenAI 的文章中,这些工件则包括:
-
AGENTS.md -
docs/ -
ARCHITECTURE.md -
PRODUCT_SENSE.md -
QUALITY_SCORE.md -
exec-plans/ -
决策日志
-
技术债务记录
-
CI 与 linter
两者表面上一个是实验项目,一个是真实代码库;但底层思想高度一致:Agent 看不到的东西,就等于不存在。 OpenAI 的文章也明确指出,从智能体视角看,无法在运行时访问的信息——比如 Google Docs、聊天记录或人脑中的隐性知识——都不属于它可用的事实;本地、版本化、可读取的代码、Markdown、schema、执行计划,才是它真正能基于其推理的材料。
所以,Harness Engineering 的第一个关键词不是 prompt,而是 可见性。
你不能指望 agent 记住它看不见的东西。你也不能指望 agent 自己判断哪些隐藏约束重要。你必须把这些信息写进环境,让它们变成 agent 工作流的一部分。
这也是为什么 Anthropic 第一篇文章如此重视 feature_list.json。它不是普通的需求列表,而是对“什么叫完成”的外部定义。Agent 不能只凭感觉说“我做完了”,它必须回到 feature list,看哪些功能仍然 failing,哪些功能经过测试后才能标记为 passing。Anthropic 甚至强调,coding agent 只能修改 passes 字段,不应该删除或改写测试项;他们最终选择 JSON,也是因为模型相对不容易像修改 Markdown 那样随意改坏 JSON 文件。
这里出现了 Harness Engineering 的第二个关键词:约束。
一个好的 harness 不只是给模型更多上下文,也不是让模型更自由地行动。相反,它要把自由行动限制在一个可验证的轨道中。
这和传统软件工程中的测试、类型系统、CI、代码评审很像。它们并不是为了限制工程师创造力,而是为了让复杂系统在多人协作、长期演进中不崩坏。Agentic coding 也是一样。随着 agent 能力变强,它不是不需要工程结构,而是更需要能够支持长程自主行为的结构。
Anthropic 第二篇文章进一步说明了这一点。作者在开篇说,他研究的是两个相互关联的问题:让 Claude 生成高质量前端设计,以及让 Claude 在无人干预下构建完整应用。为了突破 prompt engineering 和基础 harness 设计的天花板,他受到 GAN 的启发,设计了 generator 和 evaluator 的多智能体结构。
这说明 Harness Engineering 还有第三个关键词:反馈。
如果第一篇文章强调的是“如何让 agent 接上前一棒”,那么第二篇文章强调的是“如何让 agent 被评价、被纠偏、被推动到更好的方向”。
一个 agent 自己生成、自己判断、自己宣布完成,风险很高。Anthropic 第二篇文章明确指出,agent 在评价自己产物时,往往会自信地表扬自己的工作,即使在人类看来质量很一般;这个问题在设计这类主观任务上尤其明显,因为没有像自动化测试那样的二元判定标准。
所以,第二篇文章的关键动作是拆分角色:
-
生成者负责做。
-
评价者负责看。
-
规划者负责把短 prompt 扩展成产品规格。
-
工具负责提供环境反馈。
-
文件负责在角色之间传递状态。
-
测试负责把“看起来完成”变成“真的可用”。
这已经不是简单 prompt 了,而是一套完整的控制系统。
也因此,我们可以给 Harness Engineering 一个更准确的定义:
Harness Engineering 是围绕模型构建外部工作环境的工程实践。它通过上下文组织、任务拆解、工具接口、结构化工件、验证机制、评估反馈和复杂度控制,让 agent 能够在真实任务中持续、可靠、可迭代地工作。
这个定义会贯穿后文对两篇文章的逐段解读。
第二章:第一篇文章的逐段解读——长任务 Agent 的核心问题是“上下文断裂”
接下来进入第一篇文章:《Effective harnesses for long-running agents》。
原文链接:Effective harnesses for long-running agents \ Anthropic
这篇文章的主题可以概括为一句话:
如何让一个 Agent 在多个 context window 之间像真正的工程师一样交接工作,而不是每次都从半失忆状态重新开始。
2.1 开篇段落解读:能力增强之后,瓶颈从“会不会做”转向“能不能持续做”
As AI agents become more capable, developers are increasingly asking them to take on complex tasks requiring work that spans hours, or even days. However, getting agents to make consistent progress across multiple context windows remains an open problem.
文章开头先设置背景:AI agents 越来越强,开发者开始让它们承担更复杂、更长周期的任务。这些任务不再是“改一个函数”“写一个脚本”,而是可能持续数小时甚至数天的完整工程工作。问题在于,当前 agent 的工作仍然发生在离散 session 中,而每个新 session 并不会天然继承前一个 session 的完整记忆。
这一段的作用,是把问题从“模型能力不足”转向“工作形态不匹配”。
过去我们常问:模型会不会写代码?
但在 long-running agent 场景里,更关键的问题变成:
-
它能不能知道上一轮做了什么?
-
它能不能判断当前项目状态?
-
它能不能避免重复劳动?
-
它能不能识别半完成的功能?
-
它能不能在上下文耗尽前留下足够清楚的交接材料?
这已经不是模型单次推理能力的问题,而是工程流程设计的问题。
The core challenge of long-running agents is that they must work in discrete sessions, and each new session begins with no memory of what came before. Imagine a software project staffed by engineers working in shifts, where each new engineer arrives with no memory of what happened on the previous shift. Because context windows are limited, and because most complex projects cannot be completed within a single window, agents need a way to bridge the gap between coding sessions.
Anthropic 用“轮班工程师”的比喻非常准确。一个项目如果由多个工程师轮班完成,但每个新工程师都不知道上一班做了什么,那么再强的个人能力也会被上下文断裂抵消。软件工程之所以需要 commit message、issue、PR description、design doc、runbook、test report,本质上就是因为人类团队也需要跨时间交接状态。
Agent 也是一样。
所以,第一篇文章真正要解决的不是“让 Claude 更聪明”,而是“让 Claude 像处在一个有工程纪律的团队里”。
2.2 文章提出的两段式方案:initializer agent 与 coding agent
We developed a two-fold solution to enable the Claude Agent SDK to work effectively across many context windows: an initializer agent that sets up the environment on the first run, and a coding agent that is tasked with making incremental progress in every session, while leaving clear artifacts for the next session. You can find code examples in the accompanying quickstart.
在开篇之后,Anthropic 很快给出整体方案:使用两个角色。第一个是 initializer agent,负责第一次运行时搭建环境;第二个是 coding agent,负责后续每个 session 中增量推进,并为下一个 session 留下清楚的工件。
Footnotes
1. We refer to these as separate agents in this context only because they have different initial user prompts. The system prompt, set of tools, and overall agent harness was otherwise identical.
这里有一个容易被忽略的点:Anthropic 所说的两个 agent,并不一定意味着两个完全不同的模型或系统。文章脚注说明,这里称为不同 agent,主要是因为它们使用不同的初始用户 prompt;系统 prompt、工具和整体 harness 基本相同。
这说明,在 Harness Engineering 中,“角色”并不一定来自模型差异,而可以来自任务位置差异。
When experimenting internally, we addressed these problems using a two-part solution:
Initializer agent: The very first agent session uses a specialized prompt that asks the model to set up the initial environment: an
init.shscript, a claude-progress.txt file that keeps a log of what agents have done, and an initial git commit that shows what files were added.Coding agent: Every subsequent session asks the model to make incremental progress, then leave structured updates.
initializer agent 的任务不是写业务功能,而是搭建未来工作的轨道。它要创建:
-
启动项目所需的
init.sh -
记录进度的
claude-progress.txt -
初始 git commit
-
描述完整功能范围的 feature list
coding agent 的任务则是每次只推进一小步:
- 读取当前状态
- 找到尚未完成的高优先级功能
- 实现一个功能
- 测试它
- 更新状态
- 提交 git commit
- 留下进度说明
这个设计背后的思想是:长任务不是靠一次性巨大 prompt 完成的,而是靠可重复的 session protocol 完成的。
The key insight here was finding a way for agents to quickly understand the state of work when starting with a fresh context window, which is accomplished with the claude-progress.txt file alongside the git history. Inspiration for these practices came from knowing what effective software engineers do every day.
这里可以把 Anthropic 的方案理解成一种“Agent 接班制度”。
每个 coding agent 都像新上班的工程师。它到岗后的第一件事不是立刻写代码,而是先看项目状态;离岗前最后一件事也不是宣布胜利,而是留下下一任能看懂的记录。
这其实就是 Harness Engineering 对人类工程流程的抽象。
2.3 “The long-running agent problem”:为什么 compaction 仍然不够
The Claude Agent SDK is a powerful, general-purpose agent harness adept at coding, as well as other tasks that require the model to use tools to gather context, plan, and execute. It has context management capabilities such as compaction, which enables an agent to work on a task without exhausting the context window. Theoretically, given this setup, it should be possible for an agent to continue to do useful work for an arbitrarily long time.
第一篇文章接着讨论 Claude Agent SDK 的能力。Claude Agent SDK 本身已经有 context management 能力,例如 compaction,可以帮助 agent 在不耗尽上下文窗口的情况下继续工作。理论上,如果有 compaction,agent 应该能够无限期地继续完成任务。
但 Anthropic 随即指出:compaction 不够。
这是整篇文章中非常关键的一步。
However, compaction isn’t sufficient. Out of the box, even a frontier coding model like Opus 4.5 running on the Claude Agent SDK in a loop across multiple context windows will fall short of building a production-quality web app if it’s only given a high-level prompt, such as “build a clone of claude.ai.”
因为 compaction 的本质是“把前文压缩后继续塞回上下文”。它确实保留了一些连续性,但它并不能保证下一个阶段得到的是清晰、结构化、可执行的项目状态。总结可能丢失细节,可能没有明确下一步,也可能没有把“哪些功能已测、哪些功能未测”表达清楚。
这就是为什么 Anthropic 要引入外部工件,而不是完全依赖上下文压缩。
换句话说:
Compaction 是对聊天历史的压缩;
Harness 工件是对项目状态的建模。
两者差别很大。
聊天历史天然是线性的、冗长的、混杂的。里面有计划、有尝试、有错误、有修正、有解释、有工具调用结果。即使压缩之后,也很难成为一个干净的项目状态表。
而 feature_list.json、git log、progress file、init script 则不同。它们是有结构的。它们告诉 agent:
-
项目如何启动?
-
最近做了什么?
-
哪些功能完成了?
-
哪些功能没完成?
-
如何验证基本功能没有坏?
-
当前代码处于什么提交点?
-
出问题时如何回滚?
这就是第一篇文章的关键洞察:长任务 agent 不能只靠上下文续命,它需要一个外部状态系统。
2.4 两种失败模式:one-shot 与 premature completion
在解释完 compaction 为什么不够之后,Anthropic 开始具体分析 Claude 在长任务中的失败模式。文章提到两个非常典型的问题。
第一个问题是:Agent 容易试图一次性完成整个应用。
Claude’s failures manifested in two patterns. First, the agent tended to try to do too much at once—essentially to attempt to one-shot the app. Often, this led to the model running out of context in the middle of its implementation, leaving the next session to start with a feature half-implemented and undocumented. The agent would then have to guess at what had happened, and spend substantial time trying to get the basic app working again. This happens even with compaction, which doesn’t always pass perfectly clear instructions to the next agent.
Anthropic 用的是“one-shot the app”这个说法。也就是说,当你给 Claude 一个高层任务,比如“构建一个 claude.ai 的 clone”,它往往会倾向于一次性铺开所有功能,而不是像一个有经验的工程师那样先拆分范围、确定里程碑、逐步交付。结果是,模型可能在实现中途耗尽上下文窗口,留下一个半完成、未记录、难以接手的代码状态。下一轮 agent 接手时,不得不猜测前一轮到底改了什么,然后花大量时间先把基础应用救回来。Anthropic 明确指出,即使使用 compaction,这个问题仍然会发生,因为压缩后的上下文并不总是能给下一轮 agent 留下清晰指令。
这个问题非常值得展开。
从人类工程视角看,“一次性做完整个应用”通常不是高效,而是危险。因为复杂系统里每个部分都可能引入不确定性。真正稳健的工程流程通常是:
先把系统跑起来;
再实现一个最小功能;
验证这个功能;
提交;
再继续下一个功能。
但模型天然容易被 prompt 中的高层目标牵引。例如“build a clone of claude.ai”这个任务,会让模型直接面向最终形态进行想象。它会开始生成侧边栏、聊天窗口、主题切换、会话列表、消息流、输入框、设置页、错误处理等一大堆内容。看上去非常勤奋,实际上非常脆弱。
这就是 long-running agent 的第一个悖论:
Agent 越想一次性完成大目标,越容易破坏长期完成大目标的能力。
所以,harness 必须强制 agent 从“大目标想象”回到“小步验证”。
第二个问题是:Agent 容易过早宣布完成。
A second failure mode would often occur later in a project. After some features had already been built, a later agent instance would look around, see that progress had been made, and declare the job done.
This decomposes the problem into two parts. First, we need to set up an initial environment that lays the foundation for all the features that a given prompt requires, which sets up the agent to work step-by-step and feature-by-feature. Second, we should prompt each agent to make incremental progress towards its goal while also leaving the environment in a clean state at the end of a session. By “clean state” we mean the kind of code that would be appropriate for merging to a main branch: there are no major bugs, the code is orderly and well-documented, and in general, a developer could easily begin work on a new feature without first having to clean up an unrelated mess.
Anthropic 观察到,在项目进入中后期后,后续 agent 看到代码库里已经有不少功能,就可能误判项目已经完成。它会浏览一下现有状态,发现“好像有界面,好像有功能,好像可以运行”,然后宣布任务完成。
这个失败模式比第一个更隐蔽。
one-shot 失败往往表现为代码明显坏了、项目跑不起来、上下文中断。而 premature completion 更像是“半成品伪装成成品”。它可能有一个漂亮的首页,有一些按钮,有一些基本交互,但大量边缘功能、错误处理、状态持久化、真实用户路径并没有完成。
这也是为什么 Anthropic 后面要引入 feature list。因为如果没有一个外部标准,agent 就会用“当前项目看起来像不像完成”来判断是否完成。这个判断很危险。对长任务来说,“完成”不能是模型的主观感觉,而必须是一个可检查的状态集合。
因此,这两个失败模式分别对应两个 harness 设计方向:
第一个失败模式 one-shot,对应 incremental progress。
第二个失败模式 premature completion,对应 feature list。
也就是说,第一篇文章不是随便提出几个工程实践,而是每个实践都对应一个明确的 agent 失败模式。
2.5 Initializer agent:长任务开始前,先搭建“接班制度”
为了解决上面两个问题,Anthropic 把任务拆成两个阶段:initializer agent 和 coding agent。initializer agent 只在第一次 session 中运行,负责建立初始环境;coding agent 则在后续每个 session 中读取状态、选择任务、增量推进并留下交接材料。
这里最重要的不是“两个 agent”,而是“两个职责”。
initializer agent 的工作不是直接把应用写完,而是为后续所有 coding agent 创建工作环境。它会创建:
init.sh
claude-progress.txt
feature_list.json
initial git commit
这些文件共同构成了一个长任务的“项目记忆系统”。
init.sh 解决的是:新 agent 如何启动项目。
claude-progress.txt 解决的是:前面的人做了什么。
feature_list.json 解决的是:整个项目到底还差什么。
git commit history 解决的是:代码状态如何追踪、回滚和理解。
这其实是一个非常典型的 Harness Engineering 思维:先不要急着让 agent 做事,而是先让 agent 知道以后如何做事。
普通 prompt engineering 可能会写:
请构建一个完整的 web app,并确保功能完整、代码整洁、测试通过。
而 harness engineering 会问:
后续每一轮 agent 如何知道项目当前状态?
如何知道哪些功能还没完成?
如何知道怎样启动项目?
如何知道上一次做了什么?
如何防止它误删测试?
如何防止它在半坏状态下继续开发?
这两个问题层级完全不同。
prompt 是“让模型努力”。
harness 是“让系统可靠”。
这也是为什么 initializer agent 非常关键。它像项目里的第一个技术负责人,不是为了亲手完成所有功能,而是为了建立项目结构、工作规则和交接机制。
Anthropic 在文章中还补充说,这种实践的灵感来自高效软件工程师每天都在做的事情:通过进度记录和 git history,让新接手工作的人能够快速理解当前状态。
这句话非常重要,因为它说明 Harness Engineering 不是凭空发明了一套 AI 特有流程,而是把人类软件工程中早已存在的协作机制迁移给 agent。
换句话说:
长程 agent 需要的不是魔法,而是工程纪律。
2.6 Feature list:把“完成”的定义从模型脑中拿出来
第一篇文章中最核心的工件,是 feature list。
Feature list
To address the problem of the agent one-shotting an app or prematurely considering the project complete, we prompted the initializer agent to write a comprehensive file of feature requirements expanding on the user’s initial prompt. In the claude.ai clone example, this meant over 200 features, such as “a user can open a new chat, type in a query, press enter, and see an AI response.” These features were all initially marked as “failing” so that later coding agents would have a clear outline of what full functionality looked like.
Anthropic 解释说,为了解决 agent one-shot 应用和过早认为项目完成的问题,他们让 initializer agent 根据用户最初的高层 prompt,扩展出一个完整的功能需求文件。在 claude.ai clone 的例子中,这个文件包含了超过 200 个功能项,并且所有功能一开始都被标记为 failing。后续 coding agent 就可以根据这个文件理解“完整功能”到底意味着什么。
这一步看似简单,其实非常关键。
用户说“做一个 claude.ai clone”,这句话对于人类和 agent 都过于抽象。什么叫 clone?是只要长得像?还是要能新建聊天?要不要会话历史?要不要主题切换?要不要错误状态?要不要输入 loading?要不要侧边栏折叠?要不要移动端适配?
如果这些东西不写下来,agent 就会自己猜。
而 agent 自己猜,就会导致范围漂移。
feature list 的作用,就是把高层目标拆成可验证的用户行为。例如:
{
"category": "functional",
"description": "New chat button creates a fresh conversation",
"steps": [
"Navigate to main interface",
"Click the 'New Chat' button",
"Verify a new conversation is created",
"Check that chat area shows welcome state",
"Verify conversation appears in sidebar"
],
"passes": false
}
这类 feature item 有三个关键特征。
第一,它是用户行为导向的。
它不是写“实现 NewChatButton 组件”,而是写“用户点击 New Chat 后应看到一个新会话”。这让 agent 的验证目标从代码结构转向用户体验。
第二,它有明确步骤。
这些 steps 让后续 agent 知道应该如何验证,而不是只看代码是否存在。
第三,它有 pass/fail 状态。
这让“完成”变成一个外部状态,而不是模型的自我感觉。
We prompt coding agents to edit this file only by changing the status of a passes field, and we use strongly-worded instructions like “It is unacceptable to remove or edit tests because this could lead to missing or buggy functionality.” After some experimentation, we landed on using JSON for this, as the model is less likely to inappropriately change or overwrite JSON files compared to Markdown files.
Anthropic 还特别强调,他们要求 coding agent 只能修改 passes 字段,并用强硬措辞禁止删除或编辑测试项,因为那样可能导致功能缺失或 bug 被掩盖。他们后来选择 JSON,也是因为实验中发现模型相比 Markdown 更不容易随意改写或覆盖 JSON 文件。
这一点非常值得单独分析。
为什么格式重要?
因为对 agent 来说,文件格式不仅是存储格式,也是行为约束。Markdown 很灵活,模型很容易把它当成普通文档来“整理”“改写”“优化表达”。但 JSON 更像数据结构,有字段、有 schema、有明显的可解析边界。模型在面对 JSON 时,更容易把它视为状态表,而不是可随意润色的文章。
这说明 Harness Engineering 的很多细节都和“模型会如何理解环境”有关。
对人类来说,Markdown 和 JSON 可能只是两种表达格式;但对 agent 来说,它们会诱导不同的行为模式。
所以 feature list 的深层意义是:
它把“产品范围”和“完成标准”从隐性意图,变成了可被 agent 读取、维护、验证的状态机。
这也正是第一篇和 OpenAI 文章的连接点。OpenAI 在 Harness Engineering 文章中说,应该把代码仓库作为记录系统,不要让关键信息留在 Google Docs、聊天记录或人脑中;对 agent 来说,看不到的信息就不存在。
Anthropic 的 feature list 正是这个原则在长程任务中的具体实现:如果“完成标准”不在 agent 能读取的文件里,它就等于不存在。
2.7 Incremental progress:一次只做一个功能,才是长任务的快路径
Incremental progress
Given this initial environment scaffolding, the next iteration of the coding agent was then asked to work on only one feature at a time. This incremental approach turned out to be critical to addressing the agent’s tendency to do too much at once.
有了 feature list 之后,Anthropic 接下来要求 coding agent 每次只处理一个功能。这是为了直接对抗前面说的 one-shot 倾向。文章指出,这种增量方法对解决 agent 一次做太多的问题非常关键。
这一点很反直觉。
很多人使用 coding agent 时,会希望它“多做一点”。毕竟模型速度快,为什么不让它一次完成更多任务?
但在 long-running agent 场景中,速度不是单轮输出最多,而是长期有效进展最大。
一次做十个功能,看起来很快,但如果其中三个功能没测、两个功能互相破坏、一个功能让项目无法启动,下一轮 agent 就要花大量时间修复混乱状态。反过来,一次只做一个功能,虽然单轮看起来慢,但每一步都可以验证、提交、记录和回滚。
这就是软件工程中的经典经验:小步提交比大爆炸式提交更可靠。
Anthropic 还强调,coding agent 不仅要增量推进,还要在 session 结束时把环境留在 clean state。所谓 clean state,就是代码没有重大 bug、结构有序、有文档,后续开发者可以直接开始新功能,而不需要先清理无关混乱。
这个 clean state 概念非常重要。
它表明 Anthropic 并不只是让 agent “完成更多功能”,而是让 agent “以可接手的方式完成更多功能”。
这对长程 agent 来说是根本要求。因为每个 session 都可能是下一轮工作的起点。如果当前 session 留下的是一个不可运行、无记录、半实现的代码库,那么它不仅没有推进项目,反而给未来增加了债务。
Once working incrementally, it’s still essential that the model leaves the environment in a clean state after making a code change. In our experiments, we found that the best way to elicit this behavior was to ask the model to commit its progress to git with descriptive commit messages and to write summaries of its progress in a progress file. This allowed the model to use git to revert bad code changes and recover working states of the code base.
为此,Anthropic 让 coding agent 在每轮结束时做两件事:
1. 写 git commit,并使用描述性 commit message。
2. 更新 progress file,总结本轮进展。
文章指出,这样可以让模型利用 git 回滚坏代码、恢复工作状态,也减少下一轮 agent 猜测前情的时间。
这其实把 git 从“版本控制工具”变成了 agent harness 的一部分。
在人类工程里,git commit 是协作记录。
在 agent 工程里,git commit 同时还是 agent 的记忆锚点、回滚机制和上下文压缩替代物。
换句话说,git history 不只是给人看的,也是给下一个 agent 看的。
2.8 Testing:从代码级验证到用户级验证
第一篇文章的另一个重点是 testing。
Testing
One final major failure mode that we observed was Claude’s tendency to mark a feature as complete without proper testing. Absent explicit prompting, Claude tended to make code changes, and even do testing with unit tests or
curlcommands against a development server, but would fail recognize that the feature didn’t work end-to-end.
Anthropic 观察到,Claude 常常会在没有充分测试的情况下把功能标记为完成。它可能会改代码,也可能会跑一些单元测试或用 curl 请求开发服务器,但仍然没有意识到端到端功能其实不能正常工作。
这是 coding agent 中非常常见的问题:模型容易把“代码存在”误认为“功能可用”。
例如,一个按钮组件已经写了,一个 API endpoint 也存在,数据库 schema 也建好了。但用户真实点击按钮时,可能没有响应;或者前端状态没有刷新;或者请求字段不匹配;或者错误提示无法显示。单看代码很难发现这些问题。
In the case of building a web app, Claude mostly did well at verifying features end-to-end once explicitly prompted to use browser automation tools and do all testing as a human user would.
Providing Claude with these kinds of testing tools dramatically improved performance, as the agent was able to identify and fix bugs that weren’t obvious from the code alone.
因此,Anthropic 在 web app 场景中明确提示 Claude 使用 browser automation tools,像真实用户一样进行端到端测试。文章说,在被明确要求这样做后,Claude 在验证 web app 功能方面表现明显更好。
这一步非常关键,因为它把验证从“开发者视角”切换到了“用户视角”。
开发者视角会问:
函数写了吗?
组件存在吗?
接口通了吗?
测试绿了吗?
用户视角会问:
我能不能打开页面?
我能不能点击按钮?
点击后有没有发生正确变化?
我能不能完成整个任务?
失败时有没有清楚反馈?
对于完整应用开发来说,用户视角更接近真实完成标准。
这也解释了为什么 Anthropic 在第二篇文章中继续强化 evaluator,并让 evaluator 使用 Playwright MCP 去操作真实页面。第一篇中的 browser automation 还是 coding agent 自己用于验证功能;第二篇则进一步把这种验证职责拆给独立 evaluator。这个递进关系非常清楚:
第一篇:让 coding agent 学会像用户一样测试。
第二篇:让独立 evaluator 专门像用户一样测试,并反过来约束 generator。
第一篇已经发现工具反馈的重要性,但还没有完全拆分角色。第二篇正是在这里继续推进。
Some issues remain, like limitations to Claude’s vision and to browser automation tools making it difficult to identify every kind of bug. For example, Claude can’t see browser-native alert modals through the Puppeteer MCP, and features relying on these modals tended to be buggier as a result.
Anthropic 也承认,browser automation 不是万能的。例如 Claude 的视觉能力和 Puppeteer MCP 工具能力仍有限,有些浏览器原生 alert modal 无法被看到,相关功能也更容易出问题。
这点也很有启发:harness 并不会消除所有问题,它只是把问题从“模型凭空猜测”推进到“模型基于环境反馈修正”。工具本身也会形成新的盲区,因此 harness 需要持续迭代。
2.9 Getting up to speed:每个新 session 如何重新接班
第一篇文章随后进入一个非常实用的部分:每个 coding agent 开始工作时,应该如何快速进入状态。
Getting up to speed
With all of the above in place, every coding agent is prompted to run through a series of steps to get its bearings, some quite basic but still helpful:
Run
pwdto see the directory you’re working in. You’ll only be able to edit files in this directory.Read the git logs and progress files to get up to speed on what was recently worked on.
Read the features list file and choose the highest-priority feature that’s not yet done to work on.
This approach saves Claude some tokens in every session since it doesn’t have to figure out how to test the code. It also helps to ask the initializer agent to write an init.sh script that can run the development server, and then run through a basic end-to-end test before implementing a new feature.
Anthropic 给出了一组看似基础但非常重要的步骤:
1. 运行 pwd,确认当前工作目录。
2. 读取 git logs 和 progress files,了解最近做了什么。
3. 读取 feature list,选择尚未完成的最高优先级功能。
4. 读取 init.sh,启动开发服务器。
5. 在实现新功能前,先跑一个基本端到端测试。
文章指出,这些步骤能节省 token,因为 agent 不需要每次重新摸索如何测试代码;同时,initializer agent 写好的 init.sh 可以帮助后续 agent 快速启动开发服务器,并在开始新功能前先确认基础功能没有坏。
这部分其实是第一篇最像“操作手册”的地方,但它背后有一个更深的原则:
新 agent 上来之后,不应该先开发,而应该先恢复世界模型。
所谓“恢复世界模型”,就是回答几个问题:
我在哪里?
这个项目怎么运行?
最近发生了什么?
当前是否处于可用状态?
哪些功能还没完成?
如果现在继续开发,会不会把已有问题变得更糟?
这和人类工程师接手项目非常相似。一个成熟工程师不会刚打开仓库就立刻改业务代码。他会先看 README、跑测试、看最近 commit、启动项目、复现当前状态。Agent 也一样,只是这些步骤必须被明确写进 harness。
In the case of the claude.ai clone, this meant that the agent always started the local development server and used the Puppeteer MCP to start a new chat, send a message, and receive a response. This ensured that Claude could quickly identify if the app had been left in a broken state, and immediately fix any existing bugs. If the agent had instead started implementing a new feature, it would likely make the problem worse.
Anthropic 在 claude.ai clone 例子中要求 agent 每次先启动本地开发服务器,并通过 Puppeteer MCP 测试新建聊天、发送消息、接收回复等基础路径。这样可以尽早发现项目是否已经被前一轮留在坏状态中。如果基础功能已经坏了,agent 应该先修复,而不是继续实现新功能。
Given all this, a typical session starts off with the following assistant messages:
[Assistant] I'll start by getting my bearings and understanding the current state of the project.
[Tool Use] <bash - pwd>
[Tool Use] <read - claude-progress.txt>
[Tool Use] <read - feature_list.json>
[Assistant] Let me check the git log to see recent work.
[Tool Use] <bash - git log --oneline -20>
[Assistant] Now let me check if there's an init.sh script to restart the servers.
<Starts the development server>
[Assistant] Excellent! Now let me navigate to the application and verify that some fundamental features are still working.
<Tests basic functionality>
[Assistant] Based on my verification testing, I can see that the fundamental functionality is working well. The core chat features, theme switching, conversation loading, and error handling are all functioning correctly. Now let me review the tests.json file more comprehensively to understand what needs to be implemented next.
<Starts work on a new feature>
这也是长任务工程中非常重要的优先级原则:
在坏状态上继续开发,只会制造更坏的状态。
所以,getting up to speed 并不是一个可有可无的开场流程,而是 long-running harness 的安全检查。
如果把整个 harness 看成一个循环,那么每个 session 的基本生命周期就是:
读取位置
→ 恢复上下文
→ 检查项目健康
→ 选择一个未完成功能
→ 实现
→ 端到端验证
→ 更新 feature list
→ 写 progress
→ git commit
→ 留给下一轮
这个循环,正是第一篇文章要建立的核心机制。
它不是让 agent 变得“更聪明”,而是让 agent 的每一次行动都处在一个可恢复、可追踪、可验证的流程里。
2.10 失败模式与解决方案表:也是一张 Harness 设计图
第一篇文章后面给出了一张表,总结四类常见失败模式及对应解决方案。虽然这张表在原文中只是总结,但我认为它实际上是整篇文章的设计蓝图。Anthropic 总结的问题包括:Claude 过早宣布完成、留下有 bug 或无记录的环境、过早把功能标记为完成、花时间摸索如何运行应用;对应解决方案则包括 feature list、progress notes、git logs、基本测试、init.sh 等。
Agent failure modes and solutions
Problem Initializer Agent Behavior Coding Agent Behavior Claude declares victory on the entire project too early. Set up a feature list file: based on the input spec, set up a structured JSON file with a list of end-to-end feature descriptions. Read the feature list file at the beginning of a session. Choose a single feature to start working on. Claude leaves the environment in a state with bugs or undocumented progress. An initial git repo and progress notes file is written. Start the session by reading the progress notes file and git commit logs, and run a basic test on the development server to catch any undocumented bugs. End the session by writing a git commit and progress update. Claude marks features as done prematurely. Set up a feature list file. Self-verify all features. Only mark features as “passing” after careful testing. Claude has to spend time figuring out how to run the app. Write an init.shscript that can run the development server.Start the session by reading init.sh.
这张表之所以重要,是因为它体现了 Harness Engineering 的基本方法论:
先识别 agent 的稳定失败模式;
再为每种失败模式设计一个外部控制结构。
例如:
Agent 过早宣布项目完成。→ 设计 feature list,让完整范围外部化。
Agent 留下混乱环境。→ 要求 git commit 和 progress update。
Agent 没有充分测试就标记完成。→ 要求端到端验证后才能改 passes。
Agent 不知道如何运行项目。→ initializer 写 init.sh。
这里可以看出,harness 的每个组件都不是装饰,而是对失败模式的针对性补丁。
这也和第二篇文章的后半部分形成呼应。第二篇会明确提出:harness 中的每个组件都编码了一个关于“模型不能自己完成什么”的假设;随着模型能力变化,这些假设必须被重新测试。
所以,第一篇是在“添加 harness 组件”;第二篇则会进一步讨论“哪些 harness 组件仍然必要”。
这就是两篇文章的递进关系之一:
第一篇告诉我们为什么要加脚手架。
第二篇告诉我们脚手架加到一定程度后,必须检查哪些是真正承重的。
2.11 Future work:第一篇已经埋下第二篇的伏笔
第一篇的结尾非常关键,因为它直接预示了第二篇的方向。
Future work
This research demonstrates one possible set of solutions in a long-running agent harness to enable the model to make incremental progress across many context windows. However, there remain open questions.
Most notably, it’s still unclear whether a single, general-purpose coding agent performs best across contexts, or if better performance can be achieved through a multi-agent architecture. It seems reasonable that specialized agents like a testing agent, a quality assurance agent, or a code cleanup agent, could do an even better job at sub-tasks across the software development lifecycle.
Additionally, this demo is optimized for full-stack web app development. A future direction is to generalize these findings to other fields. It’s likely that some or all of these lessons can be applied to the types of long-running agentic tasks required in, for example, scientific research or financial modeling.
Anthropic 在 Future work 中说,这项研究展示了一种 long-running agent harness 的可能方案,但仍有开放问题。其中最重要的问题之一是:到底应该使用单一通用 coding agent,还是使用多智能体架构?文章还提出,testing agent、quality assurance agent、code cleanup agent 等 specialized agents,可能在软件开发生命周期中的子任务上做得更好。
这几乎就是第二篇文章的开场。
第一篇的最终系统还是 initializer agent + coding agent。虽然它已经有两种角色,但真正负责编码和验证的主要还是 coding agent 自己。coding agent 需要自己实现、自己测试、自己更新状态、自己提交。
这会引出一个天然问题:
如果 agent 不擅长评价自己的工作,为什么还要让它自己负责 QA?
第二篇文章正是围绕这个问题展开。它发现 self-evaluation 是一个未被充分解决的瓶颈:模型在评价自己产物时,往往会过度正面;即使是有可验证结果的任务,agent 也可能因为判断力不足而影响最终表现。于是,第二篇将“做事的 agent”和“评价的 agent”拆开,并进一步引入 planner。
从这个角度看,第一篇的 Future work 不是附录,而是通向第二篇的桥。
第一篇已经解决了:
如何让 agent 跨 session 继续工作?
但它留下了新问题:
谁来判断 agent 的工作质量?
谁来保证它不是自我感觉良好?
谁来把高层 prompt 扩展成合理产品规格?
谁来做更严格的用户级 QA?
第二篇的 planner / generator / evaluator 架构,正是对这些问题的回答。
第二章小结:第一篇文章真正建立了什么?
读完第一篇,我们可以把它总结为一句话:
长程 agent 的关键不是让模型在一个上下文窗口里做更多事,而是让它在多个上下文窗口之间稳定交接、增量推进、保持 clean state,并用外部工件定义进度和完成标准。
它建立了五个核心思想。
第一,上下文窗口不是长期记忆。
compaction 有帮助,但不等于可靠项目状态。长任务需要外部状态系统。
第二,完成标准必须外部化。
feature list 把用户的高层 prompt 扩展成可验证的功能集合,防止 agent 凭感觉宣布完成。
第三,长任务必须增量推进。
一次只做一个功能,不是保守,而是为了让每次改动都可测试、可提交、可回滚。
第四,测试必须接近真实用户路径。
对 web app 来说,仅有代码检查、单元测试或 curl 不够,agent 需要用浏览器自动化工具进行端到端验证。
第五,每个 session 都必须可接班。
progress file、git history、init.sh 和基础 E2E 检查,让每个新 agent 能快速恢复项目状态。
这五点构成了第一篇文章的完整 harness 逻辑。
如果用更抽象的语言说,第一篇文章完成的是 Harness Engineering 的第一阶段:
从 prompt 驱动转向 artifact 驱动
也就是说,agent 不再只是根据用户 prompt 工作,而是根据一组持续存在的项目工件工作。
这为第二篇文章奠定了基础。因为只有当 agent 能够持续工作之后,我们才有必要问下一个问题:
它持续做出来的东西,质量真的好吗?
这就是第二篇《Harness design for long-running application development》要回答的问题。它会把第一篇中的 long-running harness,进一步升级为一个多角色、可评价、可反馈、可删减的控制系统。
Acknowledgements
Written by Justin Young. Special thanks to David Hershey, Prithvi Rajasakeran, Jeremy Hadfield, Naia Bouscal, Michael Tingley, Jesse Mu, Jake Eaton, Marius Buleandara, Maggie Vo, Pedram Navid, Nadine Yasser, and Alex Notov for their contributions.
This work reflects the collective efforts of several teams across Anthropic who made it possible for Claude to safely do long-horizon autonomous software engineering, especially the code RL & Claude Code teams. Interested candidates who would like to contribute are welcome to apply at anthropic.com/careers.
第三章:第二篇文章的逐段解读——从“能持续工作”到“能持续做好”
原文链接:Harness design for long-running application development \ Anthropic
如果说第一篇《Effective harnesses for long-running agents》解决的是“长任务 Agent 如何不断线”,那么第二篇《Harness design for long-running application development》解决的就是另一个更进一步的问题:
当 Agent 已经能够跨多个 session 持续推进之后,我们如何保证它不是在持续地产出平庸结果,而是在持续地变好?
这是两篇文章之间最重要的递进关系。
第一篇文章的目标是 continuity,也就是连续性。它关心的是:Agent 如何跨上下文窗口交接状态?如何避免忘记进度?如何防止提前宣布完成?如何通过 feature list、progress file、git history 和 init script 让每个 session 都能接上前一棒?
第二篇文章的目标则是 quality,也就是质量。它关心的是:Agent 能持续工作之后,谁来判断它做得好不好?谁来发现它自己看不出来的问题?谁来把高层用户需求扩展成合理的产品规格?谁来保证应用不是只有表面完成,而是真的能用、好用、有设计感?
Harness design is key to performance at the frontier of agentic coding. Here's how we pushed Claude further in frontend design and long-running autonomous software engineering.
这也是为什么第二篇文章一开头就把两个看似不同的问题放在一起:一个是让 Claude 生成高质量前端设计,另一个是让 Claude 在无人干预下构建完整应用。作者说,这两个问题分别对应“主观品味”和“可验证正确性与可用性”两个不同领域,但它们最终都遇到了 prompt engineering 和基础 harness design 的天花板,因此需要新的 AI engineering 方法。
这句话其实已经说明:第二篇文章不是单纯的“前端设计技巧”,也不是单纯的“自动写应用技巧”。它真正讨论的是:
当任务无法仅靠一次生成完成,也无法仅靠模型自我评价保证质量时,harness 应该如何引入外部评价和反馈循环。
3.1 开篇:两个问题被连接起来
Over the past several months I’ve been working on two interconnected problems: getting Claude to produce high-quality frontend designs, and getting it to build complete applications without human intervention. This work originated with earlier efforts on our frontend design skill and long-running coding agent harness, where my colleagues and I were able to improve Claude’s performance well above baseline through prompt engineering and harness design—but both eventually hit ceilings.
第二篇文章开头,作者先介绍自己过去几个月在做两个相互关联的问题:一是让 Claude 生成高质量前端设计,二是让 Claude 在没有人类干预的情况下构建完整应用。这个开场非常重要,因为它把“设计”与“软件工程”两个表面上不同的任务放在同一个框架下理解。
为什么这两个问题可以放在一起?
因为它们都暴露了同一个瓶颈:模型可以生成东西,但不一定知道自己生成得好不好。
前端设计尤其明显。一个界面能不能用,通常可以用功能测试验证;但一个界面是否高级、是否有原创性、是否有审美一致性,就不是一个简单的二元判断。模型可以生成一个看似完整的页面,但它可能非常模板化,非常像默认组件拼装,缺少真正的设计判断。
完整应用开发也是类似的。一个 agent 可以生成很多代码,可以搭建前端、后端、数据库、API,甚至看上去功能很多。但应用真正被点击、被使用、被组合起来时,可能存在大量问题:流程不清楚,核心路径断裂,状态没有正确更新,API 与 UI 没接好,边缘情况没有处理。
所以,前端设计和完整应用开发虽然一个偏主观,一个偏工程验证,但它们都需要同一种能力:
把“看起来完成”与“实际上高质量完成”区分开。
第一篇文章已经通过 feature list 解决了一部分“完成定义”的问题。它让用户的高层需求变成一个个可验证的 feature item,让 agent 不再凭感觉宣布完成。
但第二篇文章进一步发现:有了完成清单还不够。
因为就算 feature item 被勾上,质量仍然可能很一般。
例如,一个“聊天页面”功能可以通过测试:用户能输入、能发送、能看到回复。但这个页面可能布局拥挤、视觉平庸、状态反馈不清晰、交互节奏不自然。它在功能意义上通过了,但在产品意义上仍然不够好。
这正是第二篇文章从第一篇继续前进的地方。
第一篇主要防止 agent “断片”和“误判完成”。
第二篇则进一步防止 agent “低质量完成”。
3.2 从第一篇到第二篇:任务拆解与结构化交接成为地基
To break through, I sought out novel AI engineering approaches that held across two quite different domains, one defined by subjective taste, the other by verifiable correctness and usability. Taking inspiration from Generative Adversarial Networks (GANs), I designed a multi-agent structure with a generator and evaluator agent. Building an evaluator that graded outputs reliably—and with taste—meant first developing a set of criteria that could turn subjective judgments like “is this design good?” into concrete, gradable terms.
I then applied these techniques to long-running autonomous coding, carrying over two lessons from our earlier harness work: decomposing the build into tractable chunks, and using structured artifacts to hand off context between sessions. The final result was a three-agent architecture—planner, generator, and evaluator—that produced rich full-stack applications over multi-hour autonomous coding sessions.
第二篇在开篇中明确承认,它继承了前一篇 long-running harness 的两条经验:第一,把构建过程拆解成可处理的较小块;第二,用结构化工件在不同 session 之间传递上下文。最终,作者在此基础上构建了 planner、generator、evaluator 三智能体架构,用于多小时的自主编码任务。
这句话是理解两篇文章递进关系的关键。
第一篇的贡献,不是一个孤立方案,而是第二篇的地基。没有第一篇解决的两个问题,第二篇很难成立。
为什么?
因为如果 agent 连跨 session 交接都做不好,那么引入 evaluator 没有意义。它可能还没等到评估就已经上下文混乱了。
如果 agent 没有结构化 feature list 或任务拆解,那么 planner / generator / evaluator 之间也很难协作。因为他们没有共同的工作对象。
如果 agent 不会通过文件交接上下文,那么多智能体协作也会退化成一堆临时聊天消息,无法形成稳定流程。
所以第二篇的真正起点不是“我们要做一个更复杂的 multi-agent system”,而是:
在第一篇已经建立的长程工作能力之上,加入评价、反馈和质量控制。
这也是为什么我认为这两篇文章必须放在一起读。第一篇解决的是“Agent 如何连续工作”;第二篇解决的是“连续工作之后如何持续提高质量”。
从工程系统角度看,它们分别对应两个层次:
第一篇:状态系统
- feature list
- progress file
- git history
- init script
- context handoff
第二篇:反馈系统
- planner
- generator
- evaluator
- grading criteria
- sprint contract
- QA loop
状态系统解决“不断线”。
反馈系统解决“不自嗨”。
这就是 Harness Engineering 从第一阶段进入第二阶段的标志。
3.3 Why naive implementations fall short:朴素实现为什么到达天花板
第二篇第一个正式小节叫做 “Why naive implementations fall short”。这一节其实是在回答一个问题:既然第一篇已经证明 harness design 对 long-running agentic coding 有显著帮助,为什么还需要新的架构?
Why naive implementations fall short
We've previously shown that harness design has a substantial impact on the effectiveness of long running agentic coding. In an earlier experiment, we used an initializer agent to decompose a product spec into a task list, and a coding agent that implemented the tasks one feature at a time before handing off artifacts to carry context across sessions. The broader developer community has converged on similar insights, with approaches like the "Ralph Wiggum" method using hooks or scripts to keep agents in continuous iteration cycles.
文章先回顾了早期实验:之前的 long-running harness 使用 initializer agent 将产品规格拆成任务列表,再由 coding agent 一次实现一个 feature,并通过 handoff artifacts 在 session 之间传递上下文。随后作者指出,社区中也出现了类似认识,例如通过 hooks 或 scripts 让 agent 处于连续迭代循环中。
但问题没有完全解决。
But some problems remained persistent. For more complex tasks, the agent still tends to go off the rails over time. While decomposing this issue, we observed two common failure modes with agents executing these sorts of tasks.
作者总结了两个持续存在的失败模式。
First is that models tend to lose coherence on lengthy tasks as the context window fills (see our post on context engineering). Some models also exhibit "context anxiety," in which they begin wrapping up work prematurely as they approach what they believe is their context limit. Context resets—clearing the context window entirely and starting a fresh agent, combined with a structured handoff that carries the previous agent's state and the next steps—addresses both these issues.
第一个失败模式是:模型在长任务中会逐渐失去 coherence。随着上下文窗口被填满,模型可能开始偏离任务。某些模型还会出现所谓的 “context anxiety”,也就是当它们接近自己认为的上下文限制时,会开始提前收尾。文章指出,context reset 能够缓解这个问题:清空上下文窗口,启动一个新的 agent,并通过结构化 handoff 把上一轮状态和下一步工作交给它。
这一段和第一篇的关系非常紧密。
第一篇已经说明,compaction 不足以解决所有长任务问题。第二篇在这里进一步区分了 compaction 和 context reset:
compaction 是把之前对话总结后继续放在同一个 agent 的上下文中;
context reset 是彻底清空上下文,让新 agent 通过结构化交接工件重新接手。
这两者看起来相似,实际上工程含义完全不同。
This differs from compaction, where earlier parts of the conversation are summarized in place so the same agent can keep going on a shortened history. While compaction preserves continuity, it doesn't give the agent a clean slate, which means context anxiety can still persist. A reset provides a clean slate, at the cost of the handoff artifact having enough state for the next agent to pick up the work cleanly. In our earlier testing, we found Claude Sonnet 4.5 exhibited context anxiety strongly enough that compaction alone wasn't sufficient to enable strong long task performance, so context resets became essential to the harness design. This solves the core issue, but adds orchestration complexity, token overhead, and latency to each harness run.
compaction 保留了连续性,但它也保留了上下文压力。模型仍然处在一个“越来越长、越来越压缩、越来越难以把握”的历史中。
context reset 则给了模型一个干净的工作台。它牺牲了一部分原始连续性,换取更清晰的起点。
这就是第二篇对第一篇的一个补充:长程工作不是单纯让上下文变长,而是要设计上下文重启机制。
但 context reset 也不是免费的。文章明确指出,它会带来 orchestration complexity、token overhead 和 latency。
这说明 harness 的每一项能力都伴随代价。
你获得更好的状态恢复,就要付出更多编排复杂度。
你获得更清晰的交接,就要多消耗 token。
你让 agent 更稳,就可能让整个系统更慢、更贵。
这种“能力—成本”权衡,是第二篇后半部分要重点讨论的内容。
第二个失败模式是:self-evaluation,也就是自我评价。
A second issue, which we haven’t previously addressed, is self-evaluation. When asked to evaluate work they've produced, agents tend to respond by confidently praising the work—even when, to a human observer, the quality is obviously mediocre. This problem is particularly pronounced for subjective tasks like design, where there is no binary check equivalent to a verifiable software test. Whether a layout feels polished or generic is a judgment call, and agents reliably skew positive when grading their own work.
文章指出,当 agent 被要求评价自己生成的工作时,它们往往会自信地表扬自己,即使在人类看来质量显然一般。这个问题在设计任务中尤其明显,因为设计没有像软件测试那样明确的二元验证标准。
这是第二篇真正的新问题。
第一篇关注的是:
Agent 如何知道自己做到了哪里?
第二篇关注的是:
Agent 如何知道自己做得好不好?
这两个问题差异很大。
“做到哪里”可以靠 feature list。
“做得好不好”则需要评价标准、比较、品味、经验和反馈。
例如,一个功能是否存在,可以用 pass/fail 表示。
但一个页面是否高级,一个交互是否自然,一个产品是否完整,一个工作流是否顺畅,这些都很难用简单布尔值表达。
However, even on tasks that do have verifiable outcomes, agents still sometimes exhibit poor judgment that impedes their performance while completing the task. Separating the agent doing the work from the agent judging it proves to be a strong lever to address this issue. The separation doesn't immediately eliminate that leniency on its own; the evaluator is still an LLM that is inclined to be generous towards LLM-generated outputs. But tuning a standalone evaluator to be skeptical turns out to be far more tractable than making a generator critical of its own work, and once that external feedback exists, the generator has something concrete to iterate against.
因此,第二篇提出一个关键判断:
把做事的 agent 和评价它的 agent 分离,是解决 self-evaluation 的强力杠杆。
文章也很诚实地说,分离并不会自动消除宽容倾向,因为 evaluator 本身仍然是 LLM,也可能对 LLM 生成内容过于宽松。但调教一个独立 evaluator 变得更怀疑、更严格,比让 generator 对自己的工作保持批判性要容易得多。一旦外部反馈存在,generator 就有了可以迭代的具体对象。
这一点非常重要。
它说明 evaluator 的价值不只是“打分”,而是为 generator 提供一个外部对抗面。
如果没有 evaluator,generator 的循环是:
生成 → 自我感觉不错 → 结束
有了 evaluator,循环变成:
生成 → 外部检查 → 发现问题 → 反馈 → 再生成
这就是第二篇使用 GAN 类比的原因。
3.4 Generator / Evaluator:GAN 启发下的多智能体结构
第二篇文章开头提到,作者受到 Generative Adversarial Networks,也就是 GAN 的启发,设计了 generator 和 evaluator 的多智能体结构。GAN 原本由生成器和判别器组成,生成器试图生成更逼真的样本,判别器则试图区分真假;两者通过对抗训练共同提升。Anthropic 这里不是严格复现 GAN 的数学训练过程,而是借用了它的结构思想:一个 agent 负责生成,另一个 agent 负责评价。
这个类比很有启发,但也要小心理解。
这里的 generator / evaluator 不是在训练模型权重,而是在运行时构建反馈循环。它改变的不是模型参数,而是当前任务中的输出轨迹。
也就是说,它不是传统意义上的“训练”,而是一种运行时控制系统。
在这个系统中:
generator 负责提出方案、写界面、实现功能;
evaluator 负责观察输出、依据标准打分、指出问题;
generator 再根据 evaluator 的反馈修改方向;
多轮循环后,输出质量逐渐提升。
这和第一篇的 coding agent 有很大不同。
第一篇的 coding agent 虽然也会测试和更新状态,但它基本仍然是一个 agent 同时承担多个角色:开发者、测试者、记录者、交接者。
第二篇开始明确拆分角色。它承认:一个 agent 同时做所有事时,很容易对自己过于宽容。因此,与其要求同一个 agent 既创造又批判,不如通过 harness 在系统层面制造角色分离。
这其实是软件工程中的老经验。
在人类团队中,写代码的人和 code reviewer 通常不是同一个人;做功能的人和 QA 也通常不是同一个人。不是因为开发者不能自测,而是因为人很难完全客观地审查自己的工作。
Agent 也是一样。
Harness Engineering 在这里做的事情,是把人类工程组织里的角色分工迁移到 agent 系统中。
所以,generator / evaluator 架构的意义不只是“多一个 agent”,而是:
把质量判断从生成过程内部移到生成过程外部。
这一步是第二篇相对第一篇最重要的升级。
3.5 Frontend design:如何把主观审美变成可评分标准
Frontend design: making subjective quality gradable
I started by experimenting on frontend design, where the self-evaluation issue was most visible. Absent any intervention, Claude normally gravitates toward safe, predictable layouts that are technically functional but visually unremarkable.
第二篇接下来从 frontend design 开始实验,因为前端设计最能暴露 self-evaluation 问题。文章指出,如果没有干预,Claude 通常会倾向于安全、可预测的布局:技术上可用,但视觉上不突出。
这句话对很多使用 AI 做界面的人来说应该非常熟悉。
模型生成的页面往往不是不能看,而是太像“AI 默认审美”:
白色卡片;
紫色渐变;
圆角按钮;
居中 hero section;
三栏 feature cards;
安全但无个性的布局。
这些东西单独看都没有错,但组合起来就会显得模板化、缺少真实产品的气质。
Two insights shaped the harness I built for frontend design. First, while aesthetics can’t be fully reduced to a score—and individual tastes will always vary—they can be improved with grading criteria that encode design principles and preferences. "Is this design beautiful?" is hard to answer consistently, but "does this follow our principles for good design?" gives Claude something concrete to grade against. Second, by separating frontend generation from frontend grading, we can create a feedback loop that drives the generator toward stronger outputs.
Anthropic 在这里提出了两个洞察。
第一个洞察是:审美不能被完全简化成一个分数,但可以通过评价标准变得更可操作。
With this in mind, I wrote four grading criteria that I gave to both the generator and evaluator agents in their prompts
文章说,“这个设计漂亮吗?”很难稳定回答;但“这个设计是否符合我们的好设计原则?”就更具体。于是,作者写了四个评分标准,并把这些标准同时给 generator 和 evaluator。
这四个标准分别是:
Design quality
Originality
Craft
Functionality
为了避免把原文变成简单翻译,我用自己的话解释这四个维度。
Design quality: Does the design feel like a coherent whole rather than a collection of parts? Strong work here means the colors, typography, layout, imagery, and other details combine to create a distinct mood and identity.
Design quality 关注的是整体感。
一个设计是不是像一个有统一气质的整体?颜色、排版、布局、图像和细节是否共同形成某种清晰的 mood 和 identity?这不是问某个按钮好不好看,而是问整个页面有没有统一的设计意图。
Originality: Is there evidence of custom decisions, or is this template layouts, library defaults, and AI-generated patterns? A human designer should recognize deliberate creative choices. Unmodified stock components—or telltale signs of AI generation like purple gradients over white cards—fail here.
Originality 关注的是原创性。
这个设计有没有明显的定制决策?还是只是库组件、模板布局和 AI 常见套路的拼贴?如果一个页面让人一眼看出是“默认组件 + AI 渐变”,它在这个维度上就会失败。
Craft: Technical execution: typography hierarchy, spacing consistency, color harmony, contrast ratios. This is a competence check rather than a creativity check. Most reasonable implementations do fine here by default; failing means broken fundamentals.
Craft 关注的是技术执行。
例如字体层级、间距一致性、色彩和谐、对比度等。这更像基本功检查。Anthropic 也指出,Claude 默认在这一维度通常表现还不错,因为这类技术能力对模型来说相对容易。
Functionality: Usability independent of aesthetics. Can users understand what the interface does, find primary actions, and complete tasks without guessing?
Functionality 关注的是可用性。
用户能不能理解界面在做什么?能不能找到主要动作?能不能完成任务?这和审美无关,是界面作为工具是否有效的问题。
这四个标准的高明之处在于,它们没有试图把“好设计”简化成单一分数,而是把设计拆成几个可讨论的维度。
这就让 evaluator 有了可依赖的判断框架,也让 generator 知道应该朝哪些方向改进。
这里其实出现了 Harness Engineering 的一个重要原则:
当任务目标无法直接验证时,就要先把目标拆成可评价的维度。
在第一篇中,目标被拆成 feature list。
在第二篇中,目标被拆成 grading criteria。
二者本质相同,都是把模糊目标外部化。
区别在于:
feature list 主要处理“有没有做”;
grading criteria 主要处理“做得怎么样”。
这就是从第一篇到第二篇的又一次递进。
3.6 Taste as criteria:品味如何被编码进 harness
I emphasized design quality and originality over craft and functionality. Claude already scored well on craft and functionality by default, as the required technical competence tended to come naturally to the model. But on design and originality, Claude often produced outputs that were bland at best. The criteria explicitly penalized highly generic “AI slop” patterns, and by weighting design and originality more heavily it pushed the model toward more aesthetic risk-taking.
Anthropic 接着指出,他们在前端设计实验中更强调 design quality 和 originality,而不是 craft 和 functionality。原因是 Claude 默认在 craft 和 functionality 上已经表现不错,但在设计质量和原创性上经常输出平庸结果。因此,作者让评价标准明确惩罚泛化、模板化的 “AI slop” 模式,并通过更高权重推动模型承担更多审美风险。
这一段非常值得深挖。
它说明评价标准不是中立的。
你选择强调什么,模型就会向什么方向移动。
你惩罚什么,模型就会避免什么。
你如何措辞,模型就会如何理解“好”。
换句话说,criteria 本身就是一种“品味编码”。
I calibrated the evaluator using few-shot examples with detailed score breakdowns. This ensured the evaluator’s judgment aligned with my preferences, and reduced score drift across iterations.
这和传统软件测试不同。一个单元测试通常只判断行为是否符合预期。但设计评价标准不只是判断结果,也在塑造结果。
例如,如果你在 criteria 中强调:
clean
polished
professional
enterprise-ready
模型可能会生成非常稳重、商务化、SaaS 风格的界面。
如果你强调:
museum quality
distinct visual identity
deliberate creative choices
avoid template patterns
模型就可能更愿意尝试强烈的视觉语言、更独特的布局、更高风险的设计选择。
The wording of the criteria steered the generator in ways I didn't fully anticipate. Including phrases like "the best designs are museum quality" pushed designs toward a particular visual convergence, suggesting that the prompting associated with the criteria directly shaped the character of the output.
Anthropic 在文章中也观察到,criteria 的措辞会以作者没有完全预料到的方式影响输出。例如,包含类似“最好的设计具有博物馆级质量”的措辞,会把生成结果推向某种视觉收敛,说明评价标准相关 prompt 会直接塑造输出的性格。
这对 Harness Engineering 非常重要。
很多人会以为 harness 是一种“客观流程设计”:把步骤写清楚,把测试写清楚,把工具接好就行。但第二篇告诉我们,在复杂创造性任务中,harness 还承担了另一种功能:
它把人类的偏好、品味和判断标准编码进系统。
也就是说,harness 不只是工作流,也是价值观。
在前端设计里,这种价值观表现为审美偏好。
在产品开发里,它可能表现为产品深度、交互完整性、错误处理标准。
在代码工程里,它可能表现为架构偏好、可维护性、测试覆盖率、抽象边界。
这也解释了为什么 OpenAI 那篇文章中会强调类似 PRODUCT_SENSE.md、QUALITY_SCORE.md 这样的文档。那些文件不是普通说明书,而是把团队的产品判断和质量标准变成 agent 可读的外部工件。OpenAI 也明确把代码仓库视为智能体可读取的记录系统,并强调应该把架构、产品感、质量分数、执行计划等内容放进结构化文档中,而不是留在人脑或临时聊天记录里。
Anthropic 第二篇的 grading criteria,与 OpenAI 的这些质量文档,本质上是同一种东西:
把隐性的“好”写成显性的“如何判断好”。
这一步非常关键。因为 AI agent 的能力越强,它越需要知道“朝哪个方向强”。
否则,它只会生成一种平均化的、统计意义上安全的、但缺少锋芒的结果。
3.7 前端设计循环:从一次生成到多轮反馈
I built the loop on the Claude Agent SDK, which kept the orchestration straightforward. A generator agent first created an HTML/CSS/JS frontend based on a user prompt. I gave the evaluator the Playwright MCP, which let it interact with the live page directly before scoring each criterion and writing a detailed critique. In practice, the evaluator would navigate the page on its own, screenshotting and carefully studying the implementation before producing its assessment. That feedback flowed back to the generator as input for the next iteration.
在定义好评分标准之后,Anthropic 搭建了一个 generator / evaluator 循环。generator 先根据用户 prompt 创建 HTML / CSS / JS 前端,evaluator 则借助 Playwright MCP 与真实页面交互,然后按每个评分标准打分并写出详细 critique。evaluator 不是只看静态截图,而是会自己导航页面、截图、仔细研究实现,再给出评估。
这里有一个细节非常重要:evaluator 必须接触真实运行中的页面。
如果 evaluator 只看代码,它可能无法感知实际视觉效果。
如果 evaluator 只看截图,它可能无法感知交互体验。
如果 evaluator 能够操作页面,它就更接近真实用户。
这和第一篇中 browser automation 的思想一脉相承。
第一篇说,coding agent 需要像真实用户一样测试 web app。
第二篇则把这个能力交给独立 evaluator,让它成为反馈循环的一部分。
这说明第二篇不是推翻第一篇,而是把第一篇的一些实践进一步角色化、系统化。
I ran 5 to 15 iterations per generation, with each iteration typically pushing the generator in a more distinctive direction as it responded to the evaluator's critique. Because the evaluator was actively navigating the page rather than scoring a static screenshot, each cycle took real wall-clock time. Full runs stretched up to four hours.
在前端设计实验中,evaluator 的反馈会被传回 generator,作为下一轮迭代输入。作者通常会运行 5 到 15 轮,每轮都让 generator 根据 evaluator critique 改进。由于 evaluator 会实际操作页面,每轮都需要真实墙钟时间,完整运行最长可达四小时。
这个地方可以看出第二篇和第一篇在“时间尺度”上的一致性:它们讨论的都不是一次调用,而是长时间运行的智能体系统。
但二者的长时间运行目的不同。
第一篇的长时间运行是为了完成更多 feature。
第二篇的长时间运行是为了通过反馈提升质量。
也就是说:
第一篇:长时间 = 多 session 增量完成
第二篇:长时间 = 多轮评价反馈改进
这也是一个重要递进。
I also instructed the generator to make a strategic decision after each evaluation: refine the current direction if scores were trending well, or pivot to an entirely different aesthetic if the approach wasn't working.
Across runs, the evaluator's assessments improved over iterations before plateauing, with headroom still remaining. Some generations refined incrementally. Others took sharp aesthetic turns between iterations.
Anthropic 还让 generator 在每次评价后做战略选择:如果当前方向分数趋势好,就继续 refinement;如果方向不行,就 pivot 到完全不同的审美方案。
这一点非常有意思,因为它让 generator 不只是“按照反馈修修补补”,而是要判断当前设计方向是否值得继续投入。
这其实接近真实设计过程。
人类设计师也不是每轮只改一点。有时候一个方向已经证明不行,就应该推倒重来。Anthropic 的 harness 在这里不是简单要求模型“更努力”,而是在流程中显式加入了“继续当前方向还是转向”的判断点。
这也是 Harness Engineering 的高级形态:
不仅控制模型做什么,还控制模型何时反思路径。
3.8 一个关键观察:后期结果不一定总是最好
While scores generally improved over iterations, the pattern was not always cleanly linear. Later implementations tended to be better as a whole, but I regularly saw cases where I preferred a middle iteration over the last one. Implementation complexity also tended to increase across rounds, with the generator reaching for more ambitious solutions in response to the evaluator’s feedback. Even on the first iteration, outputs were noticeably better than a baseline with no prompting at all, suggesting the criteria and associated language themselves steered the model away from generic defaults before any evaluator feedback led to further refinement.
Anthropic 在前端设计实验中还观察到一个很重要的现象:分数总体会随着迭代提升,但提升并不总是线性的。后期实现整体上通常更好,但作者也经常发现自己更喜欢中间某一轮,而不是最后一轮。随着迭代推进,实现复杂度也会增加,generator 会为了回应 evaluator 反馈而尝试更有野心的方案。
这个观察很真实,也很重要。
它说明 feedback loop 不是魔法。多轮迭代并不保证最后一轮就是最佳结果。
In one notable example, I prompted the model to create a website for a Dutch art museum. By the ninth iteration, it had produced a clean, dark-themed landing page for a fictional museum. The page was visually polished but largely in line with my expectations. Then, on the tenth cycle, it scrapped the approach entirely and reimagined the site as a spatial experience: a 3D room with a checkered floor rendered in CSS perspective, artwork hung on the walls in free-form positions, and doorway-based navigation between gallery rooms instead of scroll or click. It was the kind of creative leap that I hadn't seen before from a single-pass generation.

Create a Dutch art museum website

After 10 rounds of feedback
为什么会这样?
因为 evaluator 的反馈会推动 generator 增加复杂度,而复杂度本身可能带来新的问题。一个界面可能在第 6 轮时已经有很好的视觉平衡,但到第 10 轮为了追求 originality,又加了更多动效、布局变化和视觉元素,结果反而破坏了整体节制。
这对 Harness Engineering 有一个重要提醒:
反馈循环需要停止条件,也需要防止过度优化。
如果没有停止条件,agent 可能会不断迎合 evaluator 的短期反馈,导致输出越来越复杂、越来越“用力”,但不一定越来越好。
这类似机器学习中的 overfitting。
模型不断优化某个评分标准,最终可能获得更高分,但人类真实偏好未必同步提高。
Anthropic 的观察也说明:evaluator 不是绝对真理,它只是一个被调教出来的近似判断器。
这点对后面 full-stack coding 的 evaluator 同样成立。Evaluator 能发现很多 bug,但也可能测试不够深,也可能判断过于宽松,也可能遗漏复杂路径。第二篇后面会明确说,Claude 默认并不是一个好的 QA agent,需要通过阅读 evaluator logs、找出判断偏差、更新 QA prompt 等方式反复调教。
所以,第二篇并没有把 evaluator 神化。
它真正传达的是:
独立 evaluator 比 generator 自评更好,但 evaluator 本身也需要 harness。
这句话非常关键。
因为 Harness Engineering 最后会变成一个递归问题:
generator 需要 evaluator;
evaluator 需要 criteria;
criteria 需要人类校准;
整个 harness 需要成本控制和删减;
当模型变强,harness 需要重新评估哪些组件仍然必要。
这正是第二篇后半部分的重点。
3.9 前端设计实验的小结:从“自评”到“外部反馈”
到这里,第二篇文章的前端设计实验已经建立了一个完整逻辑:
第一,模型默认会生成安全、可用但普通的设计。
第二,设计质量很难直接二元验证,因此需要拆成可评分 criteria。
第三,把 generator 和 evaluator 分离,可以避免模型完全依赖自我评价。
第四,evaluator 需要真实操作页面,而不是只看静态输出。
第五,多轮反馈能推动输出变得更有方向感,但也可能带来复杂度上升和非线性结果。
第六,criteria 本身会塑造模型输出的审美方向,因此 harness 也是品味编码系统。
这部分和第一篇的递进关系可以总结为:
第一篇:
把“完成标准”写进 feature list,
防止 agent 误判自己已经完成。
第二篇前半部分:
把“质量标准”写进 grading criteria,
防止 agent 误判自己做得很好。
这就是从 completion 到 quality 的跃迁。
第一篇主要解决:
你是否完成了该完成的东西?
第二篇进一步解决:
你完成的东西是否足够好?
这个问题一旦成立,接下来就可以从前端设计扩展到完整应用开发。因为完整应用开发也需要同样的结构:
谁来定义产品规格?
谁来生成代码?
谁来检查功能?
谁来判断产品深度?
谁来发现 UI、API、数据库之间的断裂?
谁来决定一个 sprint 是否通过?
这就引出了第二篇后半部分的 planner / generator / evaluator 三智能体架构。
3.10 Scaling to full-stack coding:从前端设计迁移到全栈应用开发
Scaling to full-stack coding
With these findings in hand, I applied this GAN-inspired pattern to full-stack development. The generator-evaluator loop maps naturally onto the software development lifecycle, where code review and QA serve the same structural role as the design evaluator.
在完成 frontend design 实验之后,Anthropic 开始把同样的 generator / evaluator 思路迁移到 full-stack development。文章明确指出,这个模式可以自然映射到软件开发生命周期:generator 对应开发者,evaluator 对应 code review 和 QA。也就是说,第二篇不是把前端设计实验当成孤立案例,而是把它当成一种更一般的 harness pattern:一个 agent 负责生成,另一个 agent 负责评价,二者通过反馈循环推动结果改进。
这一步非常关键。
前端设计实验解决的是“主观质量如何评价”。完整应用开发则同时包含:
主观质量:产品设计、视觉一致性、交互体验;
客观正确性:功能是否可用、API 是否连通、数据库状态是否正确;
工程质量:代码结构是否可维护、功能是否真的实现,而不是 stub;
产品完整性:应用是否只是 demo,还是具备真实工作流。
这意味着 full-stack coding harness 面临的问题比 frontend design 更复杂。前端设计里 evaluator 主要判断视觉、原创性、工艺和可用性;全栈应用里 evaluator 还要检查 UI、API、数据库、状态变化、核心 workflow,以及代码层面的实现完整度。Anthropic 在第二篇中让 evaluator 使用 Playwright MCP 像真实用户一样点击运行中的应用,同时检查 UI 功能、API endpoint 和数据库状态,这说明评价已经从“看页面”升级为“验证系统行为”。
这里可以看出两篇文章之间的又一层递进:
第一篇:
让 coding agent 自己使用 browser automation 做端到端测试。
第二篇:
把端到端测试升级为独立 evaluator 的职责,
并让 evaluator 依据产品、功能、视觉和代码质量标准进行评分。
这不是简单地“多跑了一些测试”。它改变了责任结构。
第一篇中,coding agent 仍然是自己实现、自己测试、自己判断能否通过。
第二篇中,generator 虽然仍然会自评,但最终是否通过,要交给 evaluator 判断。
这一步很像从“开发者自测”走向“独立 QA”。
3.11 三智能体架构:Planner / Generator / Evaluator
The architecture
In our earlier long-running harness, we had solved for coherent multi-session coding with an initializer agent, a coding agent that worked one feature at a time, and context resets between sessions. Context resets were a key unlock: the harness used Sonnet 4.5, which exhibited the “context anxiety” tendency mentioned earlier. Creating a harness that worked well across context resets was key to keeping the model on task. Opus 4.5 largely removed that behavior on its own, so I was able to drop context resets from this harness entirely. The agents were run as one continuous session across the whole build, with the Claude Agent SDK's automatic compaction handling context growth along the way.
For this work I built on the foundation from the original harness with a three-agent system, with each agent addressing a specific gap I'd observed in prior runs.The system contained the following agent personas
在 full-stack coding 部分,Anthropic 构建了一个三智能体系统:planner、generator 和 evaluator。每个 agent 都对应此前实验中观察到的一个缺口。
这个架构可以看成第二篇的核心。
Planner:把短 prompt 扩展成产品规格
Planner: Our previous long-running harness required the user to provide a detailed spec upfront. I wanted to automate that step, so I created a planner agent that took a simple 1-4 sentence prompt and expanded it into a full product spec.
Planner 的任务是把用户提供的 1 到 4 句话 prompt,扩展成完整 product spec。Anthropic 特别强调,之前的 long-running harness 要求用户一开始提供较详细的 spec,而这次作者希望自动完成这个步骤。因此 planner 的职责不是写代码,而是把模糊的产品意图变成足够丰富、可执行的产品规格。
I prompted it to be ambitious about scope and to stay focused on product context and high level technical design rather than detailed technical implementation. This emphasis was due to the concern that if the planner tried to specify granular technical details upfront and got something wrong, the errors in the spec would cascade into the downstream implementation. It seemed smarter to constrain the agents on the deliverables to be produced and let them figure out the path as they worked.
这里可以看到一个很重要的设计取舍:planner 被要求关注产品上下文和高层技术设计,而不是过早指定非常细的技术实现细节。Anthropic 的理由是,如果 planner 在早期写下过细的技术方案,而且这些方案有错,错误就会沿着后续实现层层传递,形成 cascade。相比之下,更合理的方式是让 planner 约束“要交付什么”,而把“如何实现”留给后续 generator 在实际开发中决定。
这点非常值得重点分析。
很多人设计 agent workflow 时,会本能地想让规划阶段越详细越好。但 Anthropic 的经验恰恰说明:过度规划可能会污染后续实现。
Planner 的价值不是把所有细节提前写死,而是建立产品目标、范围边界和高层方向。
这就像人类产品开发中的 PRD。一个好的 PRD 应该说明用户是谁、场景是什么、核心能力是什么、边界在哪里、成功标准是什么;但它不应该在不了解实现细节时强行规定每个函数怎么写、每个组件怎么拆、每个 API 怎么命名。
所以 planner 的本质是:
把用户的模糊意图扩展成可执行的产品方向,但避免把不确定实现细节提前固化。
这也是第二篇对 Harness Engineering 的一个重要补充:
harness 不只是帮助 agent 执行任务,也帮助 agent 定义任务。
I also asked the planner to find opportunities to weave AI features into the product specs. (See example in the Appendix at the bottom.)
Appendix
Example plan generated by planner agent.
RetroForge - 2D Retro Game Maker
Overview
RetroForge is a web-based creative studio for designing and building 2D retro-style video games. It combines the nostalgic charm of classic 8-bit and 16-bit game aesthetics with modern, intuitive editing tools—enabling anyone from hobbyist creators to indie developers to bring their game ideas to life without writing traditional code.The platform provides four integrated creative modules: a tile-based Level Editor for designing game worlds, a pixel-art Sprite Editor for crafting visual assets, a visual Entity Behavior system for defining game logic, and an instant Playable Test Mode for real-time gameplay testing. By weaving AI assistance throughout (powered by Claude), RetroForge accelerates the creative process—helping users generate sprites, design levels, and configure behaviors through natural language interaction.
RetroForge targets creators who love retro gaming aesthetics but want modern conveniences. Whether recreating the platformers, RPGs, or action games of their childhood, or inventing entirely new experiences within retro constraints, users can prototype rapidly, iterate visually, and share their creations with others.
Features
1. Project Dashboard & Management
The Project Dashboard is the home base for all creative work in RetroForge. Users need a clear, organized way to manage their game projects—creating new ones, returning to works-in-progress, and understanding what each project contains at a glance.User Stories: As a user, I want to:
- Create a new game project with a name and description, so that I can begin designing my game
- See all my existing projects displayed as visual cards showing the project name, last modified date, and a thumbnail preview, so that I can quickly find and continue my work
- Open any project to enter the full game editor workspace, so that I can work on my game
- Delete projects I no longer need, with a confirmation dialog to prevent accidents, so that I can keep my workspace organized
- Duplicate an existing project as a starting point for a new game, so that I can reuse my previous workProject Data Model: Each project contains:
Project metadata (name, description, created/modified timestamps)
Canvas settings (resolution: e.g., 256x224, 320x240, or 160x144)
Tile size configuration (8x8, 16x16, or 32x32 pixels)
Color palette selection
All associated sprites, tilesets, levels, and entity definitions...
Generator:按 sprint 实现功能
Generator: The one-feature-at-a-time approach from the earlier harness worked well for scope management. I applied a similar model here, instructing the generator to work in sprints, picking up one feature at a time from the spec. Each sprint implemented the app with a React, Vite, FastAPI, and SQLite (later PostgreSQL) stack, and the generator was instructed to self-evaluate its work at the end of each sprint before handing off to QA. It also had git for version control.
Generator 的职责更接近传统意义上的 coding agent。Anthropic 沿用了第一篇中“one feature at a time”的思路,让 generator 按 sprint 工作,每次从 spec 中选取一个功能块推进。每个 sprint 中,generator 使用 React、Vite、FastAPI、SQLite,后来改用 PostgreSQL 这样的技术栈实现应用;它还要在 sprint 结束时自评,然后把工作交给 QA。
这里可以看到第一篇的直接继承。
第一篇中的 coding agent 是一次实现一个 feature。
第二篇中的 generator 是一次实现一个 sprint。
feature 和 sprint 的粒度不同,但思想一致:不要一次性试图完成整个应用,而是把复杂任务拆成可以验证的增量块。
不过第二篇相对第一篇多了两个变化。
第一个变化是:generator 不再负责最终裁判。它可以自评,但要交给 evaluator 审查。
第二个变化是:generator 的工作不再只由 feature list 驱动,而是由 planner 生成的完整 product spec 和后续 sprint contract 共同驱动。
这说明第二篇中的 generator 处在更复杂的组织结构里。它不是一个孤立执行者,而是夹在 planner 和 evaluator 之间:
Planner 定义产品方向
→ Generator 实现功能
→ Evaluator 验证质量
→ Generator 根据反馈修复
这就是第二篇相对第一篇的核心升级:从单一 coding loop 变成 multi-agent software lifecycle。
Evaluator:像真实用户一样测试,也像 QA 一样审查
Evaluator: Applications from earlier harnesses often looked impressive but still had real bugs when you actually tried to use them. To catch these, the evaluator used the Playwright MCP to click through the running application the way a user would, testing UI features, API endpoints, and database states. It then graded each sprint against both the bugs it had found and a set of criteria modeled on the frontend experiment, adapted here to cover product depth, functionality, visual design, and code quality. Each criterion had a hard threshold, and if any one fell below it, the sprint failed and the generator got detailed feedback on what went wrong.
Evaluator 是第二篇中最重要的角色。Anthropic 指出,早期 harness 生成的应用经常“看起来很厉害”,但真正使用时仍然有 bug。为了捕获这些问题,evaluator 使用 Playwright MCP 操作运行中的应用,像真实用户一样点击 UI,同时测试 API endpoint 和数据库状态。随后,它会根据 bug 和一组评价标准给每个 sprint 打分;这些标准包括 product depth、functionality、visual design 和 code quality。
这个设计非常关键,因为它把 evaluator 的工作从“读代码”提升到了“验证应用行为”。
很多 AI coding demo 看起来很强,是因为第一眼打开页面时视觉完整。但真正点击几分钟后,就会出现大量问题:按钮没接上、状态没刷新、页面流程断裂、后端 API 没通、数据库没有持久化、关键功能只是占位。Anthropic 在 retro game maker 的例子里也观察到,solo run 生成的应用看起来符合预期,但实际进入 play mode 后,核心游戏功能并不能正常响应。
这说明 full-stack app 的“完成”不能只靠静态观察。
一个 web app 的完成至少有三层:
第一层:界面存在。
第二层:交互可用。
第三层:端到端工作流真实成立。
很多 agent 输出停留在第一层或第二层。
Evaluator 的作用,就是推动系统进入第三层。
3.12 Sprint contract:在写代码前先定义“什么叫完成”
第二篇中最有工程味道的设计,是 sprint contract。
Before each sprint, the generator and evaluator negotiated a sprint contract: agreeing on what "done" looked like for that chunk of work before any code was written. This existed because the product spec was intentionally high-level, and I wanted a step to bridge the gap between user stories and testable implementation. The generator proposed what it would build and how success would be verified, and the evaluator reviewed that proposal to make sure the generator was building the right thing. The two iterated until they agreed.
Communication was handled via files: one agent would write a file, another agent would read it and respond either within that file or with a new file that the previous agent would read in turn. The generator then built against the agreed-upon contract before handing the work off to QA. This kept the work faithful to the spec without over-specifying implementation too early.
Anthropic 解释说,在每个 sprint 开始前,generator 和 evaluator 会先协商一个 sprint contract,也就是先就这一块工作“什么叫完成”达成一致,然后 generator 才开始写代码。这个机制存在的原因是:planner 生成的 product spec 是故意保持高层的,因此需要一个中间步骤,把 user story 和可测试实现连接起来。generator 会提出要构建什么、如何验证成功,evaluator 则审查这个方案,确认 generator 没有偏题;双方会反复迭代,直到达成一致。
这一步非常重要。
它解决的是 planner 和 generator 之间的语义缝隙。
Planner 写的是高层规格,例如:
用户应该能够创建关卡、编辑 sprite、定义 entity behavior,并进入 playable test mode。
但 generator 真正写代码前,需要更具体的问题:
本轮 sprint 要完成 level editor 的哪些行为?
用户如何创建 tile?
如何拖拽?
如何删除?
如何保存?
如何验证这些行为通过?
哪些情况算失败?
如果没有 sprint contract,generator 可能会按照自己的理解实现一个“看起来差不多”的版本。Evaluator 到最后才发现它和预期不一致,这时返工成本就很高。
Sprint contract 的价值在于:把评价标准前置。
它不是等代码写完后再问“你做得对不对”,而是在写之前就问:
我们这一轮到底要做什么?
成功如何被验证?
evaluator 会依据什么判断通过?
这和人类工程中的验收标准非常像。一个成熟团队在开工前会定义 acceptance criteria,而不是等功能做完才讨论“这是不是我们想要的”。
从 Harness Engineering 角度看,sprint contract 是一个非常典型的控制工件:
它让 generator 不至于自由发挥过度;
它让 evaluator 的评价有依据;
它把高层 spec 转换成可测试行为;
它避免 planner 过度规定实现细节;
它在不写死技术路径的情况下约束交付结果。
这里可以把第二篇和第一篇再次对应起来:
第一篇的 feature_list.json:
定义整个项目范围内“哪些功能需要完成”。
第二篇的 sprint contract:
定义当前 sprint 中“本轮什么叫完成”。
feature list 是全局完成标准。
sprint contract 是局部验收合同。
二者共同说明:Harness Engineering 的核心之一,就是不断把模糊目标转化为 agent 可执行、可验证的外部工件。
3.13 Running the harness:为什么 20 倍成本换来明显质量提升
Running the harness
For the first version of this harness, I used Claude Opus 4.5, running user prompts against both the full harness and a single-agent system for comparison. I used Opus 4.5 since this was our best coding model when I began these experiments.
I wrote the following prompt to generate a retro video game maker:
Create a 2D retro game maker with features including a level editor, sprite editor, entity behaviors, and a playable test mode.The table below shows the harness type, length it ran for, and the total cost.
Harness Duration Cost Solo 20 min $9 Full harness 6 hr $200 The harness was over 20x more expensive, but the difference in output quality was immediately apparent.
在 Running the harness 部分,Anthropic 用一个 retro video game maker 的例子对比了 solo run 和 full harness。用户 prompt 很简单:构建一个 2D retro game maker,包括 level editor、sprite editor、entity behaviors 和 playable test mode。Solo run 用时约 20 分钟,成本约 9 美元;full harness 用时约 6 小时,成本约 200 美元。也就是说,full harness 成本超过 solo run 20 倍,但作者认为输出质量差异非常明显。
这个实验非常适合用来理解 harness 的成本问题。
从成本看,full harness 显然很重。
从结果看,它确实产生了更完整、更可用、更有产品深度的应用。
I was expecting an interface where I could construct a level and its component parts (sprites, entities, tile layout) then hit play to actually play the level. I started by opening the solo run’s output, and the initial application seemed in line with those expectations.
As I clicked through, however, issues started to emerge. The layout wasted space, with fixed-height panels leaving most of the viewport empty. The workflow was rigid. Trying to populate a level prompted me to create sprites and entities first, but nothing in the UI guided me toward that sequence. More to the point, the actual game was broken. My entities appeared on screen but nothing responded to input. Digging into the code revealed that the wiring between entity definitions and the game runtime was broken, with no surface indication of where.
Solo run 的问题是:一开始看起来符合预期,但实际点击后发现布局浪费空间、工作流僵硬、用户不知道该先创建 sprites 和 entities,最关键的是 play mode 中 entity 出现在屏幕上却无法响应输入;代码层面则是 entity definitions 和 game runtime 之间的 wiring 断了。
After evaluating the solo run, I turned my attention to the harness run. This run started from the same one-sentence prompt, but the planner step expanded that prompt into a 16-feature spec spread across ten sprints. It went well beyond what the solo run attempted. In addition to the core editors and play mode, the spec called for a sprite animation system, behavior templates, sound effects and music, an AI-assisted sprite generator and level designer, and game export with shareable links. I gave the planner access to our frontend design skill, which it read and used to create a visual design language for the app as part of the spec. For each sprint, the generator and evaluator negotiated a contract defining the specific implementation details for the sprint, and the testable behaviors that would be tested to verify completion.
Full harness 的结果明显更强。Planner 把一句话 prompt 扩展成 16 个 feature,分布在 10 个 sprint 中;功能范围不仅包括核心编辑器和 playable mode,还包括 sprite animation system、behavior templates、sound effects、music、AI-assisted sprite generator、AI-assisted level designer,以及带 shareable links 的 game export。
这说明 planner 的作用不是锦上添花。没有 planner,agent 很容易 under-scope,也就是只做一个最小、表层、缺乏产品深度的应用。有了 planner,应用范围被显著扩展,并且更接近“完整产品”而不是“功能 demo”。
The app immediately showed more polish and smoothness than the solo run. The canvas used the full viewport, the panels were sized sensibly, and the interface had a consistent visual identity that tracked the design direction from the spec. Some of the clunkiness I'd seen in the solo run did remain—the workflow still didn't make it clear that you should build sprites and entities before trying to populate a level, and I had to figure that out by poking around. This read as a gap in the base model’s product intuition rather than something the harness was designed to address, though it did suggest a place where targeted iteration inside the harness could help to further improve output quality.
Working through the editors, the new run's advantages over solo became more apparent. The sprite editor was richer and more fully featured, with cleaner tool palettes, a better color picker, and more usable zoom controls.
Because I'd asked the planner to weave AI features into its specs, the app also came with a built-in Claude integration that let me generate different parts of the game through prompting. This significantly sped up the workflow.
Full harness 的优势还体现在可用性上。Anthropic 描述说,harness run 生成的应用视觉更统一,canvas 更充分利用视口,sprite editor 更丰富,颜色选择器和缩放控制也更可用;更关键的是,play mode 真的可以移动 entity 并进行游戏,虽然仍有物理碰撞等粗糙问题。
这个例子说明一个重要结论:
Harness 的价值不只是提高代码正确率,而是提高产品完整度。
很多时候,单 agent 不是完全失败,而是只做到“看上去像”。
Full harness 则更有机会做到“真的能用”。
The biggest difference was in play mode. I was actually able to move my entity and play the game. The physics had some rough edges—my character jumped onto a platform but ended up overlapping with it, which felt intuitively wrong—but the core thing worked, which the solo run did not manage. After moving around a bit, I did hit some limitations with the AI’s game level construction. There was a large wall that I wasn’t able to jump past, so I was stuck. This suggested there were some common sense improvements and edge cases that the harness could handle to further refine the app.
这里也要保持清醒:Anthropic 并没有说 full harness 生成了完美应用。文章承认,harness run 仍然存在 workflow 不够清晰、物理行为有瑕疵、AI 生成关卡存在边界问题等不足。
这反而让文章更可信。Harness 不是魔法,它不是把模型变成完美工程团队。它的作用是把问题往前推进一大步:从核心功能坏掉,推进到核心功能可用但仍有体验和边缘问题。
3.14 Evaluator 的调教:Claude 默认并不是好 QA
Getting the evaluator to perform at this level took work. Out of the box, Claude is a poor QA agent. In early runs, I watched it identify legitimate issues, then talk itself into deciding they weren't a big deal and approve the work anyway. It also tended to test superficially, rather than probing edge cases, so more subtle bugs often slipped through. The tuning loop was to read the evaluator's logs, find examples where its judgment diverged from mine, and update the QAs prompt to solve for those issues. It took several rounds of this development loop before the evaluator was grading in a way that I found reasonable.
第二篇最有价值的经验之一,是 Anthropic 对 evaluator 的反思。作者明确指出,开箱即用的 Claude 并不是一个好的 QA agent。早期运行中,它会发现真实问题,但随后又说服自己这些问题不严重,并批准工作;它还倾向于测试得比较浅,导致更隐蔽的 bug 溜过去。作者的调优方式是阅读 evaluator logs,找出 evaluator 判断和自己判断不一致的例子,然后更新 QA prompt。这个过程反复几轮后,evaluator 的判断才变得比较合理。
这段非常重要,因为它避免了一个常见误解:只要拆出 evaluator,质量问题就自动解决。
实际上,evaluator 本身也需要 harness。
Evaluator 需要:
明确的评价标准;
足够严格的 fail threshold;
few-shot examples;
对边缘情况的测试要求;
对“不要自我说服放过问题”的约束;
对日志的人工复盘;
持续 prompt 调优。
这意味着 Harness Engineering 不是一次性搭一个流程就结束,而是要观察 agent traces,发现系统性偏差,再修改 harness。
Reading through the logs, it was clear that the evaluator kept the implementation in line with the spec. Each sprint, it walked through the sprint contract's test criteria and exercised the running application through Playwright, filing bugs against anything that diverged from expected behavior. The contracts were granular—Sprint 3 alone had 27 criteria covering the level editor—and the evaluator's findings were specific enough to act on without extra investigation. The table below shows several examples of issues our evaluator identified:
Contract criterion
Evaluator finding
Rectangle fill tool allows click-drag to fill a rectangular area with selected tile
FAIL — Tool only places tiles at drag start/end points instead of filling the region. function exists but isn't triggered properly on mouseUp.
fillRectangleUser can select and delete placed entity spawn points
FAIL — Delete key handler at requires both and to be set, but clicking an entity only sets . Condition should be .
LevelEditor.tsx:892selectionselectedEntityIdselectedEntityIdselection || (selectedEntityId && activeLayer === 'entity')User can reorder animation frames via API
FAIL — route defined after routes. FastAPI matches 'r' as a frame_id integer and returns 422: "unable to parse string as an integer."
PUT /frames/reorder/{frame_id}eorder
Anthropic 在 retro game maker 的例子中展示了 evaluator 能发现的一些具体问题。例如,矩形填充工具没有真正填满区域,删除 entity spawn point 的条件判断有误,FastAPI 路由顺序导致某个 reorder endpoint 被错误解析。这些问题都不是单看 UI 第一眼能发现的,而需要 evaluator 按照 contract criterion 实际测试并检查实现细节。
这说明好的 evaluator 不是一个“打分机器人”,而是一个带工具的调查者。
它要能:
阅读 contract
操作应用
观察行为
对照预期
定位失败
给出可操作反馈
这和第一篇中的 coding agent 自测相比,是质的升级。
第一篇要求 agent 自己测试,是为了避免它完全不验证就标记完成。
第二篇则发现,自测仍然不够,因为 agent 会对自己的工作过于宽容。于是,独立 evaluator 承担更严肃的 QA 职责。
Even then, the harness output showed the limits of the model’s QAing capabilities: small layout issues, interactions that felt unintuitive in places, and undiscovered bugs in more deeply nested features that the evaluator hadn't exercised thoroughly. There was clearly more verification headroom to capture with further tuning. But compared to the solo run, where the central feature of the application simply didn't work, the lift was obvious.
但 Anthropic 也承认,即使调优后,evaluator 仍然有局限:小布局问题、交互不直觉、嵌套较深功能中的 bug 仍可能漏掉。也就是说,QA harness 还有进一步提升空间。
也就是说:evaluator 不是终点,而是另一个需要工程化的对象。
3.15 Iterating on the harness:复杂 harness 也需要被删减
第二篇后半部分进入了非常成熟的一层:当 full harness 有效果之后,下一步不是继续加复杂度,而是尝试简化它。
Iterating on the harness
The first set of harness results was encouraging, but it was also bulky, slow, and expensive. The logical next step was to find ways to simplify the harness without degrading its performance. This was partly common sense and partly a function of a more general principle: every component in a harness encodes an assumption about what the model can't do on its own, and those assumptions are worth stress testing, both because they may be incorrect, and because they can quickly go stale as models improve. Our blog post Building Effective Agents frames the underlying idea as "find the simplest solution possible, and only increase complexity when needed," and it's a pattern that shows up consistently for anyone maintaining an agent harness.
Anthropic 说,第一版 harness 的结果令人鼓舞,但它笨重、缓慢、昂贵。因此,下一步自然是寻找不降低性能的简化方式。文章提出了一个非常重要的原则:harness 中的每个组件,都编码了一个关于“模型自己不能做什么”的假设;这些假设值得被压力测试,因为它们可能本来就是错的,也可能随着模型进步迅速过时。
这可能是整篇第二篇文章中最值得反复引用的一句话。
它把 Harness Engineering 从“加脚手架”提升到了“审计脚手架”。
很多人做 agent workflow,容易陷入一种复杂度崇拜:planner 越多越好,reviewer 越多越好,critic 越多越好,reflection 越多越好,memory 越多越好,工具越多越好。
但 Anthropic 的经验恰恰相反:
每一个 harness 组件都应该被视为一项成本。
它会增加:
token cost;
wall-clock latency;
orchestration complexity;
failure surface;
调试难度;
状态同步难度;
不必要的 agent 间误差传播。
所以正确的问题不是:
我还能往 harness 里加什么?
而是:
当前模型到底还缺什么?
哪个组件是真正 load-bearing 的?
哪个组件只是历史遗留?
哪个组件随着模型升级已经不再必要?
这和 Anthropic 另一篇关于 Building Effective Agents 的原则一致:从最简单可行方案开始,只在必要时增加复杂度。第二篇也明确引用了这个思路。
这一段对理解 Harness Engineering 非常关键。
第一篇主要告诉我们:为什么需要外部工件、任务拆解和交接机制。
第二篇前半告诉我们:为什么需要 evaluator 和反馈循环。
第二篇后半则告诉我们:这些结构都不是永恒正确的。
Harness 是模型能力边界的函数。
模型变了,harness 也必须变。
3.16 Removing the sprint construct:模型变强后,哪些脚手架不再承重
In my first attempt to simplify, I cut the harness back radically and tried a few creative new ideas, but I wasn't able to replicate the performance of the original. It also became difficult to tell which pieces of the harness design were actually load-bearing, and in what ways. Based on that experience, I moved to a more methodical approach, removing one component at a time and reviewing what impact it had on the final result.
As I was going through these iteration cycles, we also released Opus 4.6, which provided further motivation to reduce harness complexity. There was good reason to expect 4.6 would need less scaffolding than 4.5 did. From our launch blog: "[Opus 4.6] plans more carefully, sustains agentic tasks for longer, can operate more reliably in larger codebases, and has better code review and debugging skills to catch its own mistakes." It also improved substantially on long-context retrieval. These were all capabilities the harness had been built to supplement.
在简化 harness 的过程中,Anthropic 首先移除了 sprint construct。原来的 sprint 结构帮助模型把任务拆成 coherent chunks。但随着 Opus 4.6 能力提升,作者认为模型可能已经可以不依赖这种分解,直接处理更长、更复杂的任务。于是,updated harness 保留 planner 和 evaluator,但移除了 sprint decomposition,并把 evaluator 改为最后阶段的一次性 QA,而不是每个 sprint 都评估。
Removing the sprint construct
I started by removing the sprint construct entirely. The sprint structure had helped to decompose work into chunks for the model to work coherently. Given the improvements in Opus 4.6, there was good reason to believe that the model could natively handle the job without this sort of decomposition.
I kept both the planner and evaluator, as each continued to add obvious value. Without the planner, the generator under-scoped: given the raw prompt, it would start building without first speccing its work, and end up creating a less feature-rich application than the planner did.
这一节非常值得重点分析,因为它展示了 Harness Engineering 的动态性。
在 Opus 4.5 上,sprint construct 是必要脚手架。
到了 Opus 4.6,这个脚手架可能就不再必要。
这说明 harness 组件是否有价值,不能脱离模型能力讨论。
With the sprint construct removed, I moved the evaluator to a single pass at the end of the run rather than grading per sprint. Since the model was much more capable, it changed how load-bearing the evaluator was for certain runs, with its usefulness depending on where the task sat relative to what the model could do reliably on its own. On 4.5, that boundary was close: our builds were at the edge of what the generator could do well solo, and the evaluator caught meaningful issues across the build. On 4.6, the model's raw capability increased, so the boundary moved outward. Tasks that used to need the evaluator's check to be implemented coherently were now often within what the generator handled well on its own, and for tasks within that boundary, the evaluator became unnecessary overhead. But for the parts of the build that were still at the edge of the generator’s capabilities, the evaluator continued to give real lift.
The practical implication is that the evaluator is not a fixed yes-or-no decision. It is worth the cost when the task sits beyond what the current model does reliably solo.
Alongside the structural simplification, I also added prompting to improve how the harness built AI features into each app, specifically getting the generator to build a proper agent that could drive the app's own functionality through tools. That took real iteration, since the relevant knowledge is recent enough that Claude's training data covers it thinly. But with enough tuning, the generator was building agents correctly.
Anthropic 进一步解释,planner 仍然保留,因为没有 planner 时,generator 会 under-scope:面对原始 prompt,它会直接开始构建,而不是先完整规划,因此最终应用的功能丰富度会下降。Evaluator 也保留,但它的作用边界发生变化:对于模型已经能可靠独立完成的任务,evaluator 可能变成不必要开销;但对于仍处在模型能力边缘的部分,evaluator 依然能带来真实提升。
这里可以提出一个很重要的观点:
Evaluator 不是固定答案,而是边界工具。
当任务位于模型舒适区内,evaluator 可能只是成本。
当任务位于模型能力边缘,evaluator 就是必要的质量放大器。
这比“要不要 evaluator”更精确。
真正的问题不是:
我是否应该使用 evaluator?
而是:
当前任务是否超出了当前模型稳定 solo 完成的范围?
如果超出了,evaluator 值得付出成本。
如果没有超出,evaluator 可能就是额外延迟和 token 消耗。
Results from the updated harness
To put the updated harness to the test, I used the following prompt to generate a Digital Audio Workstation (DAW), a music production program for composing, recording, and mixing songs:
Build a fully featured DAW in the browser using the Web Audio API.The run was still lengthy and expensive, at about 4 hours and $124 in token costs.
Most of the time went to the builder, which ran coherently for over two hours without the sprint decomposition that Opus 4.5 had needed.
Agent & Phase Duration Cost Planner 4.7 min $0.46 Build (Round 1) 2 hr 7 min $71.08 QA (Round 1) 8.8 min $3.24 Build (Round 2) 1 hr 2 min $36.89 QA (Round 2) 6.8 min $3.09 Build (Round 3) 10.9 min $5.88 QA (Round 3) 9.6 min $4.06 Total V2 Harness 3 hr 50 min $124.70 As with the previous harness, the planner expanded the one-line prompt into a full spec. From the logs, I could see the generator model did a good job planning the app and the agent design, wiring the agent up, and testing it before handing off to QA.
Anthropic 在 updated harness 中用 DAW,也就是 browser-based digital audio workstation 作为测试。Prompt 是构建一个使用 Web Audio API 的完整 DAW。updated harness 仍然耗时很长、成本很高,总计约 3 小时 50 分钟,成本约 124.70 美元;其中 builder 在没有 sprint decomposition 的情况下连续运行超过两小时,这说明新模型确实能承受更长的 coherent build。
That being said, the QA agent still caught real gaps. In its first-round feedback, it noted:
This is a strong app with excellent design fidelity, solid AI agent, and good backend. The main failure point is Feature Completeness — while the app looks impressive and the AI integration works well, several core DAW features are display-only without interactive depth: clips can't be dragged/moved on the timeline, there are no instrument UI panels (synth knobs, drum pads), and no visual effect editors (EQ curves, compressor meters). These aren't edge cases — they're the core interactions that make a DAW usable, and the spec explicitly calls for them.In its second round feedback, it again caught several functionality gaps:
Remaining gaps:
- Audio recording is still stub-only (button toggles but no mic capture)
- Clip resize by edge drag and clip split not implemented
- Effect visualizations are numeric sliders, not graphical (no EQ curve)The generator was still liable to miss details or stub features when left to its own devices, and the QA still added value in catching those last mile issues for the generator to fix.
但 QA agent 仍然发现了真实问题。例如一些核心 DAW 功能只是展示性质而缺乏交互深度:clip 不能拖动,缺少 instrument UI panel,效果器没有图形化编辑界面;第二轮 QA 又发现录音仍然只是 stub、clip resize 和 split 没有实现、效果器可视化不足等问题。
这说明即使模型更强,generator 仍然可能遗漏细节或用 stub 代替真实实现。Evaluator 的价值从“每个 sprint 都保驾护航”,变成“最后捕获 last-mile gaps”。
这是一个非常细腻的变化。
不是 evaluator 消失了。
而是 evaluator 的位置变了、频率变了、边界变了。
这正好印证第二篇最后的判断:随着模型能力提升,harness 的空间不会消失,而是移动。
3.17 What comes next:Harness 的空间不会消失,只会移动
As models continue to improve, we can roughly expect them to be capable of working for longer, and on more complex tasks. In some cases, that will mean the scaffold surrounding the model matters less over time, and developers can wait for the next model and see certain problems solve themselves. On the other hand, the better the models get, the more space there is to develop harnesses that can achieve complex tasks beyond what the model can do at baseline.
第二篇结尾提出了一个很重要的展望:随着模型继续进步,它们会处理更长、更复杂的任务。在某些情况下,围绕模型的 scaffold 会变得不那么重要,因为新模型自己就能解决旧模型需要 harness 补偿的问题;但另一方面,模型越强,我们也越有空间设计新的 harness,去完成 baseline 模型仍然做不到的复杂任务。
这句话很好地总结了第二篇文章的成熟之处。
它没有简单说:
模型越强,harness 越不重要。
也没有说:
harness 永远越复杂越好。
它说的是:
harness 的边界会随着模型能力移动。
这其实是 Harness Engineering 最重要的方法论之一。
当模型比较弱时,harness 可能主要用于补短板:
防止上下文焦虑;
防止过早完成;
防止忘记进度;
防止不测试;
防止自我评价过于宽松。
当模型变强后,一部分旧脚手架会失去价值。但与此同时,开发者会把目标推向更难的问题:
- 更长时间的自主开发;
- 更复杂的产品定义;
- 更深的端到端 QA;
- 更复杂的 agent-in-app 功能;
- 更高标准的审美和产品判断;
- 更真实的生产环境约束。
因此,harness 并不是随着模型能力提升而消失,而是从低层补丁转向高层能力放大。
With this in mind, there are a few lessons from this work worth carrying forward. It is always good practice to experiment with the model you're building against, read its traces on realistic problems, and tune its performance to achieve your desired outcomes. When working on more complex tasks, there is sometimes headroom from decomposing the task and applying specialized agents to each aspect of the problem. And when a new model lands, it is generally good practice to re-examine a harness, stripping away pieces that are no longer load-bearing to performance and adding new pieces to achieve greater capability that may not have been possible before.
From this work, my conviction is that the space of interesting harness combinations doesn't shrink as models improve. Instead, it moves, and the interesting work for AI engineers is to keep finding the next novel combination.
这个判断非常适合和 OpenAI 那篇 Harness Engineering 文章形成呼应。OpenAI 更强调代码仓库、文档、质量标准、执行计划、决策日志等组织级环境设计;Anthropic 这两篇则展示了任务级 harness 如何从状态管理、上下文交接,演化到多 agent 反馈、QA、复杂度删减。两边共同指向同一个结论:未来 AI Engineer 的核心工作,不只是调用模型,而是设计模型能够稳定工作的环境。
第三章小结:第二篇文章真正完成了什么?
读完第二篇,我们可以把它总结为一句话:
当 agent 已经可以长时间持续工作后,Harness Engineering 的核心问题从“如何不断线”转向“如何持续做得更好”,因此需要外部评价、角色分工、质量标准、反馈循环,以及对 harness 复杂度的持续审计。
第二篇相比第一篇,至少推进了五个层次。
第一,从状态系统走向反馈系统。
第一篇的 feature list、progress file、git history 主要解决状态继承。第二篇的 evaluator、criteria、sprint contract 主要解决质量反馈。
第二,从单 agent 自测走向独立 QA。
第一篇要求 coding agent 自己测试。第二篇则发现自评不可靠,因此拆出 evaluator。
第三,从“有没有完成”走向“完成得好不好”。
第一篇用 feature list 防止过早宣布完成。第二篇用 grading criteria 和 evaluator 防止低质量完成。
第四,从固定流程走向动态审计。
第二篇后半强调,harness 组件不是越多越好。每个组件都代表对模型缺陷的假设,而这些假设必须随着模型变化重新检验。
第五,从补偿模型短板走向放大模型能力。
当模型变强,某些脚手架会被移除;但新的 harness 组合又会把模型推向更复杂的任务空间。
如果把第一篇和第二篇放在一起看,它们的递进关系就很清楚:
第一篇:让 agent 能跨 session 持续推进。
第二篇:让持续推进的 agent 接受外部评价,并持续提高质量。
第一篇:解决 memory / continuity。
第二篇:解决 judgment / quality。
第一篇:建立 artifact-driven workflow。
第二篇:建立 feedback-driven workflow。
第一篇:增加必要脚手架。
第二篇:审计并删减不再承重的脚手架。
这就是 Anthropic 两篇 Harness Engineering 文章最重要的整体价值。
Acknowledgements
Special thanks to Mike Krieger, Michael Agaby, Justin Young, Jeremy Hadfield, David Hershey, Julius Tarng, Xiaoyi Zhang, Barry Zhang, Orowa Sidker, Michael Tingley, Ibrahim Madha, Martina Long, and Canyon Robbins for their contributions to this work.
Thanks also to Jake Eaton, Alyssa Leonard, and Stef Sequeira for their help shaping the post.
第四章:Anthropic两篇文章的递进关系
读完 Anthropic 这两篇文章之后,我最大的感受是:它们不是两篇并列文章,而是一组连续实验的前后两个阶段。
第一篇《Effective harnesses for long-running agents》发表于 2025 年 11 月 26 日,开篇就把问题定位为:Agent 在多个 context window 之间持续工作仍然困难,每个新 session 天然没有此前 session 的记忆,因此需要一种方式桥接 coding session 之间的断裂。文章提出的方案是 initializer agent 与 coding agent,并通过 feature_list.json、claude-progress.txt、git history、init.sh 等工件帮助 agent 跨 session 持续推进。
第二篇《Harness design for long-running application development》发表于 2026 年 3 月 24 日,它在开头明确承接了前一篇 long-running harness 的经验:把构建过程拆成较小任务,并使用结构化工件在不同 session 之间传递上下文;在此基础上,第二篇进一步提出 planner、generator、evaluator 三智能体结构,用于更复杂的长时间应用开发。
所以,两篇文章的关系可以概括为:
第一篇解决 Agent 如何持续工作;第二篇解决持续工作的 Agent 如何持续提高质量。
或者更简洁地说:
第一篇:continuity
第二篇:quality
第一篇关注的是工作能否不断线。
第二篇关注的是不断线之后,工作质量是否可靠。
这就是两篇文章最重要的递进关系。
4.1 从单次生成到长程执行
很多人最初使用 coding agent 时,默认交互模式仍然是“单次生成”:
给一个 prompt
→ 模型生成代码
→ 人类检查结果
→ 人类继续补充要求
这适合小任务,例如写一个函数、改一个组件、生成一段脚本。但 Anthropic 第一篇文章讨论的不是这种小任务,而是需要数小时甚至数天的复杂任务。文章明确指出,随着 AI agents 能力增强,开发者开始让它们承担跨越多个小时甚至多天的复杂工作,但 Agent 要在多个 context window 之间保持一致进展仍然是开放问题。
这意味着问题已经从“模型会不会写代码”变成了“模型能不能长期执行”。
这是一个非常关键的转变。
单次生成关注的是:
这一次输出是否正确?
长程执行关注的是:
连续十几次、几十次输出之后,系统是否仍然朝正确方向推进?
这两个问题完全不同。
在单次生成里,失败通常是局部的。
比如某个函数写错了,某段代码不能运行,某个组件样式不符合预期。
在长程执行里,失败是系统性的。
比如 agent 忘记前一轮做了什么,重复实现已经完成的功能,留下半实现代码,误以为项目已经完成,或者在错误状态上继续开发。
第一篇文章中提到的两个失败模式正是这种系统性失败:Claude 会试图一次性 one-shot 整个应用,导致上下文耗尽后留下半完成、无记录的代码;或者在项目后期看到已有进展后,过早宣布任务完成。
这说明,当任务从单次生成进入长程执行时,单纯提高 prompt 质量是不够的。
你不能只说:
请一步一步完成。
你必须设计一种机制,让“每一步”真的可以被保存、继承、验证和继续。
这就是第一篇文章中 initializer agent 与 coding agent 的意义。
Initializer agent 不是为了直接完成应用,而是为了建立长程执行的初始条件。Coding agent 也不是每次重新理解整个项目,而是在已有工件基础上增量推进。
因此,两篇文章递进的第一层是:
Harness Engineering 先把 Agent 从“一次性生成器”变成“长程执行者”。
没有这个转变,后面的 evaluator、planner、sprint contract 都没有意义。因为如果 agent 连持续工作都做不到,那么谈质量控制还为时过早。
4.2 从上下文窗口到外部工件
第一篇文章真正抓住的问题,是 context window 不是长期记忆。
Anthropic 明确说,long-running agents 的核心挑战在于它们必须工作在离散 session 中,而每个新 session 开始时没有前面发生过什么的记忆;这就像一个软件项目由轮班工程师负责,但每个新工程师都不知道上一班发生了什么。
这个比喻非常准确。
人类工程师之所以能协作,不是因为每个人都记得所有细节,而是因为团队有外部记录系统:
issue
PR
commit history
design doc
test report
runbook
project board
release note
Agent 也一样。
如果所有状态都只存在于聊天上下文里,那么上下文一重置,状态就消失了。即使使用 compaction,也只是把聊天历史压缩后继续传递,并不等于建立了一个可靠的项目状态系统。Anthropic 第一篇文章也明确指出,compaction 并不充分,因为它不总能把清晰指令传给下一个 agent。
因此,第一篇的关键动作是把状态外部化。
它使用:
feature_list.json
claude-progress.txt
init.sh
git history
basic E2E test
这些东西不是普通辅助文件,而是 long-running agent 的外部记忆系统。
feature_list.json让 agent 知道完整功能范围。claude-progress.txt让 agent 知道此前做了什么。init.sh让 agent 知道如何启动项目。
git history 让 agent 能追踪和回滚代码状态。
basic E2E test 让 agent 在继续开发前确认项目没有坏掉。
这正是 Harness Engineering 和 Prompt Engineering 的分水岭。
Prompt Engineering 把信息塞进模型输入。
Harness Engineering 把信息沉淀到模型可读取、可更新、可验证的环境里。
这一点也和 OpenAI 那篇 Harness Engineering 文章高度一致。OpenAI 强调,代码仓库是 agent 可以依赖的记录系统;不能在运行时访问的信息,比如人脑中的隐性知识、聊天记录或外部文档,对 agent 来说就等于不可用,因此应该用结构化文档、执行计划、质量标准和本地可读文件来组织上下文。
所以,两篇文章递进的第二层是:
Harness Engineering 把 Agent 的工作基础,从上下文窗口迁移到外部工件系统。
这也是第一篇能够支撑第二篇的原因。
第二篇中的 planner、generator、evaluator 之所以能协作,不是因为它们共享同一个巨大的上下文窗口,而是因为它们围绕 product spec、sprint contract、evaluation report、QA feedback 等结构化工件协作。
换句话说,多智能体协作的前提,不是“让多个 agent 聊天”,而是“让多个 agent 共同操作一组稳定工件”。
4.3 从单 Agent 到多角色协作
第一篇的系统表面上也有两个 agent:initializer agent 和 coding agent。但它们之间更像是时间顺序上的分工。
Initializer agent 在第一次 session 中建立环境。
Coding agent 在后续 session 中增量推进。
两者主要解决的是长任务开始与持续执行的问题。
第二篇的 planner、generator、evaluator 则是更明确的角色分工。
Planner 负责把短 prompt 扩展成产品规格。
Generator 负责实现应用。
Evaluator 负责像真实用户和 QA 一样测试并给出反馈。
这就从“流程分工”进入了“职能分工”。
第一篇中,coding agent 仍然承担很多职责:
理解当前状态
选择下一个 feature
实现代码
测试功能
更新 passes 字段
写 progress
提交 git commit
这已经比单次生成强很多,但它仍然有一个问题:开发者、测试者、记录者、评审者基本还是同一个 agent。
第二篇认为这不够。
原因是 self-evaluation 不可靠。文章明确指出,agent 在评价自己生成的工作时往往会自信地表扬自己,即使人类看来质量并不高;而设计任务尤其明显,因为它不像代码测试那样具有二元判定标准。
于是,第二篇引入 evaluator,把评价从 generator 内部分离出来。
这一步非常重要。因为它不只是“多开一个 agent”,而是改变了系统结构。
原来的结构是:
Agent 生成
→ Agent 自测
→ Agent 宣布完成
新的结构是:
Planner 定义方向
→ Generator 生成
→ Evaluator 检查
→ Generator 修正
→ Evaluator 再检查
这个结构更接近人类软件团队。
在人类团队里,产品经理、开发者、QA、设计评审、代码评审通常不是完全同一个角色。不是因为开发者不能自测,而是因为创造和批判很难由同一个主体稳定完成。
Agent 也是一样。
所以,两篇文章递进的第三层是:
Harness Engineering 把 Agent 从“一个万能执行者”推进为“多角色协作系统”。
这也是第二篇比第一篇更高级的地方。
第一篇让 agent 能持续做事。
第二篇让不同 agent 分别承担定义、生成、评价和反馈职责。
4.4 从自我验证到外部评估
第一篇其实已经非常重视测试。Anthropic 观察到,Claude 常常会在没有充分测试的情况下把功能标记为完成;即使它修改了代码,甚至跑了单元测试或用 curl 请求开发服务器,也可能没有意识到端到端功能并不工作。文章进一步指出,在 web app 场景中,一旦明确要求 Claude 使用 browser automation tools,像真实用户一样进行端到端测试,表现会明显改善。
这已经是很重要的一步。
但第一篇的测试主要还是 coding agent 自己做。它的逻辑是:
你实现了功能
→ 你自己用浏览器自动化验证
→ 你确认通过后更新 feature list
第二篇认为这仍然不够。
因为模型可以执行测试,但它仍然可能对自己的工作宽容。特别是当问题不是简单 bug,而是产品深度、视觉质量、交互完整性、代码架构、stub 实现等更复杂问题时,自我验证很容易失败。
于是第二篇把测试和评估外部化,交给 evaluator。
Evaluator 不只是看代码,而是使用 Playwright MCP 操作运行中的应用,测试 UI、API endpoint 和数据库状态,并根据 product depth、functionality、visual design、code quality 等维度评分。
这一步代表从 verification 到 evaluation 的升级。
Verification 主要回答:
这个功能有没有按预期工作?
Evaluation 进一步回答:
这个产品是否足够完整?
这个交互是否自然?
这个设计是否有质量?
代码是否真的实现,而不是 stub?
应用是否只是 demo,还是有真实工作流?
第一篇的 feature list 更偏 verification。
第二篇的 evaluator 更偏 evaluation。
这是很重要的区分。
Verification 可以相对机械。
Evaluation 需要判断力。
也正因为 evaluation 需要判断力,所以第二篇特别强调 evaluator 本身也需要调教。作者指出,Claude 默认并不是一个好的 QA agent;早期 evaluator 会发现问题,但又说服自己这些问题不严重,还会测试得太浅。因此作者需要阅读 evaluator logs,找出 evaluator 判断与自己判断不一致的地方,再更新 QA prompt。
这说明外部评估不是银弹。
但它仍然比自我评价更可靠,因为它给 generator 制造了一个外部反馈面。
所以,两篇文章递进的第四层是:
Harness Engineering 从“让 agent 自己验证自己”,推进到“让独立 evaluator 对 agent 的工作进行外部评估”。
这一步把 agent workflow 从“自我闭环”变成了“带批判面的反馈闭环”。
4.5 从“完成清单”到“质量标准”
第一篇中最重要的工件是 feature list。Anthropic 让 initializer agent 根据用户高层 prompt 生成完整功能需求文件,在 claude.ai clone 示例中包含超过 200 个 feature,并且所有 feature 初始都标记为 failing。后续 coding agent 只能在充分测试后修改 passes 状态,不应该删除或改写测试项。
feature list 解决的是“有没有完成”的问题。
它防止 agent 看到页面已经有一些功能后,就主观判断项目完成。它迫使 agent 面对一个外部范围清单:
还有哪些功能没有通过?
哪些路径还没有验证?
哪些用户行为还没有实现?
第二篇在这个基础上更进一步,提出 grading criteria。
在 frontend design 部分,Anthropic 把设计评价拆成 design quality、originality、craft、functionality 四个维度,并且更强调 design quality 和 originality,因为 Claude 默认在 craft 和 functionality 上表现较好,但容易生成安全、普通、模板化的设计。
这说明第二篇处理的是“完成得好不好”的问题。
feature list 关注 completion。
grading criteria 关注 quality。
二者的区别可以这样理解:
feature list:
你是否实现了用户能新建聊天、输入问题、看到回复?
grading criteria:
这个聊天界面是否有清晰视觉层级?
是否有独特设计语言?
交互是否自然?
整体产品是否像一个完整应用?
这就是从“完成清单”到“质量标准”的跃迁。
第一篇把“任务范围”外部化。
第二篇把“质量判断”外部化。
而这两者都是 Harness Engineering 的核心动作:
把原本存在于人类脑中的隐性判断,变成 agent 可读取、可执行、可验证、可迭代的工件。
OpenAI 那篇文章中提到的 PRODUCT_SENSE.md、QUALITY_SCORE.md、架构文档、执行计划等,也是在做同一件事:把团队的产品判断、质量标准和工程约束写入代码仓库,使其成为 agent 可以访问的记录系统。
所以,两篇文章递进的第五层是:
第一篇把“完成”写下来;第二篇把“好”写下来。
这句话非常适合作为博客中的一个关键金句。
4.6 从任务拆解到验收合同
第一篇要求 coding agent 一次只处理一个 feature。Anthropic 认为这种 incremental approach 对解决 agent 一次做太多的问题非常关键;同时要求 agent 每次结束时留下 clean state,包括 git commit 和 progress update。
这是任务拆解。
第二篇则在任务拆解之上引入 sprint contract。每个 sprint 开始前,generator 和 evaluator 会先协商本轮要构建什么,以及如何验证成功;evaluator 会审查 generator 的计划,直到双方达成一致,然后 generator 才开始实现。
这就是验收合同。
任务拆解回答:
这次做哪一块?
验收合同回答:
这一块做到什么程度才算通过?
谁来判断?
怎么判断?
这个升级非常关键。
如果只有任务拆解,没有验收合同,generator 仍然可能以自己的理解实现一个“差不多”的版本。等 evaluator 最后发现偏题时,返工成本就很高。
Sprint contract 的价值在于把评价标准前置。
它不是等实现结束后再争论“这算不算完成”,而是在实现之前就明确:
本轮目标是什么?
必须覆盖哪些用户路径?
哪些行为算失败?
evaluator 会如何验证?
这和人类工程团队中的 acceptance criteria 非常相似。
所以,两篇文章递进的第六层是:
第一篇强调任务拆解;第二篇在任务拆解之上加入验收合同。
这也说明第二篇并没有放弃第一篇的 incremental progress 思想,而是把它变得更可审查、更可协作。
4.7 从增加脚手架到审计脚手架
如果只读第一篇,很容易得到一个结论:我们应该给 agent 增加更多 scaffolding。
例如:
feature list
progress file
git history
init script
browser automation
structured handoff
这些都非常有用。第一篇清楚展示了它们如何解决 long-running agent 的常见失败模式。
第二篇前半部分似乎也在继续增加复杂度:
planner
generator
evaluator
grading criteria
sprint contract
QA logs
multi-round feedback
但第二篇最成熟的地方在后半部分:它开始反向追问,这些复杂结构是否仍然必要。
Anthropic 明确提出,harness 中的每个组件都编码了一个关于“模型自己不能做什么”的假设;这些假设应该被压力测试,因为它们可能本来就是错的,也可能随着模型进步迅速过时。
这句话非常重要。
它说明 Harness Engineering 不是复杂度崇拜。
一个 harness 组件之所以存在,应该是因为当前模型确实在某方面不稳定。比如:
模型会忘记进度 → 需要 progress file
模型会提前宣布完成 → 需要 feature list
模型会自评过宽 → 需要 evaluator
模型会 under-scope → 需要 planner
模型会任务发散 → 需要 sprint contract
但如果模型能力提升,其中某些组件可能就不再承重。
第二篇中,Anthropic 就在 Opus 4.6 后移除了 sprint construct。原本 sprint decomposition 用于帮助模型把任务拆成 coherent chunks;但新模型能力增强后,作者认为它可能可以不依赖这种结构,直接完成更长、更复杂的 build。因此 updated harness 保留 planner 和 evaluator,但移除了 sprint decomposition,并把 evaluator 改成最后阶段的 QA。
这说明 harness 不是固定模板,而是动态系统。
第一篇主要告诉我们:
需要加哪些脚手架,才能让 agent 稳定长程工作?
第二篇进一步告诉我们:
哪些脚手架是真正承重的?
哪些脚手架在新模型下已经变成成本?
所以,两篇文章递进的第七层是:
第一篇学习如何增加必要脚手架;第二篇学习如何审计并删减不再必要的脚手架。
这是 Harness Engineering 从初级走向成熟的标志。
4.8 两篇文章合起来,是一条完整的Harness Engineering演进路径
现在可以把两篇文章合成一张Harness Engineering演进图:
阶段 0:Naive Prompting
用户给一个高层 prompt
Agent 一次性生成
问题:容易 one-shot、断片、误判完成、质量不稳定
阶段 1:Long-running Harness
Initializer agent 建立环境
Coding agent 增量推进
工件:feature_list.json、progress file、git history、init.sh
目标:解决 continuity
阶段 2:Artifact-driven Workflow
完成标准、进度、启动方式、测试路径都外部化
Agent 不再依赖聊天历史,而是依赖项目工件
目标:解决 handoff 和 state recovery
阶段 3:Feedback-driven Workflow
引入 generator / evaluator
把自评变成外部评估
目标:解决 self-evaluation 和 quality
阶段 4:Multi-agent Software Lifecycle
Planner 定义产品规格
Generator 实现
Evaluator QA
Sprint contract 定义局部验收
目标:解决 product depth、functionality、visual design、code quality
阶段 5:Harness Auditing
压力测试每个组件是否仍然必要
移除不再 load-bearing 的脚手架
目标:降低成本、延迟和复杂度
这条路径非常清楚地展示了 Anthropic 对 Harness Engineering 的理解变化。
最开始的问题是:
如何让 agent 不断线?
解决方式是外部状态系统。
然后问题变成:
不断线之后,如何不自嗨?
解决方式是 evaluator 和 feedback loop。
再然后问题变成:
feedback loop 很贵,哪些部分真的必要?
解决方式是审计和删减 harness 组件。
这就是一个成熟工程系统的演化逻辑。
它不是一次性设计出完美架构,而是在观察失败模式之后不断迭代:
发现失败模式
→ 加入控制结构
→ 观察效果
→ 发现新瓶颈
→ 拆分角色
→ 引入反馈
→ 评估成本
→ 删除不承重组件
这比“写一个好 prompt”复杂得多,也更接近真实软件工程。
4.9 为什么第一篇是第二篇的地基
现在回过头看,第二篇之所以能提出 planner / generator / evaluator,并不是凭空而来。它依赖第一篇已经解决的几个基础问题。
第一,第一篇建立了长程工作单位。
如果没有 session 之间的 handoff,第二篇的多小时应用开发就会频繁断片。每个 agent 都会迷失在上下文断裂里。
第二,第一篇建立了结构化工件。
如果没有 feature list、progress file、git history 这类外部状态,第二篇的 planner、generator、evaluator 就缺少共同协作对象。
第三,第一篇建立了增量推进思想。
如果 agent 仍然倾向于 one-shot 整个应用,第二篇中的 sprint contract 和 QA loop 也很难发挥作用。
第四,第一篇建立了端到端测试意识。
如果没有 browser automation 这类真实用户路径验证,第二篇 evaluator 就很难从静态代码审查升级为运行中应用测试。
第五,第一篇提出了 multi-agent 可能性。
第一篇的 Future work 中已经提到,未来可能需要 testing agent、quality assurance agent、code cleanup agent 等 specialized agents 来承担软件开发生命周期中的子任务。
第二篇正是沿着这个方向继续前进。
所以,第一篇不是第二篇的背景材料,而是第二篇的技术和概念地基。
第一篇让我们相信:
Agent 可以在外部工件帮助下跨 context window 长时间工作。
第二篇才有资格继续问:
既然它能长时间工作,如何让它长时间高质量工作?
4.10 为什么第二篇是第一篇的升级
反过来看,第二篇也不是第一篇的简单扩展,而是一次升级。
第一篇的核心系统仍然比较像:
Initializer
→ Coding Agent
→ Feature list / progress file / git
它主要处理的是状态、进度和基础测试。
第二篇升级为:
Planner
→ Generator
→ Evaluator
→ Feedback
→ Harness simplification
它处理的是产品规格、生成质量、外部评估、审美标准、QA 严格性和复杂度成本。
第二篇相对第一篇的升级主要体现在四点。
第一,评价主体独立化。
从 coding agent 自测,升级为 evaluator 外部评估。
第二,质量标准显性化。
从 feature list 的 pass/fail,升级为 design quality、originality、product depth、functionality、visual design、code quality 等多维标准。
第三,任务定义前置化。
从用户 prompt 直接扩展 feature list,升级为 planner 生成 product spec,再通过 sprint contract 转成局部验收标准。
第四,复杂度可审计化。
从添加 harness 组件,升级为检查每个组件是否仍然 load-bearing。
所以,第二篇真正完成的不是“加了更多 agent”,而是让 harness 从状态管理系统进化为质量控制系统。
第一篇的核心是:
How do we keep going?
第二篇的核心是:
How do we keep getting better?
这就是二者最本质的区别。
第四章小结:Anthropic 的 Harness Engineering 演进路线
综合来看,两篇 Anthropic 关于Harness Engineering的文章形成了一条非常清晰的演进路线:
从单次生成到长程执行;
从聊天上下文到外部工件;
从单 agent 自我推进到多角色协作;
从自我验证到外部评估;
从功能完成到质量判断;
从增加脚手架到审计脚手架。
这条路线说明,Harness Engineering 的核心不是 prompt 技巧,而是围绕 agent 建立一套工程化工作系统。
这套系统必须解决五类问题:
1. 状态问题:Agent 如何知道此前发生了什么?
2. 范围问题:Agent 如何知道完整目标是什么?
3. 执行问题:Agent 如何一步步推进,而不是一次做太多?
4. 评价问题:Agent 如何知道自己做得好不好?
5. 成本问题:哪些 harness 组件真的必要?
第一篇主要解决前 3 个问题。
第二篇主要解决第 4 和第 5 个问题。
这也是为什么两篇文章必须放在一起读。
只读第一篇,容易把 Harness Engineering 理解成“长任务状态管理”。
只读第二篇,容易把 Harness Engineering 理解成“多 agent 评估架构”。
两篇合起来,才能看到完整图景:
Harness Engineering 是通过外部工件、任务拆解、角色分工、工具反馈、质量标准和复杂度审计,让 Agent 在长程复杂任务中持续、可靠、可改进地工作的系统设计方法。
第五章:与 OpenAI Harness Engineering 的对照
在阅读 Anthropic 这两篇文章之前,我先读过 OpenAI 的《Harness engineering: leveraging Codex in an agent-first world》。那篇文章给人的第一印象,是 OpenAI 在真实软件工程组织中尝试把 Codex 作为主要生产力,让人类工程师从“亲自写代码”转向“设计 agent 能够稳定工作的环境”。OpenAI 在文章中明确提出,context management 是让 agent 在大型复杂任务中发挥作用的最大挑战之一,因此他们没有把 AGENTS.md 做成一本巨大的百科全书,而是把它当成目录;真正的知识库放在结构化 docs/ 目录中,并把这个目录作为 repository 的 system of record。
Anthropic 的两篇文章则从另一个方向切入。它们不是讲一个真实组织如何改造代码库和研发流程,而是讲一个 long-running agent harness 如何从最小可行结构开始,逐步演化为 planner / generator / evaluator 多智能体系统。第一篇聚焦 feature_list.json、claude-progress.txt、init.sh、git history 等工件如何帮助 agent 跨 context window 接力;第二篇则进一步引入 sprint contract、evaluator criteria、Playwright MCP QA 和 harness simplification。
如果用一句话概括两者差异:
OpenAI 讲的是“如何让一个代码库适合 agent 长期参与”;Anthropic 讲的是“如何让一个 agent 在长任务中持续推进并持续变好”。
一个偏组织与代码库层面。
一个偏任务与实验系统层面。
但它们的底层逻辑高度一致:
Agent 的可靠性不只来自模型能力,而来自模型周围的工程环境。
5.1 OpenAI 是组织级 harness,Anthropic 是任务级 harness
首先要区分两者的规模。
OpenAI 的 Harness Engineering 面向的是一个真实代码库和真实团队。它关心的问题是:如果一支工程团队越来越多地依赖 Codex agent 来写代码、开 PR、跑测试、调试问题、修复 bug,那么整个 repository 应该如何组织?文档如何维护?质量标准如何表达?上下文如何渐进式披露?agent 如何找到正确的事实来源?OpenAI 给出的方案是把 repository 的知识库放进结构化 docs/ 目录,将其作为 system of record;短小的 AGENTS.md 主要作为地图,指向更深层的事实来源。
Anthropic 第一篇的规模更小。它讨论的是一个 long-running coding task:比如让 Claude 构建一个复杂 web app。问题不是一个组织的长期知识管理,而是一个任务如何跨多个 session 不断线。于是,它使用 initializer agent 生成 feature list、progress notes、init script 和初始 git repo;后续 coding agent 每次读取这些文件,选择一个 feature,完成后更新进度和 git commit。
Anthropic 第二篇的规模介于两者之间。它不再只是一个单一 coding agent 接力,而是引入 planner、generator、evaluator 三个角色,模拟一个小型软件开发生命周期:planner 写 product spec,generator 实现,evaluator 做 QA 和评价,三者通过文件沟通。
所以可以这样理解:
OpenAI:组织级 / 代码库级 harness
Anthropic 第一篇:任务级 / session 级 harness
Anthropic 第二篇:任务级 harness 向“小型软件团队”演化
这三个层级其实是连续的。
任务级 harness 解决单个复杂任务如何稳定完成。
代码库级 harness 解决大量 agent 任务如何在同一工程环境中长期积累。
也就是说,OpenAI 更像是在讲 harness 的“生产形态”,Anthropic 更像是在讲 harness 的“实验演化过程”。
这也是为什么它们非常适合放在一起读:
OpenAI 告诉我们终局可能是什么样;Anthropic 告诉我们这个终局是如何一步步被构造出来的。
5.2 二者共同承认:上下文窗口不是可靠记忆
OpenAI 和 Anthropic 最重要的共同点,是它们都不再把模型上下文窗口当作可靠长期记忆。
OpenAI 明确说,context management 是让 agent 在大型复杂任务中有效工作的最大挑战之一;他们早期尝试过把所有东西塞进一个巨大的 AGENTS.md,但这种方式会快速腐烂、难以验证、难以维护,因此最终把 AGENTS.md 改成地图,而不是百科全书。真正的知识库被放进结构化 docs/ 目录,并作为 repository 的 system of record。
Anthropic 第一篇也从同一个问题出发:long-running agents 要在离散 session 中工作,而每个新 session 开始时没有前面发生过什么的记忆。Anthropic 用“轮班工程师”来类比这个问题:如果每个新工程师上班都不知道上一班做了什么,项目自然难以推进。它的解决方案是把状态写进 feature_list.json、claude-progress.txt、git history 和 init.sh。
两者使用的工件不同,但解决的是同一个问题:
OpenAI:
把组织知识外部化到 repo docs。
Anthropic:
把任务状态外部化到 feature list、progress file、git history。
这说明 Harness Engineering 的第一原则可以写成:
不要把上下文窗口当作记忆系统;要把记忆沉淀到 agent 可读取、可维护、可验证的外部工件中。
这也是“repo as system of record”和“feature list / progress file”的共同本质。
OpenAI 的 system of record 偏长期,面向整个代码库。
Anthropic 的 progress file 偏短期,面向一个长任务。
但它们都在做同一件事:把隐性上下文变成显性工件。
5.3 AGENTS.md 与 feature_list.json:一个是地图,一个是验收表
OpenAI 的 AGENTS.md 和 Anthropic 的 feature_list.json 很容易被混为一谈,因为它们都是给 agent 看的文件。但它们的职责其实不同。
OpenAI 强调,AGENTS.md 不应该是百科全书,而应该是目录或地图。它大约 100 行,被注入上下文,主要告诉 agent:项目中有哪些更深层的事实来源,应该去哪里找架构文档、产品规格、执行计划、技术债务记录、生成的 schema 等。
也就是说,AGENTS.md 的作用是导航。
它回答:
这个代码库的知识在哪里?
我遇到问题应该读哪份文档?
哪些目录代表什么?
哪些约束必须遵守?
Anthropic 的 feature_list.json 则不是地图,而是验收表。它由 initializer agent 根据用户 prompt 扩展而来,包含完整的端到端 feature 描述,所有 feature 初始都是 failing;coding agent 每轮读取它,选择一个 feature 实现,并只有在仔细测试后才能把 passes 改成 true。Anthropic 还强调,coding agent 不应该删除或改写测试项,以免掩盖 bug 或丢失需求。
feature_list.json 回答的是:
这个任务到底包括哪些功能?
哪些功能已经通过?
哪些功能还没完成?
某个功能应该如何端到端验证?
所以二者的差异可以这样概括:
AGENTS.md:帮 agent 找到知识。
feature_list.json:帮 agent 判断任务是否完成。
一个是导航结构,一个是完成标准。
但它们都体现了同一种 Harness Engineering 思维:不要让 agent 靠猜。
不要让 agent 猜代码库知识在哪里,也不要让 agent 猜一个任务到底做完没有。
把这些内容写成工件,让 agent 读它、遵守它、更新它。
5.4 OpenAI 的 docs/ 与 Anthropic 的 handoff artifacts:都是渐进式披露
OpenAI 在文章中反对“一本巨大说明书”式的上下文管理。他们选择让 AGENTS.md 作为入口,而把真正的知识组织到结构化 docs/ 目录里,包括 design docs、exec plans、product specs、references、generated schema 等。这样 agent 不必一开始读完所有知识,而是通过地图逐步找到当前任务所需的信息。
这其实是一个很重要的思想:渐进式披露。
复杂系统中的知识不应该一次性塞进模型上下文。
它应该被组织成可导航结构,让 agent 在需要时读取。
Anthropic 第一篇中的 handoff artifacts 也有类似作用。Coding agent 每次开始 session 时,不需要重读全部聊天历史,而是按固定流程读取 progress notes、feature list、git log 和 init script。Anthropic 的示例中,agent 会先确认目录、读取 claude-progress.txt、读取 feature_list.json、查看最近 git log,再根据 init.sh 启动开发服务器。
这也是渐进式披露:
先读当前进度。
再读功能清单。
再看最近代码历史。
再运行启动脚本。
再做基础 E2E 测试。
OpenAI 的渐进式披露发生在代码库知识层面。
Anthropic 的渐进式披露发生在任务状态层面。
两者都避免了一个常见错误:把所有东西一次性塞进 prompt。
这正是 Harness Engineering 与传统 Prompt Engineering 的区别。
Prompt Engineering 容易把问题理解成“怎么把更多信息写进 prompt”。
Harness Engineering 则会问:“哪些信息应该放进上下文?哪些应该放进文件?哪些应该按需读取?哪些应该由测试或工具反馈提供?”
这是一种完全不同的信息架构思维。
5.5 OpenAI 的执行计划与 Anthropic 的 sprint contract
OpenAI 的文章中提到结构化 docs/ 目录,其中包含 exec-plans/,用于记录 active、completed 和 tech-debt 等执行计划。OpenAI 的整体思想是让 agent 的工作建立在结构化、版本化、可维护的计划和文档之上,而不是依赖临时对话或人脑记忆。
Anthropic 第二篇中的 sprint contract,也可以放在这个框架中理解。
Sprint contract 是 generator 和 evaluator 在每个 sprint 开始前协商出来的局部验收合同:generator 提出本轮要构建什么、如何验证成功;evaluator 审查计划,确保它没有偏离 spec;双方迭代直到达成一致,然后 generator 才开始写代码。Anthropic 明确说,这个机制存在是因为 product spec 被故意保持在较高层级,需要一个步骤把 user story 和可测试实现连接起来。
这和 OpenAI 的 exec plans 有相似之处:它们都让 agent 的工作从“即时生成”变成“先计划、再执行、再验证”。
区别在于:
OpenAI exec plans:
更像代码库中的长期执行记录,服务于多人/多 agent 协作和项目演进。
Anthropic sprint contract:
更像单个 sprint 的局部验收协议,服务于 generator 与 evaluator 的协作。
但底层功能一致:
把“我要做什么”和“怎么判断完成”提前写下来。
这是 agentic software engineering 中极其重要的转变。
人类开发中,很多计划可以存在于脑中、会议中或 Slack 对话中。但 agent 无法稳定访问这些隐性信息。只要这些计划没有写进可读工件,它们对 agent 来说就不存在。
所以,无论是 OpenAI 的 exec plans,还是 Anthropic 的 sprint contract,本质上都在做一件事:
把临时意图变成可追踪的执行工件。
5.6 OpenAI 的质量文档与 Anthropic 的 evaluator criteria
OpenAI 的文章提到,代码库中不仅需要架构文档和执行计划,也需要类似产品规格、质量文档、技术债务记录等内容;文章示例目录中包含 product specs、exec plans、generated schema 和 tech-debt tracker 等结构。
Anthropic 第二篇则在任务级别上展示了质量标准如何被写进 harness。前端设计部分,作者把评价拆成 design quality、originality、craft、functionality;全栈应用部分,evaluator 按 product depth、functionality、visual design、code quality 等标准评分。Anthropic 还强调,criteria 的措辞会影响 generator 的输出风格,例如强调 originality 和 design quality,会推动模型摆脱模板化的 “AI slop”。
这说明质量标准不是附属文档,而是 harness 的核心组件。
OpenAI 的质量文档偏组织级:
这个代码库的好代码是什么样?
这个产品的质量标准是什么?
这个团队如何判断架构决策是否合理?
哪些技术债务必须被记录?
Anthropic 的 evaluator criteria 偏任务级:
这个设计是否有原创性?
这个 sprint 是否实现了真实功能?
这个应用是否有产品深度?
这个代码是否只是 stub?
但它们的共同作用是:
把“好”的判断标准外部化。
这点非常重要。
Agent 不只是需要知道“做什么”,还需要知道“怎样算做好”。
在传统软件团队里,“好”的标准通常通过 code review、团队文化、资深工程师判断、设计评审和产品讨论传递。但 agent 不能稳定吸收这些隐性文化。它需要显性的 criteria、examples、quality docs、tests、linters 和 reviewer feedback。
因此,OpenAI 和 Anthropic 都在说明同一个趋势:
未来的软件工程知识,不只是给人读,也要给 agent 读。
这会改变我们写文档的方式。文档不再只是补充说明,而是 agent 运行时的控制面。
5.7 OpenAI 的代码库可读性与 Anthropic 的应用可测试性
OpenAI 的 Harness Engineering 强调让 repository 成为 agent 可导航、可理解、可验证的工作环境。这不仅包括文档,也包括 CI、linters、generated schema、架构约束、执行计划等机制。OpenAI 的目标是让 Codex 能在真实代码库中找到事实、理解约束、提交变更,并通过自动化反馈进行迭代。
Anthropic 则更强调让应用在运行时对 agent 可测试。第一篇要求 coding agent 使用 browser automation tools 做端到端验证,避免只看代码或运行浅层测试就标记完成。第二篇进一步让 evaluator 使用 Playwright MCP 操作 UI、测试 API endpoint 和数据库状态,像真实用户和 QA 一样验证应用。
这两个方向可以合并成一个更大的原则:
软件不仅要对人类工程师可读,也要对 agent 可读、可运行、可观察、可验证。
OpenAI 更偏 repository legibility。
Anthropic 更偏 runtime testability。
Repository legibility 解决的是:
Agent 能否理解代码库?
Agent 能否找到事实来源?
Agent 能否知道架构约束?
Agent 能否根据文档推进任务?
Runtime testability 解决的是:
Agent 能否运行应用?
Agent 能否像用户一样点击?
Agent 能否观察真实行为?
Agent 能否发现 UI、API、数据库之间的断裂?
两者缺一不可。
如果代码库可读但应用不可测试,agent 容易生成看似合理但实际不可用的代码。
如果应用可测试但代码库不可读,agent 容易陷入局部修补,缺少架构理解。
所以真正成熟的 harness,应该同时具备:
可读的代码库
可导航的文档
可运行的本地环境
可观察的日志和状态
可执行的测试
可验证的质量标准
可回滚的版本历史
这也是 OpenAI 和 Anthropic 共同指向的工程方向。
5.8 OpenAI 更强调“人类注意力”,Anthropic 更强调“模型失败模式”
OpenAI 文章的一个重要背景是:当 agent 能生成大量代码后,真正稀缺的资源变成人类时间和注意力。OpenAI 的文章开头就把问题定义为如何最大化人类时间和注意力这一稀缺资源,而不是单纯最大化模型输出。
这决定了 OpenAI 的 Harness Engineering 更偏向组织效率:
如何让 agent 自主做更多?
如何让人类只在关键节点介入?
如何减少人类反复解释上下文?
如何让 repo 自动承载知识和约束?
如何通过 CI、文档和工具降低人工监督成本?
Anthropic 的文章则更像实验日志,它不断观察 agent 的具体失败模式:
Claude 会 one-shot 应用。
Claude 会过早宣布完成。
Claude 会不充分测试。
Claude 会自评过宽。
Claude 会生成模板化设计。
Claude 会 under-scope。
Evaluator 会测试过浅。
Sprint construct 可能变成不必要开销。
然后 Anthropic 为每个失败模式设计对应 harness 组件。
这两种视角非常互补。
OpenAI 问的是:
在真实团队中,如何让 agent-first engineering 可持续?
Anthropic 问的是:
面对一个具体 agent 失败模式,我们应该设计什么控制结构?
OpenAI 更像系统架构。
Anthropic 更像实验方法论。
如果把两者结合起来,就可以得到一套更完整的 Harness Engineering 思维:
从 Anthropic 学习:
如何识别 agent 的稳定失败模式,并设计对应的工件、角色和反馈循环。
从 OpenAI 学习:
如何把这些机制沉淀到真实代码库、团队流程和长期知识管理中。
这也是这篇博客把三篇文章放在一起讨论的价值。
5.9 OpenAI 与 Anthropic 的共同结论:工程师在设计环境
尽管切入点不同,OpenAI 和 Anthropic 最终指向同一个结论:工程师的角色正在从“直接写代码”转向“设计 agent 能够稳定工作的环境”。
OpenAI 的文章标题中就强调 agent-first world,文章内容也反复说明,团队需要设计 repository、文档、反馈循环、工具、CI 和上下文管理方式,让 Codex 能够有效工作。
Anthropic 两篇文章则通过更细粒度的实验告诉我们,这个环境可以如何被构造:
用 feature list 定义任务范围;
用 progress file 继承上下文;
用 init.sh 降低启动成本;
用 git history 保持可回滚状态;
用 browser automation 验证用户路径;
用 planner 扩展产品规格;
用 generator 实现;
用 evaluator 评价;
用 sprint contract 前置验收标准;
用 criteria 编码品味和质量;
用 harness auditing 删除不必要复杂度。
这些东西合起来,就是 agent 的工作环境。
所以 Harness Engineering 的真正对象不是模型。
模型当然重要,但 Harness Engineering 不直接训练模型,也不主要改模型权重。它改变的是模型周围的结构:
模型看到什么;
模型能调用什么;
模型如何知道当前状态;
模型如何判断完成;
模型如何接受反馈;
模型如何恢复错误;
模型如何被约束;
模型如何把工作交给下一轮。
这也是为什么“harness”这个词很贴切。它不是马本身,也不是驾驶员本身,而是一套把力量、方向、约束和负载连接起来的结构。
在 AI agent 场景中,模型是能力来源。
Harness 是把能力转化为可靠工作的系统。
5.10 对开发者的启示:不要只问模型能不能做,要问环境是否支持它做好
把 OpenAI 和 Anthropic 放在一起看,最直接的实践启示是:当 agent 表现不好时,不要只问“是不是模型不够强”,还要问“是不是环境没有给它足够好的工作条件”。
例如,当 agent 忘记之前做过什么时,不一定是模型太差,可能是没有 progress file、没有 git commit 规范、没有结构化 handoff。
当 agent 提前宣布完成时,不一定是模型懒,可能是没有 feature list 或验收标准。
当 agent 写出看似完整但不能用的 app 时,不一定是模型不会写代码,可能是没有 browser automation、没有真实用户路径测试、没有 evaluator。
当 agent 生成的界面平庸时,不一定是模型没有审美,可能是没有设计 criteria、没有好坏样例、没有外部 critique。
当 agent 在大型代码库中迷路时,不一定是模型上下文不够长,可能是 repo 没有 system of record,AGENTS.md 不是地图,docs 没有结构化,事实来源不清楚。
这就是 Harness Engineering 的核心思维转换:
旧问题:
如何写一个更好的 prompt?
新问题:
这个 agent 缺少哪种环境支持?
缺少记忆?
缺少地图?
缺少验收标准?
缺少运行反馈?
缺少评价者?
缺少可观察性?
缺少回滚机制?
还是 harness 反而过度复杂?
这也是为什么 OpenAI 和 Anthropic 的文章都不应该被读成“技巧清单”。它们真正提供的是一种新的工程问题分解方式。
第五章小结:OpenAI 与 Anthropic 是同一个范式的两个尺度
综合来看,OpenAI 和 Anthropic 的 Harness Engineering 有明显差异,但它们属于同一个范式。
差异在于:
OpenAI:
组织级、代码库级、生产工程视角。
重点是 repo as system of record、AGENTS.md 作为地图、结构化 docs、执行计划、质量文档、CI 和长期协作。
Anthropic 第一篇:
任务级、session 级、长程执行视角。
重点是 feature list、progress file、init.sh、git history、incremental progress、context handoff。
Anthropic 第二篇:
任务级、多 agent 质量控制视角。
重点是 planner、generator、evaluator、sprint contract、criteria、Playwright QA、harness simplification。
共同点在于:
1. 都不相信上下文窗口可以充当长期记忆。
2. 都强调外部工件是 agent 工作的真实基础。
3. 都把“完成标准”和“质量标准”写成可读结构。
4. 都让工具、测试、CI 或浏览器自动化成为反馈来源。
5. 都把工程师角色从直接写代码,转向设计 agent 的工作环境。
6. 都承认 harness 需要迭代,而不是一次写完。
因此,可以把三篇文章合成一个统一判断:
OpenAI 展示了 Harness Engineering 在真实代码库和工程组织中的生产形态;Anthropic 两篇文章展示了 Harness Engineering 在长程任务中的实验演化路径。前者告诉我们 agent-first engineering 的代码库应该长什么样,后者告诉我们这种环境为什么需要从状态管理、外部工件、角色分工、评估反馈和复杂度审计一步步构建。
换句话说:
OpenAI 是宏观形态,Anthropic 是微观机制。
OpenAI 是组织级 harness,Anthropic 是任务级 harness。
二者共同说明,AI 时代的软件工程不只是“让模型写代码”,而是“设计让模型可靠工作的系统”。
第六章:我对 Harness Engineering 的重新理解
读完 OpenAI 和 Anthropic 这三篇文章之后,我对 Harness Engineering 的理解发生了一个明显变化。
一开始,我会很自然地把 Harness Engineering 理解成一种“让 Agent 更好完成任务的工程技巧”。比如给它写更好的说明、给它准备文档、让它跑测试、设计多智能体流程。
但现在我更倾向于把它理解成:
Harness Engineering 是把人类工程师过去依靠经验、记忆、判断、审美和流程完成的隐性控制,转化为 Agent 可读取、可执行、可验证、可迭代的外部系统。
这个定义里有几个关键词:隐性控制、外部系统、可读取、可执行、可验证、可迭代。
人类工程师在真实开发中会做很多隐性判断。
例如:
这个功能看起来还没真正完成。
这个界面虽然能用,但产品感不够。
这个代码现在能跑,但以后不好维护。
这个需求描述太模糊,需要先拆成验收标准。
这个任务不能一次做完,应该分阶段提交。
这个项目现在状态不干净,不能继续叠功能。
这个测试虽然过了,但没有覆盖真实用户路径。
这个计划太细了,反而会误导实现。
这个流程太复杂了,已经超过它带来的收益。
这些判断对资深工程师来说很自然,但对 Agent 来说,如果没有被写进环境,它们就不存在。
Harness Engineering 的意义,就是把这些判断显性化。
它不是简单告诉模型“请认真一点”“请像资深工程师一样思考”“请确保质量高”。这些话当然可以写进 prompt,但它们太抽象、太软、太不可验证。
真正有效的 harness 会把这些要求变成结构:
不要提前宣布完成 → feature_list.json
不要忘记前一轮状态 → progress file + git history
不要不知道怎么启动项目 → init.sh
不要只看代码就说完成 → browser automation / E2E test
不要自评过宽 → independent evaluator
不要把模糊需求直接写成代码 → planner / product spec
不要写完才讨论验收标准 → sprint contract
不要生成模板化设计 → design criteria / originality scoring
不要无限加复杂度 → harness auditing / load-bearing check
这就是 Harness Engineering 真正有价值的地方:
它把抽象要求变成可操作的系统结构。
6.1 Harness 是人类工程经验的外化
第一篇 Anthropic 文章最打动我的地方,是它并没有提出某种特别神秘的 AI 方法。相反,它做的事情非常像人类软件工程中早已存在的协作机制:
写清楚任务列表;
记录当前进度;
每次做一小步;
做完提交 git;
留下 commit message;
启动项目前先跑基本测试;
接手工作前先读历史记录;
不要在坏状态上继续开发。
这些都是人类工程团队非常熟悉的实践。
Anthropic 只是把这些实践重新组织成 Agent 可以使用的形式。
这说明 Harness Engineering 不是凭空创造一套 AI 专属流程,而是把人类工程经验外化、结构化、机器可读化。
人类工程师有长期记忆。
Agent 没有可靠长期记忆,所以需要 progress file。
人类工程师知道项目不是看起来有界面就算完成。
Agent 容易误判完成,所以需要 feature list。
人类工程师知道大任务要拆成小步提交。
Agent 容易 one-shot,所以需要 incremental progress。
人类工程师知道自己写的东西需要别人 review。
Agent 自评容易宽松,所以需要 evaluator。
人类工程师知道产品质量不是只有功能,还包括体验、审美、完整性。
Agent 容易生成平均化结果,所以需要 criteria。
从这个角度看,Harness Engineering 很像是把一个隐形的工程团队,翻译成一套显性的文件、角色、工具和反馈循环。
它不是让 Agent “像人一样自己悟出来”,而是把人类工程师的工作方式拆开,变成 Agent 可以遵守的外部结构。
这也解释了为什么 OpenAI 那篇文章如此强调代码仓库、文档、执行计划和质量记录。对人类来说,这些东西是协作辅助;对 Agent 来说,它们是认知基础。
6.2 Harness 是对模型短板的工程补偿
第二个理解是:Harness 本质上是对模型短板的工程补偿。
每一个 harness 组件都不是凭空存在的。它背后都对应一个模型短板。
例如:
模型无法稳定继承长程上下文 → 需要 context handoff artifacts
模型容易一次性做太多 → 需要 one-feature-at-a-time
模型容易提前宣布完成 → 需要 feature list
模型容易不充分测试 → 需要 explicit E2E testing
模型容易自我评价过宽 → 需要 independent evaluator
模型容易 under-scope → 需要 planner
模型容易产出模板化设计 → 需要 originality / design quality criteria
模型可能被过度复杂流程拖慢 → 需要 harness simplification
这一点在第二篇文章后半部分表现得非常清楚。Anthropic 明确提出,每个 harness 组件都编码了一个关于“模型自己不能做什么”的假设;这些假设必须被重新检验,因为它们可能随着模型能力提升而过时。
这句话改变了我对 harness 的理解。
以前我可能会觉得,好的 harness 就是尽可能完整:
更多角色、更多检查、更多文档、更多反馈、更多流程。
但现在我觉得,好的 harness 不是“多”,而是“准”。
它应该精确补偿当前模型最稳定、最关键、最影响任务成功的短板。
如果模型已经能稳定完成某个步骤,那么继续保留相应脚手架,可能只是增加成本和延迟。
如果模型在某个环节仍然经常失败,那么缺少对应 harness,系统就会不可靠。
所以,Harness Engineering 不是堆流程,而是诊断模型能力边界。
你要先问:
当前模型在哪些地方会稳定失败?
这些失败是偶发 bug,还是系统性模式?
这些失败能不能通过 prompt 解决?
如果不能,是否需要文件、工具、角色、测试或反馈机制?
这个机制带来的收益是否超过成本?
这是一种非常工程化的思维。
它不是迷信模型,也不是不信任模型,而是把模型当成一个能力强但有稳定缺陷的组件,然后为它设计周边系统。
这和传统软件工程中的容错设计很像。
数据库会失败,所以需要事务和备份。
网络会失败,所以需要重试和超时。
人会忘记,所以需要文档和 issue。
Agent 会断片、自嗨、误判完成,所以需要 harness。
6.3 Harness 是可进化系统,不是一次性模板
第三个理解是:Harness 不是一次性模板,而是可进化系统。
这点非常重要。
很多人看到 Anthropic 的第二篇文章,可能会想直接复制它的 planner / generator / evaluator 架构。看到第一篇文章,可能会想直接复制 feature_list.json、claude-progress.txt、init.sh。看到 OpenAI 的文章,可能会想直接建一个 AGENTS.md 和一堆 docs/。
这些当然有参考价值,但如果只是机械复制,很容易错过 Harness Engineering 的本质。
真正重要的不是某个固定结构,而是它背后的演化方法:
观察 Agent 失败模式
→ 设计一个外部控制结构
→ 运行
→ 观察 trace 和输出
→ 找到新的瓶颈
→ 调整 prompt、文件、工具或角色
→ 评估收益和成本
→ 保留承重结构,删除非承重结构
这是一种持续实验过程。
Anthropic 第二篇里,evaluator 不是一开始就很好。作者需要阅读 evaluator logs,找出 evaluator 为什么放过问题,然后修改 QA prompt。也就是说,evaluator 本身也是被调教出来的。
Sprint construct 也不是永远必要。它在某个模型版本上有价值,但到 Opus 4.6 后,作者开始移除它,因为新模型可能已经可以在没有 sprint decomposition 的情况下保持更长时间的 coherence。
这说明 harness 的设计与模型能力、任务复杂度、成本约束、工具能力高度相关。
一个适用于今天模型的 harness,明天可能过度复杂。
一个适用于 demo 应用的 harness,放到生产代码库可能不够。
一个适用于前端设计的 evaluator,未必适用于后端数据一致性。
一个适用于全栈 app 生成的 planner,未必适用于代码重构或 bug triage。
因此,Harness Engineering 不是“设计一次,永久使用”。
它更像是一套持续校准的工程系统。
这也意味着,一个好的 AI Engineer 不能只会写 prompt,还要会读 agent trace。
因为 harness 需要通过观察来改进。你要知道:
Agent 是在哪一步偏离的?
它是真的不知道,还是没有看到相关信息?
它是工具反馈不足,还是评价标准不清楚?
它是任务范围过大,还是计划过细导致错误级联?
它是 evaluator 太宽松,还是 generator 没有执行反馈?
只有能回答这些问题,才能真正迭代 harness。
6.4 最好的 Harness 不是最复杂的 Harness
第四个理解是:最好的 harness 不是最复杂的 harness,而是当前模型能力边界外的最小必要结构。
这句话可以拆成三层。
第一,harness 必须服务于模型能力边界。
如果任务在模型舒适区内,复杂 harness 可能只是浪费。比如让模型写一个简单脚本,可能不需要 planner、evaluator、sprint contract、progress file 和多轮 QA。一个直接 prompt 加一次测试就够了。
第二,harness 必须针对“边界外”问题。
当任务超出模型单次稳定完成能力时,harness 才开始发挥价值。例如:
任务太长 → 需要上下文交接;
范围太模糊 → 需要 planner;
完成标准太隐性 → 需要 feature list;
质量判断太主观 → 需要 evaluator criteria;
执行链路太复杂 → 需要 E2E 工具;
模型自评太乐观 → 需要独立 evaluator。
第三,harness 必须是最小必要结构。
也就是说,在解决问题的前提下,尽量不要引入多余复杂度。因为复杂度本身会成为新的失败源。
多一个 agent,就多一次上下文传递。
多一个工件,就多一个可能被误读或过时的状态。
多一个流程,就多一次同步成本。
多一个评价环节,就多一次延迟和 token 消耗。
多一个 contract,就多一层计划与实际之间的偏差风险。
所以,Harness Engineering 需要一种“复杂度节制”。
这也是第二篇最成熟的部分:它不满足于证明 full harness 比 solo run 更好,而是继续追问 full harness 的哪些部分可以移除。
这个思想对实际开发很重要。
如果我们在自己的项目里引入 agent,不应该一开始就搭一个非常庞大的 multi-agent 系统。更合理的方式可能是:
第一步:
先让 repo 对 agent 可读。
补一个简洁的 AGENTS.md。
整理关键 docs。
确保测试和启动脚本可靠。
第二步:
观察 agent 在任务中经常失败在哪里。
如果它忘记状态,加 progress file。
如果它误判完成,加 feature list。
如果它测试不足,加 E2E harness。
如果它自评过宽,加 reviewer/evaluator。
如果它 under-scope,加 planning step。
第三步:
定期审计这些结构是否仍然有用。
能删就删,能合并就合并,能自动化就自动化。
这比一上来设计一个复杂 multi-agent 流程更稳健。
6.5 Harness 的核心控制原语:文件、工具、角色、反馈、审计
综合三篇文章,我认为 Harness Engineering 至少包含五类核心控制原语。
第一类:文件
文件是 agent 的外部记忆和共享工作面。
包括:
AGENTS.md
docs/
feature_list.json
claude-progress.txt
init.sh
product spec
sprint contract
evaluation report
exec plan
quality score
architecture doc
文件的价值在于稳定、可读、可版本化、可被多个 agent 共享。
如果一个事实只存在于聊天上下文中,它很脆弱。
如果一个事实写进文件,它就变成可继承的项目状态。
第二类:工具
工具让 agent 接触真实环境,而不是只在文本中推理。
包括:
git
test runner
browser automation
Playwright / Puppeteer
CI
linter
database inspection
API calls
logs
screenshots
local dev server
工具的价值在于把“模型猜测”变成“环境反馈”。
没有工具时,agent 很容易写出看起来合理但实际不可用的代码。
有工具时,agent 至少可以观察真实运行结果。
第三类:角色
角色让不同认知职责分离。
包括:
initializer
coding agent
planner
generator
evaluator
QA agent
reviewer
cleanup agent
角色的价值在于避免一个 agent 同时承担创造、评价、规划、测试、记录所有职责。
特别是 generator / evaluator 分离,是第二篇文章最重要的升级之一。
第四类:反馈
反馈让 agent 不只是生成,而是迭代。
包括:
feature pass/fail
test result
browser interaction result
evaluator critique
scorecard
QA report
git diff
CI failure
human review
反馈的价值在于让 agent 的下一步行动基于外部信息,而不是基于自我感觉。
没有反馈,agent 容易自嗨。
有反馈,agent 才有可能修正。
第五类:审计
审计让 harness 不至于无限膨胀。
包括:
哪些组件真的提升质量?
哪些组件只是增加成本?
哪些组件已经因模型升级而过时?
哪些失败模式仍然存在?
哪些 prompt 或 criteria 需要更新?
哪些流程可以合并或删除?
审计的价值在于让 harness 保持轻量、有效、可维护。
这五类控制原语可以作为我后续理解 Harness Engineering 的基本框架:
文件解决记忆问题。
工具解决反馈问题。
角色解决职责问题。
反馈解决质量问题。
审计解决复杂度问题。
或者更简洁地说:
文件让 Agent 记得住,工具让 Agent 看得见,角色让 Agent 不自嗨,反馈让 Agent 能改进,审计让 Harness 不膨胀。
6.6 Harness Engineering 改变了“写文档”的意义
阅读这几篇文章后,我还有一个很强的感受:在 agent-first 的软件工程里,文档的意义会发生变化。
过去,很多文档主要是写给人看的。
它们可能不完整、不及时、不精确,但人类工程师可以通过会议、聊天、经验、上下文补全信息。
但 Agent 不具备这种组织内隐性经验。它看不到会议,也不知道团队习惯,更不会自动理解某个历史决策背后的原因。它只能基于可访问的上下文、文件、工具输出和测试结果工作。
所以,文档开始变成 agent 的运行时输入。
这会改变我们写文档的方式。
未来有价值的文档,可能不只是“解释系统”,还要能“约束 agent”:
这个目录的职责是什么?
这个模块不能违反哪些边界?
这个产品功能的验收标准是什么?
这个 UI 的质量标准是什么?
这个技术债务为什么存在?
这个测试失败时应该怎么排查?
这个任务执行到哪里了?
这个 agent 下一步应该先看什么?
这种文档不是静态知识库,而是 harness 的一部分。
OpenAI 的
AGENTS.md是地图。
Anthropic 的feature_list.json是验收表。claude-progress.txt是交接记录。sprint contract是局部协议。evaluator criteria是质量标准。exec plans是执行轨迹。
这些都不是传统意义上“写给人类以后查阅”的文档,而是 agent 当前工作流中的控制面。
这意味着,未来工程师写文档时,要多问一个问题:
这份文档是否能帮助 Agent 更好地行动?
如果不能,它可能只是说明书。
如果能,它就是 harness。
6.7 Harness Engineering 改变了“工程师能力”的定义
在传统软件工程中,工程师的核心能力很大程度上体现在:
理解需求;
设计架构;
写代码;
调试;
测试;
重构;
发布;
维护。
在 agent-first 的环境中,这些能力不会消失,但它们的表达方式会发生变化。
工程师不一定每一行代码都亲自写,但他要能设计一个环境,让 agent 写出的代码可控、可测、可审查、可迭代。
于是,工程师的能力会更多体现在:
能不能把模糊需求拆成 agent 可执行任务;
能不能把隐性质量标准写成 criteria;
能不能设计有效的 handoff artifact;
能不能判断哪些工具反馈是必要的;
能不能发现 agent 的稳定失败模式;
能不能调教 evaluator;
能不能读懂 agent trace;
能不能区分模型能力问题和 harness 设计问题;
能不能删掉不再必要的复杂流程。
这是一种新的工程能力。
它不是完全替代编码能力,而是建立在编码、架构、产品、测试和系统设计能力之上的更高层抽象。
因为如果你自己不懂软件工程,你就很难知道 agent 哪里做错了。
如果你没有产品判断,你就写不出好的 evaluator criteria。
如果你不懂测试,你就设计不出有效的 E2E harness。
如果你不懂架构,你就无法判断 agent 生成的代码是否只是短期可用。
如果你不懂成本权衡,你就会搭出复杂但低效的 multi-agent 系统。
所以,Harness Engineering 不是降低工程师要求,而是改变工程师发力点。
过去,工程师直接写系统。
现在,工程师还要写“让 Agent 写系统的系统”。
这句话有点绕,但很准确。
6.8 我目前对 Harness Engineering 的定义
经过前面的分析,我会给 Harness Engineering 一个更完整的定义:
Harness Engineering 是一种面向 AI Agent 的工程环境设计方法。它通过结构化工件、工具反馈、任务拆解、角色分工、质量标准、上下文交接和复杂度审计,把模型的生成能力嵌入到一个可持续、可验证、可迭代的软件生产流程中。
这个定义里,最重要的是“工程环境设计”。
Harness Engineering 不等于:
写更长 prompt;
套一个 multi-agent 框架;
加几个 reviewer;
让模型多反思几次;
把所有文档塞进上下文;
把人类流程机械搬给 AI。
它更接近:
识别当前模型在当前任务中的关键短板;
为这些短板设计最小必要外部结构;
让模型通过文件、工具和反馈与真实工程环境连接;
观察输出和 trace;
持续调整 harness;
在模型能力提升后删减不必要复杂度。
因此,Harness Engineering 的成熟度不取决于它看起来多复杂,而取决于它是否精准解决了当前任务中的真实失败模式。
一个好的 harness 应该让 agent:
知道目标;
知道当前状态;
知道下一步;
知道如何启动;
知道如何测试;
知道谁来评价;
知道哪里失败;
知道如何修正;
知道什么时候停止;
知道如何把工作交给下一轮。
如果一个系统能做到这些,它就已经不仅仅是 prompt,而是 harness。
第六章小结:从“让模型做事”到“设计模型工作的系统”
这一章可以总结为一句话:
Harness Engineering 的核心,不是让模型更努力,而是让模型处在一个更适合长期工作的工程系统里。
我的重新理解主要有六点:
第一,Harness 是人类工程经验的外化。
它把人类工程师隐性的记忆、判断、审美和流程,转化为 agent 可读取的工件和规则。
第二,Harness 是对模型短板的工程补偿。
每个组件都应该对应一个真实失败模式,而不是为了复杂而复杂。
第三,Harness 是可进化系统。
它需要通过观察 agent trace、运行结果和失败模式持续调整。
第四,最好的 Harness 是最小必要结构。
它既不能缺少关键控制,也不能无限堆叠流程。
第五,Harness 的核心原语包括文件、工具、角色、反馈和审计。
这五类原语分别解决记忆、观察、职责、质量和复杂度问题。
第六,Harness Engineering 改变了工程师的发力点。
工程师不仅写代码,也设计让 Agent 稳定写代码、测代码、评代码、改代码的环境。
如果说 Prompt Engineering 的问题是:
我该如何对模型说?
那么 Harness Engineering 的问题是:
我该如何设计一个系统,让模型在其中可靠地工作?
这个转变,是理解 agent-first software engineering 的关键。
结语:Harness Engineering 的真正对象是“人与 Agent 的协作边界”
读完 Anthropic 的两篇文章,再回看 OpenAI 那篇关于 Harness Engineering 的文章,我越来越觉得,Harness Engineering 不是一个小众技巧,也不是 Prompt Engineering 的高级版本。它更像是一种新的软件工程分层。
过去,我们习惯把软件工程理解为人围绕代码工作,而在 agent-first 的软件工程里,这个结构开始变化。模型开始承担越来越多的执行工作:写代码、修改文件、运行测试、生成界面、搭建应用、修复 bug、解释代码、补全文档。
但这并不意味着工程师消失了,相反,工程师的工作对象发生了变化。
工程师不只是直接生产代码,也开始设计一种新的生产环境:
Agent 应该看到什么?
Agent 应该读哪些文档?
Agent 如何知道当前进度?
Agent 如何知道任务是否完成?
Agent 如何测试自己的产物?
Agent 如何接受外部评价?
Agent 如何避免自我感觉良好?
Agent 如何跨 session 交接?
Agent 如何在错误状态中恢复?
Agent 如何在模型能力提升后减少不必要流程?
这些问题加起来,就是 Harness Engineering。
1. Anthropic 两篇文章的最终价值:展示了 Harness 的演进过程
Anthropic 的两篇文章最有价值的地方,不只是给出了具体方案,而是展示了一个 harness 如何演进。
第一篇从 long-running agent 的上下文断裂问题出发。它发现,模型能力再强,只要任务跨越多个 context window,就会遇到接力问题:新 session 不知道上一轮做了什么,agent 容易 one-shot,容易提前宣布完成,容易在没有充分测试的情况下标记功能通过。
于是,第一篇给出的核心方案是:
initializer agent
coding agent
feature_list.json
claude-progress.txt
init.sh
git history
incremental progress
browser automation testing
这些机制共同解决一个问题:
如何让 Agent 跨 session 持续工作?
第二篇则在此基础上继续向前。它承认第一篇的任务拆解和结构化交接工件是地基,但进一步追问:如果 Agent 已经能持续工作,它做出来的东西质量如何?它会不会只是持续地产出“看起来完成”的平庸结果?
于是,第二篇引入:
planner
generator
evaluator
grading criteria
sprint contract
Playwright QA
multi-round feedback
harness simplification
这些机制共同解决另一个问题:
如何让持续工作的 Agent 持续做得更好?
所以,两篇文章的递进关系可以压缩成一句话:
第一篇解决 continuity,第二篇解决 quality。
或者换一种说法:
第一篇让 Agent 不断线,第二篇让 Agent 不自嗨。
这个递进非常重要。因为它说明 Harness Engineering 的目标不是单纯延长模型工作时间,而是让长时间工作变得可控、可验证、可反馈、可改进。
2. OpenAI 与 Anthropic 的共同方向:让工程环境变成 Agent 可操作的系统
OpenAI 的文章和 Anthropic 的两篇文章,切入点不同。
OpenAI 更像是在讲真实代码库和工程组织如何适应 agent-first world。它关心的是 repository 如何成为 system of record,AGENTS.md 如何作为地图,docs/ 如何承载结构化知识,执行计划和质量文档如何帮助 Codex 在复杂代码库中工作。
Anthropic 更像是在讲一个任务级 harness 如何从实验中演化出来。它关心的是 long-running agent 如何跨 session 交接,如何通过 feature list 定义完成标准,如何通过 evaluator 定义质量标准,如何通过 sprint contract 前置验收,如何通过 harness auditing 删除不再必要的复杂度。
但两者底层方向一致:
把原本隐性的工程知识,变成 Agent 可读取、可执行、可验证的环境结构。
这些东西过去主要是给人类团队协作使用的。
现在,它们同时也成为 Agent 的认知基础和行动边界。
换句话说,软件工程中的很多“辅助设施”,正在变成 Agent 能否可靠工作的核心条件。
3. Harness Engineering 的真正对象不是模型,而是协作边界
如果说 Prompt Engineering 的对象是“模型输入”,那么 Harness Engineering 的对象就不是模型本身,而是模型与环境、模型与人、模型与任务之间的协作边界。
它关心的是边界如何被设计:
人类意图如何进入系统?
任务状态如何被保存?
模型如何读取事实?
模型如何行动?
工具如何反馈?
谁来评价结果?
错误如何被发现?
进度如何被继承?
质量如何被定义?
复杂度如何被控制?
这就是为什么我认为 Harness Engineering 的真正对象是:
人与 Agent 的协作边界。
这个边界如果设计得不好,Agent 会表现得像一个聪明但不可靠的实习生:能写很多代码,但容易忘记上下文,容易误解范围,容易提前宣布完成,容易自我评价过高,容易在没有验证的情况下继续前进。
这个边界如果设计得好,Agent 就更像一个处在成熟工程流程中的团队成员:知道去哪找资料,知道当前任务状态,知道怎样验证,知道什么时候交接,知道谁来 review,知道哪些标准不能违反。
这就是 Harness 的价值。
它不是让模型变成完美工程师,而是让模型进入一个更接近成熟工程团队的工作结构。
4. 未来软件工程师的新能力:设计 Agent 的工作系统
这几篇文章给我最大的启发,是未来软件工程师的能力结构会发生变化。
过去,工程师的核心能力是直接写系统。
未来,工程师还需要具备另一种能力:
设计让 Agent 写系统的系统。
这不意味着工程师不再需要懂代码。恰恰相反,Harness Engineering 对工程师提出了更综合的要求。
你需要懂软件工程,才能判断 Agent 的代码是否可靠。
你需要懂测试,才能设计有效的验证路径。
你需要懂产品,才能写出好的 quality criteria。
你需要懂架构,才能避免 Agent 生成短期可用但长期不可维护的代码。
你需要懂协作流程,才能设计 handoff artifact、progress file、exec plan。
你需要懂模型行为,才能发现它的稳定失败模式。
你还需要懂成本权衡,才能知道什么时候该加 evaluator,什么时候该删掉 sprint construct。
所以,AI Engineer 或未来的软件工程师,不只是“会用 AI 写代码的人”。
更准确地说,他应该是:
能够识别模型能力边界,并把这些边界转化为环境、工件、工具、反馈和流程设计的人。
这也是 Harness Engineering 和普通工具使用之间的区别。
普通工具使用关注:
这个模型能帮我做什么?
Harness Engineering 关注:
我要怎样设计一个系统,让模型持续、可靠、可验证地做成这件事?
5. 一个最终定义
如果要用一句话总结我现在对 Harness Engineering 的理解,我会这样定义:
Harness Engineering 是一种面向 AI Agent 的工程环境设计方法。它通过结构化工件、工具反馈、任务拆解、角色分工、质量标准、上下文交接和复杂度审计,把模型的生成能力嵌入到一个可持续、可验证、可迭代的软件生产流程中。
这个定义有三个重点。
第一,它是工程环境设计,不是单次 prompt 设计。
第二,它关注可持续、可验证、可迭代,而不是一次性生成。
第三,它把模型能力嵌入流程,而不是把全部责任交给模型。
所以,Harness Engineering 的成熟形态,应该不是一个庞大的 prompt,也不是一个固定的 multi-agent 模板,而是一套随着模型、任务和组织不断演化的工程系统。
6. 最后收束:从“让 Agent 做事”到“让 Agent 在系统中做事”
Anthropic 第一篇文章告诉我们:如果没有外部状态系统,长任务 Agent 会断片。
Anthropic 第二篇文章告诉我们:如果没有外部评价系统,长任务 Agent 会自嗨。
OpenAI 的文章告诉我们:如果没有适合 Agent 的代码库、文档和质量体系,agent-first engineering 很难在真实组织中长期成立。
这三篇文章合起来,给出的不是某个技巧,而是一个范式转变:
我们不再只是让 Agent 做事,而是让 Agent 在一个被精心设计的工程系统中做事。
这个工程系统需要记忆,也需要反馈;需要自由,也需要约束;需要任务拆解,也需要质量判断;需要多 agent 协作,也需要复杂度审计;需要利用模型能力,也需要诚实面对模型短板。
这正是 Harness Engineering 的意义。
它不是 AI 时代软件工程的边角料,而可能会成为 agent-first 软件工程的核心能力之一。
当模型越来越强,单次生成能力会继续提升。但只要我们希望 Agent 参与真实、复杂、长期的软件工程任务,问题就不会只是“模型能不能写代码”,而会变成:
我们能不能设计出一个足够好的工作系统,让模型写出的代码可靠地进入真实工程流程?
更多推荐


所有评论(0)