Harness Engineering: 让 Coding Agent 可靠完成长程任务¶
Ch04.071 Harness Engineering: 让 Coding Agent 可靠完成长程任务¶
📊 Level ⭐⭐ | 18.6KB |
entities/harness-engineering-让-coding-agent-可靠完成长程任务-v2.md
相关实体¶
- Harness Engineering - 让 Coding Agent 可靠完成长程任务
- Harness Engineering:让 Coding Agent 可靠完成长程任务
- Agent生产级Harness工程指南
- Agent架构关键变化:Harness正在成为新后端
- Martin Fowler AI 研发 Harness:非确定性承重层
- Agent Reliability: Context Drift & Tool Calling Hallucination
- 长周期 Agent 详解:从 Ralph Loop 到可接管 Harness
- Harness Design Peer Review Framework
- 深入理解 Claude Code 源码中的 Agent Harness 构建之道
- 两万字详解Claude Code源码核心机制
- Agent Harness 架构
- Agent 自我改进的六条路
- Karpathy 最新访谈:从 Vibe Coding 到 Agentic Engineering
- Boris Cherny 新访谈:开发工具正在从 IDE 变成 Agent 控制台
- Harness如何支撑Agent在生产环境稳定运行?
- Agent架构关键变化:Harness正在成为新后端
- AI Coding Agent 记忆系统
- 你不知道的 Agent 原理架构与工程实践
- Agent Skill 设计模式
- 柚漫剧 AI 全流程提效拆解
- Harness Engineering 框架
- Coding Harness 工程本质
- Thin Harness Fat Skills
- Design Patterns for AI Agents 2026
核心定义¶
Harness Engineering 是针对 AI Coding Agent 在大规模、长周期任务中的可靠性工程化实践。Harness(缰绳)的隐喻表明:模型能力本身已足够强大,关键在于提供一个稳定、可控的框架,使其在安全边界内被稳定地引导和复用。 长程任务的三个共同特征:
- 规模大:涉及成百上千个文件
- 运行时间长:一次跑不完,可能跨越多个会话
- Token 消耗极高:动辄几千万到上亿 Token
核心关注点¶
效果¶
任务能否完成、完成的真实性(Agent 是否会未完成就声称完成)、中断后的连续性、结果的可验证性。
速度¶
1000 个文件串行处理需要 8+ 小时,10 路并发可在 1 小时内完成。
成本¶
一次没做对整个上下文 Token 就浪费了,Agent 在长会话中逐渐偏离预期会导致前面几十万 Token 全部白费。
三大核心困难¶
上下文耗尽¶
模型上下文窗口有限,随着任务推进、历史信息累积,上下文被填满后触发压缩,每压缩一轮前面的细节就模糊一层。模型还会出现"上下文焦虑"——感知到快到上限时就开始提前收草草了事,明明还有文件没处理却自己宣布"任务完成"。
中断要重来¶
网络断开、Token 用尽、模型超时不是异常而是常态。Agent 没有跨会话记忆,中断意味着从头再来,不仅浪费已完成的工作,还可能导致"永远无法达到终点"的尴尬境地。
规模大了行为不可控¶
单个文件处理得好不代表一千个文件都能处理得好。规模放大后个别文件处理失败、输出格式不一致、生成的代码破坏构建等问题都会发生。如果一个文件的失败导致整个任务挂掉,那这个流程就不可能在生产环境中使用。
四大核心原则¶
任务拆解¶
对应上下文耗尽的问题。将大任务拆成合理粒度的子任务,每个子任务是 Agent 能在单次会话内独立完成的工作单元,使上下文里只有当前任务需要的信息。
并行执行¶
对应速度的问题。拆完的几十上百个子任务必须支持多个 Agent 同时跑不同的子任务,才能实现速度的本质提升。
可续传¶
对应中断要重来的问题。任务进度必须持久化到会话之外的地方,使得任何一次中断后新的会话都能接着上次的进度继续,而不是从零开始。
有完成条件¶
对应行为不可控的问题。每个子任务必须有明确的、可程序化检查的成功标准,通过客观手段验证产出确实符合预期。
理念¶
任务边界清晰¶
每个子任务有明确的输入、输出、约束,子任务之间不共享状态、不交叉引用。根据任务间关系的不同,边界的实现方式分三种:
- 无依赖,直接并行:子任务之间没有文件级别的依赖,各自处理各自的文件
- 有依赖,拓扑排序:存在顺序约束,被依赖的叶子文件先处理,依赖它的文件后处理
- 有冲突,物理隔离:多个子任务可能修改同一个文件,在独立的 Git Worktree 中操作
错误在最小范围内解决¶
核心原则是:不将错误带到后续阶段,不将错误带出子任务。子任务内闭环,阶段内收敛。每完成一个子任务就立刻校验,不要攒到最后一次性验证。
允许局部失败¶
1000 个文件中有 5 个处理失败,不应该阻塞其他 995 个。"失败"分两种情况:确实搞不定回退给人工;能搞定但不完美接受有限的妥协(如状态设为 DONE_WITH_WARNINGS)。
关键技巧¶
任务粒度¶
合理的粒度取决于三个因素:模型的上下文窗口大小、单个文件的平均规模、任务本身的推理复杂度。实践中经验公式:以 Claude Sonnet 为例,有效上下文窗口约 200K Token,3000 行代码是一个让单次子任务能在上下文窗口内完成的经验上限。
子任务的 CLI 化与并发调度¶
子任务作为独立的 CLI 进程执行而非在 Agent 对话里嵌套调用,带来几个重要好处:
- Prompt 的确定性:程序化组装,所有子任务拿到的指令结构一致
- Token 消耗大幅降低:每个 CLI 子任务是全新的 Agent 会话,消除上下文累积
- 并发数量可控:可由 dispatch.js 脚本自由控制并发数
- 可在前后插入逻辑:预处理和后处理由脚本完成,不需要 Agent 参与
File As Progress¶
所有进度状态持久化到文件系统,不依赖 Agent 的记忆和会话上下文。每完成一步操作立即写入文件,新会话开始时只需读文件就知道"上次跑到哪了"。
任务状态设计¶
状态设计的核心理念是:仅凭当前状态就能决定下一步做什么。状态机:TODO → IN_PROGRESS → DONE/SKIPPED/FAILED。
多轮重试¶
- 内层(恢复会话):网络异常、进程崩溃导致异常退出,恢复同一个会话说"继续"
- 中层(带反馈重试):产出不满足校验条件,开新的子 Agent 会话把错误信息作为上下文喂进去
- 外层(主 Agent 重新调度):中层耗尽后留下的 FAILED 文件由主 Agent 层面决策是否重新 dispatch
示例¶
全量 Code Review¶
21 个前端模块做一轮全量代码审查。按模块分组,单文件源码行数超过 500 行则独立成组。dispatch 脚本以 CLI 方式启动多路 subAgent 并发审查。审查意见的质量属于主观维度,需要独立的 Evaluator Agent 校验。
JS to TS 迁移¶
将整个项目的 JavaScript/JSX 文件批量迁移到 TypeScript/TSX。按同目录归组,累计行数不超过 3000 行。文件间存在依赖关系,被依赖的叶子文件必须先迁移完成,依赖它的文件才能开始。程序化验证:Babel AST 对比确保逻辑结构不变,tsc 做类型检查确保编译通过。
深度分析¶
Harness Engineering 的本质定位¶
Harness Engineering 处于一个微妙的中间地带——它既不是模型本身的能力增强,也不是传统意义上的工程基础设施,而是介于两者之间的"编排认知层"。这篇文章的核心贡献在于识别出:长程任务的失败往往不是模型能力不足,而是框架对模型行为的约束和引导不足。 当任务规模放大时,模型本身的能力仍然很强,但它会逐渐失去对全局目标的聚焦,表现为"上下文焦虑"提前收尾、"忘记"早期建立的约定、重复犯前面已纠正过的错误。这些问题不能通过更强的模型解决,而需要通过更好的任务编排框架来解决。
任务拆解的粒度控制是工程成败的关键¶
文中给出的 3000 行经验值(以 Claude Sonnet 为例)本质上是一个Token 预算约束下的最优解,而非绝对数字。这个数字的得出过程值得注意:它考虑了 Prompt 模板(约 1K Token)、输入文件内容(30K-60K Token)、Agent 工作过程(60K-180K Token),三部分相加约 90K-240K Token,在 200K 上下文中给多轮交互和修复留有余量。 关键洞察是:粒度是否合适要用实际运行数据检验——看子任务的 Token 消耗是否经常逼近上下文窗口的 80%,而不是直接套用经验公式。这是一个典型的"测量驱动工程"思维,而非"理论推导标准答案"思维。
File As Progress 是最小化状态爆炸的核心设计¶
传统的"进度持久化"方案往往倾向于记录大量中间状态和历史记录,但这会引入新的复杂性——Agent 需要理解这些状态记录才能续传。File As Progress 的聪明之处在于:它只记录当前状态,不记录历史状态。恢复逻辑不需要知道"之前发生了什么",只需要知道"当前是什么",就能推导出下一步。 这种设计的隐含假设是:每个状态都是自描述的,状态本身就携带了"接下来该怎么办"的信息。这与状态机的设计哲学一脉相承——状态的迁移规则是确定性的,不依赖于到达这个状态的路径。
Evaluator Agent 的跨会话隔离是保证评估客观性的关键¶
文章指出了一个反直觉但极为重要的现象:在同一个会话内,Agent 的历史推理过程会形成一种"自我说服"效应,影响后续的判断,让 Agent 倾向于认为自己之前的产出是正确的。 这个观察触及了 LLMs 的一个深层问题:推理过程中的中间步骤会改变模型对问题的初始判断。当 Agent 在同一个会话中完成了任务的执行,它已经对产出形成了某种"叙事",这种叙事会渗透到它对产出的评估中。解决方案是物理性的——用完全独立的会话、独立的上下文来做评估,这样评估者面对的是"干净的产出",而不是"我参与了这个产出的生成过程"这一事实。
多轮重试的分层设计体现了成本意识的工程化思维¶
重试不是无限度的,而是在三个层次上有明确边界和策略:
- 内层恢复会话:成本最低,因为复用同一个会话的上下文,Agent 可以从断点继续,不需要重新开始
- 中层带反馈重试:需要开新的会话,但可以通过精确的错误信息定位问题,避免全量重跑
- 外层主 Agent 重新调度:成本最高,需要重新分组、生成新的 Prompt、启动新的子 Agent,只有在前两层耗尽后才有意义 这种分层设计的核心思想是:让每一次重试的边际成本与可能的收益相匹配。
从 meta-skill 到"让 Agent 自己生产工具"的范式跃迁¶
文章最后提出的 long-term-task-orchestration meta-skill 代表了一种更高层次的抽象:不是让 Agent 做一次任务,而是让 Agent 生产出能反复做这类任务的工具。这实质上是把"经验到框架到可复用的工具"这个工程化过程本身也交给了 Agent。 meta-skill 的关键价值在于:它解决的是"每一次长程任务都需要工程师亲自编排"的成本问题。通过让 Agent 自动生成 SKILL.md、scripts、references,工程师只需要用自然语言描述任务目标,系统就能自动生成完整的执行框架。这代表着一种新的编程范式:意图驱动的自动化框架生成,而非传统的步骤驱动的手工编码。
实践启示¶
立即可落地的实践¶
1. 在所有长程任务中强制引入 File As Progress 机制 不要依赖 Agent 的记忆或会话上下文。每次执行都把状态写入文件,下一个新会话开始时第一件事就是读状态文件而非回顾历史。这应该是长程任务的默认范式,而非可选项。 2. 用实际的 Token 消耗数据来校准任务粒度 不要套用文章中的 3000 行或 500 行经验值,而是先跑几组样本,测量实际的 Token 消耗分布。如果经常逼近 80% 上限就缩小粒度,如果只用 30-40% 就适当放大。这是一个持续校准的过程,不是一次性设定后就不再改动。 3. 将 Evaluator Agent 与执行 Agent 严格隔离在不同会话中 这是确保评估客观性的最简单最有效的手段。在评估场景中,主 Agent 编排、subAgent 执行审查和修复、Evaluator Agent 对意见做批判性评估。Evaluator 的 Prompt 要带有挑战性语气,主动挑毛病而非寻找优点。
中期建设方向¶
4. 为团队建立长程任务 Skill 模板仓库 当团队积累了一定数量的长程任务实践后,应该将这些实践抽象成可复用的 Skill 模板。每个模板包含标准的目录结构(SKILL.md、scripts/、references/、evals/),团队成员可以直接基于模板创建新的长程任务,而不是从零开始编排。 5. 实现 dispatch 脚本的统一设计 所有长程任务 Skill 的调度方式应该一致——统一的参数接口(--root、--concurrency、--dry-run、--retry-failed),统一的调度策略(随到随补,不等齐再发),统一的状态文件格式。这使得团队成员切换不同任务类型时不需要重新学习调度方式。 6. 引入 DONE_WITH_WARNINGS 状态处理"能搞定但不完美"的情况 不要把"基本正确但有妥协"当作硬失败处理。这会导致大量文件在"99% 搞定"的状态下被反复重跑,浪费 Token。引入一个中间状态(如 DONE_WITH_WARNINGS),记录遗留问题作为后续优化清单,照常合入主流程。
长期演进视角¶
7. 持续审视 Harness 边界随模型能力变化而移动 文章最后的观点值得深思:Harness 中的每一个环节都隐含了一个"当前模型做不到"的假设。随着模型能力提升,这些假设会逐渐过期。每一代新模型出现时,应该重新审视 Harness 边界,去掉一个环节观察对结果的影响,找到模型能力和工程可靠性之间的新平衡点。 8. 将 meta-skill 作为团队基础设施建设的长期目标 从长远看,团队应该追求"让 Agent 自己生产工具"的能力,而非每次都需要工程师手工编排。这要求团队在早期就注重经验的抽象和模板化,为后续 meta-skill 的构建积累素材。