Harness Engineering 十四讲
副标题:郑晔风格——结构化教学体,写给一线工程师和技术管理者
开篇:写给那些”也开始让 agent 写代码”的团队
最近一年,我接触过的研发团队里,没有一支没在用 coding agent。无论是用 Cursor、Claude Code、Codex,还是企业内部基于开源模型搭的方案,agent 已经成了开发现场的标配。
但当我和这些团队的负责人坐下来聊,几乎每个人都会冒出同一类问题:
- “为什么我们的 agent 速度看起来很快,但合并的 PR 反而要返工三次?”
- “为什么我们让 agent 写测试,覆盖率上去了,可线上 bug 没少?”
- “为什么我们写了 AGENTS.md,但它好像越写越长,最后没人维护?”
- “我应该怎么衡量 agent 给团队带来的实际收益?是 PR 数?工时数?还是别的?”
这些问题听起来五花八门,但抽象一下,其实都在问同一件事:如何让 AI agent 在我们的工程系统里靠谱地工作?
这就是 Birgitta Böckeler 在 Martin Fowler 的网站上提出的”Harness Engineering”想解决的事。这里要先澄清一点:那篇《Harness engineering for coding agent users》虽然挂在 martinfowler.com,但作者是 Thoughtworks 的 Birgitta Böckeler,不是 Fowler 本人。所以下文我说”Fowler / Thoughtworks 思想脉络”时,指的是这一整脉技术思想生态——重构、CI/CD、测试金字塔、技术债、演进式架构——而不是把所有观点都安到 Fowler 个人头上。
我打算用 14 讲,把这个话题讲透。每一讲都对应一个核心概念,配实践建议,最后给一份可以发给团队的 checklist。希望这套内容能成为你和团队讨论”我们怎么用好 agent”时的一份共同语言。
第 1 讲:先看清楚 Harness Engineering 到底在解决什么
核心结论:Harness Engineering 不是新名词,它是软件工程基本功在 AI 时代的延伸。
我们先来定义。Böckeler 在那篇文章里给出的描述是:harness 是 agent 周围的那一整套外部工程环境,包括上下文、规范、质量检查、工作流指导、工具、测试、反馈信号——也就是让 agent 知道自己有没有走偏的全部机制。
注意她用的英文词是 harness。这个词在马具里的意思是”挽具”,是马身上那套缰绳和肩带。它不是用来禁锢马,是用来让马的力量被引导到对的方向。这个词选得非常精确:它不是笼子,也不是牵绳,是一整套让强大但不完全可控的执行体能被驾驭的环境。
Böckeler 在文章里直接借用了控制论的语言。她说,agent 的 harness 像控制论里的 governor(调速器):它结合前馈(feed-forward)和反馈(feedback),把代码库调节到期望的状态。
这就把问题的层级拉高了。我们要解决的不再是”怎么写好提示词”,也不是”怎么挑一个更好用的 IDE 插件”,而是:怎么设计一个让人类、agent、代码库、测试、部署、生产监控、用户反馈共同构成的可控系统?
你会发现,这个问题描述其实是软件工程一直在问的老问题。Martin Fowler 写《Refactoring》《Continuous Integration》《Continuous Delivery》《Building Evolutionary Architectures》,本质上都在解决一个问题:如何让一个大型软件系统,长期、安全、快速地演进? AI agent 的到来没有改变这个问题,只是把它放大了——因为变化的速度被拉到了人类阅读速度之上。
所以我建议你建立这样一个心智模型:
Harness Engineering = 在 AI agent 时代,把软件工程的”基本功”重新组织成一个可执行、可观测、可治理的反馈系统。
带着这个框架,下面 13 讲的所有内容,都会显得顺理成章。
第 2 讲:澄清一个常见误会——Harness Engineering 不是 Prompt Engineering
核心结论:提示词是控制策略的一种表达,但真正的控制系统依赖多层传感器和反馈闭环。
我经常听到团队负责人这样汇报:”我们今年重点投入了 prompt engineering,沉淀了一批高质量提示词。”
这是好事。但如果你仅仅停在这一层,那其实只解决了 harness 的很小一部分。
我们用控制系统的语言来对比:
- Prompt engineering:关注”我们怎么对模型说话”,对应控制论里的”控制信号设计”。
- Harness engineering:关注”我们怎么搭一个让错误更容易暴露、好行为更容易发生、偏差更容易被纠正的工程环境”,对应控制论里的”整个被控对象 + 调节器 + 传感器 + 反馈通路”。
提示词是 feed-forward,是 agent 行动之前给它的引导。而 harness 还包括 feedback——agent 行动之后,靠测试、类型检查、lint、CI、静态分析、生产监控、用户行为这些信号让系统发现偏差,并修正偏差。Böckeler 的原文里,她甚至直接说:harness 像一个 cybernetic governor。她不是在用比喻,她是在指出方向——这件事必须用控制论的方式去想。
我建议你在团队内部统一这样的语言:
| 维度 | Prompt Engineering | Harness Engineering |
|---|---|---|
| 解决问题 | 怎么让 agent 听懂我说什么 | 怎么让 agent 在系统里可靠地工作 |
| 主要对象 | 提示词 / 上下文 / few-shot | 工程环境 / 反馈系统 / 治理机制 |
| 触发时机 | 行动之前 | 行动之前 + 行动之后 + 长期演化 |
| 失败模式 | 表达不清 / 上下文不够 | 反馈不及时 / 边界不清 / 治理失效 |
这张表你可以直接搬到团队周会上用。它能帮你判断:当我们今天遇到的问题,是 prompt 层面的,还是 harness 层面的?
经验告诉我:超过一半被报告为”prompt 不好用”的问题,根因都在 harness 那一层——是反馈链路太慢,是测试在装样子,是规则没人执行。
第 3 讲:基本功复盘——持续集成、测试金字塔、重构、技术债、演进式架构
核心结论:Fowler 这一脉积累了三十年的工程实践,每一项都是一个反馈系统的部件。
要理解 Harness Engineering,先把基本功做一次盘点。我会快速过一遍,每一项都强调它和”反馈系统”的关系。
持续集成(CI)。Fowler 给 CI 的经典定义是:团队成员至少每天把工作集成到主线,每次集成都由自动化构建和测试验证,从而尽早发现错误。CI 的目标不是仪式,而是缩短反馈周期、降低集成风险、维持健康代码库。
我特别想强调他反复提的两点:第一,broken build 必须立刻修;第二,build 时间最好不超过十分钟。这两条不是程序员的洁癖,是反馈系统设计的基础——反馈太慢,开发者就会忽略;反馈越快,越容易形成行为闭环。
持续交付(CD)。CI 关注代码变化的快速验证,CD 把反馈范围扩展到发布能力。CD 的核心不是”每天都上线”,而是”随时具备安全上线的能力”。这背后是一种可控性思想:当发布变成罕见、巨大、不可预测的事件,组织就失去了反馈;当发布变成频繁、小步、自动化、可回滚、可观测的过程,组织就获得了控制。
测试金字塔。Fowler 网站收录的 Thoughtworks 文章《The Practical Test Pyramid》写得很清楚:底层是大量快速的单元测试,中间是服务或集成层测试,顶部是少量端到端 UI 测试。重点是,反馈系统本身需要架构:单元测试快、定位清晰,但覆盖系统交互有限;E2E 测试信心高,但慢、脆、维护成本高。好的反馈系统是不同粒度传感器的合理组合,而不是一味堆砌检查。
重构。Fowler 给重构的定义是:在不改变外部可观察行为的前提下,逐步改善代码内部结构。重构不是”把代码改漂亮”,而是回答一个工程问题:软件开发真正的困难,不是第一次写出某个功能,而是在未来无数次变化中还能保持系统可理解、可修改、可验证。所以重构是受控改变的技能,是后续所有”安全演进”的基础。
技术债。Fowler 把技术债解释为:代码中的 cruft 让未来修改和扩展变得更困难;这些额外成本就像债务利息,而清理结构问题相当于偿还本金。Fowler 的技术债象限提醒我们,债务不一定是愚蠢决策——团队可能有意识地承担债务,也可能在学习后才发现早期设计有局限。重要的不是”消灭所有债务”,而是让债务可见、可估、可还。
演进式架构与 Fitness Function。Fowler 在《Building Evolutionary Architectures》前言里说,架构不能交给偶然;演进式架构的核心是小步变化和反馈循环;fitness function 用于持续监控架构。这一项把”架构治理”也变成了反馈系统:以前架构靠架构师脑袋,现在架构靠可执行规则。
把这五件事放一起看,你会发现一个共同特征:它们都不是关于”写代码”的,它们是关于”让代码能被持续安全地改”的。
这就是 Harness Engineering 的根。AI agent 没有让这些基本功过时,反而让它们更重要——因为变化速度被放大了,没有反馈系统,速度等于失控。
第 4 讲:上下文工程——AGENTS.md 和服务模板该怎么写
核心结论:在 AI 时代,文档不再只是给人看的说明书,更是 agent 的操作环境。
很多团队接触 agent 后做的第一件事,是写 AGENTS.md。这是对的方向。但落地时常常走两个极端:
- 一种是写得太少。一句话:”我们用 Spring Boot,请遵循我们的代码规范。” agent 完全无从下手。
- 另一种是写得太长。十几页,把所有规范、风格、提交规则、目录布局、CR 要求、对线上事故的反思全堆进去。Thoughtworks 在 Radar 里专门提到这种现象,叫 agent instruction bloat——过长、冲突、臃肿的指令会被忽略或产生副作用。
正确的方式是 progressive context disclosure:分层组织,按任务渐进披露。
我建议你的团队按这个结构来组织:
- 全局原则(顶层 AGENTS.md,控制在一两屏内):领域语言、架构原则、技术栈、提交规范、不可触碰的边界。这一层只放”不会因任务变化的”内容。
- 服务级约束(每个微服务一份 AGENTS.md):本服务的限界上下文、对外契约、依赖规则、特殊约束。
- 模块级契约(关键模块的 README):本模块的不变量、典型调用方式、易踩坑的地方。
- 任务级验收标准(写在 issue / PR 描述里):这一次任务的目标、验收条件、关键测试点。
- 运行时反馈(CI / lint / test / fitness function):这些是机器自动给 agent 的硬性反馈,不依赖文档。
- 历史经验沉淀(事故复盘 / 重复 review comment):把它们升级为 lint 规则、模板约束或 agent instruction,而不是在文档里反复写。
OpenAI 在 2026 年那篇关于 harness engineering 的文章里也提了类似看法:repo knowledge base 应该成为系统记录,文档和检查应当结合,信息要渐进披露,并通过 lint、CI 等机械方式执行。这和我们对中国研发团队的建议是一致的。
几条容易被忽视的实操:
- AGENTS.md 必须版本化、CR 化,和代码同步演化。否则它会成为一份谁都不信的过时文档。
- 不要把”团队文化”塞进 AGENTS.md。团队文化靠人讲,靠 1on1。AGENTS.md 是给 agent 看的,要写它能执行的内容。
- 服务模板(service template)的价值远高于文档。一个好的服务模板让 agent 一开始就处在可治理状态:lint、test、CI、可观测性、健康检查全部默认就位。这比任何”风格指南”都管用。
- 对反复出现的 review comment,请把它升级为 lint 规则或模板。让机器替你说话,比让人不断重复管用得多。
记住一句话:好的上下文不是越多越好,而是越能被 agent 拿着用越好。
第 5 讲:Harnessability——让代码库变成 Agent 友好的环境
核心结论:不是所有团队都能同等受益于 coding agent,原因不在模型,而在代码库。
Böckeler 在文章里引用了控制论的 Ashby Law:一个调节器要有效控制系统,其可处理的变化复杂度必须至少匹配被控制系统的变化复杂度。她据此提出一个非常重要的概念:harnessability——代码库被 harness 化的难易程度。
她的判断标准是:类型检查、模块边界、框架和清晰结构会让代码库更适合被 harness;遗留系统和缺乏结构约束的代码库则更难被 agent 安全处理。
这个洞察对中国大量”在维护期”的团队尤其重要。我接触过一些金融、电信、政务系统的团队,他们的代码库历史超过十年,结构难以言说,文档与代码完全脱节。这种代码库直接放 agent 进去,结果几乎一定是混乱被加速:
- 没有清晰的限界上下文,agent 会跨越边界写代码;
- 没有类型系统或弱类型,agent 的猜测空间过大;
- 没有覆盖到位的测试,agent 改动后没有反馈;
- 没有架构规则的可执行表达,agent 会自然漂移。
所以我给这种团队的建议是反直觉的:先别急着推 agent,先做半年的 harnessability 改造。
可以从这几件事开始:
- 画清楚限界上下文。基于 DDD 思想,让团队明确每一块业务的边界。这一步不要求一步到位,可以从最核心的两三个上下文开始。
- 把核心模块的类型补完。如果你们用的是 Java / TypeScript / Go,把核心数据结构、对外接口的类型严格化;如果是 Python,至少在核心模块加上 type hint 并启用 mypy。
- 把测试先建起来。优先级是:先有契约测试和关键路径的集成测试,再补单元测试。这一步的目标不是覆盖率,而是”任何破坏行为都能在 CI 里立刻显形”。
- 把架构规则可执行化。用 ArchUnit、依赖扫描、模块边界检查、Spring Modulith 之类工具,把”不能依赖什么”、”不能跨过什么”变成 CI 里的硬规则。
- 建立服务模板。所有新服务从模板出发,模板默认带好 CI、lint、可观测性、健康检查、安全基线。
做完这些事,你的代码库才有”被 harness 化”的基础。然后 agent 进来才会真的产生杠杆,而不是制造灾难。
总结成一句话给团队听:AI coding agent 的生产力不是模型单独决定的,而是模型能力 × 代码库 harnessability × 工程反馈系统质量的乘积。模型能力大家差不多,真正拉开差距的是后两个因子。
第 6 讲:反馈传感器——六层反馈环的合理布局
核心结论:Harness 不是一个调节器,是一组同时呼吸、各有节奏的反馈环。
我把一个完整的工程反馈系统拆成六层。每一层各自有自己的延迟、自己的成本、自己的检查目标。
第一层:本地与编辑器反馈(毫秒到秒级)
类型检查、语法检查、格式化、IDE 提示、编辑器内 lint。这一层是反馈最快的部分,成本最低,应该最先建。
第二层:预提交与 CI 早期反馈(秒到几分钟)
单元测试、契约检查、静态分析、基础安全扫描、依赖审计。Thoughtworks Radar 把它叫做 “feedback sensors for coding agents”——agent 必须能直接访问这些反馈,让失败能即时触发自我修正。
第三层:CI 完整反馈(几分钟到几十分钟)
集成测试、API/服务级测试、性能基准、构建产物校验。这一层的关键是:要快但不能省。Fowler 的”十分钟构建”是一个好的目标线,超过这个线开发者就会开始敷衍。
第四层:部署与预生产反馈(几十分钟到几小时)
端到端测试、灰度发布、金丝雀、影子流量、合成监测。E2E 测试昂贵,所以要保留给最关键的用户旅程。
第五层:生产与用户反馈(小时到天)
错误率、SLO、可观测性、用户行为、留存、商业指标。这一层是 agent 看不到的——它必须通过人类工程师或自动化反馈通道回到代码改进。
第六层:架构与组织学习反馈(周到月,甚至季度)
架构漂移、依赖健康、模块耦合、变更热点、技术债利息、事故复盘、团队负担。这一层最慢但最重要,决定了系统的长期可演进性。
我的建议是:让你的团队画一张这六层的”反馈地图”,看哪些层是空的,哪些层是慢的,哪些层是没人看的。
我接触过很多团队,他们一二层做得不错,第三层勉强,四五六层基本是空的。当 agent 进来之后,他们的体感是”agent 看起来很灵但生产 bug 没少”。原因就在这里:agent 只能在前三层的反馈里自我修正,而四五六层的偏差,等到上线才发现,agent 已经又往前跑了几百步。
补齐这六层,是 Harness Engineering 落地最具体的工作之一。
第 7 讲:从 Human in the loop 到 Human on the loop
核心结论:在 AI 时代,人类的位置不是”在每一行代码上把关”,而是”监督和改进 harness 本身”。
传统的人机协作模型叫 human in the loop(人在回路中):每一个关键决策点都需要人来审查和批准。这个模型在 agent 一次只改一两行的时代是合理的。
但当 agent 一次提交可以改 30 个文件、写 60 个测试、引 3 个新依赖时,human in the loop 的成本变得不可承受。如果你坚持每行都看,team velocity 会比没用 agent 还慢。
Böckeler 在文章里提了一个更细的位置:human on the loop——人不在每个动作里,但在 loop 之外,监督、调整、改进反馈系统本身。
这不是放弃审查,是审查对象的转移。
| 维度 | Human in the loop | Human on the loop |
|---|---|---|
| 主要审查对象 | 每一行代码 / 每一次产出 | 反馈系统 / 规则 / 治理机制 |
| 主要问题 | 这次产出对不对? | 我们的系统在长出什么? |
| 时间分配 | 大量花在 review 上 | 大量花在改 harness 上 |
| 失败模式 | 来不及看 / 被淹没 | 长期看不见 / 反应慢 |
落到具体行为上,我建议你的团队这样分工:
- 核心代码:仍然是 in the loop。每一行人类都看。这是不能让步的红线。
- 边缘代码:上 on the loop。靠测试、生产反馈、监控兜底,PR 看结构和命名而不是每行。
- 临时代码:完全交给 agent,但要标记”过期日”。
同时,团队里要专门有人——不一定是专职——负责改进 harness 本身:观察重复出现的失败、定期 review lint 规则、维护 AGENTS.md、迭代服务模板、在 retrospective 里把人工经验升级为机制。这个角色我管它叫 harness steward,对应一个新工种。
记住:AI 时代工程师不是从”写代码的人”变成”点按钮的人”,而是从”局部执行者”变成”系统调节者”。
第 8 讲:度量——别只量速度,更要量协作质量
核心结论:错的指标会拉来大量低质量代码;对的指标能让团队真的变好。
AI agent 给组织带来一个最大诱惑:那些”看起来很美”的指标。
- 每周生成代码行数 ↑
- 每周合并 PR 数 ↑
- 每个工程师节约工时 ↑
- 测试覆盖率 ↑
我直说:这些指标如果单独看,几乎都是有害的。它们会鼓励团队”合更多 PR、写更多测试、生成更多代码”,而不是”做对的事”。
Thoughtworks Radar 2026 给出了一个更平衡的指标体系。我把它整理成三类,放在你的度量看板上:
第一类:局部反馈指标(看 agent 自己干得怎么样)
- 测试失败率 / lint 违规率 / 类型错误率
- agent 任务的迭代次数(迭代次数过多通常是上下文不够或边界不清)
- 构建时间 / pre-commit 时间
- agent 输出的 first-pass acceptance(一次通过率)
第二类:交付流指标(看团队整体怎么样,DORA 派系)
- Lead time for changes(变更前置时间)
- Deployment frequency(部署频率)
- Change failure rate(变更失败率)
- Mean time to recovery(恢复时间)
- 在此基础上,再加一个 review burden(人均 review 工作量)
第三类:长期健康指标(看一年后的事)
- 架构漂移指数(依赖跨界违规数 / 月)
- 依赖健康(过期依赖数、CVE 暴露数)
- 模块耦合演化(耦合度趋势)
- 测试有效性(mutation testing 杀死率)
- 技术债利息估算
- 生产事故趋势 / 用户体验信号
这三类指标合起来用,才能避免被 AI 表面速度欺骗。
但我必须提醒一件事,这是 Thoughtworks 自己也提的:指标应作为指导,而不是管理激励。一旦你把这些指标变成 KPI 和奖金挂钩,团队的行为就会立刻畸变——人会去优化指标,而不是优化系统。
我的建议是:把这些指标公开、定期 retrospective、用来推动团队对话和学习;但绩效评估仍然要靠综合判断、产品成果、长期能力。这是郑晔老师的偏见,但我相信它经得起检验。
第 9 讲:安全与 Zero Trust——给 Agent 设最小权限
核心结论:Coding agent 不是可信同事,而是需要受控权限的自动化执行体。
这一讲我想讲得短一点,但希望你记住每一句。
当 agent 可以读写代码、运行命令、调用工具、访问网络、安装依赖、甚至触发部署时,它的攻击面非常大。Thoughtworks Radar 直接把 sandboxed execution 列为 coding agent 的合理默认:要限制文件系统访问、网络访问、资源访问,因为 permission-hungry agents 会带来 prompt injection、tool poisoning、不安全路径等风险。
请按 Zero Trust 的原则来设计 agent 的运行环境:
- 默认沙箱:agent 在容器或沙箱里跑,文件系统、网络、密钥都隔离。
- 最小权限:每个任务只给完成它必需的权限。读代码不等于改代码,改代码不等于推送,推送不等于部署。
- 凭据隔离:production 凭据永远不进入 agent 上下文;secrets 用临时 token,过期失效。
- 可疑动作要二次确认:删除文件、改 CI 配置、改 IAM、改密钥、安装新依赖——这些都要 human approval。
- 审计日志:所有动作可追溯。一次事故发生时,你能清楚地知道是 agent 还是人,做了什么。
- 网络出口控制:agent 默认不允许访问任意外网,只允许白名单。
- 依赖审查:agent 引入新依赖时,自动经过供应链安全扫描。
我见过的最危险的实践,是有团队让 agent 拥有 kubectl 和生产数据库的写权限,理由是”这样它能自己 debug”。它确实能自己 debug,但有一天它也会自己删表。
记住一句话:把 agent 当作实习生,但是有键盘自动化能力的实习生。给它的权限请按这个心智模型来设。
第 10 讲:技术债治理——从季度盘点到持续传感器
核心结论:技术债不是季度盘点出来的,是持续传感出来的。
Thoughtworks 关于 scaleups 的一篇文章把技术债列为成长型企业的常见瓶颈。它把债务分成几类:代码质量、测试、耦合、低价值或未使用功能、过时库和框架、工具、可靠性和性能。这套分类很实用,可以直接用来给团队画一张债务清单。
但我想在这一讲讲得更具体:在 AI 时代,技术债治理不能只靠”季度复盘 + 临时清理周”。Agent 制造小不一致的速度比这个节奏快得多。我们要把识别嵌入开发流。
几条具体可落地的做法:
- 变更热点高亮:用 git history 找出最近 N 个月被频繁修改的文件。这些文件是 bug 和重复修复的高发区,应该提高 agent 在这里的检查强度,强制人类 reviewer。
- 回归缺陷与契约测试挂钩:当某个模块出现回归 bug,在修复 PR 中要求补充契约测试。这一步是机械的,可以写成 PR 模板。
- 依赖健康看板:依赖过期、CVE 暴露、license 风险,自动每天扫描,自动开 PR。这件事 agent 干得很好,比人类省心。
- mutation testing 抽样:每周对核心模块跑一次 mutation testing,看测试到底有没有真本事。覆盖率 100% 但 mutation kill rate 30%,意味着你的测试都在装样子。
- 架构边界检查:把限界上下文、依赖规则编码成 fitness function。一旦 agent 跨界,CI 直接挂掉。
- review comment 模式识别:每个月统计哪些 review comment 在重复。重复 N 次的,升级为 lint 规则或 AGENTS.md 条目。让机器替你说话。
- agent 一次通过率追踪:如果 agent 在某个模块一次通过率持续低于平均,意味着这个模块的 harnessability 有问题——可能是文档缺、可能是边界乱、可能是测试少。把它列入下个迭代的整理清单。
OpenAI 那篇 harness 文章里有句话我一直记得:反复出现的失败不是单个 agent 的”犯错”,而是工具、文档、护栏或验收标准缺失的信号。
这就是技术债治理的核心思路:把偶发人工判断转化为持续系统能力。
第 11 讲:团队治理——自治 + 平台 + 轻量规则
核心结论:好的治理不是中央审批,是让正确行为成为默认路径。
Thoughtworks 长期支持团队自治,但他们提出的”自治”是有结构的——轻量规则 + paved road + 反馈机制。我特别认同这个组合。
几条具体的组织设计建议:
- 平台团队提供 paved road,不做审批瓶颈。一条 paved road 是默认带好 CI、lint、可观测性、安全基线、agent harness 的服务模板。任何团队走这条路,享受全部基础设施;不走这条路,自己负责合规。这比”必须经过架构审批”管用得多。
- 业务团队拥有自己的 agent 用法。但所有团队的实践要进入一个共享的 radar / 知识库,新经验、新失败定期回流。
- 建立 harness steward 角色。可以是兼职,也可以是 community of practice。负责把跨团队的失败模式、好做法、规则演进沉淀下来。
- 中央团队做”信号”,不做”审批”。中央团队的工作是观察整体趋势:哪些模块在出 bug、哪些团队在累、哪些技术栈在过期、哪些 agent 模式在失败。把这些发现变成 paved road 上的下一步改进。
- 技术债治理纳入产品迭代。不要做”集中清债周”——那是创可贴。要让债务清理成为每个迭代里固定比例的工作(比如 20%),并由团队自己决定还哪些。
- 失败日志与学习闭环。每次 incident 之后,必须问三个问题:哪些反馈环没生效?哪些规则该升级?哪些 agent instruction 该改?把答案变成下个版本的 harness。
记住一句话:治理不是束缚,治理是让”不出错”成为最便宜的选择。当正确路径是默认路径,团队就不需要勇气去做正确的事。
第 12 讲:Harness 也会失效——警惕虚假安全感
核心结论:调节器自己也是系统的一部分,它会衰老、生锈、漂移、被滥用、被绕过。
讲到这里,我必须给你泼一盆冷水。
你做完了 AGENTS.md,搭好了 CI,铺了 fitness function,建了观测,定了指标,分配了 harness steward——这是不是就万事大吉了?
不是。Böckeler 自己在文章里也明确写了一个开放问题:你怎么知道你的 harness 是否真的有效?传感器从来不触发,是因为系统真的健康,还是传感器根本没覆盖到风险?
这是一个非常深刻的问题。我见过太多团队栽在”虚假安全感”上:
- 测试在装样子:覆盖率高,断言空洞,重构一改全部通过。
- lint 在装样子:规则全开,但都是格式化级别,没有约束架构。
- AI review 在装样子:每个 PR 都有 LLM 评论,看上去很专业,但漏掉关键安全漏洞。
- 架构规则过时:fitness function 还在检查三年前的架构,新结构早已经悄悄长出来。
- 指标驱动错误行为:为了 first-pass acceptance 高,agent 学会了写最保守的代码,用最简单的实现,跳过所有复杂边界。
- AGENTS.md 越写越长,没人维护:上面的规则一半已经过时,但新人来了还在按它走。
Thoughtworks 自己也明确指出:AI 生成的测试目前还不能完全信任,尤其是行为层面的 harness 仍然困难。
所以成熟的 Harness Engineering 必须包含一项工作:对 harness 自身的反馈环。
几条具体做法:
- mutation testing 定期跑:抽样核心模块,看测试到底有没有真本事。
- incident-driven harness review:每次 incident 之后,问”我们的 harness 为什么没拦住?”如果答案是”没有这条规则”,加一条规则;如果答案是”有但被关了”,搞清楚为什么被关。
- lint 规则定期 review:每季度把所有 lint 规则拿出来过一遍,删掉过时的,加上新发现的。
- AGENTS.md 定期 trim:每半年把它瘦身一次,删除过时和冲突的条款。
- 抽样人工 review:即使有 AI review,团队 leader 每月抽样几个 PR 自己看,校准 AI 的判断质量。
- 对 harness 本身做 retro:retrospective 不只是 retro 项目,也要 retro harness。
记住一句话:好的 harness 不是”永远正确的自动化规则”,而是一个不断被现实校正的控制系统。
第 13 讲:给团队的实操 Checklist
讲完前面 12 讲,我们落到一份团队可以直接拿走的 checklist。我把它分成五块。
A. 上下文与指令
- 团队有一份顶层 AGENTS.md,控制在两屏内,明确架构原则、技术栈、不可触碰的边界。
- 每个核心服务有自己的 AGENTS.md,写清楚限界上下文和对外契约。
- 重复出现的 review comment 已升级为 lint 规则或 AGENTS.md 条目,而不是反复在 PR 里写。
- AGENTS.md 与代码同仓库、同版本、走同样的 CR 流程。
- 有一份服务模板,新服务从模板出发,自带 CI、lint、可观测性、安全基线。
B. 反馈系统
- 本地与编辑器反馈(类型、lint、格式)齐全。
- 预提交反馈(单元测试、契约检查、静态分析)秒级可用。
- CI 完整反馈在十分钟内(核心服务),二十分钟内(整体集成)。
- 端到端测试只覆盖关键用户旅程,且稳定(flaky rate < 5%)。
- 生产可观测性能在小时级反馈到代码改进。
- 架构与债务反馈(fitness function、依赖扫描、热点统计)每周输出。
C. Harnessability
- 核心模块类型严格化,弱类型语言至少有 type hint + 静态检查。
- 限界上下文已画清楚,模块边界在 CI 里可执行。
- 关键路径有契约测试与集成测试,覆盖率不是目标,破坏行为能否被发现才是。
- 定期跑 mutation testing 抽样,了解测试真实有效性。
D. 安全与权限
- Agent 默认在沙箱里跑。
- Agent 没有生产凭据。
- 高风险操作(删文件、改 CI、改 IAM、装依赖)需要人类二次确认。
- 所有 agent 操作可审计、可回溯。
- 网络出口白名单。
E. 治理与度量
- 看板上同时有三类指标:局部反馈、交付流(DORA)、长期健康。
- 这些指标用于 retrospective,不直接挂钩个人绩效。
- 有 harness steward 角色,负责持续改进 harness 本身。
- 每季度做一次 harness review:lint 规则 / AGENTS.md / fitness function 是否过时?
- 每次 incident 之后,必须更新某一处 harness。
这份 checklist 不一定全做完才算合格。我建议你和团队一起过一遍,挑出最差的 5 项,作为下一季度的目标。三个季度做下来,整个团队的工程纪律会发生一次根本变化。
第 14 讲:小结——AI 时代的工程师是什么样的?
最后一讲,我想给你一个更整体的图像。
如果你把过去三十年 Fowler 这一脉的工程思想串起来,你会看到一条非常清晰的主线:
- 持续集成解决的是集成反馈。
- 持续交付解决的是发布反馈。
- 测试金字塔解决的是行为反馈架构。
- 重构解决的是结构改善与行为保持。
- 技术债理论解决的是长期修改成本的可见化。
- Design Stamina Hypothesis 解释了为什么短期速度不能替代长期耐力。
- 演进式架构与 fitness function 解决的是架构反馈。
- Technology Radar 解决的是组织层面的技术选择反馈。
- Harness Engineering 把这些思想带入 AI coding agent 时代,形成一个新的控制平面。
软件工程的核心,从来不是写更多代码,而是让系统可以长期、安全、快速地演进。AI 没有让这件事变简单,反而让它变得更急迫。因为变化的速度被拉到了人类阅读速度之上,没有 harness,速度等于失控。
所以 AI 时代的工程师,不是被 AI 替代的执行者,也不是仅仅审查 AI 写了什么的把关人。他是这个新工程系统的设计者:
- 他设计上下文,让 agent 知道我们在干什么;
- 他设计反馈环,让偏差能被快速发现;
- 他设计架构边界,让结构不容易漂移;
- 他设计指标,让团队不被表面速度欺骗;
- 他设计治理机制,让正确路径成为默认路径;
- 他设计学习闭环,让每次失败都让系统变得更健壮。
他是一个在控制论意义上重新定义自己工作的人。
如果你今天读完这 14 讲,能记住一句话,我希望是这一句:
AI 时代的软件组织,竞争的不是谁拥有最强模型,而是谁拥有最强的反馈系统。
模型大家都买得到。反馈系统得自己长出来。这件事不是几周就能完成的,但每一周都可以变好一点。
希望你和你的团队,从下一个 sprint 开始,就让它变好一点。
推荐阅读
- Birgitta Böckeler, Harness engineering for coding agent users(martinfowler.com)
- Martin Fowler, Refactoring, Continuous Integration, Continuous Delivery
- Neal Ford, Rebecca Parsons, Patrick Kua, Building Evolutionary Architectures
- 《人月神话》(Brooks)—— 关于”没有银弹”的那一篇
- 《Tidy First?》(Kent Beck)—— 关于先小整理再做改动
- 《领域驱动设计》(Eric Evans)—— 关于限界上下文
- Thoughtworks Technology Radar 2026 —— 重点看 “Putting coding agents on a leash” 主题
- OpenAI, Harness engineering for coding agent users(2026 年发表)