Harness 设计 可视化阅读
阅读原文
Engineering at Anthropic · 2026 年 3 月 24 日

面向长任务的应用 Harness 设计

目标不是做一个更炫的多 Agent 图,而是让 Claude 能在无人持续干预的情况下, 把一个真实应用从一句 Prompt 推进到可用项目。为此,Harness 必须先解决长程项目里会反复出现的跑偏、漏做和自评过宽。

作者:Prithvi Rajasekaran,Anthropic Labs 发布于 2026 年 3 月 24 日 约 12 分钟阅读
TL;DR · 核心想法

这篇文章的主线是:为了让 Agent 自动完成一个完整项目, 先用 Planner 把含糊 Prompt 扩成 feature list,再让 Generator 和挑剔的 Evaluator 围绕每个 feature 反复协商、实现、测试和修复。

Generator/Evaluator 的价值来自两个失败事实:长程任务会失去连贯性,模型又很容易宽容地通过自己的半成品。 外部 QA、硬阈值和可测试契约,才把“看起来完成”推向“真的能用”。

3
Agent 角色:Planner / Generator / Evaluator
4
评分维度:设计感 · 原创性 · 工艺 · 可用性
~20×
同 Prompt 下,Harness 跑相对单 Agent 的成本
27
仅关卡编辑器一个 Sprint 契约里的测试条目数
阅读方式建议:按顺序读:设计目的 → 错误形式 → 解决方案 → 证据。 这篇文章真正的主线不是“多 Agent 越多越好”,而是:每个 Harness 组件都应该对应一个当前模型确实补不上的能力缺口。
01 · 设计目的

目标是自动完成一个项目,而不是单次生成一个页面

原文讨论的 Harness,不是为了让输出看起来更复杂,而是为了让模型从一句模糊需求出发, 在几个小时的无人干预中持续推进,最后交付一个功能真的可用的完整应用。

这篇文章的起点是一个产品工程问题:用户只给 1-4 句话, Claude 要自己补全产品规格、拆出 feature、实现应用、发现问题、再修到可用。 如果只把它理解成“Generator 和 Evaluator 互相发消息”,就会丢掉最重要的设计目的。

所以叙事应该先问:一个长程项目为什么不能靠单 Agent 一路写到底? 然后再看 Harness 里的每个部件分别补哪个缺口。 Planner 补规格,Generator 补实现,Evaluator 补外部判断和真实使用验证

Target outcome
从一句 Prompt 到完整可用应用
Harness 的成功标准不是“产出很多代码”,而是让模型持续完成一个有产品边界、有交互链路、 有 QA 反馈的项目。原文里的 2D 复古游戏制作器,就是用来测试这一点。
What must be automated
1
补全规格:把短 Prompt 扩成明确的 feature list。
2
推进实现:每次围绕一个 feature 建立可测试目标。
3
外部验收:通过真实页面操作、API 和数据库检查发现偏差。
4
闭环修复:把 QA 反馈交回 Generator,直到当前 feature 过线。
02 · 朴素 Harness 为什么不够用

两类长期存在的失效模式

过去的长任务 Harness 已经在用「初始化 Agent + 编码 Agent + 结构化交接」, 但在复杂任务上,Agent 仍然会跑偏。把这件事拆开来看,能分成两个截然不同的问题。

这部分是理解全文的地基。作者并不是一开始就想做复杂的多 Agent 系统, 而是先从失败日志里拆出了两个反复出现的问题:长上下文下的连贯性下降,以及模型对自己产出的过度宽容。

第一个问题偏工程编排:什么时候该重置上下文,怎样交接状态。 第二个问题偏判断力:即使任务有测试,模型也可能因为自我评估太松而把半成品当成完成品。 后文的 Planner、Generator、Evaluator 都是在回应这些具体失败,而不是为了架构复杂而复杂。

失效模式 01
连贯性丢失 &「上下文焦虑」
随着上下文越填越满,模型在长任务上会逐渐失去连贯性。某些模型(Sonnet 4.5 尤为明显) 还会出现「上下文焦虑」:当它以为自己快撞到上下文上限时,会开始草草收尾。
→ 解法 上下文重置 —— 完全清空窗口、起一个全新 Agent,靠结构化交接传递状态。 这和压缩(compaction)不同:压缩是原地总结历史,保留连续性但不给 Agent 一张白纸, 焦虑因此仍然存在。Opus 4.5 大幅缓解了这个问题,新 Harness 已经可以不用重置。
失效模式 02
自信地胡夸 —— 自我评估失灵
让 Agent 评估自己产出时,它会信心满满地夸——即使质量在人眼里明显平庸。 这一点在主观任务(设计)上最明显,但在可验证任务上同样可见: 做事过程中糟糕的自我判断会拖累整体表现。
→ 解法 把「干活的」和「打分的」分开。这本身不会自动消除偏宽 —— Evaluator 仍然是个 LLM —— 但把单独的 Evaluator 调教得挑剔,比让 Generator 自我批判要可控得多。
03 · 解决方案

Planner 先确定 feature list,再让 Generator 和 Evaluator 围绕 feature 迭代

真正的结构不是两个 Agent 空转互评,而是先把项目边界固定下来: Planner 把需求扩成 feature list;随后每个 feature 都经历“契约 → 实现 → QA → 修复”的闭环。

这套 Harness 的关键,是把“完成一个应用”拆成两个层级。 第一层是全局规划:Planner 不写实现细节,而是把一句话需求变成有野心但仍然高层的产品规格和 feature list。 第二层是局部闭环:Generator 每次只拿一个 feature,先和 Evaluator 谈清楚怎样算完成,再开始写代码。

Evaluator 的职责也不是“事后写几句评价”,而是像用户一样打开真实应用, 点击 UI、调用 API、检查数据库状态,并用硬阈值决定当前 feature 是否通过。 不通过时,反馈回到 Generator,下一轮围绕同一个 feature 修复。

Correct mental model
Planner
把 1-4 句 Prompt 扩成产品规格,不提前钉死实现细节。
Feature 01Project dashboard
Feature 02Sprite editor
Feature 03Level editor
...16 features / 10 sprints

围绕当前 feature 闭环

repeat until pass

Generator

提出 sprint contract,说明要做什么、怎样验证,然后实现当前 feature。

Evaluator

先审核 contract,再用 Playwright MCP 操作真实应用;未达标就返回具体 Bug。

当前 feature 通过后才进入下一个 feature;这就是为什么它能把长程项目约束在 feature list 上,而不是让 Generator 漫无目的地自我迭代。
04 · 角色与契约

三个 Agent 各自补一个缺口,Sprint 契约把 feature 变成可验收行为

上一节是总图;这一节拆开看每个角色为什么存在,以及 contract 为什么要发生在写代码之前。

这套设计的关键不是把任务平均分给三个 Agent,而是让每个 Agent 避开不适合自己的判断。 Planner 不决定底层实现;Generator 不独自裁决质量;Evaluator 不写主要代码,而是把“是否真的可用”拉回到外部证据上。

这里最值得注意的是 Sprint 契约。 产品规格刻意保持高层,避免过早钉死实现细节;但真正写代码之前, Generator 和 Evaluator 要先把“这一步怎样算完成”谈清楚。 这一步把抽象需求翻译成了可测试行为。

P
Planner
1–4 句 Prompt → 完整产品规格
把用户那一两句话 Prompt 扩成一份有野心的完整产品规格。 只停留在产品语境和高层设计,不下沉到细节实现 —— 这样上游错了不会向下游级联。 还会被要求主动把 AI 功能编进规格里。
prompt frontend design skill
G
Generator
按 Sprint 推进,每次只做一个 feature
从规格里一次挑一个 feature 来做。每个 Sprint 用 React + Vite + FastAPI + SQLite / PostgreSQL 实现, 收尾前先自评一次再交给 QA。自带 git 做版本管理。
React + Vite FastAPI PostgreSQL git
E
Evaluator (QA)
像真实用户那样点击运行中的应用
通过 Playwright MCP 驱动真实应用 —— 走 UI、调 API、看数据库。 评分维度从前端实验改造而来:产品深度、功能、视觉设计、代码质量。 每个维度都有硬阈值,一项不过 → Sprint 直接判失败。
Playwright MCP 硬阈值评分 Bug 记录
spec 规格
━━━▶
sprint contract ⇄ build
━━━▶
QA + 打分
Sprint 契约 —— 在任何代码写出来之前先谈妥
在「高层用户故事」和「可测试实现」之间搭一座桥;通过文件交互反复迭代,直到双方达成一致。
Generator 提案:这次准备做什么、怎样算「成功」。
Evaluator 审核:确认 Generator 真的在做正确的事,两边来回直到达成一致。
为什么这一步重要:产品规格是有意保留在高层的,所以「规格 → 可测试行为」需要一个独立的环节。 通信完全通过文件 —— 一边写、另一边读取并回应。这样既能让工作忠于规格,又不会过早把实现细节钉死。
05 · Harness 实战 · Opus 4.5

