Harness Engineering:Agent 写代码不难,难的是让它别乱写

本文首发地址 https://h89.cn/archives/610.html

2026 年 2 月,OpenAI Codex 团队发了一篇文章,里面有个数字很扎眼:

3 个工程师,5 个月,约 100 万行生产级代码,没有一行是人手写的。

他们大约合并了 1,500 个 Pull Request,人均每天 3.5 个 PR。OpenAI 的说法是,这个内部 beta 产品只用了传统手写开发大约 1/10 的时间。

他们没有拿到一个普通人用不到的神秘模型。差别在于,他们没有把 Agent 当成“更聪明的代码补全”,而是给 Agent 搭了一套可以稳定工作的工程环境。

这个东西后来被叫作 Harness Engineering。

但我一开始对这个词没什么感觉。直到我复盘一个 Android 车机图库项目,才发现:Agent 能不能交付复杂功能,核心不在于那次 prompt 写得多漂亮,而在于它有没有被放进一个足够清楚、足够硬的工程约束里。

封面


一、先看一个真实项目

这个项目是一个 Android 车机图库应用。

它不是 demo。它要处理 USB 设备插拔、多来源媒体、本地数据库、播放记录、图片预览、视频播放、车速安全限制、全屏交互、缩略图性能优化等一堆细节。

技术栈是 Kotlin + MVVM + Room + ExoPlayer,运行在 Android 车机系统上。最后从项目历史看,一共 38 个 commit,从骨架到完整功能基本都是 Agent 推进的。

大致演进路径是这样:

Phase 1: 搭骨架(commit 1-8)
  包拆分 + Koin DI + Room 数据库 + AGENTS.md 初稿

Phase 2: 建能力(commit 9-20)
  USB 扫描 + 媒体索引 + 播放记录 + DataStore 偏好设置

Phase 3: 做界面(commit 21-30)
  集锦列表 + USB 文件夹浏览 + 照片预览 + 视频播放

Phase 4: 打磨(commit 31-38)
  缩略图优化 + 全屏 UI + 选择态优化 + 构建验证

这个项目里最关键的文件不是某个 Activity,也不是某个 ViewModel,而是根目录里的 AGENTS.md

它只有 97 行,但内容很密:

  • 架构分层:UI Layer 到 ViewModel 到 DataSource,UI 不直接访问 DAO 和文件系统
  • 命名规范:Activity、Fragment、ViewModel、数据类怎么命名
  • 数据存储:Room 表结构、主键格式、DataStore Key 不能随意变更
  • 交互规则:USB 拔出时显示占位,缩略图短边固定 324dp,车速超过 15km/h 限制视频播放交互
  • 验证方式:通过 install.sh 编译 APK 并安装到车机

这份 AGENTS.md 不是一次写完的。它在项目里改了 15 次。

这点很重要。它不是“项目说明书”,更像是错误记录和工程边界的沉淀。Agent 每踩一次坑,工程师就把对应规则固化进去。

最典型的一次是 e1db227 这个 commit。当时 Agent 在开发照片预览功能,直接在 PhotoFragment 里调用了 mediaDao.queryById()。代码能跑,但违反了项目里的 MVVM 分层:UI 层不能直接访问 DAO。

工程师 review 时发现问题,回退并让 Agent 通过 ViewModel 获取数据。之后,AGENTS.md 里“UI Layer 不直接访问 DAO”的规则被加粗,职责划分也写得更具体。

这个 commit 同时改了代码和规则。

这就是 Harness 在真实项目里的样子:不是写一句“请注意架构规范”,而是把一次错误变成以后不会再犯的边界。

封面


二、Harness 到底解决什么问题

用 Agent 写一个函数,大多数人都已经不惊讶了。问题出在更长的任务上。

你让它实现一个完整功能,它会遇到这些情况:

  • 不知道项目里已有的约定,重新造一套写法
  • 为了让功能跑通,绕过原来的架构分层
  • 改了代码但没改文档,过几轮之后口径漂移
  • 单元测试能过,但真实设备上跑不起来
  • 反复改同一个文件,越修越偏
  • 新会话接手时,不知道上一次做到哪里

这些问题不是靠“prompt 写清楚点”就能解决的。

Prompt 解决一次交互怎么表达。Context 解决一次任务中给 Agent 哪些信息。Harness 解决的是:同一类任务反复交给 Agent 时,怎么让它稳定地按项目规则执行,并且能被验证、被纠正、被接续。

研发人员可以把它拆成四件事:

问题 Harness 要做的事 常见载体
Agent 不懂项目 把项目约定放进代码库 AGENTS.md / CLAUDE.md / docs
Agent 会绕规则 把关键约束变成自动检查 Hooks / Linter / 结构测试
Agent 不知道对错 给它持续反馈 CI / 测试 / 构建脚本 / Reviewer Agent
Agent 产出越多越乱 定期清理漂移和重复 lint 规则 / 清理 Agent / 重构任务

这四件事合起来,才是 Harness Engineering。

它听起来像一个新词,但本质上很工程:把口头提醒变成项目资产,把人工经验变成可重复执行的流程。


三、第一层:代码库本身就是真相源

Agent 最怕的不是不知道怎么写代码,而是不知道“这个项目里应该怎么写”。

在车机图库项目里,AGENTS.md 起到的作用就是把项目约定固定下来。比如:

## 架构约束
- UI Layer 只能和 ViewModel 交互,不能直接访问 DAO 或文件系统
- 数据读取通过 DataSource 封装
- Room 表字段和主键格式不得随意变更

## 验证方式
- 修改后运行 ./install.sh
- 编译失败或安装失败都不算完成

这类内容不应该写成“请写高质量代码”。那没有用。

有用的是 Agent 猜不到、但项目必须遵守的信息:目录结构、分层边界、命名约定、数据契约、构建命令、危险操作、验收标准。

OpenAI Codex 团队也踩过类似坑。他们尝试过把所有信息塞进一个巨大的 AGENTS.md,结果失败了。上下文窗口是稀缺资源,几百行说明会挤掉当前任务需要的代码和信息。

更好的做法是让 AGENTS.md 做导航:文件本身保持短,把架构、接口、业务规则拆到不同文档里。Agent 需要时再去读对应内容。

这就是第一层 Harness:代码库不是被动材料,而是 Agent 的工作说明、边界和记忆。


四、第二层:规则要能自动拦住错误

只写在 AGENTS.md 里的规则,本质上还是软约束。Agent 可能遵守,也可能在任务复杂时绕过去。

稳定的约束,要进入工具链。

Claude Code 的 Hooks 就是一个例子。按照官方文档,Hooks 由三层组成:

  1. Hook event:触发点,比如 PreToolUsePostToolUseUserPromptSubmitSessionStart
  2. Matcher group:匹配范围,比如只匹配 Bash,或只匹配 Edit|Write
  3. Hook handler:具体处理器,可以是 commandhttpmcp_toolpromptagent

最常见的用法是:

  • PreToolUse:在工具执行前拦截危险命令或敏感文件修改
  • PostToolUse:在文件修改后自动跑格式化、lint、测试或安全扫描
  • UserPromptSubmit:在用户输入进入模型前做检查或补充上下文

官方文档里还有一个容易写错的点:command hook 收到的是标准输入里的 JSON,不是命令行参数。比如要拦截 Bash 命令,脚本应该从 JSON 里读取 .tool_input.command,再通过 JSON 输出返回决策。要拒绝工具调用,应该返回 permissionDecision: "deny" 和原因。

这和“提醒 Agent 不要做危险操作”不是一个层级。

提醒是建议,Hook 是门禁。

在车机图库项目里,机械化约束还不够完整。它有 AGENTS.mdinstall.sh,但没有自动检查“UI 层是否直接引用 DAO”。这就是下一步可以补的地方:写一个结构测试或 Hook,扫描 Fragment / Activity 中是否出现 DAO 引用,发现就阻断。

这类规则一旦写好,后面每次 Agent 改代码都会自动检查。工程师不再靠肉眼一遍遍重复发现同一个问题。


五、第三层:反馈必须足够快

Agent 很容易在错误方向上继续努力。它不是故意偷懒,而是没有及时反馈。

反馈可以分四层:

层级 什么时候触发 反馈什么
即时反馈 工具调用前后 格式、安全、语法、架构违规
构建反馈 提交或 PR 时 测试、lint、类型检查、编译结果
运行反馈 部署或真机运行后 日志、性能、崩溃、设备兼容
评审反馈 功能完成后 需求遗漏、体验问题、边界场景

车机图库项目没有完整 CI/CD,因为它要跑在车机环境里,GitHub Actions 很难直接覆盖。但它有一个轻量反馈机制:install.sh

这个脚本会编译 APK,并通过 adb 安装到设备。编译失败、安装失败,都能马上反馈给 Agent。对这个项目来说,这比只跑单元测试更有价值,因为很多问题只有在 Android 构建和设备安装阶段才暴露。

Anthropic 在长时运行 Agent 的文章里也强调了类似问题:新会话没有旧会话记忆,如果没有外部状态记录,Agent 很容易重复劳动或接错进度。

他们的方案是两阶段:

阶段 Agent 产出
Phase 1 Initializer Agent init.sh、功能清单、进度文件
Phase 2 Coding Agent 增量实现、描述性 commit、端到端测试

每次新会话启动,都先读进度文件、看 git 历史、跑初始化脚本,再开始下一个任务。

这套机制解决的不是“模型记忆不够强”,而是把记忆从模型里拿出来,放到仓库、脚本和提交历史里。


六、第四层:Agent 产出越多,越要管理熵

AI 生成代码带来的质量问题,很多不是传统 bug。

它们更像缓慢退化:

类型 表现
文档漂移 注释和代码不一致,README 过期
架构侵蚀 为了快速完成任务绕过分层
风格不一致 同一个项目出现多种命名和实现模式
重复代码 已有能力不复用,又写一套相似实现

这些问题短期内不一定报错,但会让后续 Agent 和人类开发者越来越难理解代码库。

OpenAI Codex 团队的处理思路是,把代码质量标准尽量规则化。比如团队约定 API 响应必须用 snake_case,就不要只写在文档里,而是做成 linter 或结构测试。错误信息本身最好就是修复指南,让 Agent 看到后能直接改。

这句话很关键:

品味捕获一次,强制执行无限次。

但 Harness 也不能无限加复杂度。

Philipp Schmid 提到过一个提醒:Harness 必须设计成可删除的。今天需要复杂管线才能完成的任务,明天可能一个更强模型加一条提示就能搞定。Manus 团队 6 个月内重构了 Harness 5 次,Vercel 删除 80% 的 Agent 工具后效果反而更好,都是同一个方向:别把临时补丁做成永久负担。

所以 Harness 不是越多越好,而是越贴近真实失败模式越好。


七、外部案例说明了同一件事

回到开头的 OpenAI Codex 案例。

OpenAI 的重点不是“Agent 会写 100 万行代码”,而是他们围绕 Agent 建了完整工程环境:AGENTS.md、结构测试、CI、约束分层、定期清理。工程师的主要工作从手写代码,转向设计环境、明确意图、验证产出。

LangChain 的数据更直接。

他们在 Terminal Bench 2.0 上优化 deepagents-cli,模型保持 GPT-5.2-Codex 不变,只调整系统提示、工具和中间件 Hooks,分数从 52.8% 提升到 66.5%,排名从 30+ 到 Top 5。

对比维度 改善前 改善后
Terminal Bench 2.0 得分 52.8% 66.5%
排名 30+ Top 5
模型 GPT-5.2-Codex GPT-5.2-Codex
改动 - 系统提示 + 工具 + 中间件 Hooks

这说明一个现实问题:很多团队以为瓶颈是模型,其实瓶颈是运行环境。

Stripe 的 Minions 也是类似方向。公开报道里,Stripe 的自主编码 Agent 每周能产生 1,300 多个 PR,所有变更仍然需要人工 review,但代码本身不是人手写的。它背后依赖的是内部开发工具、CI、Blueprint、人工审核和大量系统约束。

这些案例规模不同,但结论一致:Agent 能不能稳定交付,不只取决于模型,还取决于你有没有把它放进一个可控的工程系统。


八、最小落地方案

