Harness Engineering的介绍与实践

这篇文章想讨论一个最近越来越频繁出现的词:Harness Engineering。如果说提示词工程解决的是“怎么和模型说话”,上下文工程解决的是“给模型看什么资料”,那么 Harness Engineering 关心的就是:如何搭一个系统,让 AI 代理能安全、稳定、可验证地完成工程任务。

一、为什么会出现 Harness Engineering

过去两年,AI 编程工具的能力变化很快。

一开始,我们更多是在和模型聊天:让它解释代码、生成函数、补全脚本。这个阶段的重点是 Prompt Engineering,也就是把需求说清楚。

后来,大家发现只会写提示词还不够。模型如果不了解项目结构、接口约定、历史设计和运行方式,就很容易一本正经地胡说八道。于是 Context Engineering 变得重要:要把正确的文件、文档、错误日志、接口说明和项目约束放进上下文里。

但当 AI 从“问答助手”变成“能自己改文件、运行命令、修复测试、提交补丁的代理”时,问题又变了。

它不只是会不会答对,而是会不会:

  1. 改错文件;
  2. 破坏已有架构;
  3. 忽略测试失败;
  4. 反复在错误假设上打补丁;
  5. 在长任务里丢失目标;
  6. 执行高风险命令。

这些问题不是单靠一句“请你小心一点”就能解决的。我们需要一套工程系统,把 AI 的行为放到可控轨道里。这套系统,就是 Harness。

一个比较好理解的公式是:

Agent = Model + Harness

模型提供推理能力,Harness 提供环境、工具、约束、状态和反馈。没有 Harness,模型只是一个会说话的大脑;有了 Harness,它才更接近一个能做事的工程代理。

二、Harness 到底是什么

Harness 这个词可以理解成“支架”“线束”“测试夹具”或者“护栏系统”。放在 AI 编程里,它不是某一个工具,而是一整套围绕模型运转的工程控制层。

它至少包括以下几件事:

  1. 上下文管理:让代理知道项目结构、编码规范、任务目标和相关文件。
  2. 工具接口:允许代理读取文件、搜索代码、运行测试、调用 API。
  3. 执行沙盒:让代理的命令在隔离环境中运行,避免误伤真实环境。
  4. 约束规则:通过 lint、类型检查、架构规则、权限控制限制越界行为。
  5. 验证循环:把测试失败、构建错误、审查意见反馈给代理,让它继续修正。
  6. 人工闸门:在删除文件、部署生产、修改核心配置等高风险操作前要求人工确认。

所以 Harness Engineering 的重点,不是写一个更长的提示词,而是设计一个让 AI 可以反复试错、及时纠偏、最终收敛的工程环境。

三、从 Prompt 到 Context,再到 Harness

我理解这三个概念可以这样区分:

阶段关注点典型问题解决方式
Prompt Engineering怎么表达任务需求描述不清角色、步骤、示例、输出格式
Context Engineering给什么信息模型不了解项目事实检索文件、注入文档、压缩上下文
Harness Engineering如何控制执行代理行为不可控沙盒、工具、约束、验证和人工闸门

这三个阶段不是互相替代,而是层层叠加。

一个好的提示词能让模型更容易理解任务;一个好的上下文能减少幻觉;一个好的 Harness 则能把“不确定的智能”放进“确定的工程流程”里。

四、一个 AI 编程 Harness 应该包含什么

如果要在团队里落地,我觉得可以把 Harness 拆成五层。

1. 项目地图层

AI 代理进入项目时,最怕两件事:不知道入口在哪里,以及不知道什么不能碰。

所以项目最好有一个轻量的说明文件,比如 AGENTS.mdCLAUDE.md 或者团队内部约定的工程手册。它不需要长篇大论,重点是告诉代理:

  1. 项目是什么技术栈;
  2. 源码、测试、配置分别在哪里;
  3. 常用构建和测试命令是什么;
  4. 代码分层和依赖方向是什么;
  5. 哪些目录不能手动修改;
  6. 常见坑和禁止模式是什么。

这个文件相当于代理的“世界地图”。比起把所有信息一次性塞进提示词,更好的方式是提供索引,让代理按需读取。

2. 工具层

模型本身不会真的“看见”仓库,它需要工具。

最基础的工具包括:

  1. read_file:读取文件;
  2. grep / rg:搜索代码;
  3. list_files:了解目录结构;
  4. shell:运行测试和构建;
  5. apply_patch:以可审查的方式修改文件;
  6. git diff:查看变更范围。

工具设计其实是 AI 代理的用户体验。工具太少,代理只能猜;工具太散,代理容易乱试;工具权限太大,又会带来安全风险。

因此比较理想的做法是:给代理足够完成任务的工具,但把危险能力放到审批之后。

3. 沙盒层

让 AI 运行命令之前,必须先回答一个问题:它失败的时候会不会伤到真实环境?

沙盒的价值就在这里。它可以限制文件写入范围、网络访问、危险命令、环境变量和系统权限。对 AI 编程来说,沙盒不是锦上添花,而是底线。

比如:

  1. 修改代码只允许发生在当前工作区;
  2. 访问外部网络需要显式批准;
  3. 删除文件、重置分支、部署服务需要人工确认;
  4. 测试写临时文件时限制在指定目录;
  5. 密钥和生产配置不直接暴露给代理。

这类约束看似麻烦,但它让我们敢于把更多任务交给 AI。

4. 验证层

AI 生成代码最大的风险,不是语法错误,而是“看起来很对”。

Harness 需要把验证做成闭环,让代理不能只凭自信结束任务。常见的验证信号包括:

  1. 格式化检查;
  2. lint;
  3. 类型检查;
  4. 单元测试;
  5. 集成测试;
  6. 构建结果;
  7. 静态安全扫描;
  8. 人工 review。

这些验证信号可以分层执行。越便宜、越快的检查越应该前置,例如格式化、lint、类型检查;越昂贵的检查可以放到 CI 或人工验收阶段。

关键是:失败信息要能回到代理手里,形成“修改 → 验证 → 读取错误 → 再修改”的循环。否则测试只是拦截器,不是 Harness 的反馈系统。

5. 收敛层

长任务里,AI 很容易出现一种情况:修 A 引入 B,修 B 又破坏 C,最后越改越偏。

所以 Harness 需要定义“什么时候算完成”。这个完成条件不能只靠模型说“我已经完成了”,而应该来自外部事实:

  1. 目标文件已修改;
  2. 相关测试通过;
  3. 构建通过;
  4. diff 范围符合预期;
  5. 没有无关文件变更;
  6. 高风险操作已被用户确认;
  7. 最终说明能对应实际变更。

当这些条件都满足时,任务才算收敛。反过来,如果代理连续多次在同一个错误上失败,Harness 也应该让它停下来重新分析,而不是继续盲目尝试。

五、一个小型实践流程

以“让 AI 修复一个后端接口 bug”为例,一个 Harness 化的流程可以这样设计:

  1. 任务输入:用户描述 bug,并给出复现方式。
  2. 上下文收集:代理搜索接口、测试、日志和最近相关提交。
  3. 计划生成:代理给出修改计划,明确将触碰哪些文件。
  4. 受控修改:代理通过 patch 修改代码,而不是随意重写整个模块。
  5. 局部验证:运行最相关的单元测试。
  6. 失败反馈:如果测试失败,把错误日志重新交给代理分析。
  7. 扩展验证:局部测试通过后,再运行更大范围测试。
  8. 人工验收:输出变更摘要、验证命令和风险点。

这套流程里的重点不是“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 应该按风险分级:

  1. 低风险任务可以自动完成;
  2. 中风险任务需要运行验证;
  3. 高风险任务需要人工确认;
  4. 生产操作必须有独立审批。

八、如何衡量 Harness 是否有效

一个 Harness 好不好,不能只看演示效果,而要看长期指标。

可以关注这些数据:

  1. 任务解决率:AI 在无人介入情况下完成任务并通过验证的比例。
  2. 首次通过率:第一次修改就通过测试的比例。
  3. 返工率:AI 生成代码合并后,需要人工二次修复的比例。
  4. 无关变更率:一次任务中混入不相关改动的比例。
  5. 验证覆盖率:关键路径是否有自动化检查兜底。
  6. 人工中断次数:高风险操作是否被正确拦截。

这些指标能帮助团队判断:问题到底是模型不行、上下文不够,还是 Harness 的反馈和约束设计不合理。

九、我的理解

Harness Engineering 的本质,是把 AI 编程从“相信模型”变成“相信系统”。

模型负责生成可能的解决方案,Harness 负责让这些方案在工程环境里接受检验。通过上下文导引、沙盒隔离、工具约束、自动化测试和人工闸门,我们可以把 AI 的高产出能力转化为可落地的工程生产力。

未来程序员的工作不会只是写代码,也会越来越多地变成:

  1. 设计任务边界;
  2. 编写项目规则;
  3. 维护验证体系;
  4. 建立自动化反馈;
  5. 审查 AI 无法自证的部分。

也就是说,AI 负责编码速度,人类负责工程确定性。

当 AI 写代码的速度超过人类逐行阅读的速度时,真正值得信任的不是某一次生成结果,而是背后那套能够持续发现问题、限制风险并推动收敛的 Harness。

参考资料

  1. 本地参考稿:《AI Harness 工程详解与实践》
  2. 知乎参考链接:https://zhuanlan.zhihu.com/p/2021716359613032366
  3. LangChain Blog: The rise of context engineering
  4. Agents Cookbook: Harness engineering
  5. 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/) 转载或引用必须申明原指尖魔法屋来源及源地址!