# Harness Coding：与其调教模型，不如设计模型的工作环境

> 过去半年我换了三次 AI coding agent，从 Cursor 到 Claude Code 再到自己拼的；编排器。结论很反直觉——**真正影响产出质量的从来不是换更强的模型，而是模型；周围那一层我一开始压根没意识到存在的东西；这层东西有个名字：**Harness**

- URL: https://tenggouwa.com/posts/harness-coding/
- 发布: 2026-05-21
- 标签: Harness, vibe coding, AI, Agent

# Harness Coding：与其调教模型，不如设计模型的工作环境

> 过去半年我换了三次 AI coding agent，从 Cursor 到 Claude Code 再到自己拼的
> 编排器。结论很反直觉——**真正影响产出质量的从来不是换更强的模型，而是模型
> 周围那一层我一开始压根没意识到存在的东西**。
>
> 这层东西有个名字：**Harness**。

## 一、Agent = Model + Harness

业界这两年逐渐形成一个共识公式：

```
Agent = Model + Harness
```

模型（GPT / Claude / Gemini …）只是 Agent 的一部分。模型之外的所有东西——
工具集、规则文件、反馈机制、工作流编排、上下文组装策略、CI 门禁——
统称为 **Harness**。

Addy Osmani 引过一个挺震撼的数据点：在 Terminal Bench 2.0 上，**同一个 Claude
Opus 4.6**，套在某通用 CLI 里只能排到 Top 30，套到一个精心设计的定制 harness
里能跳到 Top 5。模型一字没改，只换了它工作的"环境"。

口号：
> **一个体面的模型 + 出色的 harness，能打败出色的模型 + 糟糕的 harness。**

这意味着，当你抱怨"AI 写的代码不行"的时候，大概率不是模型不行，是你给它的
环境不行——这件事现在叫 **Harness Engineering**（或 Harness Coding）。

## 二、三大支柱：约束 / 反馈 / 门禁

一个完整的 harness 大致三层：

```
┌────────────────────────────────────────────────┐
│  ① Feed-forward Constraints（前馈约束）          │
│  在代码生成前缩小解空间                            │
│  → AGENTS.md / Cursor Rules / 类型系统 / 架构图    │
├────────────────────────────────────────────────┤
│  ② Feedback Loops（反馈循环 / Sensors）          │
│  让 agent 在你看之前自己发现问题并自我纠正           │
│  → Linter / 类型检查 / 测试 / Hook                 │
├────────────────────────────────────────────────┤
│  ③ Quality Gates（质量门禁）                      │
│  阻止不合格代码进入主干                            │
│  → CI / pre-commit / Required Reviews              │
└────────────────────────────────────────────────┘
```

这三层的本质差别是**约束生效的时机**：

- **前馈**是"开始写之前先告诉它规矩"
- **反馈**是"写完之后立刻让它知道错了"
- **门禁**是"错了的不许合"

很多人只做了第一层（写 prompt / 写 rules 文件），结果发现"AI 老是不听话"。
原因是只有前馈、没有反馈和门禁——LLM 是概率模型，告诉它"请遵守 X"，
它**大概率**会遵守，剩下那 5% 就是你的事故来源。

### Prompt 里说 vs Lint 里卡

举个最经典的对照：

```
告诉 agent：「请遵守我们的编码规范」     ← 概率性合规
写一条 linter 规则，违规直接 fail PR       ← 确定性合规
```

这两件事是**根本不同的东西**。Harness 思维就是：能用确定性手段卡住的，
绝不留给概率性手段。

## 三、把 AGENTS.md 当代码维护

`AGENTS.md`（OpenAI / Cursor / Claude Code 都认这个文件名，逐渐成为跨工具
标准）是 harness 最常被忽视的入口。常见的几条反模式：

❌ **600 行的风格指南**——LLM 实际上读不完，注意力会被稀释
❌ **"请尽量"、"建议"、"考虑"这种软措辞**——概率性表达，不可执行
❌ **没有人维护，半年没更新**——和代码漂移之后越用越坑
❌ **每条规则都是凭空写的**——没有来源，没人记得为什么有这条

正确的几条原则：

✅ **保持在 60 行以内**——超过这个数说明该拆成 lint 规则了
✅ **每条规则可以追溯到一个具体失败事件**（"棘轮原则"，下一节细讲）
✅ **用三级边界**：必须做 / 先请示 / 禁止做——别让 LLM 自己拿捏
✅ **把 AGENTS.md 当代码**：进 PR、过 review、定期重构

口诀：**AGENTS.md is code, treat it like code.**

## 四、棘轮原则（Ratchet Principle）

这是 harness engineering 最重要的一条**操作方法论**：

> **每一次失败都应该被转化为一条永久规则。**
>
> **每一条 AGENTS.md 的规则都应该可以追溯到一个具体的失败事件。**

为什么叫"棘轮"——棘轮只能向一个方向转。你的 harness 应该是**单调收紧**的：
出过的错不能再出第二次。

实操循环：

```
1. Agent 出了一个错（比如建了个我不想要的 helper class）
2. 别只在当前 PR 里改掉，问自己：这个错该怎么"在源头"防住？
3. 三个选项，按强度排序：
   a) 加一条 AGENTS.md 规则（最弱，前馈）
   b) 加一条 linter / 类型规则（中等，反馈）
   c) 加一条 CI 门禁（最强，门禁）
4. 选能用的最强那一档，提交进 harness 仓库
5. 下次同样的错不会再发生
```

这个循环跑顺了，你的 agent 就会**随着时间越来越好用**，而不是反过来。

## 五、让错误信息本身成为 prompt

Harness 的反馈层有个非常容易被忽视的细节：**报错文案要写给 LLM 读**。

对照：

