AI 简报中心 / 案例与方法 / 方法 · AI 工程
METHOD NOTE · AI 工程

Harness Engineering:让 AI Agent 不再散架的系统设计

大多数人在错误的层面改进 agent——失败了改 prompt,再失败加指令,然后换模型、加工具、扩上下文。但很多失败根本不是推理失败,而是环境失败:agent 不知道哪些文件重要、丢掉了上一轮的决定、没跑检查就宣称成功、部分失败后重复了同一个动作。模型未必是问题,模型周围那套系统不完整才是——那套系统叫 harness。

本文是对原文的提炼与结构重组,非逐句翻译。原文为 agent 工程社区共识的高质量综述,不是原创研究,当框架用合适,当「新发现」看会高估。

来源Lunar @LunarResearcher
类型方法 AI 工程 · agent 可靠性
收录2026-09-08
篇幅原文 19 节,此处重组为五组
状态已读 尚未应用

核心论点

Prompt 只改变一次尝试,harness 改变每一次尝试。

模型能推理、生成、比较、选择,但 agent 还必须与真实环境交互:找到相关上下文、选择并使用工具、保存状态、遵守权限、检查结果、从失败中恢复,并且证明工作已完成。模型是推理引擎,harness 是让推理可执行的其余一切——强模型装在弱 harness 里仍然是弱 agent。

harness 工程的目标不是消除模型的不确定性,而是把不确定性关进一个能观察、能验证、能恢复的系统里。

模型居中,外围是 harness 的六个部件:上下文、状态、检查、工具、策略、恢复
原文配图 · harness 的解剖。模型居中,外面一圈是上下文、状态、检查、工具、策略、恢复——「Intelligence needs an environment.」

框架:原文 19 节按主题合并为五组

01 · 先认清问题在哪一层

模型不是 agent;动手前先写任务契约

模糊意图(「改进一下 onboarding」)拿来聊天够用,拿来自主执行不够。harness 应把请求转成一份任务契约,回答五个问题:必须产出什么结果、什么在范围内、什么绝对不能改、什么证据能证明完成、哪些动作需要人工审批。

这把 agent 的问题从「我下一步该做什么」换成了「哪个动作能让环境更接近契约里的结果」。没有契约,它优化的是看起来像在干活。

02 · 喂什么,怎么动手

给地图不给手册;要工具网关不要工具堆;分开大脑、手和历史

把整个仓库和所有历史塞进上下文不是上下文工程,是上下文洪水。正确做法是先给小地图,需要时再下钻——上下文的膨胀应该由任务驱动,不是由「信息存在」驱动。目标是每 token 的信号量最大,不是上下文最大。

给 agent 二十个工具不会让它更能干,只会给它二十种犯错方式。工具网关负责隐藏无关工具、校验参数、限制路径、加超时、让重试幂等、返回证据而不只是「成功」。模型可以提议动作,网关决定这个动作是否有效到可以执行。

脆弱的 agent 把推理、工具调用、报错、陈旧观察全混进一条越来越长的记录里。更强的系统分三块:模型要的是正确的当前状态而非全部原始事件;沙箱要的是安全执行一个有边界的动作;会话日志要的是在上下文消失后保住发生过什么。对话历史不是记忆,它只是事件流——原始历史留给审计,编译出的持久状态留给执行。

03 · 怎么才算做完

完成需要证据;验证要攻击结果;模型提议、策略授权

agent 说「done」只是又一次模型输出。完成必须由环境中可观察的变化判定,而且要先跑最便宜的确定性检查——凡是编译器、schema、校验和、查询或测试能回答的,就别再问模型。模型处理歧义,代码处理管道。

执行者和验证者不该共享目标:执行者想做出最强方案,验证者要找出应该拒绝它的理由。让同一个 agent 在同一个上下文里「再检查一遍」,它往往会保留造成错误的那些假设。验证阶段需要明确的拒绝标准、全新上下文,以及「可以只拒绝、不负责修」的权力。

有些规则不该依赖模型记不记得——它们不是提示词建议,是策略,应该放在推理循环之外,后果越严重闸门越硬。自主不是没有约束,是在清晰强制的边界内自由行动。

04 · 失败之后

按失败类型恢复;指令沉淀成基础设施;观察过程;留变更回执

