Harness Engineering : 为什么模型强却执行不可靠,Harness 到底是什么
目录
系列目录
本系列共三篇:
一个让我困惑很久的问题
用 AI 写代码久了,我反复遇到同一件事:模型明明很强,但真让它干活,结果经常让人失望。
给它一个需求,它跑 20 分钟,信心满满地说"做完了"。我一看代码——功能是加了,但测试挂了;bug 是改了,但引入了新 bug。根本不是我要的东西。
我的第一反应和大家一样:"是不是模型不行,该换个更贵的?"
后来我才意识到,问题很可能根本不在模型身上。
模型能力 ≠ 执行可靠性
截至 2025 年底,最强的 coding agent 在 SWE-bench Verified 上的通过率大约在 50-60%。这个数字听起来不错,但别急着高兴——那些都是精心挑选过的任务:有明确的 issue 描述、现成的测试用例。等你把自己日常的需求丢过去——需求模糊、没有现成测试、隐含的业务规则散落在各处——通过率只会更低。
遇到这种情况,大多数人的第一反应是"这模型不行,换一个更贵的"。先别急着掏钱包,问题可能不在模型身上。
Anthropic 的对照实验:同一个 prompt("做一个 2D 复古游戏编辑器")、同一个模型(Opus 4.5),跑了两次。第一次裸跑,20 分钟花了 $9,游戏核心功能跑不起来;第二次配上完整的 harness(planner、generator、evaluator 三 agent 架构),6 小时花了 $200,游戏可以正常游玩。模型没有换,换的是马具。
OpenAI 的 Codex 实验:三个工程师不写代码,只让 Codex 写。从空仓库起步,五个月下来仓库有了约 100 万行代码,应用逻辑、基础设施、工具、文档全是 agent 生成的,共开了 1,500 个 PR。起初进展很慢——Codex 并不差,但缺少完整的工具和结构去推进高层次目标。工程师把大目标拆成小的积木块(设计、编码、审查、测试),让 agent 逐个搭建。每当某件事做砸了,问题几乎从来不是"不够努力",而是 agent 还缺什么。Codex 在一个 harness 搭得好的仓库里,表现能从"不可靠"直接跳到"可靠"——注意这个用词,不是"好了一点",是质变。
Agent 到底栽在哪儿
复盘我自己用 AI 写代码翻车的经历,失败模式其实就那么几类:
- 需求描述模糊,agent 只能猜。 我说"加个搜索功能",这话说了等于没说:搜索的对象是什么?全文本还是结构化查询?结果要不要分页、要不要高亮?你没说明白,agent 就只好自己猜。猜对了算运气好,猜错了你再改,来回一折腾,比一开始说清楚多花好几倍的时间。
- 隐性约定没写下来,agent 无从遵守。 你们全组都用 SQLAlchemy 2.0 的新语法,但 agent 默认写了 1.x 的代码;所有 API 端点必须走 OAuth 2.0 认证,可这条规矩只存在于你脑子里和三个月前一条 Slack 消息里。Agent 压根不知道有这么回事,不是不想遵守,是真没见过。
- 环境配置有缺口,agent 把精力花在修环境上。 开发环境配置不完整、依赖缺了、工具版本不对,agent 把宝贵的上下文窗口花在了
pip install报错、Node 版本冲突这些事上,真正该干的活反而没精力做。 - 缺少验证手段,agent 自己觉得做完了就算完成。 没有测试、没有 lint、或者验证命令根本没告诉 agent。Agent 写完代码,自己看了看觉得没问题,就说完成了。更糟的是,当它感觉上下文快满了,会慌慌张张收尾、跳过验证步骤、选一个简单的方案而不是最优方案——Anthropic 把这叫"上下文焦虑"。
- 跨会话状态丢失,每个新会话都要重新探索。 上次会话的发现全丢了,每次新会话都得重新探索项目结构、理解代码组织。缺乏持久化状态的 agent 在超过 30 分钟的任务中失败率急剧上升。
关键名词解释
理解了上面的场景,这些概念就不再是一堆术语了:
- 能力鸿沟(Capability Gap):模型在基准测试上的表现和真实任务上的表现之间的巨大落差。SWE-bench Verified 上 50-60% 的通过率意味着近一半的真实 issue 解不了。
- Harness:模型权重之外的一切工程基础设施——指令、工具、环境、状态管理、验证反馈。不是模型权重的部分,全是 harness。也就是我们说的"马具"。
- Harness 诱导失败:模型本身能力足够,但因为执行环境有结构性缺陷而失败。Anthropic 的对照实验已经证明了这一点。
- 验证缺口:agent 对自己输出的信心评估和实际正确性之间的偏差。agent 说"我做完了"但实际没做完——这是最常见的失败模式。
- 诊断循环:执行 → 观察失败 → 定位到 harness 的哪一层出了问题 → 修补那一层 → 重新执行。这是 harness 工程的核心方法论。
- 完成定义(Definition of Done):一组可以用命令验证的条件——测试通过、lint 没报错、类型检查通过。没有显式的完成定义,agent 就会自己编一个。
Harness 到底是什么:五个子系统
harness 这个词在 AI coding agent 的圈子里被用得越来越多,但大部分人说 harness 的时候,其实指的是一个 prompt 文件。一个 prompt 文件不是 harness。
先讲一个类比:想象你是一个刚入职的工程师,被丢进一个没有任何文档的项目里。没有 README,代码里没有注释,没有人告诉你怎么跑测试。你能写出好代码吗?也许能——但你会花大量时间在"搞清楚这个项目是怎么回事"上,而不是在"解决问题"上。AI agent 面对的困境一模一样,甚至更糟——你至少可以问同事,agent 只能看到你放在它面前的文件和它能执行的命令。
Harness 由五个子系统组成,每个子系统都有明确的职责和评判标准:
| 子系统 | 职责 | 典型产物 |
|---|---|---|
| 指令 | 告诉 agent 项目是什么、规则是什么 | AGENTS.md / CLAUDE.md |
| 工具 | 给 agent 足够的执行能力 | shell、终端、最小权限原则 |
| 环境 | 让环境状态自描述、可复现 | pyproject.toml、.nvmrc、Docker |
| 状态 | 长任务的进度跟踪 | PROGRESS.md |
| 反馈 | 告诉 agent 怎么算做对 | 验证命令 |
五个子系统缺一个,harness 就不完整。其中,反馈子系统通常是投入最少、回报最高的——先把验证命令写清楚:
# AGENTS.md 里的验证命令
验证命令:
- 测试:pytest tests/ -x
- 类型检查:mypy src/ --strict
- Lint:ruff check src/
- 完整验证:make check(包含以上全部)
量化 harness 组件价值:用"控制变量排除法"——保持模型不变,逐个移除五个子系统,看哪个子系统缺失时性能下降最多。下降最多的组件说明它在当前任务里边际贡献最大。但要定位真正的瓶颈,不能只靠拆除实验,还要看失败记录和归因:任务没说清楚、上下文不足、环境不可复现、验证反馈缺失,还是状态管理断裂。
你熟悉的工具都是 harness
- Claude Code:会读仓库里的
CLAUDE.md,能用 shell 跑命令,有会话历史,能跑测试看结果。但如果你不告诉它怎么跑测试,它就没法验证自己做得对不对。 - Cursor:
.cursorrules文件是指令来源,终端是工具,能读项目结构和 lint 配置。但状态管理相对弱,关掉 IDE 再打开,上次的上下文就没了。 - Codex:用 git worktree 隔离每个任务的运行环境,配合本地可观测性栈。它在有
AGENTS.md和清晰验证命令的仓库里,表现远超在"裸"仓库里。 - AutoGPT:反面教材。缺乏结构化的状态管理导致长任务中上下文不断累积,缺乏精确的反馈机制导致 agent 陷入循环。很多人说 AutoGPT"不行",但其实是它的 harness 不行。
遇到失败,先修 harness
核心原则只有一条:遇到失败,先别换模型,先检查 harness。
具体怎么做?每次失败都归因到具体层。不要笼统地说"模型不行",问自己:是任务没说清楚?是上下文不够?是没有验证手段?把每次失败归到五层防御里——任务规范、上下文供给、执行环境、验证反馈、状态管理。
然后,给每个任务写显式的完成定义。不要说"加个搜索功能",要说清楚:
完成标准:
- 新增 GET /api/search?q=xxx 端点
- 支持分页,默认 20 条
- 返回结果包含高亮片段
- 所有新代码通过 pytest
- 类型检查通过(mypy --strict)
一个 AGENTS.md 文件可能比你换一个更贵的模型更有效——这话不是开玩笑。
一个更接地气的例子
一个团队用 Claude Sonnet 给一个中等规模的 Python Web 应用(FastAPI + PostgreSQL + Redis,约 15,000 行代码)添加新的 API 端点。
起初他们只给了一句话:"在 /api/v2/users 下添加用户偏好设置端点"。结果 agent 花了 40% 的上下文窗口探索仓库结构,产出了看似合理的代码但没遵循项目的错误处理模式,用了旧版 SQLAlchemy 语法,宣称完成但端点实际有运行时错误。下一个会话还得重新做发现工作。
后来他们加了 AGENTS.md(描述项目架构和技术栈版本)、显式的验证命令(pytest tests/api/v2/ && python -m mypy src/)、和架构决策记录。同一模型在三次独立运行中全部成功,上下文使用效率提高了约 60%。
模型没变。变的还是 harness。
总结
- 模型能力和执行可靠性是两回事。
- 失败的时候先看 harness,再看模型。换模型是成本最高的选择,而且很多时候根本不是模型的问题。
- 每次失败都是一个信号:harness 有结构性缺陷,找出来、修掉。
- 遇到失败不要笼统地说"模型不行"。任务没交代清楚、上下文不够、环境没配好、验证手段缺失、上一个会话做到哪了新会话接不上——五个地方逐个排查,问题十有八九出在其中一层。
- 一个
AGENTS.md文件可能比你换一个更贵的模型更有效。
接下来两篇会展开具体怎么做:基础入门讲如何把仓库、会话和任务边界搭起来,进阶讲如何让 agent 做得对、看得见,并最终自动化运行。
参考资料: