第四章 Harness Engineering 官方深度解读

过去半年,Anthropic 连发两篇工程博客,系统公开了他们内部做长任务 Agent 的方法论——"Harness Engineering"。这套东西被硅谷圈子称为 "2025 是 Agent,2026 是 Agent Harness"。这篇把两篇官方博客揉到一起,讲清它到底是什么、为什么重要、你该怎么用。
一、一句话读懂 Harness Engineering
✍️
Anthropic 给了一个极其朴素的定义:Agent = Model + Harness,If you're not the model, you're the harness.翻译过来:一个 Agent 产品里,除了大模型本身,所有的代码、配置、执行逻辑、上下文管理、工具绑定——全都叫 harness(字面意思是"马具")。
马很强壮,但没有马具,它跑不了长途、驮不了重物。
Harness 不是在"命令模型",而是在"约束、引导、承载模型"。
二、第一篇(2025 年 11 月):长任务 Agent 的 Harness 设计
核心贡献是两个具体的架构模式:
🍰
模式 1:两段式 PromptAnthropic 发现,Agent 的第一次启动和后续上下文继续需要完全不同的 prompt。
•
首次启动(fresh start):需要详尽的 system prompt、工具说明、任务描述
•
后续继续(resume):不需要重复这些,只需要告诉 Agent "上次你做到哪了"
•
官方的原句是:"The harness uses a different prompt for the very first context window."这个洞察看似简单,但大多数 Agent 框架都没做——它们每次重启都用同一个 system prompt,浪费大量 token 在重复告知"你是谁、你能用什么工具"。
模式 2:claude-progress.txt + Git HistoryAnthropic 在博客中披露了一个极简的上下文传递机制:
代码块
Python
workspace/
├── claude-progress.txt ← Agent 自己维护的进度笔记
└── .git/ ← Git 历史,天然的"外部记忆"
当 Agent 在新的上下文窗口重启时,它做的第一件事是:读 claude-progress.txt——了解上次工作的意图和状态读 git log——看自己最近提交了什么代码推断当前应该从哪继续这比任何花哨的 Memory Framework 都更可靠。因为 git log 是操作系统级可信数据,不会产生幻觉。模式 3:Initializer + Coding Agent 双 Agent复杂任务不由一个 Agent 从头啃到尾,而是拆成两个:Initializer Agent:读 product spec,分解成 feature 列表Coding Agent:一次只做一个 feature,完成后交接 artifacts 给下一个 coding agent每一个 coding agent 的生命周期就是一个 feature。这样每个 agent 的上下文都保持"干净而聚焦"。
三、第二篇(2026 年 3 月):GAN 式多 Agent Harness
标题是"Harness Design for Long-Running Application Development",公开了 Anthropic 内部为前端开发和长任务编程设计的多 Agent 架构——"GAN 式 Harness"**。借用 GAN 的核心思想生成对抗网络(GAN)有两个网络:Generator:生成假样本Discriminator:判别真假,反向监督 GeneratorAnthropic 把这个思路搬到了 Agent 工程:
#bFFBkRgrNDFh text { white-space: pre; }#bFFBkRgrNDFh .fb0 { stroke: var(--N900-FG, 0.15); }#bFFBkRgrNDFh .fb0 {stroke: rgba(31,35,41, 0.15)}#bFFBkRgrNDFh .fx0 { stroke-miterlimit: 10; }#bFFBkRgrNDFh .fx0 {stroke-miterlimit: 10}#bFFBkRgrNDFh .fa1 { fill: rgb(187, 191, 196); }#bFFBkRgrNDFh .fa1 {fill: rgb(187, 191, 196)}#bFFBkRgrNDFh .fx1 { font: 400 12px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#bFFBkRgrNDFh .fx1 {font-style: normal}#bFFBkRgrNDFh .fx2 { text-anchor: middle; }#bFFBkRgrNDFh .fx2 {text-anchor: middle}#bFFBkRgrNDFh .fx3 { dominant-baseline: central; }#bFFBkRgrNDFh .fx3 {dominant-baseline: central}#bFFBkRgrNDFh .fx4 { stroke: none; }#bFFBkRgrNDFh .fx4 {stroke: none}#bFFBkRgrNDFh .fc0 { fill: var(--text-caption); }#bFFBkRgrNDFh .fc0 {fill: #646a73}#bFFBkRgrNDFh .fa2 { fill: var(--text-link-disabled); }#bFFBkRgrNDFh .fa2 {fill: rgb(187, 191, 196)}#bFFBkRgrNDFh .fa3 { fill: rgb(225, 234, 255); }#bFFBkRgrNDFh .fa3 {fill: rgb(225, 234, 255)}#bFFBkRgrNDFh .fx5 { font: 400 16px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#bFFBkRgrNDFh .fx5 {font-style: normal}#bFFBkRgrNDFh .fx6 { text-anchor: start; }#bFFBkRgrNDFh .fx6 {text-anchor: start}#bFFBkRgrNDFh .fx7 { dominant-baseline: alphabetic; }#bFFBkRgrNDFh .fx7 {dominant-baseline: alphabetic}#bFFBkRgrNDFh .fc1 { fill: rgba(0, 0, 0, 0.9); }#bFFBkRgrNDFh .fc1 {fill: rgba(0, 0, 0, 0.9)}#bFFBkRgrNDFh .fx8 { font: 700 16px MonospacedNumber, LarkHackSafariFont, LarkEmojiFont, LarkChineseQuote, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Tahoma, "PingFang SC", "Microsoft Yahei", Arial, "Hiragino Sans GB", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; }#bFFBkRgrNDFh .fx8 {font-style: normal}#bFFBkRgrNDFh .fb1 { fill: var(--N900-FG, 0.15); }#bFFBkRgrNDFh .fb1 {fill: rgba(31,35,41, 0.15)}#bFFBkRgrNDFh .fb2 { fill: rgb(187, 187, 187); }#bFFBkRgrNDFh .fb2 {fill: rgb(187, 187, 187)}#bFFBkRgrNDFh .fb3 { fill: rgb(221, 221, 221); }#bFFBkRgrNDFh .fb3 {fill: rgb(221, 221, 221)}#bFFBkRgrNDFh .fa4 { fill: var(--bg-body); }#bFFBkRgrNDFh .fa4 {fill: #fff}ABC123组件角色开发工程师QA 工程师职责按 sprint 实现 feature,使用标准技术栈用测试工具验证 UI、API、数据库状态Generator AgentEvaluator Agent
这两个 Agent 不是并行的,而是协商 + 对抗的关系:Sprint Contract 机制每一个 sprint 开始前,Generator 和 Evaluator 协商一份Sprint Contract:
代码块
JSON
{"sprint_goal":
"实现用户登录流程",
"deliverables":
["POST /api/login 端点","前端登录表单","session 管理中间件"],
"acceptance_criteria":
["正确密码返回 200 + token","错误密码返回 401","token 可以在后续请求中通过验证"],
"test_scenarios":
["happy_path", "wrong_password", "expired_session"]}
Generator 照合约干活Evaluator 照合约验收验收不通过?Generator 按 Evaluator 的反馈修改,再次提交这就是 "对抗但协作" 的工作循环——和 GAN 的本质完全一致。实际效果Anthropic 博客披露的数据:在长任务(多小时、多 feature、跨多个 context window)场景下,GAN 式 harness 的任务完成率比单 Agent 架构高出约 40%,错误率降低约 60%。
四、真正的爆点:Anthropic 在呼吁大家"删掉自己的 harness"
两篇博客读下来,你会发现一个反直觉的观点——Anthropic 不是在教你"怎么搭更复杂的 harness",而是在教你"怎么删掉多余的 harness"。官方原文:> "Find the simplest solution possible, and only increase complexity when needed."> "Each component in a harness encodes an assumption about what the model can't do on its own."翻译:你 harness 里的每一行代码,都是在假设模型做不了某件事。在 Claude 3 时代,这些假设大多成立——所以 harness 越复杂越好。到了 Claude 4.6 / 4.7 时代,很多假设已经不成立:模型会自己规划任务?→ 你的 task planner 可以删了模型会自己压缩上下文?→ 你的 summary layer 可以删了模型会自己检查错误?→ 你的 validator 可以简化了所以 Anthropic 提出了一个新哲学——"The Art of Subtraction"(减法的艺术)。
五、模型进化 → Harness 设计不变少,而是"迁移"
这是两篇博客里最精妙的一个观察:> "As models improve, the space of interesting harness combinations doesn't shrink. It moves."意思是:模型变强不会让 harness 工程变简单,只会让 harness 要解决的问题"换位置"。用一个比喻:Claude 3 时代的难题:怎么让模型按步骤推理?→ 解法:CoT prompt、ReAct 框架Claude 4 时代的难题:怎么让模型跑 8 小时不崩?→ 解法:Context compaction、progress fileClaude 4.7 时代的难题:怎么让多个模型协作不互相踩脚?→ 解法:GAN 式 harness、sprint contract下一代的难题:?(还没出现,但注定会有)每一代模型,都会有新的 harness 难题出现。这是一个持续存在的工程学科,不会因为模型变强就消失。
六、"五层 Harness 模型":Anthropic 交付了三层,两层留给你
Han HELOIR 博士在近期的分析中提炼了一个很清晰的分层框架,完美对应 Anthropic 这两篇博客:
表格加载中...
翻译过来:Anthropic 正在把 harness 的前 4 层做成"managed 服务",你作为开发者,只需要做好最上面两层——业务评估 + 用户体验。这其实是一种"商业信号":Anthropic 希望你少写代码,多调他们的服务。好不好?见仁见智——但至少 Anthropic 的方向很清楚:harness 的下层基础设施正在被吞并,开发者价值上移到业务层。
七、对我们的实战启示(5 条)
读完两篇博客,能落地的做法有这些:
1. 立刻引入 progress.txt 文件这是两篇博客里最容易复制、收益最大的动作。任何长任务 Agent 都应该维护一个进度笔记文件。
2. 区分"首次 prompt"和"续跑 prompt"系统 prompt 不要写成一个巨大的字符串。拆成两份,根据上下文状态选用。
3. 复杂任务拆成 Initializer + Worker不要让一个 Agent 啃完整个任务。让一个 Agent 负责规划,另一个负责执行。
4. 考虑 GAN 式双 Agent如果你的场景涉及"生成 + 验证"(编程、内容创作、设计),认真考虑 Generator + Evaluator 架构。不要把生成和验证塞给同一个 Agent。
5. 定期 review 你的 harness,问"能删什么"每次模型升级后,逐条检查 harness 里的每个组件:这个组件解决的问题,新模型是不是已经自己能处理了?如果能,删掉它会不会让系统更简洁、更快、更便宜?Anthropic 的建议非常朴素——"能删就删"。
八、写在最后
这两篇 Anthropic 博客之所以重要,不是因为给了多少新技术细节,而是因为它们把 "harness engineering" 正式确立成一个工程学科。2023 年大家卷 prompt engineering。2024 年大家卷 context engineering 和 RAG。2025 年大家卷 agent 框架。2026 年,分水岭变成了 harness engineering。同一个 Claude Opus 4.7,放在不同的 harness 里,产出效果可以差 3-5 倍。这个差距不在模型里,在你的工程里。接下来 AI 产品的护城河,不再是"你用了哪个模型",而是——你的 harness 设计得比别人聪明多少。