「出错了再试一次」不是恢复,是重复。要先给失败分类再选动作,一次重试至少要改变一个相关条件,否则只是在花钱复现同一个失败。每个循环都要有预算:尝试次数、时间、花费、破坏范围、升级条件。

指令解释「本地现实」时有用,但本身是很弱的强制手段——规则反复重要,就往下沉一层。prompt 负责解释判断,harness 负责强制不变量。

干净的最终产物可能掩盖糟糕的过程:读了错误的数据、忽略了失败的命令、花了十倍预算、用错误的理由得到正确答案。要的不是监控,是局部修复——第 18 步失败时能从可信检查点重启,而不是重放整个任务。运行结束再编译一张变更回执:它不是模型说了什么的摘要,而是系统能证明什么的摘要。

最弱的团队修复失败的输出,最强的团队还修复允许这个失败发生的系统。改对一个答案只帮到一次运行,改对一个 harness 帮到之后每一次。

05 · 别过度建设

harness 也会腐化;按层建;在正确层级度量

为昨天的模型做的绕行方案,可能挡住今天的模型用更好的策略。把 harness 组件当生产代码,定期问:它防的是哪种失败?那种失败还多久发生一次?增加了多少复杂度?去掉它会怎样?最好的 harness 不是最大的那个,而是能可靠闭合「意图」与「证据」之间差距的最小系统。Build to delete。

度量也要在正确层级:token 数不是终极指标,尝试的任务数也不是,有用的单位是「被接受的工作」。否则会掉进一个幻觉——agent 看起来极其高产,同时制造出昂贵的复核工作。

最小可用 harness:按层加,不要一次搭平台

  1. 有边界的任务 目标、范围、约束、验收检查
  2. 可读的环境 项目地图、命令、本地说明、已知依赖
  3. 受控的动作 类型化工具、参数校验、路径与权限边界、结构化结果
  4. 持久的执行 显式运行状态、检查点、决策、教训
  5. 证据 确定性检查、对抗式验证、变更回执
  6. 恢复与学习 失败分类、有界重试、升级、从重复失败反哺 harness

只建能消除你真实遇到的那个失败的最小一层。不要因为一个 prompt 偶尔需要澄清就上多 agent 架构——复杂度应该由观察到的失败来赢得。

可操作清单

原文配图

agent 声称完成必须先通过由测试、浏览器、数据组成的证据闸门
证据闸门。「Task complete」不能直达终点,要穿过 tests / browser / data 组成的闸门——只有环境能证明完成。
失败先分类再分流:超时用退避、坏输入去修复、缺上下文去检索、冲突升级给人
失败分类 → 恢复策略。超时用退避、坏输入去修复、缺上下文去检索、冲突升级给人——一次重试必须改变一个相关条件。

什么时候不需要重型 harness

直接用 prompt 就行

任务短、输出容易检查、失败代价低、没有外部副作用、人一直在环里。

该上 harness 了

工作跨多个工具或多次会话、环境会变、动作有真实后果、完成度难以人工判断、同一个失败反复出现、人工复核成为瓶颈。

我用在哪了

应用记录 · 尚未应用

这一节是这个库存在的理由。没有它,收录一篇方法就只是往收藏夹里再扔一条链接。状态改成「已应用」时,这里要写清楚:用在哪个项目、具体改了什么、之后有没有少踩坑。

候选落点(站方初判,尚未验证):

  • daily-pantosoph 的每日生成流水线——目前渲染完没有任何确定性检查,正好缺第 5 层的「证据闸门」:报告页生成后自动验一遍必填标记是否完整、导航日期是否最新、图片是否 404,跑不过就不算这期完成。
  • novel-factory 的 agent 编排——「任务契约」和「失败分类 → 恢复策略」这两条最直接;长篇写作跨很多会话,「持久状态而非对话历史」也对得上。
  • 日常用 Codex / Claude Code 的工作流——「指令阶梯」:反复要交代的规则往下沉进 AGENTS.md 或脚本,别每次靠 prompt 重说。
待补。状态从「已读」改为「已应用」时补齐:落到哪个项目 / 具体改了什么 / 改之前和之后的失败率或返工次数 / 哪些条目试过之后判断不值得。