AI 写代码写到一半就出轨?你缺的不是更好的提示词,是 Harness

TL;DR:Harness Engineering 是继 Prompt Engineering 和 Context Engineering 之后 AI 开发的第三阶段,通过把架构约束、执行计划、上下文管理机械化,让 AI Agent 可以稳定完成工程级别的任务。入门方法很简单:从一个 CLAUDE.md 文件开始,把你教过 AI 的每一件事都写进去。

AI 写代码写到一半就出轨,根源不是模型不够聪明

你让 Claude 帮你重构一个模块,它开始做了,做了三步之后开始自作主张修改另一个文件,最后交出来的代码和你要的完全不一样。这不是模型的问题,是你没有给它”马具”。

Harness Engineering 这个词来自一个比喻:AI 模型是马,马具(Harness)是让马按你意图工作的约束系统,工程师是骑手。没有马具,再好的马也跑不到你要去的地方。

这篇文章讲清楚三件事:Harness Engineering 是什么、为什么 Prompt Engineering 和 Context Engineering 不够用、以及如何从零开始落地。

Prompt → Context → Harness:三个阶段解决三个不同问题

大多数工程师接触 AI 开发的路径是这样的:

第一阶段 Prompt Engineering:写更好的提示词。”你是一个资深工程师,请帮我…”,加 few-shot 示例,调 temperature。这能解决单次对话的质量问题,但对跨会话、多步骤任务没有任何帮助。

第二阶段 Context Engineering:把更多信息塞进上下文。RAG、代码库索引、工具调用。模型看到的信息更多了,但还是不知道”下一步该干什么”、”遇到这种情况该怎么选择”。

第三阶段 Harness Engineering:不只是给模型信息,而是给模型一套机械化的工作框架——包括执行路径、约束规则、进度追踪、错误处理机制。Prompt ⊂ Context ⊂ Harness,每个阶段都包含前一个阶段,但解决的是更高层次的问题。

区别在于:Prompt/Context 是在”喂”模型,Harness 是在”装备”模型。

四个核心要素,缺一个都会崩

一个完整的 Harness 系统包含四个要素:

1. Agent 驱动执行:不是人工逐步操作,而是 Agent 自主执行一系列步骤,包括调用工具、读写文件、运行命令。人只在关键决策点介入。

2. 架构约束机械化:把”不能这样做”变成规则文件,让模型在执行时自动遵守,而不是靠每次提示词提醒。比如”不能修改 src/legacy/ 目录下的文件”写成 lint 规则,而不是每次在 prompt 里说一遍。

3. Plan 作为一等公民:多步骤任务必须先生成可审查的执行计划,计划经过人工确认后再执行。计划本身是持久化的,跨会话可以恢复。这是解决”做了三步出轨”问题的关键。

4. 渐进式上下文展现:不把所有信息一次性塞给模型,而是根据任务进展按需加载。执行第三步的时候才把第三步需要的文档拿出来。

这四个要素对应一个分层架构:执行内核(工具调用、代码运行)→ 上下文引擎(按需加载信息)→ 会话状态层(跨会话进度持久化)→ 编排层(任务分解、计划生成)→ 操作界面(人类审查和干预点)。

从一个 CLAUDE.md 文件开始,不需要一步到位

Harness Engineering 听起来很重,但入门成本极低。

最简单的 Harness 就是一个 CLAUDE.md(或 AGENTS.md)文件,放在项目根目录,写下 AI 在这个项目里应该知道的所有约束和上下文:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 项目规范

## 禁止操作
- 不要修改 `src/legacy/` 目录
- 不要直接 push 到 main 分支

## 代码风格
- 使用 TypeScript strict 模式
- 函数命名用 camelCase,文件命名用 kebab-case

## 当前任务状态
- [ ] 重构 UserService(进行中)
- [x] 迁移数据库连接池

## 常见错误和解决方案
- 遇到 `ECONNREFUSED` 时检查 Docker 服务是否启动

这个文件解决了一个核心问题:每次新开会话,模型的记忆清零,但项目知识不应该清零。

5 步把 Harness 从玩具变成生产工具

从第一个 CLAUDE.md 到一个真正可靠的 Harness,有一条清晰的路径:

第 1 步:记录 Agent 犯的每一个错误

不要只是在当次对话里纠正,要把错误写进文档。格式很简单:

1
2
3
错误:Agent 修改了 legacy 目录下的文件
原因:没有明确的约束
解决方案:在 CLAUDE.md 中添加禁止规则

这一步听起来繁琐,但它是后续所有优化的数据来源。