如果你现在想开始,不需要先搭复杂平台。

第一步只做三件事:

  1. 在项目根目录写一个短的 AGENTS.mdCLAUDE.md
  2. 写清楚 5 类信息:技术栈、常用命令、架构边界、禁止事项、验证方式
  3. 每次 Agent 犯错后,只补一条能防止复发的规则

一个可用的最小模板是:

# AGENTS.md

## 项目概况
- 语言/框架:Kotlin + Android + MVVM
- 构建命令:./install.sh

## 架构边界
- UI 层只和 ViewModel 交互
- UI 层禁止直接访问 DAO、文件系统和网络请求
- 数据读取统一通过 DataSource

## 数据约定
- Room 表结构变更必须同步迁移
- DataStore Key 不能重命名,除非同时处理兼容

## 禁止事项
- 禁止修改 .env、密钥、签名文件
- 禁止绕过构建脚本直接声称完成

## 完成标准
- 代码修改后必须运行 ./install.sh
- 编译、安装、关键页面启动都通过,才算完成

等这份文件稳定下来,再补第二层:Hook、linter、结构测试。

不要一开始就做大而全的平台。先抓最常见、最贵、最容易复发的错误。

比如车机图库项目里,最值得补的不是“自动优化所有代码质量”,而是一个很具体的检查:Fragment 和 Activity 不能直接引用 DAO。这个规则一旦机械化,之前 PhotoFragment 直接访问 mediaDao 的问题就不会反复出现。


九、冷一点看

Harness Engineering 解决不了所有问题。

它解决的是“Agent 在工程环境里稳定工作”的问题,不保证业务判断一定正确。

Linter 能抓格式,结构测试能抓分层,CI 能抓编译和测试,但这些东西未必能判断“用户注册流程是不是应该加邮箱验证”“车速限制的交互是不是符合真实驾驶场景”。这部分仍然需要产品判断、领域经验和人工 review。

另一个问题是遗留项目。新项目从第一天就写 AGENTS.md、加测试、设计边界,难度还可控。一个已经有几十万行历史代码、约定不统一、测试不足的项目,要给 Agent 搭 Harness,会困难很多。

所以不要把 Harness 理解成“让人退出开发”。更准确的说法是:工程师少写一部分重复代码,但要多做环境设计、约束设计和验证设计。

对大多数团队来说,模型能力越来越难形成长期差异;可积累的,是围绕自己项目沉淀下来的规则、脚本、测试、文档和执行轨迹。

前期投入 30 分钟写清楚项目规则,后面每次会话少解释 5 分钟。更重要的是,Agent 少犯一次架构错误,你省下的可能不是 5 分钟,而是一轮 review、返工和回归测试。

这才是 Harness Engineering 值得关注的原因。


参考与延伸阅读

  1. Harness engineering: leveraging Codex in an agent-first world - OpenAI,2026 年 2 月
  2. Unlocking the Codex harness: how we built the App Server - OpenAI,2026 年 2 月
  3. Unrolling the Codex agent loop - OpenAI,2026 年 1 月
  4. Effective context engineering for AI agents - Anthropic,2025 年 9 月
  5. Effective harnesses for long-running agents - Anthropic,2025 年 11 月
  6. Harness design for long-running application development - Anthropic,2026 年 3 月
  7. My AI Adoption Journey - Mitchell Hashimoto,2026 年 2 月
  8. Improving Deep Agents with harness engineering - LangChain,2026 年 3 月
  9. GStack - Garry Tan
  10. Stripe Engineers Deploy Minions, Autonomous Agents Producing Thousands of Pull Requests Weekly - InfoQ,2026 年 3 月

本文链接:Harness Engineering:Agent 写代码不难,难的是让它别乱写 - https://h89.cn/archives/610.html

版权声明:原创文章 遵循 CC 4.0 BY-SA 版权协议,转载请附上原文链接和本声明。

标签: Harness, AGENTS, CLAUDE, Engineering

🎓 呈言英语 智能英语学习平台
📚单词学习 🎧听说练习 📖阅读理解 ✏️拼写练习 🌟 AI智能推荐 · 科学记忆曲线
🚀 立即开始免费学习

添加新评论