Harness Engineering
用缰绳驾驭 AI
AI 编程时代的工程方法论 —— 模型是大脑,harness 是手和脚。不替代核心力量,而是让核心力量变得可控、可靠、可用。
Harness 到底是什么
- 不是 KOL 造的词:2026 年 2 月,OpenAI 发正式博文、Mitchell Hashimoto 写长文、Martin Fowler 团队做分析、LangChain 出技术拆解——互不相关的团队指向了同一个东西,用了同一个词。
- 词源很古老:「harness」至少可追溯到 1300 年的古法语「harnois」(军队补给品),先指盔甲,后演变为马具;动词「驾驭并利用力量」的比喻义出现在 1690 年代。
- OpenAI 的工程定义:「A harness is the tool shell that allows an AI agent to affect the real world.」——如果推理模型是大脑,harness 就是手和脚。
- 不是发明,是终于认识到:航天、工业控制、软件测试早就做过类似的事。AI 圈不是发明了 harness engineering,是终于意识到自己需要几十年前就有的工程纪律。
Reading files, fixing code, running tests, deploying to production: all of it happens inside the harness.
OpenAI 官方博文 · 读文件、改代码、跑测试、部署生产——全发生在 harness 内部五个领域,五种 harness,同一件事
不替代核心力量,而是让核心力量变得可控、可靠、可用。
词源对照表
| 领域 | Harness 形态 | 核心功能 | 对应 AI Agent 中的 |
|---|---|---|---|
| 马术 | 缰绳 / 马具 | 引导方向和力量 | 约束 + 方向 |
| 航天 | 电气线束 | 精密信号传输 | 信息 / 上下文管道 |
| 软件测试 | 测试线束 | 隔离 + 模拟环境 | 沙盒 + 反馈循环 |
| 安全 | 安全带 | 失败时的保护 | Guardrails / 回滚 |
| 军事(词源) | 盔甲 / 装备 | 保护 + 赋能 | Agent 的完整装备 |
没有 harness 的马是一匹乱跑的野马——力气再大,方向不对,拉不了车。缰绳不让马变强,但让马的力量变得有用。AI 模型也一样:强大、快速,但自己不知道该去哪。
六十年简史:人和工具的关系
- 1968 软件危机:人人都是唯一创造者,工具极其原始;Dijkstra 提出结构化编程。人:写每一行代码。
- 1970 瀑布模型:史上最讽刺的误读——Royce 从没用过「waterfall」一词,还警告单次顺序通过是「有风险且招致失败的」。
- 1994 设计模式:第一次把「代码该长什么样」变成可讨论的东西;卖超 50 万册、译成 13 种语言。
- 2001 敏捷 + TDD:人开始系统化地和自动化工具协作;「验证机制」这个概念登场,后面会反复出现。
- 2010 DevOps / IaC:写「我要 3 个实例、2GB 内存、跑这个镜像」,工具自己实现——描述意图让系统执行。
- 2021 Copilot:AI 第一次坐到程序员旁边;你仍是方向盘,AI 只是油门助力。
- 2024 Agent 时代:Devin 在 SWE-Bench 无辅助解决 13.86%(此前最佳 1.96%);Cursor 16 个月 100 万用户。
- 2025 Claude Code + Vibe Coding:AI 直接进代码库干活;Karpathy 造词 vibe coding——人只负责「这感觉对不对」。
- 2026 Harness Engineering:3 名工程师、5 个月、100 万行代码、零行手写——工程师的主要工作变成了设计环境、明确意图、构建反馈循环。
那条暗线:从亲手做,到设计系统
三次命名:Prompt → Context → Harness
- 第一次觉醒 · Prompt(2022–2024):怎么问才能问到好答案。角色设定、few-shot、chain-of-thought。用马具比喻:这是你对马说的话。局限:一次性的、无上下文、不可复用。
- 第二次觉醒 · Context(2025):2025 年 6 月 Shopify CEO Tobi Lutke 与 Karpathy 几乎同时命名。不是一句话,而是动态构建整个信息包:文档、历史、工具定义、RAG 结果。用马具比喻:帮马看路的一切。
- 第三次觉醒 · Harness(2026):2026 年 2 月 5 日 Mitchell Hashimoto 博文、2 月 11 日 OpenAI 正式博文、Martin Fowler 跟进、LangChain 拆解——一个月内从博客术语变成行业共识。
- 关键公式(LangChain):Agent = Model + Harness。裸模型在被 harness 赋予状态、工具执行、反馈循环和可执行约束后,才成为 agent。
- 最硬的数据:LangChain 的 coding agent 在 Terminal Bench 2.0 上从 52.8% 涨到 66.5%、Top 30 → Top 5。模型完全没换——只改了系统提示词、工具配置、中间件钩子。同一匹马,换了套缰绳。
| 维度 | Prompt Engineering | Context Engineering | Harness Engineering |
|---|---|---|---|
| 时期 | 2022–2024 | 2025 | 2026 |
| 核心问题 | 怎么问 | 给什么信息 | 整个系统怎么运转 |
| 马具比喻 | 你对马说的话 | 帮马看路的一切 | 缰绳+马鞍+围栏+道路 |
| 人的角色 | 提问者 | 策展人 | 架构师 |
| 可复用性 | 低(每次重写) | 中(模板化) | 高(系统化) |
| 命名者 | 社区自发 | Karpathy / Tobi Lutke | Mitchell / OpenAI |
有没有这些名字,活照样干——但有了名字,事情才能被讨论、被拆解、被教。LangChain 能写《The Anatomy of an Agent Harness》,Fowler 团队能提出三支柱框架。一个概念有了名字,经验才传得开。
Harness 的五个组件
逐组件拆解
- ① 指令:最基础的一层。CLAUDE.md / AGENTS.md / .cursorrules,本质一样——用 Markdown 把你的意图编码成 AI 可读的规则。原则:每一行都问「删掉它会导致 Claude 犯错吗?不会就删」。
- ② 约束:指令是建议,约束是法律——代码不合规就编译不过。OpenAI 概括为两个动词:约束(事前拦截)+ 纠正(事后修复)。Claude Code 用 Hooks 做程序级硬拦截;Codex CLI 走沙箱路线。
- ③ 反馈:AI 最大的问题不是写错代码,是以为自己写对了。解法是给它「眼睛」:测试、截图、DOM 快照、可观测性日志。Boris Cherny 的第一条建议:给 Claude 验证手段,最终结果质量提升 2–3 倍。
- ④ 记忆:Agent 没有记忆就是金鱼。静态记忆(CLAUDE.md)→ 动态记忆(auto-memory)→ 结构化笔记(跨上下文窗口的持久笔记)。原则:找到最小的高信号 token 集合。
- ⑤ 编排:任务足够复杂时需要多 Agent 协作:Subagents(独立上下文+精简摘要)、Agent Teams(互相通信)、Middleware(6 个 hook 点)。
| 五组件模型 | OpenAI 四动词 | Fowler 三块 | 典型实现 |
|---|---|---|---|
| 指令 | 告知 inform | 上下文工程 | CLAUDE.md / AGENTS.md / .cursorrules |
| 约束 | 约束 constrain | 架构约束 | Hooks / Linter / Sandbox / CI |
| 反馈 | 验证 verify | 垃圾回收 | Evaluator Agent / 测试 / 可观测性 |
| 记忆 | 告知 inform | 上下文工程 | 知识库 / auto-memory / ExecPlan |
| 编排 | 纠正 correct(勉强) | —(未覆盖) | 多 Agent / Pipeline / Middleware |
一开始只要「指令」(写一个 CLAUDE.md)和基本的「反馈」(让 AI 跑测试)。约束在「被 AI 搞烦了之后」自然会加;记忆在受够了重复解释之后自然会建;编排是最后才需要的。Harness 是长出来的,不是设计出来的。
少即是多:Harness 的减法哲学
- 上下文焦虑(context anxiety):Sonnet 4.5 是第一个「意识到自身上下文窗口」的模型,会在接近极限时过早收尾、赶工,对剩余 token 的估计「非常精确但是错的」。Anthropic 不得不加入 context reset 机制。直到 Opus 4.5 该行为才自行消失。
- 上下文有副作用:塞进去的信息越多,模型准确回忆任何单条信息的能力越差。约 100 万 token 处有明显性能天花板——不管技术上支持多大的窗口。
- 100 行地图,不是 1000 行手册:OpenAI 试过超大 AGENTS.md,「效果很差」。全面的指令文件会挤占任务上下文和相关代码的空间。
- ETH Zurich 实证(2026.03):系统测试 AGENTS.md 的影响,结论出人意料——某些场景下 AGENTS.md 不仅没帮忙,反而妨碍了表现。建议:只写人类不可推断的信息。用了 React?AI 打开 package.json 就知道;写了「写干净代码」?AI 本来就会。
- 推理三明治:LangChain 在 Terminal Bench 2.0 上测不同推理预算——全程最高推理反而最低分(53.9%,大量超时),因为资源在不需要的地方被浪费。资源分配比资源总量更重要。
什么时候该砍规则(5 个信号)
- 模型升级后的旧规则:Sonnet 4.5 时代需要 Sprint 分解,换成 Opus 4.6 后 Sprint 机制完全移除——为旧模型弱点写的规则,在新模型上可能变成噪音。
- AI 读代码就能发现的东西:标准语言惯例、详细 API 文档、教程式长解释、「写干净代码」之类不言自明的实践——写了反而浪费上下文。
- 频繁变化的信息:版本号、当前 Sprint 任务、今天的会议记录,不该进 CLAUDE.md。
- 互相矛盾的规则:时间一长前后规则可能打架,agent 遇到矛盾指令行为不可预测——定期做一轮垃圾回收。
- 没被触发过的「以防万一」:Mitchell 的方法是纯归纳:只在 agent 犯错时加规则。没犯过错,就没有规则。
✅ 应该保留
- Agent 反复犯的错(验证过的真实问题)
- 项目特有的架构决策和约定
- 与默认行为不同的规则
- 关键的安全和质量红线
- 指向深层文档的指针
❌ 应该砍掉
- 为旧模型弱点写的补丁
- AI 看代码就能发现的惯例
- 「以防万一」的预防性规则
- 频繁变化的具体信息
- 教程性质的长解释
砍掉一条规则后出了问题,你会后悔;但保留一条没用的规则,你感知不到它的成本——而每一条多余的规则都在稀释真正重要规则的权重。好的 harness 不是规则最多的那个,是每条规则都在干活的那个。模型变强了,harness 应该变薄。
OpenAI Codex:零行手写代码的百万行产品
五条原则,逐条拆
- ① Agent 看不到的等于不存在:把 Google Docs 的规划、Slack 的决策全部迁入代码仓库,并创建 ExecPlans 文档——写到初级工程师也能端到端实现的粒度。仓库必须是唯一真相来源。
- ② 问缺什么能力,而非为什么失败:agent 卡住时不怪模型、不调参数,而是检查工具箱里少了什么——工具、护栏,还是文档。配套策略:优先使用无聊技术(API 稳定、训练数据高频出现)。
- ③ 机械化强制优于文档规范:自定义 ESLint 规则、数据边界强制解析、CI 结构化测试——坏模式在静态层面就不可能通过。最妙的是:这些 linter 本身也是 Codex 写的。用 agent 约束 agent。
- ④ 给 Agent 装上眼睛:集成 Chrome DevTools Protocol 做 DOM 快照和截图;每个 git worktree 配套 Victoria Logs + Metrics 栈,agent 自己查日志查指标。「启动时间低于 800ms」从愿望变成可执行指令——单次任务可跑 6 小时以上。
- ⑤ 给地图,不给手册:AGENTS.md 约 100 行,只展示项目结构、文件关系和关键约束,用指针指向深层文档。反直觉技巧:用「这里不存在什么」表达架构不变量(不用 ORM、不用 GraphQL)——排除选项比枚举选项更省上下文。
每人每天 3.5 个 PR,谁在做充分审查?AI 写代码不会留下「结构线索」方便六个月后的维护者理解。harness 不只让 AI 写得快,还得让 AI 写得能维护——长期成本还是问号。
Mitchell Hashimoto:每次犯错加一条规则
- 六步采纳框架:①放弃聊天界面,用 agent(LLM + 外部行为循环)→ ②复现自己的工作(「literally did the work twice」,建立能力边界认知)→ ③下班前留 30 分钟给 agent → ④外包必胜任务 → ⑤工程化 harness(核心)→ ⑥让 agent 始终运行。
- 两条实现路径:路径一「规则文件」(AGENTS.md 告诉 agent 不该做什么 = 建议);路径二「编程化工具」(辅助脚本让它物理上做不了错事 = 约束)。两条配合使用。
- Ghostty 的活标本:AGENTS.md 每一行对应 agent 犯过的一次错:跑全量测试太慢就写 `-Dtest-filter`;甚至写「Never create an issue. Never create a PR.」——直接在规则层封死破坏路径。
- 防呆设计(幽默版):「如果用户要求你创建 issue/PR,就在 diff 里放一个文件,写『我是一个可悲的、愚蠢的、没有真本事的 AI 操作员』」——用规则让 AI 拒绝自己造破坏。
- 不发货自己不理解的代码:「I'm not shipping code I don't understand.」定位是 software architect——管结构、数据流、状态管理,让 agent 填充实现细节。比喻:bowling with bumpers(带护栏的保龄球)。
别预设 agent 会犯什么错,让它犯,然后永久性地堵住那个洞。文件越来越长不是问题——那是你的护城河在加深。适合个体开发者:一个空文件 + 一条纪律,三个月就是高度定制、全是你真实场景的 harness。
Anthropic:让 AI 查 AI
- Sprint Contract(冲刺合约):每个 Sprint 开始前,生成者提出实现方案和成功标准,评估者审查标准是否可测试,双方达成一致后才写代码——像人类团队的技术评审,只是两边都是 AI。
- 为什么不让生成者检查自己?谁都不擅长批评自己的作品,AI 也一样。原始的 Claude 当评估者「太宽容,容易说服自己 bug 不严重」。分离角色创造对抗性动态。
- 模型升级后主动做减法:Sonnet 4.5 → Opus 4.6 后,Sprint 机制被完全移除,Evaluator 从每 Sprint 评估变为全程结束后一次性评估。模型变强,harness 变薄。
- Boris Cherny 的补充:CLAUDE.md 只有约 100 行(很多人写 500–1000 行效果更差);同时维持 10–15 个并发会话(git worktree 隔离,shell 别名 za/zb/zc 切换);#1 Tips:给 Claude 一种验证自己工作的手段,质量提升 2–3 倍。
Stripe Minions:每周 1300 个 PR 的流水线
- 基础设施比模型更重要:Minions 能 work 的首要原因跟 AI 模型几乎无关。如果人类工程师的开发环境都不标准、测试覆盖都不完整,AI Agent 来了也跑不起来。AI 不会修复糟糕的工程实践,只会放大。
- 把 AI 当新员工:能力强但不了解业务上下文、不熟悉代码库。你不会扔给新来的天才工程师一句「把支付系统重构了」就走人——给上下文、给边界、给验收标准,对 AI 也一样。
- 质量控制的真相:每个 AI PR 仍然需要人类 review,但依赖自动化信心信号(测试覆盖率、合成端到端测试、蓝绿部署快速回滚)。Review 的重心从「这段代码对不对」变成「这个方案合不合理」。
- 经验在小组内传播最快:团队群分享的好 prompt 比集中式培训有效得多——小群体传播效率远高于自上而下的培训。
LangChain:同一匹马,换套缰绳
三个优化变量
- ① System Prompt → 四阶段工作流:Planning & Discovery(读任务、扫代码库、建验证计划)→ Build(带着测试意识实现)→ Verify(跑测试、对照规格)→ Fix(分析错误、回到需求)。关键:把思考顺序约束住,不再是「你是个优秀助手」的空话。
- ② Tools → 环境感知 + 完成检查:LocalContextMiddleware 启动时注入工作目录结构、Python 版本、可用命令——解决「agent 浪费大量时间摸索自己在哪」;PreCompletionChecklistMiddleware 在 agent 准备退出时强制对照规格检查。因为最常见的失败模式是:写完重读自己的代码,觉得没问题,就停了。
- ③ Middleware → 防止 doom loop:LoopDetectionMiddleware 追踪单个文件编辑次数,重复 N 次后注入提示「考虑换个方法」。Doom loop 就是「同一种坏方法的 N 个变体」,越走越远还觉得快到了。
| Hook 点 | 触发时机 | 典型用途 |
|---|---|---|
| before_agent | 调用开始时执行一次 | 加载记忆、连接资源 |
| before_model | 每次模型调用前 | 历史裁剪、PII 过滤 |
| wrap_model_call | 包裹整个模型调用 | 缓存、重试、动态工具可用性 |
| wrap_tool_call | 包裹工具执行 | 注入上下文、控制工具访问 |
| after_model | 模型响应后 | human-in-the-loop 干预 |
| after_agent | 完成时执行一次 | 保存结果、清理资源 |
自我确认偏差(写完就觉得没问题)→ 用完成检查清单拦住;Doom loops(同一文件迭代 10+ 次坏方法)→ 用循环检测拦住;环境不熟悉(陌生目录里浪费时间)→ 用环境注入解决;时间管理失败(推理太猛导致超时)→ 用推理三明治解决。不是换更聪明的模型,是给同一个模型一个更好的运行环境。
Kent Beck:极限编程教父的 CLAUDE.md
- CLAUDE.md 第一行:「你是一个资深软件工程师,遵循 Kent Beck 的 TDD 和 Tidy First 原则。」然后规则围绕两个核心展开:TDD 循环(Red → Green → Refactor)和 Tidy First。
- Tidy First:永远不在同一个 commit 里混合结构性变更(重排代码、改善命名、提取函数)和行为性变更(加功能、修 bug)。混合变更是所有代码库腐化的起点——分开后每个变更都能独立验证、独立回滚。
- 前两次尝试失败了:复杂度积累太多,AI 完全卡住。关键教训:必须更积极地介入设计决策,拦住 AI 的提前编码(coding ahead)——AI 收到任务就立刻开写,用代码量掩盖设计缺陷。
- Augmented Coding vs Vibe Coding:Beck 的立场是两者都有价值,但不能混着来——周末 hackathon 项目可以 vibe coding;服务百万用户的生产系统,最好 augmented coding。
Augmented Coding(增强式)
- 关心:代码质量、复杂度、测试覆盖
- 价值观:和手写代码相同,整洁的代码能工作
- 人的角色:主导设计决策,AI 执行
- 适用:需要长期维护的生产代码
Vibe Coding(感觉式)
- 关心:系统行为和最终结果
- 价值观:能跑就行,有错喂回 AI
- 人的角色:描述需求,AI 全权负责
- 适用:原型、一次性脚本、探索项目
Kent Beck and I have both said this is the biggest change to coding we've seen in our 50+ year careers.
Martin Fowler 访谈 · 但 Beck 的反应不是恐慌,是把他最擅长的东西搬过来用花叔:零代码经验到百万用户
- 生长模式(一直在转的循环):被 AI 搞烦 → 加一条规则 → 规则太多 → 重构 → 新问题 → 再加。空文件→加规则→路由器重构→发现规则不够→加 hooks→hooks 太多→封装 skills→skills 冲突→再重构。
- 从规则到系统:规则是建议(有时听有时不听),hooks 才是约束(没有商量余地);重复十几遍的痛苦流程封装成 skill(配图、飞书同步、小红书排版、字幕分析……)。
- 100+ 个 skills:每一个都是从具体需求里长出来的,不是一次性设计的。每个 skill 做且只做一件事,描述写得像给同事的一句话交代。
- 经验不能跳过:判断力不来自写代码的经验,但来自另一种经验——和 AI 反复较劲的经验。踩坑来自大量重复,大量重复来自时间。没有捷径,换了个赛道而已。
别想那么多,先打开一个空的 CLAUDE.md。什么都不用写,等 AI 犯了第一个让你烦的错,写进去;犯了第二个,再写。三个月后回头看,它已经变成了只属于你的 harness——全是你的场景、你的痛点、你的工作方式。你需要的不是编程经验,是耐心和时间。
从空白开始:你的第一个 Harness
| 工具 | 文件名 | 位置 | 建议起步长度 |
|---|---|---|---|
| Claude Code | CLAUDE.md | 项目根目录(支持三层继承) | 20–50 行 |
| Codex CLI | AGENTS.md | 项目根目录(逐层遍历,override 优先) | 50–100 行 |
| Cursor | .cursor/rules/*.mdc | .cursor/rules/ 目录(支持 glob) | 每个 20–30 行 |
| GitHub Copilot | copilot-instructions.md | .github/ 目录 | 20–50 行 |
空文件开始,犯错驱动——10 条规则的演练
假设你刚接手一个 React 项目,前 10 条规则会是什么?每一条背后都是一个具体问题:
- 测试跑错了:agent 用 npm test,但项目用 Vitest → 写「运行测试:`pnpm vitest run`」
- 错误的包管理器:npm 和 pnpm 的 lock 文件冲突 → 写「只用 pnpm,禁止 npm 和 yarn」
- 不知道项目结构:组件放错目录 → 写一段目录地图(components/ features/ lib/ api/)
- 用了 TypeScript enum:团队规范用 union type → 写「❌ enum → ✅ literal union type」
- 直接 push 到 main:→ 写「永远不要直接 push 到 main,走 feature/ 分支提 PR」
- 生成了 500 行的巨大组件:→ 写「单文件 <200 行,超过拆子组件,逻辑用 hook 抽离」
- 为小功能引入大依赖:→ 写「先确认现有依赖能否实现;date-fns 已装,别引 moment/dayjs」
- 不跑 lint 就提交:→ 写「提交前必须 `pnpm lint && pnpm type-check`」
- 错误处理太简陋:到处是空 catch 和 console.log → 写「不允许空 catch,统一用 AppError 类」
- API 调用散落各处:→ 写「所有请求走 src/api/ 模块,组件里禁止直接 fetch」
① 给地图不给说明书:指令文件像地图:结构、关系、关键约束,不写死每步。② 每次犯错加一条规则:不预设、不猜测,agent 犯一个错加一条。③ 让 AI 查 AI:写完后开新对话把结果贴进去说「找出所有问题」——第二个 AI 能发现第一个漏掉的一堆问题。
指令层:给 AI 一张地图,不是说明书
- 路由器模式(花叔):根 CLAUDE.md 不写具体规则,只判断任务属于哪个工作区并指向对应文件。为什么要这样?因为 CLAUDE.md 每次会话都会加载进上下文——臃肿的文件会让 Claude 忽略你真正的指令(Boris Cherny 原话)。
- OpenAI 的目录指针模式:AGENTS.md 约 100 行只做目录+指针,指向 docs/ 下的 ARCHITECTURE.md(代码库地图)、design-docs/、exec-plans/、product-specs/ 等。agent 在小而稳定的入口 + 指向专业知识的结构中表现最好。
- Cursor 的 glob scoping:不同规则只对特定文件路径生效(如 src/api/**/*.ts)——编辑 API 代码时不会被组件规范干扰。四种激活模式:alwaysApply / glob 匹配 / 手动 @mention / AI 判断。
- 行业正在标准化:2026 年 3 月 AGENTS.md 被纳入 Linux 基金会旗下 Agentic AI Foundation 管理;Windsurf 自动识别 AGENTS.md;Copilot 的格式也越来越像。你写的内容 80% 在不同工具间通用。
| ✅ 应该写 | ❌ 不应该写 |
|---|---|
| agent 猜不到的命令(如 pnpm vitest run) | agent 读代码就能发现的(如用了 React) |
| 与默认不同的代码风格规则 | 标准语言惯例 |
| 测试指令和首选测试运行器 | 详细的 API 文档(给链接即可) |
| 分支命名、PR 惯例 | 频繁变化的信息 |
| 项目特定的架构决策 | 教程和长篇解释 |
| 常见陷阱和非显而易见的行为 | 「写干净代码」之类不言自明的原则 |
删掉它会导致 Claude 犯错吗?如果不会,就删掉。
Boris Cherny · 保持指令文件精简的最佳判断标准约束层:建议和约束是两回事
❌ 建议(指令文件)
写在 CLAUDE.md 里:
「请不要删除数据库迁移文件」
- 大概率被遵守,但不保证
- 上下文太长、任务太复杂时可能被忽略
- 适合:编码规范、风格偏好、架构指引
✅ 约束(Hooks / CI / Sandbox)
PreToolUse hook 拦截对 migrations/ 目录的删除操作
- 100% 可靠,不受上下文影响
- 程序级、确定性、不可绕过
- 适合:安全红线、生产环境保护、不可逆操作
两个实用的 hooks 示例
- Claude Code 的 Hooks:二十多种生命周期事件,最关键是 PreToolUse——可以返回 deny 信号,从程序层面阻止操作。Anthropic 官方:「CLAUDE.md 的指令是建议性的,hooks 是确定性的,保证动作一定执行。」
- OpenAI 的硬约束三层:①依赖层架构(Types → Config → Repo → Service → Runtime → UI,只能沿固定方向依赖);②自定义 linter(Codex 自己写的,错误信息带修复指导和文档链接);③CI 强制(物理上合不进主分支)。
- Codex 的 Sandbox:默认模式只能写工作区文件、网络关闭;.git/ 和 .codex/ 始终受保护。「agent 做不了的事就是做不了」——不是在规则层面告诉它不要做,是在环境层面让它没法做。
- 一个有意思的细节:你可以让 Claude 自己写 hooks——「Write a hook that runs eslint after every file edit」,agent 给自己套上约束。
问自己:agent 违反这条规则,后果是什么?代码风格不一致——恼人但不致命,建议就行;删掉了生产数据库——灾难性后果,必须约束;推到了 main——可以 revert 但很麻烦,约束。约束不限制 AI 的力量,约束让 AI 的力量变得可信。
能力层与记忆层:agent 的天花板
- Skills:放在 .claude/skills/ 目录,一个 .md 文件定义一个能力。平时不占 context,按需加载。设计原则:每个 skill 做且只做一件事,描述写得像给同事的一句话交代——「帮我把文章发到飞书」比「执行飞书 API 文档创建流程」好。
- MCP:AI 编程工具的 USB 接口:一个协议连接数据库、API、网页、GitHub、Jira、Slack。Goose 通过 MCP 连接 3000+ 服务;Stripe Minions 深度依赖 MCP 和工具扩展。
- 工具设计(ACI):在工具文档和测试上花功夫,和在 UI 设计上花功夫一样重要。命名让 AI 理解意图(search_knowledge_base 而非 process_data)、有参数示例、报错告诉 agent 哪里出了问题。
- 动态记忆只有三个工具有:Claude Code(auto-memory)、Windsurf(Cascade Memories)、Cline(Memory Bank MCP)——其余全靠人工维护指令文件。
- 上下文腐烂(context rot):token 越多,准确回忆单条信息的能力越差,约 100 万 token 处性能断崖。Claude Code 官方直觉判断:如果修正 Claude 超过两次还是错,清空重来比继续修正好——上下文被失败方案污染后,继续修只会越修越歪。
编排层:让十匹马同时跑
- Boris 的 10–15 并发会话:最朴素的编排——人来当编排器。5 个在终端(shell 别名 za/zb/zc 切换)、5–10 个在浏览器,每个跑在独立 git worktree 上代码不冲突。这是他们团队内部 the single biggest productivity unlock。
- Anthropic 的三 Agent(GAN 直觉):规划者扩规格、生成者按 Sprint 实现、评估者像真人 QA 一样测试。「工程化一个严厉的独立评估者,远比教一个生成者自我批判容易得多。」
- 穷人版三 Agent(三个会话窗口就够):①复杂任务先进 Plan Mode 让 AI 定计划(可再开第二个 Claude 以 staff engineer 身份审查计划);②确认后切 Normal Mode 执行;③写完后开全新对话把结果贴进去「找出所有问题」——全新上下文的 AI 没有自我偏见。
- Writer/Reviewer 并行模式:一个写一个审。批量处理时一个文件一个进程,失败不影响其他文件。
- Agent Teams:Claude Code 目前唯一支持 agent 间直接通信的方案——一个 session 当 team lead 拆任务、收结果,teammates 之间可以直接沟通。Cursor 2.0 最多 8 个并行但互不通话(八匹马各跑各的,没有缰绳)。
| 场景 | 推荐模式 | 理由 |
|---|---|---|
| 改个 bug、加个功能 | 单 Agent | 上下文足够,没有并行需求 |
| 重构一个模块 | 单 Agent + Plan Mode | 需要全局视角,拆开反而丢上下文 |
| 同时改 5 个独立模块 | 手动多会话(Boris 模式) | 任务独立,不需要 agent 间通信 |
| 写代码 + 审代码 | Writer/Reviewer 双会话 | 消除自我审查偏差 |
| 复杂全栈应用从零开始 | Planner/Generator/Evaluator | 任务跨前后端,需要规划和验证 |
| 大规模迁移 / 批量处理 | Pipeline 脚本编排 | 任务高度重复,可并行 |
| 1000+ PR/周的企业规模 | Stripe Minions 式平台 | 需要专用基础设施 |
经验工程:谁来设计下一代的缰绳
- 中间层在消失:Shopify 把实习生项目从 25 人扩大到 1000 人(「实习生用 AI 的方式更有趣」);Block 以 AI 提升效率为由裁员 40%。两个方向,同一个问题。
- Junior 最重要的属性不是产出:Martin Fowler:「Junior developer 最重要的属性不是他们现在能产出什么,而是他们能成长为 senior developer。」如果 AI 替代了 junior 的产出却剥夺了成长路径,那不是效率提升,是透支未来。
- 设计好 harness 的人都有深厚领域经验:Mitchell 懂终端模拟器的每个细节、OpenAI 那 3 个人知道什么架构会在三个月后爆炸、Kent Beck 花了 30 年理解好代码。问题是这些经验从哪来。
- 花叔的诚实:「我能设计 harness,不是因为我天生懂系统设计,是因为我在和 AI 协作的上千小时里观察到了它的行为模式。」直觉来自踩坑,踩坑来自大量重复,大量重复来自时间。没有捷径,换了个赛道而已。
- 痛苦的形状变了,痛苦的总量可能没变:以前的赛道是写代码、调 bug、被线上事故搞到半夜;现在的赛道是写 CLAUDE.md、配 hooks、被 AI 的幻觉搞到半夜。
- 判断力从哪来?从做了很多次之后知道哪些路走不通来。工程师的核心贡献不是代码,是判断力——判断构建什么、如何验证、何时信任输出、何时反驳。
- Karpathy 已经在身体力行了:2025 年 12 月起不再手写代码。AutoResearch 项目——630 行代码加一个 markdown prompt——2 天跑了 700 次实验。但那个 prompt 之所以有效,是因为写它的人有几十年的研究直觉。
你在教 AI 怎么做,AI 在学你怎么教。这个循环里,谁在设计缰绳,可能比谁在骑马更重要。这个我也不确定。留给你想。
《Harness Engineering》手册 · §18CLAUDE.md 指令文件
Claude Code 的指令文件,Markdown 格式,每次会话自动加载。原则:100 行左右,像地图不像手册。
AGENTS.md 指令文件
Codex CLI 的指令文件,2026 年 3 月起由 Linux 基金会旗下机构管理,正在成为行业标准。
Hooks 钩子
Claude Code 的生命周期脚本。建议变约束的关键:PreToolUse 可以 deny,程序级硬拦截。
MCP 协议
Model Context Protocol,让 AI 连接数据库、API、网页等外部世界的「USB 接口」。
Skills 技能
一个 .md 文件定义一个能力,按需加载不占上下文。每个 skill 做且只做一件事。
Subagents 子代理
运行在独立上下文中,探索完只返回精简摘要(1000–2000 tokens),不污染主对话。
上下文焦虑 Context Anxiety
模型感知到上下文快满时会提前收尾、赶工。解法:context reset 或直接开新会话。
推理三明治 Reasoning Sandwich
xhigh(规划)→ high(实现)→ xhigh(验证)。全程拉满反而超时,得分最低。
Doom Loop 死循环
agent 锁定一个方向后反复做微小变动——同一种坏方法的 N 个变体。用循环检测中间件提醒它换方法。
Sprint Contract 冲刺合约
生成者和评估者在写代码前对「完成」的定义达成一致——人类团队里的技术评审,双方都是 AI。
ExecPlan 执行计划
OpenAI 的自包含设计文档,写到初级工程师也能端到端实现。不是给人看的笔记,是给 agent 执行的指令。
复利工程 Compounding Eng.
Boris Cherny 的 CLAUDE.md 维护方式:每次 Claude 犯错加一条规则,PR 里用 @.claude 标签更新。
路由器模式 Router
根 CLAUDE.md 只做路由,判断任务属于哪个工作区并指向子文件——每次只加载相关规则。
垃圾回收 GC Agent
Fowler 三支柱之一:专职 agent 只找文档矛盾和架构违规,对抗代码库熵增。
护栏保龄 Bowling w/ Bumpers
Mitchell 的比喻:护栏设好,球怎么扔都不会掉沟里——约束让 AI 的力量变得可信。
5 分钟看懂:Harness 到底是什么
六十年编程工具简史:一条暗线讲完
缰绳的五根线:Harness 五组件拆解
OpenAI Codex:零手写代码的百万行产品
从空文件开始:搭出你的第一个 harness
AI 时代的判断力:经验工程
上面的视频卡片为配套教程位(点击跳转 B站搜索「AI进化论-花生」频道)。建议先看图文图解建立框架,再用视频加深理解——图像负责「看懂」,视频负责「听一遍」。