为什么强大的模型仍然会失败?learn-harness-engineering 第一课:模型能力不等于可靠执行

原创2026-09-21 18:58:361,346 阅读

为什么强大的模型仍然会失败?learn-harness-engineering 第一课:模型能力不等于可靠执行

导读:本篇文章以 learn-harness-engineering 仓库中 docs/ar/lectures/lecture-01-why-capable-agents-still-fail/index.md(第一讲:Strong Models Don't Mean Reliable Execution)为核心,讲解一个反直觉的事实——当 AI 编程智能体搞砸任务时,问题往往不在模型本身,而在于模型之外的一切。读完本文,你将掌握五层防御的诊断框架、可落地的 AGENTS.md 与 Definition of Done 写法,并能在仓库配套的 Project 01 对照实验中亲手验证"同一个模型在弱 Harness 与完整 Harness 下产出天差地别"这一结论。

能力不等于可靠:Capability Gap 从何而来

截至 2025 年底,最强编程智能体在 SWE-bench Verified 上的通过率大约只有 50%–60%。这个数字初看不错,但请注意其构成:那是经过精挑细选的任务、清晰的 Issue 描述、现成的测试用例。一旦把日常需求交给智能体——模糊的规格、没有存量测试、散落在代码库各处的隐式业务规则——通过率只会进一步下降。原文档给出的场景非常典型:智能体运行 20 分钟然后自信地告诉你"全部完成",你打开代码却发现它加了功能却弄坏了测试、修了一个 bug 却引入两个新 bug,甚至产出的根本不是你要的东西。

这就是 Capability Gap(能力落差):模型在基准测试上的表现与在真实任务中的表现之间存在巨大鸿沟。SWE-bench Verified 上 50%–60% 的通过率意味着,几乎一半的真实 Issue 没有被解决。

大多数人的第一反应是"模型不够好,换个更贵的"。但在掏钱包之前,请先认真考虑一个可能性:问题根本不在模型。

同一匹马,不同的命运:Anthropic 的对照实验

原文档引用了一个极具说服力的对照实验(Anthropic 官方博客《Effective Harnesses for Long-Running Agents》所描述的实验):

  • 提示词相同:"构建一个 2D 复古游戏编辑器";
  • 模型相同:Opus 4.5;
  • 第一次运行:裸奔、无任何支持——20 分钟、9 美元,游戏核心功能根本无法工作;
  • 第二次运行:完整的 Harness(规划器 + 生成器 + 评估器的三智能体架构)——6 小时、200 美元,游戏完全可玩。

他们没有换模型。Opus 4.5 还是那个 Opus 4.5,改变的只是"马的装备"(tack)。OpenAI 2025 年关于 Harness 工程的文章说得更直接:在 Harness 良好的仓库中,Codex 从"不可靠"直接跃迁到"可靠"——注意措辞,不是"好了一点",而是质变。

这里的 Harness 定义是:模型权重之外的全部工程基础设施——指令、工具、环境、状态管理、验证反馈。凡不是模型权重,就属于 Harness。

智能体到底在哪里"卡住":五种典型失败模式

原文档把具体失败模式归结为五类,每一种都对应一个可以在本仓库中找到证据的工程问题。

1. 需求模糊——智能体只能靠猜

"加一个搜索功能"这句话几乎等于什么都没说。搜索什么?全文检索还是结构化数据?结果要不要分页?要不要高亮?你没说清楚,智能体就只能猜。猜对了是运气,猜错了返工成本是当初说清楚的好几倍。

本仓库用两个配套文件把这种失败具象化:

  • underspecified-task.md 给出了一个典型的欠定义任务示例:"构建一个带 AI 问答的知识库桌面应用",限制条件一栏全是"未指定":未指定任何约束、未给出运行命令、未提供目录结构指引、未定义数据模型、没有显式的完成标准。文档明确列出这类 prompt 的典型结果:智能体自行发明结构、应用能编译却无法稳定启动、界面先于可用的导入/查询路径出现、智能体经常在"看起来成功"之后就停下。

2. 隐式约定没有写下来——智能体无从遵守

团队全员都在用 SQLAlchemy 2.0 语法,但智能体默认写 1.x 代码;所有 API 端点必须走 OAuth 2.0 认证,但这条规则只存在于你的头脑和三个月前的一条 Slack 消息里。智能体不知道——不是不想遵守,而是字面上从未见过这条规则。

3. 环境不完整——智能体把精力花在修环境上

开发环境不完整、依赖缺失、工具版本错误。智能体把宝贵的上下文窗口烧在 pip install 报错和 Node 版本冲突上,而不是解决你交给它的实际任务。原文档的比喻很贴切:你请了一位熟练的木匠,却忘了给他锤子、钉子和一张平整的工作台——无论他多熟练,都无法开工。

4. 没有验证手段——智能体"感觉完成"就算完成

没有测试、没有 lint,或者验证命令从未传达给智能体。它写完代码、看一眼、觉得没问题、宣布完成。Anthropic 还观察到一种有趣的现象:当智能体感知到上下文即将耗尽时,会匆忙收尾、跳过验证步骤、选择简单方案而非最优方案——他们把这种现象称为 context anxiety(上下文焦虑),就像考试快结束时开始蒙答案一样。

本仓库的 failure-pattern-demo.ts 用一段可运行的 TypeScript 把上述"能力足够却仍然失败"的路径模拟成了四步:

  1. Incomplete Context(上下文不完整):只有项目结构和路由定义,缺少 auth 中间件、限流策略、测试标准;
  2. Locally Reasonable Changes(局部合理的改动):加上 auth 后局部看起来完整,但全局看仍缺限流;
  3. No Global Verification(缺乏全局验证):功能表面完整,但没有测试,回归风险与标准违背;
  4. Premature Completion(过早完成):智能体输出"Done. Added search endpoint.",任务被标记完成,实际上不完整。

你可以直接用 npx tsx docs/ar/lectures/lecture-01-why-capable-agents-still-fail/code/failure-pattern-demo.ts 运行它,终端会打印每一步的"可用上下文 / 缺失上下文 / 采取动作 / 局部结果 / 全局影响",最后汇总一张对比表,展示 5 项必要上下文里缺了几项——这个脚本本身就是对"每一步孤立看都很合理"这一核心失败模式的演示。

配套的 failure-signals-checklist.md 则是一份复盘清单,用于审查弱 Harness 运行的产物:智能体是否问过或猜错了应用的运行方式?是否创建了与目标产品不匹配的目录或抽象?是否在搭好可见 UI 骨架后停步而没有完整工作流?是否留下便于后续会话接手的备注?一个新会话能否在五分钟内理解之前发生了什么?

5. 跨会话状态丢失——每个新会话从零开始

上一个会话的所有发现全部丢失,每个新会话都要重新探索项目结构、重新理解代码组织。原文档给出的经验阈值是:没有持久状态的智能体,在超过 30 分钟的任务上失败率急剧上升。

核心术语一览

原文档在描述完这些场景后,给出了六个不再只是"行话"的核心概念:

术语 含义
Capability Gap 模型在基准测试与真实任务之间的表现落差;SWE-bench Verified 50%–60% 意味着近半真实 Issue 无法解决
Harness 模型之外的一切——指令、工具、环境、状态管理、验证反馈;不是模型权重,就是 Harness
Harness-Induced Failure 模型能力足够,但执行环境存在结构性缺陷;Anthropic 的对照实验已证明这一点
Verification Gap 智能体对输出的自信与实际正确性之间的差距;"说完成了其实没完成"是最常见的失败模式
Diagnostic Loop 执行 → 观察失败 → 归因到特定 Harness 层 → 修复该层 → 重新执行;这是 Harness 工程的核心方法论
Definition of Done 一组可用命令验证的条件——测试通过、lint 干净、类型检查通过;没有显式的完成定义,智能体就会发明它自己的定义

失败时先修 Harness:五层防御与实操步骤

原文档的核心原则只有一条:当事情失败时,不要先换模型——先检查 Harness。 如果同一个模型在类似的、结构良好的任务上能成功,那就假定问题是 Harness 的问题,而不是模型的问题。就像汽车抛锚,不要立刻假设发动机坏了,先检查是不是没油了。

把每个失败归因到具体层

不要说"模型不行"。问自己:任务不清晰吗?上下文不充分吗?没有验证手段吗?把每个失败映射到五个防御层之一:

  1. 任务规格(task specification)——任务是否被明确定义;
  2. 上下文供给(context provision)——智能体是否拿到了足够的相关信息;
  3. 执行环境(execution environment)——环境是否完整、工具版本是否正确;
  4. 验证反馈(verification feedback)——是否有测试、lint、类型检查并已传达给智能体;
  5. 状态管理(state management)——跨会话的发现是否被持久化。

养成这个习惯后,你会发现在日志里"模型不够好"这句话出现得越来越少。

为每个任务写显式的 Definition of Done

不要说"加一个搜索功能",要像原文档给出的示例一样写清楚:

Completion criteria:
- New endpoint GET /api/search?q=xxx
- Supports pagination, default 20 items
- Results include highlighted snippets
- All new code passes pytest
- Type checking passes (mypy --strict)

这份清单必须全部可由命令验证——这正是"Definition of Done 是一组可用命令验证的条件"这一术语定义在实践中的落点。

创建 AGENTS.md

在仓库根目录放置一个 AGENTS.md 文件,告诉智能体项目的技术栈、架构约定和验证命令。原文档强调:这是 Harness 工程的第一步,也是投入产出比最高的一步——一个 AGENTS.md 文件可能比升级到更贵的模型更有效,这并非玩笑。

本仓库的 projects/project-01/solution/AGENTS.md 就是一个可以直接对照学习的范本,它包含四个关键区块:

  • Startup Rules(启动规则):写任何代码之前,按顺序完成——完整阅读本文件、阅读 docs/ARCHITECTURE.md 理解 Electron 分层结构、阅读 docs/PRODUCT.md 理解功能需求、运行 bash init.sh 验证构建干净、读取 feature_list.json 查看全部功能状态;
  • Electron Layer Boundaries(分层边界):严格定义 main / preload / renderer / services 四层各自的职责与禁止事项(例如 renderer 永不导入 Node 模块、preload 是主进程与渲染进程之间的唯一桥);
  • Conventions(约定):TypeScript 严格模式、只使用命名导出、IPC 频道名统一定义在 src/shared/types.ts、渲染进程禁用同步 I/O;
  • Definition of Done:TypeScript 编译通过(npm run check)、应用可启动且窗口可见(npm run dev)、功能在 feature_list.json 中标记为 "pass" 并附证据、遵守分层边界、正常运行无控制台错误。

配套的 feature_list.json 展示了"以功能清单作为进度的唯一事实源"的实践:每个功能有 id、name、description、status(pass / fail / not-started)、evidence(验收证据)与 testedAt 时间戳。例如 window-launch 的 evidence 写明了"npm run dev 以 1200x800 启动窗口,contextIsolation=true 且 nodeIntegration=false"——这就是可验证的完成标准。

建立诊断循环并度量改进

不要把失败当作"智能体又犯蠢了",而要当作 Harness 暴露缺陷的信号。每次失败:识别层 → 修复 → 确保不再以同样方式失败。几轮之后 Harness 变强、智能体表现趋于稳定。同时维护一个简单日志:每个任务成功还是失败、是哪个层导致的失败。几轮之后你就会看出哪个层是瓶颈,把精力集中在那里。

百万行实验:OpenAI 的 Codex 实践

原文档记录了 OpenAI 2025 年的一个大胆实验:人类绝不直接写代码,只由 Codex 写。从空的 Git 仓库开始,五个月后仓库里有了约一百万行代码——应用逻辑、基础设施、工具、文档、内部开发工具,全部由智能体生成。三名工程师共开合并约 1,500 个 PR,平均每人每天 3.5 个。

初始进展出奇地慢——不是因为 Codex 不行,而是环境不够完整:智能体缺少朝高层目标推进所需的工具、抽象和内部结构。三名工程师逐渐摸索出模式:把大目标拆成小积木(设计、编码、评审、测试),让智能体逐个拼装,再用这些积木去组合更复杂的任务。当某件事失败时,问题几乎从来不是"不够努力",而是"智能体还缺什么能力,以及如何让这个缺失的能力变得可理解、可执行"。

这个实验直接证明了本讲的核心论点:同一个模型,在裸环境与完整 Harness 环境中,产出的结果有本质差异。模型没变,环境变了。

更接地气的例子:Claude Sonnet 与一个中型 Python 项目

原文档还给出了一个更贴近日常的场景:一个团队用 Claude Sonnet 给一个中型 Python Web 应用(FastAPI + PostgreSQL + Redis,约 15,000 行代码)添加新的 API 端点。

  • 第一轮:只给一句话——"add user preferences endpoints under /api/v2/users"。结果:智能体把 40% 的上下文窗口烧在探索仓库结构上,产出的代码看似合理但不遵循项目的错误处理模式、使用了过时的 SQLAlchemy 语法,还宣布完成——实际上端点存在运行时错误,下一个会话不得不重做全部探索工作;
  • 第二轮:加入 AGENTS.md(描述项目架构与技术栈版本)、显式验证命令(pytest tests/api/v2/ && python -m mypy src/)和架构决策记录。同一个模型在三次独立运行中全部成功,上下文效率提升约 60%。

他们没有换模型。他们换了 Harness。

项目实战印证:Project 01 对照实验

这一讲在仓库中对应的实操项目是 projects/project-01-baseline-vs-minimal-harness/index.md(Project 01: Baseline vs Minimal Harness),其设计意图与本讲内容严丝合缝:对比弱 Harness(仅 prompt)与显式 Harness(规则文件 + 验证机制)对智能体任务完成率的影响。

  • starter/ 是起点:只有一个模糊的 task-prompt.md,全文只有一句话——"Build an Electron app that can show documents and answer questions.",没有 AGENTS.md、没有 feature_list.json。这就是"弱 Harness"版本;
  • solution/ 是参考实现:同样的应用代码,但配齐了完整 Harness 文件(AGENTS.md、feature_list.json、init.sh、claude-progress.md、docs/ARCHITECTURE.md 与 docs/PRODUCT.md)。

对照实验的进行方式(只读地运行与对比,无需修改仓库):

# 1. 先用 starter(弱 Harness)跑一次
cd starter
npm install
# 把 task-prompt.md 的内容作为 prompt 交给 Claude Code / Codex
# 要求智能体完成:窗口启动、文档列表、QA 面板、数据目录四项功能
# 本次运行不要给智能体 solution 的文件

# 2. 用 solution(显式 Harness)跑同一任务
cd ../solution
npm install
# 让智能体在碰代码之前先读 AGENTS.md、init.sh、feature_list.json、claude-progress.md

# 3. 对比两次结果
# - 任务是否完成?
# - 需要多少次重试?
# - 智能体是否过早宣布"完成"?

其中 init.sh 用 set -euo pipefail 严格地按顺序执行三步:npm install → npm run check(类型检查)→ npm run build(构建),任何一步失败立即中断——这正是"写代码之前先验证环境干净"的工程化落地,也对应原文档五层防御中的"执行环境"与"验证反馈"两层。

项目用一张功能对照表来度量完成度:窗口启动对应 src/main/main.ts 与 feature_list.json 的 window-launch、文档列表面板对应 src/renderer/components/DocumentList.tsx 与 document-list、问答面板对应 QuestionPanel.tsx 与 question-panel、数据目录对应 src/services/persistence-service.ts 与 data-directory。项目的明确定位是"对照实验而非普通填空作业",学习成果就是测量出 prompt-only 运行与"从显式仓库规则和验证产物出发"运行之间的可量化差异——把本讲的核心论点变成一次可重复的实验。

核心结论

  • 模型能力与执行可靠性是两回事。即便是纯血统的赛马,也需要好的装备;
  • 失败时先查 Harness,再查模型。换模型是最贵的选择,而且多数时候根本不是模型的问题;
  • 每个失败都是一个信号:你的 Harness 有结构性缺陷,找到它、修复它;
  • 系统地走完五层防御:任务未明确定义、上下文不足、环境配置错误、缺少验证、会话间状态丢失——十有八九问题出在这五层中的某一层;
  • 一个 AGENTS.md 文件可能比升级到更贵的模型更有效。

练习建议

  1. 对照实验:选一个你熟悉的代码库和一个非平凡的修改任务。先不带任何 Harness 支持运行智能体并记录失败;然后加入 AGENTS.md 和显式验证命令,用同一个智能体再跑一次。对比两次结果,把每个失败归因到五层防御之一。

  2. 度量 Verification Gap:选 5 个编程任务。每个任务完成后记录智能体是否声称完成,再用独立测试验证真实正确性。计算"声称完成但实际未完成"的比例——这就是你的 Verification Gap。然后思考:什么验证命令能降低这个比例?

  3. 训练诊断循环:在项目里找一个智能体反复失败的任务。跑一次并记录失败,归因到五层之一,修复那一层,再跑一次。重复 3–5 轮,逐轮记录改进。

  4. 阅读配套代码:运行 failure-pattern-demo.ts 观察四步失败模式,对照 failure-signals-checklist.md 审查一次你最近的智能体运行产物,再结合 Project 01 完成一次完整的强弱 Harness 对比实验。

登录后查看全文
learn-harness-engineering