上一章我们先把最轻的情况说清楚了:
如果任务很小,直接 prompt 就够了。
但一旦任务开始变复杂,问题就不再只是“模型会不会写”,而是“模型能不能在边界内持续做对”。

这时候,才需要给 AI 加一层 Harness

在这本书里,Harness 不是一个花哨的概念,它就是放在模型外面的控制层。
它负责把任务范围、允许动作、验收条件和失败反馈组织起来,让 AI 不只是“能输出”,而是“能在约束下完成任务”。
更重要的是,Harness 不是永远加厚的控制层。
它先是为了救场,等任务稳定、模型能力增强、测试和工具链变强之后,它应该逐步收缩到最小必要控制。
也就是说,本书讲的不是“控制越多越好”,而是“什么时候该加,什么时候该收”。


1. 以修改程序为例

程序项目的常见结构:

  • 主代码(Main Code):负责核心业务逻辑,比如结算、登录、路由或数据处理。
  • 测试(Tests):验证修改后行为是否仍然正确。
  • 配置(Config):控制运行参数、环境和依赖。
  • 日志(Logs):记录修改过程和验证结果。
  • 问题记录(Open Issues):保存暂时不能解决,但不能忘掉的问题。

比如一个空购物车结算问题,通常会涉及:

  • checkout/service.py:结算逻辑
  • tests/test_checkout.py:回归测试
  • revision_log.md:修改日志
  • open_issues.md:开放问题
  • current_task.md:当前任务

这类任务一开始看起来像一个小修补,
但只要开始涉及多文件、验证、回写和后续跟进,它就已经不再只是“改一行代码”了。


2. Harness 解决的不是写代码能力,而是控制问题

如果只靠 prompt,AI 可以开始做事,但它不一定知道:

  • 当前任务到底限定在哪个文件
  • 哪些内容可以改,哪些不能改
  • 改完以后怎么判断通过
  • 失败以后该不该继续

这就是为什么本书强调:

Prompt 解决“怎么说”,Harness 解决“能不能做,做完怎么验收”。

这两者不是同一层问题。

在轻量任务里,prompt 足够。
但当任务涉及多轮修改、跨文件影响、失败恢复和结果验收时,只靠 prompt 就不够了。

另外,当前阶段的 AI 编程,很多时候并不能像人类在 IDE 里那样单步调试、看变量、设断点、反复观察。
所以我们只能通过日志、Hook、状态文件和验收,把执行过程“照亮”。

这看起来有点像回到最原始的 printf 调试,
但本质上不是倒退,
而是在为黑盒建立可观测性。

也就是说,Harness 不只是控制边界和验收,
它还负责把黑盒打开一点:

  • 在关键点插入观测
  • 在失败时留下轨迹
  • 在下一轮继续时保留事实

没有这些观测点,AI 往往只能继续猜;
有了这些观测点,项目才有机会慢慢收敛。


3. 什么时候该引入 Harness?

判断标准不是看任务本身永远有多复杂,而是看当前模型 + 当前工具链 + 当前流程能不能稳住这个任务。

3.1 任务开始跨文件

如果一轮修改只改一个局部,还能直接处理。
但如果任务开始影响多个文件,或者修改可能波及正文、状态、日志和问题记录,那就需要 Harness

因为这时,AI 很容易:

  • 顺手改到授权范围外
  • 忘记任务只允许改某个文件
  • 把局部任务扩大成全局改动

3.2 任务开始有风险

当修改会影响:

  • 代码库的稳定性
  • 测试结果
  • 接口兼容性
  • 状态文件的正确性

这类任务就不能让模型自由扩散。
必须先定义边界,再让它动。

3.3 任务需要持续推进

如果一次修改就能结束,直接 prompt 就行。
但如果任务需要反复检查、调整和继续,那就不能只停留在一次性输出。
这时 Harness 的作用,就是让每一步都在可检查的范围内推进。


4. Harness 在本书里到底管什么?

这本书里的 Harness,至少管四件事:

4.1 当前任务

当前任务写在 current_task.md 里。
它不是聊天记录,而是当前这一轮真正要做什么。

例如:

  • 只修改结算逻辑
  • 不改认证模块
  • 修改后更新 revision_log.md
  • 发现范围外问题就写入 open_issues.md

4.2 允许范围

Harness 要知道这轮能动哪些文件,不能动哪些文件。

这不是形式主义,而是为了防止模型把局部任务做成扩散修改。

4.3 结果检查

做完以后要检查:

  • 有没有越界修改
  • 行为是否符合预期
  • 回归测试是否通过
  • 状态文件有没有同步更新

