Harness Engineering的介绍与实践
这篇文章想讨论一个最近越来越频繁出现的词:Harness Engineering。如果说提示词工程解决的是“怎么和模型说话”,上下文工程解决的是“给模型看什么资料”,那么 Harness Engineering 关心的就是:如何搭一个系统,让 AI 代理能安全、稳定、可验证地完成工程任务。
一、为什么会出现 Harness Engineering
过去两年,AI 编程工具的能力变化很快。
一开始,我们更多是在和模型聊天:让它解释代码、生成函数、补全脚本。这个阶段的重点是 Prompt Engineering,也就是把需求说清楚。
后来,大家发现只会写提示词还不够。模型如果不了解项目结构、接口约定、历史设计和运行方式,就很容易一本正经地胡说八道。于是 Context Engineering 变得重要:要把正确的文件、文档、错误日志、接口说明和项目约束放进上下文里。
但当 AI 从“问答助手”变成“能自己改文件、运行命令、修复测试、提交补丁的代理”时,问题又变了。
它不只是会不会答对,而是会不会:
- 改错文件;
- 破坏已有架构;
- 忽略测试失败;
- 反复在错误假设上打补丁;
- 在长任务里丢失目标;
- 执行高风险命令。
这些问题不是单靠一句“请你小心一点”就能解决的。我们需要一套工程系统,把 AI 的行为放到可控轨道里。这套系统,就是 Harness。
一个比较好理解的公式是:
Agent = Model + Harness
模型提供推理能力,Harness 提供环境、工具、约束、状态和反馈。没有 Harness,模型只是一个会说话的大脑;有了 Harness,它才更接近一个能做事的工程代理。
二、Harness 到底是什么
Harness 这个词可以理解成“支架”“线束”“测试夹具”或者“护栏系统”。放在 AI 编程里,它不是某一个工具,而是一整套围绕模型运转的工程控制层。
它至少包括以下几件事:
- 上下文管理:让代理知道项目结构、编码规范、任务目标和相关文件。
- 工具接口:允许代理读取文件、搜索代码、运行测试、调用 API。
- 执行沙盒:让代理的命令在隔离环境中运行,避免误伤真实环境。
- 约束规则:通过 lint、类型检查、架构规则、权限控制限制越界行为。
- 验证循环:把测试失败、构建错误、审查意见反馈给代理,让它继续修正。
- 人工闸门:在删除文件、部署生产、修改核心配置等高风险操作前要求人工确认。
所以 Harness Engineering 的重点,不是写一个更长的提示词,而是设计一个让 AI 可以反复试错、及时纠偏、最终收敛的工程环境。
三、从 Prompt 到 Context,再到 Harness
我理解这三个概念可以这样区分:
| 阶段 | 关注点 | 典型问题 | 解决方式 |
|---|---|---|---|
| Prompt Engineering | 怎么表达任务 | 需求描述不清 | 角色、步骤、示例、输出格式 |
| Context Engineering | 给什么信息 | 模型不了解项目事实 | 检索文件、注入文档、压缩上下文 |
| Harness Engineering | 如何控制执行 | 代理行为不可控 | 沙盒、工具、约束、验证和人工闸门 |
这三个阶段不是互相替代,而是层层叠加。
一个好的提示词能让模型更容易理解任务;一个好的上下文能减少幻觉;一个好的 Harness 则能把“不确定的智能”放进“确定的工程流程”里。
四、一个 AI 编程 Harness 应该包含什么
如果要在团队里落地,我觉得可以把 Harness 拆成五层。
1. 项目地图层
AI 代理进入项目时,最怕两件事:不知道入口在哪里,以及不知道什么不能碰。
所以项目最好有一个轻量的说明文件,比如 AGENTS.md、CLAUDE.md 或者团队内部约定的工程手册。它不需要长篇大论,重点是告诉代理:
- 项目是什么技术栈;
- 源码、测试、配置分别在哪里;
- 常用构建和测试命令是什么;
- 代码分层和依赖方向是什么;
- 哪些目录不能手动修改;
- 常见坑和禁止模式是什么。
这个文件相当于代理的“世界地图”。比起把所有信息一次性塞进提示词,更好的方式是提供索引,让代理按需读取。
2. 工具层
模型本身不会真的“看见”仓库,它需要工具。
最基础的工具包括:
read_file:读取文件;grep/rg:搜索代码;list_files:了解目录结构;shell:运行测试和构建;apply_patch:以可审查的方式修改文件;git diff:查看变更范围。
工具设计其实是 AI 代理的用户体验。工具太少,代理只能猜;工具太散,代理容易乱试;工具权限太大,又会带来安全风险。
因此比较理想的做法是:给代理足够完成任务的工具,但把危险能力放到审批之后。
3. 沙盒层
让 AI 运行命令之前,必须先回答一个问题:它失败的时候会不会伤到真实环境?
沙盒的价值就在这里。它可以限制文件写入范围、网络访问、危险命令、环境变量和系统权限。对 AI 编程来说,沙盒不是锦上添花,而是底线。
比如:
- 修改代码只允许发生在当前工作区;
- 访问外部网络需要显式批准;
- 删除文件、重置分支、部署服务需要人工确认;
- 测试写临时文件时限制在指定目录;
- 密钥和生产配置不直接暴露给代理。
这类约束看似麻烦,但它让我们敢于把更多任务交给 AI。
4. 验证层
AI 生成代码最大的风险,不是语法错误,而是“看起来很对”。
Harness 需要把验证做成闭环,让代理不能只凭自信结束任务。常见的验证信号包括:
- 格式化检查;
- lint;
- 类型检查;
- 单元测试;
- 集成测试;
- 构建结果;
- 静态安全扫描;
- 人工 review。
这些验证信号可以分层执行。越便宜、越快的检查越应该前置,例如格式化、lint、类型检查;越昂贵的检查可以放到 CI 或人工验收阶段。
关键是:失败信息要能回到代理手里,形成“修改 → 验证 → 读取错误 → 再修改”的循环。否则测试只是拦截器,不是 Harness 的反馈系统。
5. 收敛层
长任务里,AI 很容易出现一种情况:修 A 引入 B,修 B 又破坏 C,最后越改越偏。
所以 Harness 需要定义“什么时候算完成”。这个完成条件不能只靠模型说“我已经完成了”,而应该来自外部事实:
- 目标文件已修改;
- 相关测试通过;
- 构建通过;
- diff 范围符合预期;
- 没有无关文件变更;
- 高风险操作已被用户确认;
- 最终说明能对应实际变更。
当这些条件都满足时,任务才算收敛。反过来,如果代理连续多次在同一个错误上失败,Harness 也应该让它停下来重新分析,而不是继续盲目尝试。
五、一个小型实践流程
以“让 AI 修复一个后端接口 bug”为例,一个 Harness 化的流程可以这样设计:
- 任务输入:用户描述 bug,并给出复现方式。
- 上下文收集:代理搜索接口、测试、日志和最近相关提交。
- 计划生成:代理给出修改计划,明确将触碰哪些文件。
- 受控修改:代理通过 patch 修改代码,而不是随意重写整个模块。
- 局部验证:运行最相关的单元测试。
- 失败反馈:如果测试失败,把错误日志重新交给代理分析。
- 扩展验证:局部测试通过后,再运行更大范围测试。
- 人工验收:输出变更摘要、验证命令和风险点。
这套流程里的重点不是“AI 一次写对”,而是允许它在受控环境里多次尝试,并且每次尝试都有清晰反馈。
六、AGENTS.md 是最低成本的 Harness
对个人项目或小团队来说,不一定一开始就要搭复杂平台。最简单、最有效的第一步,是维护好项目根目录的 AGENTS.md。
一个实用的 AGENTS.md 可以包含:
# 项目说明
## 技术栈
- Hugo static site
- 自定义 thinkblog 主题
## 常用命令
- hugo server -D
- hugo
## 目录约定
- content/post/ 存放文章
- themes/thinkblog/ 存放主题源码
- public/ 为构建产物,不要手动编辑
## 修改原则
- 优先小步修改
- 不要混入无关格式化
- 修改主题后需要验证首页、详情页、列表页和搜索页
这就是一个非常朴素的 Harness:它在代理行动前给出导引,在代理行动后要求验证。
如果某类错误反复出现,就把它写进 AGENTS.md。这相当于给代理增加项目级长期记忆。
七、常见误区
1. 把 Harness 等同于提示词模板
提示词模板只是 Harness 的一小部分。真正的 Harness 一定包含外部验证和执行约束。
如果一个系统只能告诉 AI“请遵守规范”,却不能在它违反规范时发现并阻止,那它还只是建议,不是护栏。
2. 把所有知识塞进一个大文件
超长说明文件会稀释重点。更好的做法是使用“入口索引 + 按需读取”。
入口文件只写最关键的信息,然后链接到更细的文档、脚本和测试说明。这样既节省上下文,也能降低模型漏读关键约束的概率。
3. 只追求模型升级
更强的模型当然有用,但模型能力不是可靠性的全部来源。
如果没有测试、没有沙盒、没有权限边界、没有人工闸门,再强的模型也可能在错误路径上高速前进。Harness 的意义,就是用软件工程的方法对冲模型的不确定性。
4. 不区分任务风险
改文案、补测试、修 lint 和迁移数据库,风险完全不同。
Harness 应该按风险分级:
- 低风险任务可以自动完成;
- 中风险任务需要运行验证;
- 高风险任务需要人工确认;
- 生产操作必须有独立审批。
八、如何衡量 Harness 是否有效
一个 Harness 好不好,不能只看演示效果,而要看长期指标。
可以关注这些数据:
- 任务解决率:AI 在无人介入情况下完成任务并通过验证的比例。
- 首次通过率:第一次修改就通过测试的比例。
- 返工率:AI 生成代码合并后,需要人工二次修复的比例。
- 无关变更率:一次任务中混入不相关改动的比例。
- 验证覆盖率:关键路径是否有自动化检查兜底。
- 人工中断次数:高风险操作是否被正确拦截。
这些指标能帮助团队判断:问题到底是模型不行、上下文不够,还是 Harness 的反馈和约束设计不合理。
九、我的理解
Harness Engineering 的本质,是把 AI 编程从“相信模型”变成“相信系统”。
模型负责生成可能的解决方案,Harness 负责让这些方案在工程环境里接受检验。通过上下文导引、沙盒隔离、工具约束、自动化测试和人工闸门,我们可以把 AI 的高产出能力转化为可落地的工程生产力。
未来程序员的工作不会只是写代码,也会越来越多地变成:
- 设计任务边界;
- 编写项目规则;
- 维护验证体系;
- 建立自动化反馈;
- 审查 AI 无法自证的部分。
也就是说,AI 负责编码速度,人类负责工程确定性。
当 AI 写代码的速度超过人类逐行阅读的速度时,真正值得信任的不是某一次生成结果,而是背后那套能够持续发现问题、限制风险并推动收敛的 Harness。
参考资料
- 本地参考稿:《AI Harness 工程详解与实践》
- 知乎参考链接:https://zhuanlan.zhihu.com/p/2021716359613032366
- LangChain Blog: The rise of context engineering
- Agents Cookbook: Harness engineering
- Thoughtworks: Patterns for building effective AI coding assistants
版权声明: 本文首发于 指尖魔法屋-Harness Engineering的介绍与实践(https://blog.thinkmoon.cn/post/993_harness-engineering%E7%9A%84%E4%BB%8B%E7%BB%8D%E4%B8%8E%E5%AE%9E%E8%B7%B5/) 转载或引用必须申明原指尖魔法屋来源及源地址!