同一句 Prompt:单 Agent vs 完整 Harness

Prompt:「做一个 2D 复古游戏制作器,包含关卡编辑器、精灵编辑器、实体行为系统,以及可试玩的测试模式。」
Harness 跑的成本是单跑的 20 倍以上 —— 但输出质量的差距是肉眼可见的。

这组对比是全文最有说服力的部分:单 Agent 版本看起来接近完成, 但一旦真实使用,核心玩法链路就断了。完整 Harness 贵很多、慢很多, 但它把同一句简单 Prompt 扩成了更完整的产品,并且让关键路径真的可用。

所以这里的结论不是“多花钱就一定更好”,而是当任务处在模型单跑能力边缘时, Planner 和 Evaluator 会把输出从“表面完整”推向“实际可操作”。

单 Agent 跑
Single agent
用时
20 min
成本
$9
初看应用还像那么回事。点进去操作之后问题逐一冒出来:布局浪费空间、流程僵硬、 UI 不引导,最关键的是 —— 实体能显示在屏幕上,但对输入完全没反应。 实体定义和运行时的连接环节坏了,而且界面上没有任何提示在哪里坏了。
!
固定高度的面板让大半屏幕空着。
!
流程僵硬,UI 不引导用户先去做精灵和实体。
!
游戏不能玩:实体出现了,但完全不响应输入。
完整 Harness 跑
Planner + Generator + Evaluator
用时
6 hr
成本
$200
Planner 把同一句 Prompt 扩成了一份 10 个 Sprint、16 个 feature 的规格 —— 远超单 Agent 所做的范围:精灵动画系统、行为模板、音效与音乐、AI 辅助关卡设计、 带分享链接的游戏导出等等。
画布用满了视口,面板尺寸合理,整体视觉风格一致。
精灵编辑器更完整:调色盘更整洁、取色器更好、缩放控件能用。
内置了 Claude 集成:可以直接通过 Prompt 生成游戏要素
试玩模式真的能玩:物理边缘略糙,但核心机制是通的。
单跑 · 核心功能直接是坏的
试图布关卡时系统提示你要先建精灵和实体,但 UI 完全不引导这个顺序。 即便建完之后,实体能显示但对输入没反应 —— 实体定义和运行时之间的连接断了, 而且界面上看不出在哪里断的。
Harness · Evaluator 把实现牢牢拽在规格上
每个 Sprint,Evaluator 都通过 Playwright 走一遍契约里的测试条目,对偏离行为逐一开 Bug。 仅 Sprint 3(关卡编辑器)就有 27 条测试,开出的 Bug 描述具体到不需要额外排查就能直接动手修。 Harness 也并非完美 —— 还有小布局问题、深层 feature 里没被覆盖的 Bug —— 但和「核心功能直接不能用」的单跑比起来,提升非常明显。
06 · Evaluator 抓到的真实 Bug

颗粒度足够细的契约,定位到具体的失败点

Evaluator 报出的问题具体到不需要额外排查就能直接动手修 —— 指出代码位置、函数名、错误的路由顺序。开箱即用的 Claude 其实是个糟糕的 QA (会主动给自己台阶下,把真问题说成不大要紧),需要好几轮对 QA Prompt 的调教才达到能用的水平。

这些 Bug 例子应该直接露出来,因为它们证明 Evaluator 不是在写泛泛而谈的建议。 好的 QA 反馈要能落到具体行为、具体代码路径、具体失败条件上,Generator 才能在下一轮真正修复。

Evaluator findings
FAIL
矩形填充工具:拖拽时应该用所选 tile 填充选中的矩形区域
+
目前只在拖拽起点和终点放了 tile,并没有填充整个区域。 fillRectangle 函数已经存在,但没有在 mouseUp 上正确触发。
FAIL
用户可以选中并删除已放置的实体出生点
+
LevelEditor.tsx:892 处的 Delete 键处理同时要求 selectionselectedEntityId 都被设置,但点选一个实体时只会设 selectedEntityId。 条件应改成 selection || (selectedEntityId && activeLayer === 'entity')
FAIL
用户可以通过 API 重新排序动画帧
+
PUT /frames/reorder 路由定义在了 /{frame_id}。 FastAPI 把 'reorder' 当成了 frame_id 整数去解析, 直接返回 422: "unable to parse string as an integer."
07 · Harness 演进