4.4 失败记录

如果这一轮失败了,不能只停在“没做对”。
还要把失败轨迹留下来,供下一轮继续用。

这就是为什么书里会有:

  • project_map.md
  • current_task.md
  • revision_log.md
  • open_issues.md

它们不是额外负担,而是让下一轮继续推进的基础。

不过这里也要注意:
这些控制并不是永远都要一样重。
随着模型能力增强、测试更成熟、工具链更稳定,Harness 里的一部分职责会逐步被测试框架、静态规则或模型本身吸收。
所以 Harness 要保持最小必要控制,而不是无限加厚。


5. 贯穿全书的例子:修复空购物车结算问题

这本书一直用一个例子:
修复空购物车结算报错,避免影响已有下单流程。

这个例子很适合说明为什么要加 Harness

任务输入

“修复空购物车结算报错,但不能影响已有下单流程。”

真正风险

模型很容易为了“修好”顺手去改:

  • 结算服务
  • 订单状态
  • 支付流程
  • 相关测试
  • 甚至配置和文档

如果没有 Harness,这种扩散很难被及时拦住。

有 Harness 以后

Harness 会先告诉模型:

  • 只允许改结算相关文件
  • 其他模块不能动
  • 修改后必须检查 diff
  • 结果要写回状态

这样,模型不是在整个代码库里自由游走,而是在一个明确边界里完成任务。


6. 为什么 Harness 会让系统更容易收敛?

因为它把“无边界试错”变成了“有边界循环”。

没有 Harness 的时候,模型可能这样跑:

  • 改一点
  • 看起来不对
  • 再换个说法
  • 再改一点
  • 继续扩大范围

最后系统虽然还在动,但不一定是在收敛。

Harness 之后,流程会变成:

  1. 读取 current_task.md
  2. 只在允许范围内动作
  3. 修改后检查结果
  4. 把结果写回 revision_log.md
  5. 如果发现范围外问题,写入 open_issues.md
  6. 下一轮基于新状态继续

这时,循环不是空转,而是在把任务往前推。


7. 一个最小 Harness 可以长什么样?

本书不主张一上来就把系统做得很重。
一个最小 Harness,最关键的是把职责分开。

context:
  - current_task.md
  - project_map.md
  - relevant files

permissions:
  allow:
    - checkout/service.py
    - tests/test_checkout.py
    - revision_log.md
    - open_issues.md
  deny:
    - auth/*
    - payment_gateway/*
    - docs/*
    - unrelated modules

checks:
  - diff scope
  - regression test
  - behavior preservation
  - state update

这个结构的重点不是 YAML,
而是它表达了本书的核心思想:

  • 任务要明确
  • 边界要明确
  • 验收要明确
  • 会影响下一轮的事实要回写

同时也要记住:
这类控制不是永远固定不变的。
有些检查最后会被测试吸收,有些边界会被规则固化,有些临时状态会被清理掉。
Harness 的目标不是把系统锁死,
而是先把项目救回来,再慢慢收缩到最小必要控制。

8. 什么时候该收缩控制层?

这里要讲严谨一点。

本书不是说任务结束后就“回到什么都不管的轻量模式”,
而是说:

  • 临时状态要清理
  • 已验证的长期状态要保留
  • 控制层要根据后续任务风险降级
  • 只保留当前任务真正需要的最小约束

也就是说,收缩的不是“知识”,而是“临时负担”。

可以清理的部分

  • 一次性的草稿
  • 中间产物
  • 已经过期的试错轨迹
  • 当前轮不再需要的临时缓存

应该保留的部分

  • 已验证的项目地图
  • 已确认的任务边界
  • 需要长期追踪的 open_issues
  • 对后续任务仍然有效的验收规则

所以,更准确的说法是:

任务完成后,清理临时状态,保留已验证的长期状态;控制层按任务风险降级,但不丢掉已经确认的规则和事实。

这样就不会让人误解成“系统又回到混沌状态”。

9. 本章小结

这一章想讲清楚的,其实就是一句话:

Harness 不是为了让 AI 更复杂,而是为了让 AI 在复杂任务里不乱跑。

它把任务范围、允许动作、结果检查和失败记录组织起来,让模型可以在边界内继续推进。
而当任务结束后,应该清理临时状态,保留已经验证过的长期状态,再按风险决定是否降级控制层。

这也就是本书从 prompt 走向 Harness,再走向 state 的原因。

下一章,我会继续讲:什么时候需要引入状态,以及为什么状态会让循环更容易收敛。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