```
# 普通 lint 错误（写给人看）
error: max-complexity exceeded (12 > 10)

# 写给 agent 看的 lint 错误
error: Function complexity is 12 (limit: 10).
       Refactor by extracting the early-return validation block into
       a separate `validateInput(...)` helper, or by collapsing the
       nested switch into a lookup table.
       See: docs/complexity.md#how-to-fix
```

第二种写法里，错误信息**就是修复指南**。Agent 拿到这条 lint 输出，下一轮
就有 70% 概率能自己改对。

这件事的转变是：**Linter / 类型检查器 / 测试报错文案，从给 reviewer 看的
工件，变成给 agent 看的反馈接口。** 这是 harness 时代的新职业素养。

附带一条相关的反模式：

> **禁止 agent 使用 inline disable**（`// eslint-disable-next-line` 一类）。

不然 agent 会把"违规"压成"抑制违规"——表面看 lint 过了，本质上规则被
绕过去了。Harness 必须堵死这个口子。

## 六、Plan → Execute → Verify

别让 agent 一口气把多步任务做完。强制走 PEV：

```
Plan       — 先输出明确的 step list，人/工具过一下
Execute    — 按 plan 走，每一步独立可观察
Verify     — 跑测试 / 对照 plan / 跑 sensor，确认对了再下一步
```

每个转换点（plan → execute / execute → verify）都是一个**插入约束的
机会**——是写"必须先 plan 再写代码"的 hook、还是写"verify 不过就回退到
plan 重做"的循环，看你的场景。

经验：把 PEV 写进 harness 之后，**最大的好处不是 agent 写得更对，而是
你能在 plan 阶段截停**——省下一堆"已经写了 200 行才发现方向错了"的痛苦。

## 七、工具集：10 个比 50 个好

很多人给 agent 接 MCP 接到 50 个工具，觉得"能力越多越好"。实测反过来——
**工具菜单太长，LLM 选错工具的概率显著上升**。

经验法则：

- 同类工具不要超过 2 个（"读文件"不要既有 `Read` 又有 `Cat` 又有 `FileGet`）
- 每个工具的 description 必须**和别的工具有明确区分**
- 危险工具（删除 / 推送 / 调外部 API）单独放一组，加确认
- 周期性 audit：看 trace 里哪些工具 90 天没被调用过，删掉

口诀：**10 个聚焦工具 > 50 个重叠工具**。

## 八、长任务：双层 agent + 进度文件

跨多个上下文窗口的长任务（比如让 agent 跑两周建一个项目），单 agent 跑不动。
Anthropic 推荐的双层架构：

```
Init Agent     — 只跑一次，搭骨架：
                 - 生成 init.sh（一键起开发环境）
                 - 生成 features.json（200+ 任务清单 + 状态）
                 - 建初始 git 仓库 + 第一条进度记录

Coding Agent   — 每次 session 跑一轮：
                 1. 读 git log + progress.md → 知道上次到哪
                 2. 从 features.json 挑一个未完成的最高优先级项
                 3. 跑 init.sh 起环境 + 冒烟测试
                 4. 做这一项 → 测试 → commit → 更新 progress
                 5. 退出
```

关键设计：

- **进度文件是 agent 的"持久记忆"**——不依赖上下文窗口
- **一次 session 只做一个 feature**——防止"宣告完成幻觉"
- **会话开始先验证环境**——防止"在脏环境里写代码"
- **会话结束必须 commit**——防止下次 session 看到不一致状态

把这套搬到非 coding 场景也成立——研究 / 数据建模 / 写作，都能用同一套
"init agent + work agent + 进度文件"模式跑。

## 九、度量你的 harness

Harness 是软件，软件就该有指标。几个 Augment Code 在用的：

| 指标 | 怎么测 | 为什么有用 |
|---|---|---|
| 任务解决率 | 自动化测试通过率 | Harness 整体健康度 |
| 代码变更率 | 两周内被重写的代码 % | 衡量"agent 写的代码站不站得住" |
| 验证开销 | 审计时间 / 首次提交时间差 | 衡量人工 review 负担 |
| 缺陷逃逸率 | 上线后按 commit 来源标记的 bug | 终极指标 |

没有指标的 harness 优化，约等于凭感觉调 prompt。

## 十、心智模型转变

我感觉 harness coding 真正难的地方是**心智模型的转变**：

| 旧思路 | 新思路 |
|---|---|
| 我在让 AI 写代码 | 我在设计让 AI 写代码的环境 |
| Prompt 没写好，再调 prompt | Prompt 一次性的，规则要进 harness |
| Agent 又出错了，骂它一顿 | Agent 又出错了，问 harness 哪里漏了 |
| 模型不行，等下一代 | 模型够用，harness 还差很多 |
| 写代码 | 写 harness |

最后一行我觉得最重要——**未来工程师的核心产出，从代码本身，逐渐转移到
"约束代码生成过程的那套系统"**。代码是 agent 在 harness 边界内的副产品。

---

## 怎么开始

如果你完全没动过 harness，从最便宜的三步开始：

1. **审计最近 5 个 agent 写的 PR**——找重复出问题的模式
2. **挑 3 条模式编码成 lint / type 规则**——记得报错文案要写给 agent 看
3. **在 CI 里硬卡这 3 条**——并记录修改前后的"人工 review 时长"

跑两周。如果 review 时间下降，恭喜，你已经在做 harness engineering 了。

剩下的事情就是把"棘轮"持续转下去。

---

*相关阅读*：

- *Effective harnesses for long-running agents* — Anthropic
- *Agent Harness Engineering* — Addy Osmani
- *Harness Engineering for AI Coding Agents* — Augment Code
- *Harness engineering for coding agent users* — Martin Fowler
