大多数人都在错误的层面上试图修复 AI Agent。
当 Agent 失败时,他们会重写提示词。如果再次失败,他们就添加更多指令、切换模型、扩大上下文窗口,或者接入另一个工具。
然后,同样的问题又卷土重来。
Agent 会忘记一个重要的决定;用错工具;忘了三步之前发生了什么;没检查结果就宣称任务完成;反复重试同一个失败的操作,直到预算耗尽。
问题并不总是出在模型上。
问题出在它周围的环境。
这个环境就是 harness(执行框架)。
Harness Engineering(框架工程)指的是围绕模型构建一套系统,由它来决定模型能看到什么、能做什么、记住什么、怎样算成功,以及出错时该怎么办。
更好的提示词只能改善单次回答。
更好的 harness 能让每一次运行都变得更好。
关注我的 Substack,获取更多关于 AI Agent、自动化和生产系统的实战拆解:
1. 模型不等于 Agent
模型可以推理、生成、比较和选择。
但这并不能让它成为一个可靠的 Agent。
真正的 Agent 还需要找到正确的上下文、使用工具、保持状态、遵守权限、验证自己的工作,并在环境表现与预期不符时进行恢复。
模型只是推理引擎。
而 harness 是把这种推理变成真正执行的一切。
1用户请求2 |3 v4+-----------------------------+5| HARNESS |6| |7| 契约 上下文 |8| 工具 状态 |9| 策略 验证 |10| 追踪 恢复 |11+-----------------------------+12 |13 v14 模型15 |16 v17 真实环境
把同一个模型放进聊天框,它只会回答问题。

把它放进一个拥有终端访问权限、测试、浏览器工具、项目记忆、受控权限和审查循环的代码仓库里,它就能完成真正的工作。
模型没有变。
变的是 harness。
2. 把每个请求都变成一份契约
自然语言是灵活的。
但自主执行不该如此。
像这样的请求:
优化新用户引导流程。
当有人坐在模型旁边盯着时,这么写没问题。
但作为生产环境的指令,它糟透了。
在 Agent 动手之前,先把请求转化为一份有边界的任务契约。

1objective: 降低新用户引导流失率23inputs:4 - 产品简介5 - 分析数据6 - 代码仓库78constraints:9 - 保留身份验证逻辑10 - 不修改数据库结构11 - 保持当前移动端行为不变1213deliverable:14 - 可审查的 pull request1516done_when:17 - 测试通过18 - 埋点事件正确触发19 - 桌面端流程通过审查20 - 移动端流程通过审查2122approval_required:23 - 生产环境部署
最关键的部分是 done_when(何时算完成)。
没有它,Agent 可能会去解决一个稍微简单点的版本,然后依然自信地宣布任务完成。
有了它,完成度就变得可衡量。
Agent 不该问:
我接下来该做什么?
它应该问:
哪个动作能让当前环境更接近契约约定的结果?
这是一个强得多的循环。
3. 给 Agent 一张地图,而不是一个巨大的上下文窗口
面对 Agent 犯错,常见的反应是给模型塞更多上下文。
更多文档。
更多对话历史。
更多文件。
更多工具输出。
最终,Agent 收到了一切,却理解得更少。
上下文不是存储空间。
它是注意力预算。

与其在每次运行时把整个项目倒进去,不如给 Agent 一张小地图,告诉它有用的信息在哪里。
1项目地图23产品规则 -> docs/product/4架构 -> docs/architecture.md5前端 -> apps/web/6后端 -> services/api/7测试 -> tests/8命令 -> docs/commands.md9安全 -> docs/security.md
只在需要时才展开细节。
1任务2 |3 v4项目地图5 |6 v7相关系统8 |9 v10具体文件11 |12 v13局部指令
原文把这称为渐进式披露(progressive disclosure):harness 应该因为任务需要才加载更多信息,而不是仅仅因为信息存在就全塞进去。
目标不是最大化上下文。
目标是最大化有效信号。
4. 在模型和工具之间加一道网关
给模型二十个工具,并不意味着它的能力自动翻了二十倍。
它可能只是多了二十种出错的方式。
每个工具都应该有一份契约。
1工具:edit_file23输入4path5patch67前置条件8path 存在9path 在工作区内1011成功12patch 已应用13返回 diff1415失败16结构化错误17不允许部分覆盖1819风险20可逆
于是执行路径变成了:
1模型提出方案2 |3 v4网关切校验5 |6 v7策略授权8 |9 v10工具执行11 |12 v13HARNESS 记录结果
模型决定它想做什么动作。
harness 决定这个动作是否合法、被允许且安全。

当工具能发消息、改生产环境、花钱或删数据时,这个区分就变得至关重要。
一个好的工具网关还能加上超时控制、校验参数、限制文件路径、统一错误格式,并让重试变得安全。
好的工具能减少模型需要猜的东西。
5. 把记忆移出对话
对话不应该成为系统的唯一记录。
长时间运行的 Agent 终究会撞上上下文上限、崩溃、重启,或者把工作交接给另一个会话。
如果所有重要决定都只存在于聊天记录里,那这个工作流就非常脆弱。
把持久化状态单独存起来。

1{2 "task_id": "feature_042",3 "status": "verifying",4 "current_step": "mobile_check",56 "completed": [7 "implementation",8 "unit_tests",9 "desktop_check"10 ],1112 "decisions": [13 "复用现有的导出接口",14 "保留当前的日期格式"15 ],1617 "artifacts": [18 "export.csv",19 "desktop-after.png"20 ],2122 "open_risks": [23 "移动端工具栏可能会溢出"24 ],2526 "next_action": "渲染移动端视口"27}
一个好用的系统会把记忆分成四类:
1事实2稳定的知识34决策5选了什么,为什么这么选67状态8当前运行到哪一步了910经验教训11那些应该影响未来运行的失败
下一个 Agent 会话继承的应该是工作的状态,而不是一段被压缩过的“上次聊了什么”的故事。
6. 让证据成为完成的门槛
Agent 说一句“搞定了”,并不能证明活儿真干完了。

那只是模型的又一次输出。
harness 需要可观测的证据。
1主张 证据23"bug 修好了" 原本失败的测试现在通过了45"页面能用" 浏览器流程跑通了67"数据是对的" 数值与源数据一致89"迁移是安全的" 预演 + 回滚通过1011"任务完成了" 所有验收检查都通过
优先使用确定性检查。
1语法2 |3 v4类型5 |6 v7定向测试8 |9 v10集成测试11 |12 v13视觉 / 语义审查14 |15 v16人工审批
别用另一个模型去回答编译器、测试、schema 或数据库查询就能证明的事。
让模型负责判断。
让确定性系统负责事实。
模型产出交付物。
环境产出关于交付物的证据。
harness 判断证据是否充分。
7. 把构建者和验证者分开
自己审查自己还有另一个问题。
制造错误的那个 Agent,往往会把同样的假设带进审查环节。

更稳健的架构会把执行者和验证者分开。
1构建者2 |3 v4生成候选结果5 |6 v7验证者8 |9 +-- 检查契约10 +-- 寻找遗漏的用例11 +-- 测试站不住脚的主张12 +-- 尝试破坏结果13 |14 +------ 通过 ------> 接受15 |16 +------ 失败 ------> 返回证据
验证者不该问:
这看起来不错吧?
它应该问:
什么情况会让它不可接受?
这把审查从“确认”变成了“试图证伪”。
原文明确建议:给验证环节设定独立的拒绝标准,并赋予足够的独立性,去挑战产生第一个结果时的那些假设。
8. 把权限移出模型
有些规则永远不该指望模型去记住。
1未经批准绝不发布2绝不泄露密钥3绝不超出支出上限4绝不在工作区之外写入5没跑过测试就绝不声称测试通过
这些不是提示词里的建议。

它们是策略。
一个简单的权限阶梯:
1低风险23读取4搜索5检查67-> 自动放行89可逆操作1011编辑工作区12运行测试13创建草稿1415-> 自动放行 + 记录追踪1617外部影响1819发送20部署21购买2223-> 需要审批2425不可逆 / 敏感操作2627删除数据28轮换凭证29全局发布3031-> 硬性拦截或禁止
后果越严重,控制就要越强。
模型可以推荐动作。
harness 负责授权。
工具负责执行。
自主性不是没有控制。
而是在强制边界内的自由。
9. 别再盲目重试了
最糟糕的恢复策略之一是:
出错了,再试一次。
如果什么都不改变,系统只是在花钱重复同一个错误。
失败应该先分类。