每个部件都编码了一个假设 —— 都得拿出来重新检验

第一版 Harness 笨重、慢、贵。后续的「瘦身」一半是常识,一半是更深一层的原则: Harness 里的每个部件,本质上都在编码一个关于「模型自己做不到什么」的假设 —— 模型一变强,这些假设就可能立刻过时。

后半篇的重点是“删东西”。作者不是把三 Agent Harness 当成最终形态, 而是随着 Opus 4.6 的能力变化,重新检查哪些组件还在承重。 Sprint 切分从必要约束变成了可以移除的开销,Evaluator 也从每个 Sprint 都评估,变成最后集中评估。

这让文章的观点更细:Harness 不是越复杂越先进。 它应该随着模型能力移动,只在模型当前还不可靠的边界上增加外部结构。

V1

更早期的 Harness

Sonnet 4.5
  • 初始化 Agent + 编码 Agent
  • 会话间做上下文重置
  • 用户需要提供详细规格
  • 一次只做一个 feature
V2

三 Agent Harness

Opus 4.5
  • + Planner:1–4 句 → 完整规格
  • + 带 Playwright MCP 的 Evaluator
  • + Sprint 契约
  • 去掉了上下文重置(Opus 4.5)
V3

精简后的 Harness

Opus 4.6
  • 保留 Planner
  • 保留 Evaluator(改为最后一次性评估)
  • 移除 Sprint 切分
  • + 针对 AI feature 的更精细 Prompt 调教
实战含义。Evaluator 不是一个固定的「要 / 不要」选择 —— 当任务已经超出当前模型独立可靠完成的边界时,加上它才划算。 模型能力一涨,边界就向外移,原本需要 Evaluator 兜底的任务会被 Generator 单跑吃掉。
V3 实测 · DAW Prompt ——「在浏览器里基于 Web Audio API 做一个功能完整的 DAW。」
Agent / 阶段用时成本
Planner4.7 min$0.46
Build · 第 1 轮2 hr 7 min$71.08
QA · 第 1 轮8.8 min$3.24
Build · 第 2 轮1 hr 2 min$36.89
QA · 第 2 轮6.8 min$3.09
Build · 第 3 轮10.9 min$5.88
QA · 第 3 轮9.6 min$4.06
V3 Harness 总计3 hr 50 min$124.70
大部分时间花在 Builder 上 —— 连续运行超过两小时仍然连贯,不再需要 Sprint 切分。 QA 仍然抓到了真问题:录音功能只是空壳、片段不能拖边调长、效果可视化只用了数字滑块没做图形化。 Generator 单干时仍然容易漏细节、留半成品,这时候 QA 依然有它的价值。
08 · 接下来

有意思的 Harness 组合空间不会缩小 —— 只是会移动

模型变强时,套在它外面的脚手架往往会变得不那么重要。 但反过来:模型越强,越有空间去搭一些超出它原生能力之外的复杂 Harness。

最后的结论可以压成一句工程判断: 先用真实模型在真实任务上读 trace,再决定要给模型外面加什么结构。 如果一个组件不能解释清楚它补的是哪个能力缺口,就应该被怀疑。

01 · 总是这样做
用你实际要部署的那个模型去做实验
在真实问题上读它的 trace,针对你想要的结果去调。 「上下文焦虑」这个假设在 Sonnet 4.5 上成立,但到 Opus 4.6 上几乎消失了 —— 脚手架必须反映你真正用的那个模型
02 · 任务复杂时
分解任务,给每个面专门派一个 Agent
Planner / Generator / Evaluator 各补一个具体的洞。 先找最简单的方案,仅在确有必要时再加复杂度 —— 但当确有必要时,「拆」是一个非常有效的杠杆。
03 · 新模型来了
回头审 Harness,把不再「承重」的部件砍掉
Sprint 切分从「必要」(4.5)变成「不需要」(4.6)。 同时加上能让模型够到此前够不到的能力的新部件 —— 目标不是「Harness 越小越好」,而是「Harness 真的有用」。
做完这套工作之后,我的信念是:随着模型变强, 有意思的 Harness 组合空间并不会缩小,而是在移动。 AI 工程师真正有意思的工作,就是不断去找下一个新颖的组合。
— Prithvi Rajasekaran · Anthropic Labs