第 2 步:把高频错误变成 Linter 规则或文档约束

如果同一类错误出现 3 次,就不应该靠提示词解决。要么写成 ESLint/ruff 规则让 CI 自动拦截,要么写成明确的文档约束让模型在执行前读到。

约束的优先级:机器执行的规则 > 文档里的约束 > 提示词里的提醒。越靠前越可靠。

第 3 步:为多步骤任务添加跨会话进度追踪

任何超过 5 步的任务都需要一个持久化的计划文件。格式不重要,关键是两点:每步完成后要更新状态,新会话开始时要先读取当前状态。

一个实用的方法是让 Agent 在每次会话结束前写一个”handoff note”:

1
2
3
4
5
6
7
8
## 当前进度
完成了步骤 1-3,正在执行步骤 4(重构 UserService.login 方法)

## 下一步
完成 login 方法后,需要更新对应的单元测试

## 注意事项
login 方法依赖 `src/utils/crypto.ts`,修改时注意不要破坏其他调用方

第 4 步:部署后台 GC Agent 观察长期一致性

随着 AI 生成的代码越来越多,会出现一类”缓慢漂移”问题:每次改动都是合理的,但积累下来之后代码风格不一致、同一逻辑有多个实现、技术债慢慢堆积。

GC Agent(Garbage Collection Agent)定期扫描代码库,识别这类问题并生成报告。不需要每次都自动修复,但要让人类知道漂移在哪里。

第 5 步:随模型能力提升,精简 Harness

这一步经常被忽视。6 个月前需要写 3 页约束文档才能让模型正确处理的事情,今天的模型可能默认就能做好。

Harness 应该是”可撕裂”的(tearable):写进去的每一条规则都应该标注”为什么需要这条规则”,定期检查是否还有必要。过度工程化的 Harness 会成为新的技术债。

多提供商设计:不要把 Harness 绑死在一个模型上

一个常见的失误是把 Harness 设计成只能用 Claude 或只能用 GPT-4。三个月后模型市场格局会变,你不应该为了换模型而重建整套框架。

多提供商设计的核心原则:

  • 工具调用接口抽象化:不要直接调 Claude API,通过统一的 tool interface 封装
  • 提示词不依赖模型特性:避免使用只有某个模型才能理解的特殊格式
  • 测试套件跨模型运行:同样的任务在 Claude、GPT-4、Gemini 上跑,对比结果

切换模型时,理想情况是只改一个配置项,其他全部不变。

数字说话:Harness Engineering 的实际规模效应

这不是理论,已经有团队在生产环境验证:

OpenAI 内部工程团队用 5 个月实现了 0 行手写代码,100 万行 AI 生成代码,平均每人每日合并 3.5 个 PR。这个数字不是某个超级程序员的成绩,是团队平均值。

Stripe 的 Minions 系统每周自动合并超过 1000 个 PR,处理的是真实生产代码库的变更,不是玩具项目。

这些数字的背后是系统,不是聪明的提示词。

三个真实的局限,不解决会踩坑

复合错误率问题:一个 10 步任务,如果每步有 5% 的错误概率,完整执行成功率只有 60%。步骤越多,累积误差越大。解决方案是在关键检查点加人工审查,而不是让 Agent 一路跑到底。

成本与效率的矛盾:Harness 会增加 token 消耗——更多的上下文、更多的计划生成、更多的状态追踪。对于简单的单次任务,Harness 是过度设计。要根据任务复杂度决定用哪个层次的约束。

Harness 本身也会成为技术债:你积累了 500 条约束规则,但没有人知道哪些还有效、哪些已经过时。Harness 需要维护,这个维护成本不是零。”可撕裂”原则不只是建议,是防止这个问题恶化的必要措施。

验证你的 Harness 是否真正有效:把同一个任务做两遍

有一个简单的测试方法:选一个中等复杂度的任务(比如给某个模块添加完整的错误处理),先自己完整做一遍,记录步骤和决策点;再让 Agent 在你的 Harness 下做一遍,对比结果。

差异点就是你的 Harness 的漏洞。你做这个任务时自然而然想到的事情,Agent 没想到,说明这个约束没有被机械化。

这个测试每个月做一次,Harness 会越来越精准。

现在可以做的第一步

不需要等到架构设计完整才开始。今天就可以做的事:

  1. 在你的主力项目根目录创建 CLAUDE.md
  2. 把最近 AI 犯过的 3 个错误写进去(错误 + 原因 + 规则)
  3. 把项目里”不言自明”但 AI 不知道的约束写进去

下个月回来看,你已经有了一个初版 Harness。