1工具超时2-> 退避后重试34参数无效5-> 修复工具调用67缺少上下文8-> 拉取缺失的来源910测试失败11-> 检查失败的行为1213权限被拒14-> 申请审批1516需求冲突17-> 上报1819重复失败且无变化20-> 停止
一个有用的 Agent 循环长这样:
1观察2 |3 v4决策5 |6 v7行动8 |9 v10衡量11 |12 +---- 接受13 |14 +---- 修复15 |16 +---- 上报17 |18 +---- 停止
每个循环都应该对尝试次数、时间、花费和破坏范围设限。
可靠的 Agent 需要知道怎么继续。
也需要知道什么时候再试一次已经不值得了。
10. 把重复的指令变成基础设施
假设提示词里写着:
始终运行格式化程序。
如果格式化程序能自动运行,这条规则会更牢固。
假设指令说:
UI 代码不能直接访问数据库。
把它变成一个架构测试——一旦违规就让测试失败——会更强。
演进过程是这样的:
1说明2 |3 v4清单5 |6 v7模板8 |9 v10自动化检查11 |12 v13强制执行策略
提示词应该解释判断逻辑。
harness 应该强制保证不变量。
每一个反复出现的错误,都应该顺着这个阶梯往下推一点。
最终,模型不再需要记住这个教训。
环境替它记住了。
11. 记录运行过程
完美的最终产物,可能掩盖了一条糟糕的执行路径。
也许 Agent 访问了错误的数据源。
也许它忽略了一个失败的命令。
也许它把某个外部操作重复执行了两次。
也许它花了十倍于预期的预算。
也许它用错误的理由得出了正确的答案。
记录足够的信息,以便还原到底发生了什么。
109:14 创建任务契约209:15 加载 architecture.md309:17 编辑 checkout.ts409:18 定向测试失败509:21 修复实现609:22 定向测试通过709:24 集成测试通过809:25 部署被拦截:需要审批
有用的追踪信息包括:上下文来源、工具调用、状态变更、验证结果、重试原因、审批决定、成本和延迟。
重点不是为了好玩而收集日志。
重点是让失败局限在局部。
如果第 18 步出了问题,你应该能只修复第 18 步。
而不是被迫重跑整个过程。
12. 给每次运行一张回执
别逼着人去翻四十条消息的聊天记录。
把结果整理成一张简短的回执。
1目标23修复优惠券重复使用的问题。45变更内容67结账校验8回归测试910已验证1112lint 通过13单元测试通过14集成测试通过1516未验证1718生产环境支付服务商1920风险2122旧版移动端客户端不可用2324需要审批2526部署到 staging
这不是模型自称发生了什么的总结。
而是 harness 能证明发生了什么的总结。
正是这个区别,让回执在审查、交接和未来的 Agent 会话中真正有用。
13. 让每次失败都改进 harness
大多数团队只会修复那个失败的输出。
更好的做法是修复允许这次失败发生的系统。
1缺少上下文2-> 改进项目地图34用错工具5-> 改进路由或工具契约67输出质量差8-> 增加验证器910死循环11-> 加重试上限1213不安全操作14-> 加权限关卡1516丢失决策17-> 持久化状态1819未知失败20-> 改进追踪
这就是 harness engineering 开始产生复利的地方。
修复一个输出,只帮到一次运行。
修复一次 harness,能让之后的每一次运行都变好。
最优秀的 Agent 系统之所以越来越可靠,是因为错误留下了基础设施。
14. 从最小可用的 harness 开始
你不需要一开始就搭一个庞大的编排平台。
分层构建。
1第 0 层23提示词4模型56第 1 层78任务契约9项目地图10工具1112第 2 层1314结构化状态15验证16有界循环1718第 3 层1920权限21追踪22恢复23人工关卡
一个简短的研究任务,可能只需要一条提示词和一次审查。
而一个长达六小时、涉及文件访问、网络访问和部署能力的编码任务,需要的就多得多。
只有当失败面大到值得时,再加复杂度。
别只是因为 Agent 架构看起来很酷就去堆料。
Harness Engineering 检查清单
在给 Agent 真正的自主权之前,先问自己:
1[ ] 执行前是否已经定义了成功标准?23[ ] Agent 能否在不加载全部内容的情况下4 找到正确的上下文?56[ ] 每个工具是否有明确的用途、7 schema 和失败状态?89[ ] 重要决策是否存储在10 对话之外?1112[ ] 完成是否需要证据?1314[ ] 高风险操作是否受策略保护?1516[ ] 每个循环是否有重试上限?1718[ ] 中断后运行能否恢复?1920[ ] 你能否还原每一个重要操作?2122[ ] 失败是否能改进某条规则、工具、23 测试、地图或权限?2425[ ] 最终变更能否回滚?
如果有好几个答案都是“否”,那么换个更强的模型也不会自动让 Agent 变可靠。
它可能只会让失败来得更快、更贵。
真正的转变
Prompt engineering 问的是:
我该告诉模型什么?
Context engineering 问的是:
模型此刻应该知道什么?
Harness engineering 问的是:
什么样的系统能让模型行动、验证自己的工作、从失败中恢复并安全运行?
1提示词2-> 指令34上下文5-> 工作视图67HARNESS8-> 运行环境910循环11-> 局部修正1213图14-> 协调
模型会不断迭代。
持久的优势长在它们周围。
你的契约会越来越好。
你的工具会越来越好。
你的测试会越来越好。
你的状态会越来越干净。
你的权限会越来越安全。
你的恢复逻辑会越来越聪明。
你的失败会变成基础设施。
这就是强大的模型变成可靠 Agent 的方式。
这就是 Harness Engineering。
如果你读到了这里
收藏这份指南。
在 X 上关注我: x.com/0xjmori
订阅我的 Substack: substack.com/@lunarresearcher
把这篇文章转给那些还在试图用更长提示词来修复 Agent 各种报错的人。



![[致歉] 我不再推荐通过自由职业实现独立。](/cdn-cgi/image/width=1920,quality=90,format=auto,metadata=none/https%3A%2F%2Fcms-assets.youmind.com%2Fmedia%2F1790615558140_ndvona_HTQ9s6laYAAX4J7.jpg)

