最近在帮几个团队做AI编程落地评审,发现一个很有意思的现象:大家都在拼命试各种AI编程工具,但真正把AI稳定用进生产流程的团队少之又少。差不多的工具,有的团队效率翻倍,有的团队代码库一周就乱了套。差别不在工具本身,在于有没有一套驾驭AI产出的工程方法——这个缺口,就是Harness Engineering要解决的问题。
Harness这个词,本意是马具、安全带,工程领域也指用来约束和传导能量的装置。放在AI时代的软件工程语境里,它说的就是:如何定义、约束、引导AI模型的能力,让不确定的智能输出变成可靠、可测、可维护的软件资产。这套思路正在成为软件工程3.0阶段的核心方法论,也是AI编程从“个人玩具”走向“团队基建”的真正分水岭。这篇文章不聊概念空谈,直接聊我自己的理解、拆解框架和落地踩坑经验。
1. Harness Engineering的本质:从编写软件到驾驭智能
1.1 软件工程演进的三个台阶
要理解Harness Engineering为什么在当下被频繁提起,得先看软件工程这几十年是怎么走过来的。
软件工程1.0时代,核心是过程管理。瀑布模型、CMMI、需求评审、设计文档,目的是把人的思考过程规范化、可追溯,解决的是“少数天才写代码、多数人看不懂”的混乱。2.0时代,核心是反馈速度。敏捷、持续集成、持续交付、DevOps,把软件交付从半年一个版本压到一天多个版本,解决的是“市场等不起”的焦虑。
现在进入的3.0时代,变化更本质:代码的生产主体正在从“人的双手”向“AI生成、人来治理”迁移。你写代码的方式变成了一部分人写、一部分AI生成、人负责定义目标和验收。这时候,传统软件工程那一套“管人”的方法论不够用了,因为AI不像人那样会主动理解业务约束,它只对上下文里的指令负责。怎么给AI套上缰绳、设好围栏、修好赛道——这就是Harness Engineering的核心命题。
1.2 为什么传统软件工程管不住AI了
我见过不少团队把AI编程引入实际项目后,第一周很兴奋,第三周开始头疼。原因无非这几类:
第一,AI的产出是概率性的。同一个Prompt问两次,代码结构可能完全不同,这跟传统软件工程“输入确定、输出确定”的基本假设直接冲突。第二,AI的“聪明”伴随着幻觉。它会一本正经地调用一个不存在的API,或者把边界条件悄悄改掉,从代码逻辑上完全自洽,但行为就是变了。第三,传统测试体系建立在“人写的代码有清晰意图”之上,可AI生成的代码可能带着隐藏的假设,测试很难全部覆盖。
打个比方。以前做软件工程像训练一支施工队,你得管流程、管进度、管质量;现在你手里多了一台挖机,动力强劲但不会自己看图纸。Harness Engineering就是给这台挖机装方向盘、装限位器、装实时仪表盘。它的目标不是限制AI的能力,而是让AI的能力在可控范围内发挥到最大。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Harness Engineering的四大核心要素
我自己梳理了一套理解框架,不一定权威,但带着几个团队实践下来,方向是对的。核心就四件事:规格(Spec)、上下文(Context)、护栏(Guardrail)、反馈(Feedback)。四个词首字母合起来是SCGF,好记,也好落地。
2.1 Spec:把模糊需求翻译成AI可执行的语言
人跟AI协作的第一道坎,是需求传递。传统开发里,产品经理写PRD、工程师读PRD,中间靠的是人的经验和默契。但AI没有这种默契,你给它一句“把这个订单模块拆出来,顺便加个缓存”,它给你交出来的方案大概率跟你心里想的不一样。
所以Harness Engineering的第一步,是把需求写成机器可验证的规格,而不是停留在自然语言描述。我自己用的模板是Given/When/Then结构:
markdown复制功能:订单查询接口缓存
Given: 有效订单号 order_12345,缓存为空
When: 调用 GET /api/orders/order_12345
Then: 返回200,响应体包含订单金额,且Redis中写入 key=order:12345, ttl=300s
Given: 同一订单号在缓存有效期内再次请求
When: 调用 GET /api/orders/order_12345
Then: 返回200,响应体与第一次一致,且订单服务实际查询次数不增加
这么写的好处是,AI在生成实现代码的时候能拿到明确的验收条件,生成之后也能直接用这些条件写测试。我在实践中的体感是,凡是把规格写成Given/When/Then的任务,AI生成代码的一次通过率能提高一倍以上。所谓“一次通过”,不是指代码跑通,而是指代码经过评审后不需要推翻重写。
2.2 Context:为AI搭建认知围栏
AI模型的能力上限由参数决定,但它在具体任务里的表现上限,很大程度上由你给它的上下文决定。市面上很多AI编程翻车案例,根因往往不是模型不行,而是上下文给得不行。
最常见的错误是“把整个代码库喂给AI”。上下文窗口是有限的,塞进去越多无关文件,模型注意力就越分散,生成结果就越平庸,甚至开始胡言乱语。这就像你让一个资深工程师在堆满杂物的桌面上找一颗螺丝钉,他能找到,但效率一定比整洁桌面低得多。
我的做法是为每个核心模块维护一份AGENTS.md文件,放在模块根目录。这份文件不是给人看的文档,是专门给AI消费的“模块使用说明书”。内容大致包括:模块职责、关键依赖、常用命令、边界约束、常见坑。比如:
markdown复制# Order Service - AI Agent Instructions
## 职责
订单查询与状态流转,不涉及支付逻辑。
## 依赖
- 数据库: order_db(只读访问,禁止直接写库)
- 缓存: Redis cluster,key统一前缀 `order:`
- 消息队列: order_event_topic(仅发布订单状态变更事件)
## 常用命令
- 本地测试: make test
- 代码检查: make lint
## 边界约束
- 禁止修改 PaymentService 的公共接口
- 新缓存key必须包含统一前缀并设置TTL
- 异常处理必须返回业务错误码,禁止直接抛500
当AI需要改动这个模块时,先让它读AGENTS.md再动手,效果立竿见影。这个做法GitHub官方也在推,但它只是提供了约定,真正的功夫在于你如何把团队积累的经验沉淀进这份文件。我从2023年底开始给核心模块维护这类文件,到现在最值钱的那份已经迭代了60多个版本,全是团队用血泪踩坑换来的约束条件。
2.3 Guardrail:给AI的产出装多层安全气囊
有了规格和上下文,AI生成的代码质量会明显提升,但还是不能直接信。这时候需要护栏系统兜底。
我把护栏分成三层。第一层是确定性护栏,包括类型检查、Lint、编译检查。这些是底线,AI生成的代码必须过,不过就返工。第二层是测试护栏,包括单元测试、集成测试、契约测试。这一层开始有判断了,能拦住大部分逻辑错误。第三层是运行时护栏,包括监控告警、灰度发布、熔断降级。这一层解决的是“代码逻辑没毛病,但业务上出了问题”的情况。
三层护栏缺一不可。很多团队只做了第一层,AI生成的代码能通过编译、能跑通本地,就直接合进去了,结果上线出问题。还有个容易被忽视的点:AI生成的测试代码和实现代码同源,很容易出现“测试和实现一起错”的情况。后面踩坑实录里我会细说这个问题。
2.4 Feedback:让AI在闭环中越用越准
Harness Engineering里最容易被忽视、但长期价值最大的一环,是反馈闭环。
单次使用AI,本质是一次搜索;把每次使用后的结果沉淀下来,反哺下一次生成,才叫工程。具体怎么做?我目前在团队里跑通了三套反馈机制。
第一套,失败用例回流。AI生成的代码跑挂了,把报错信息、失败堆栈、修复后的正确实现,同步记录回规格文档或测试用例集。下次AI再碰类似任务时,这些就是few-shot样本。第二套,人工修正日志。每次人工修改AI生成的代码,顺手记一笔修改原因——是逻辑错了、规范不符、还是边界没覆盖。积累一个月,你会发现AI经常犯的错误就那几类,把这些规律写回AGENTS.md,AI的犯错率会肉眼可见地下降。第三套,Eval集。像维护回归测试一样维护一组评估任务,每次换模型、换Prompt模板、换上下文策略时,都拿这组任务跑一遍,用结果对比来判断改动方向对不对。
这套反馈机制,本质上就是把AI当成一个不断成长的新人工程师:你给他清晰的目标、充分的背景、明确的红线,然后在他犯错之后认真复盘、把教训沉淀成下一次的指导。长期下来,这个“虚拟新人”的能力会越来越贴合你的团队风格和业务特性——这才是AI编程真正拉开团队差距的地方。
3. 实战落地:一个AI辅助微服务改造的完整案例
概念讲再多,不落地就是空中楼阁。我拿最近帮一个团队做的订单服务拆分+缓存改造举例,完整拆解一遍Harness Engineering怎么在真实项目里落地。
3.1 场景设定与目标
背景是一个电商后端团队,订单逻辑耦合在单体应用里,高峰期数据库压力大。目标:把订单查询接口拆到独立服务,并引入Redis缓存。团队有6个人,3个后端熟手、3个初级工程师,引入了AI编程助手和AI Agent辅助开发。看起来任务明确,但实际操作中有一堆隐藏复杂度:接口契约怎么定、缓存一致性怎么保证、数据库权限怎么收敛、拆出去之后原有功能怎么回归验证。
3.2 任务Harness化拆解
一开始团队负责人找我,说准备直接把“拆分订单服务并加缓存”这个任务丢给AI编程工具,让它出一版改造方案。我拦住了。这个任务太大了,AI一次根本吃不下,硬做只会产出不可控的巨型Diff。正确的姿势是先把任务拆成一串可以独立验证的小任务。
我帮他们拆成了六张卡:
| 任务卡 | 完成定义 | 验收标准 |
|---|---|---|
| 1. 接口契约设计 | 订单查询接口的OpenAPI定义,含字段、状态码、错误结构 | 契约文档通过评审,虚拟数据可联调 |
| 2. 数据模型隔离 | 订单服务独立的数据库Schema,权限收敛到最小 | 新建只读账号,旧服务无法直连新库 |
| 3. 缓存策略确定 | 缓存key设计、TTL设置、失效策略 | 压测通过,命中率≥90% |
| 4. 服务骨架生成 | 基于契约生成服务骨架、数据库访问层、错误处理 | 编译通过,单元测试全绿 |
| 5. 缓存一致性保障 | 订单更新时主动失效缓存、补偿任务兜底 | 并发更新场景无脏读 |
| 6. 回归验证与灰度 | 全量接口回归、流量灰度切10% | 监控无异常、错误率<0.1% |
每个任务都定义了“完成定义”和“验收标准”,这才敢放心交给AI去跑。拆解的原则是:任务粒度要小到AI一次能消化、人一次能评审完,我一般控制在一个任务产生的代码Diff不超过300行。
3.3 结合AI Coding的执行流程
任务拆好之后,执行流程就很顺了。以第4张卡“服务骨架生成”为例,实际跑了一遍完整链路。
第一步,把任务卡翻译成AI能看懂的Prompt,核心是把验收标准写进去。Prompt模板大概是这样的:
text复制你是订单服务模块的后端工程师。请基于以下契约生成服务骨架:
[粘贴OpenAPI定义片段]
要求:
1. 使用Java 17 + Spring Boot 3,依赖管理用Maven
2. 数据库访问层使用MyBatis-Plus,只读操作
3. 所有错误返回统一业务错误码结构
4. 不实现缓存逻辑,只留接口
5. 生成后执行 mvn -q compile 确认通过
请先读模块目录下的 AGENTS.md 再开始编码。
第二步,AI生成代码后,我先花10分钟做人工Review。重点不是逐行看逻辑,而是看接口签名是否符合契约、依赖方向是否正确、有没有引入预期之外的东西。这个环节叫“结构性审查”,比逐行审查效率高得多,能拦住八成问题。
第三步,把AI生成的代码交给初级工程师,让他基于任务卡的验收标准补充单元测试。为什么不让AI自己写测试?因为前面说过,测试和实现同源容易共谋,换个工程师用独立视角去写测试,更容易暴露问题。
第四步,跑完整测试套件,然后进入第5张卡的缓存一致性实现。这一步同样拆解:先生成缓存读写工具类,人工Review后再接入业务代码,最后用并发压测验证正确性。
3.4 实际数据与项目收益
整个改造用了4天半完成,比团队之前预估的8人日少了将近一半。我记录了几个关键指标:AI生成的代码占整个项目代码量约60%,但经过人工Review后最终保留且没有结构性问题的比例在70%左右;核心接口的单元测试覆盖率达到85%;上线后缓存命中率92%,订单查询接口的P99时延从120ms降到18ms。
这些数字不是一个严格的对照组实验数据,但它能说明一件很重要的事:Harness Engineering提升的不是AI生成代码的速度,而是AI代码被团队接受并长期维护的可能。如果不上这套方法,AI生成的代码可能需要三倍时间去返工,最后还不如人写。
4. 踩坑实录:AI时代软件工程最常见的5个坑
4.1 把整个仓库塞给AI,上下文爆掉
这是最常见的错。有次一个工程师让AI工具“看着整个代码库”帮忙找一个Bug,结果AI在理解阶段就迷失了,给出了一个改到无关模块的方案。后来我们把AGENTS.md建起来、把任务相关的上下文裁剪到3-5个文件内,这类问题基本消失。
4.2 测试全绿,上线就挂
前面提到的共谋问题。AI写的实现和AI写的测试,往往是基于同一套错误假设生成的,测试再多也测不出问题。比如AI实现了一个接口,测试也按同样错误的参数去调用,两边自洽但业务上就是不对。解决方法是测试先行或人写测试,至少关键路径的测试必须由人独立设计。
4.3 AI重构后业务规则悄悄变了
AI非常喜欢“优化”代码。你让它加个日志,它顺手把三元表达式简化了、把异常吞掉改成log了、把边界条件“修正”了。代码看起来更简洁,但行为变了。我现在的做法是,在Prompt里显式声明“禁止修改与本次任务无关的逻辑”,评审时优先看Diff里那些“跟任务无关的改动”,一旦发现直接打回。
4.4 AI Agent循环失控
AI Agent能自己改代码、跑测试、发现问题、继续改代码。听起来很美好,但失控的时候也很可怕。有一次Agent为了修一个测试失败,绕了三圈,改出来一个“能过测试但完全不符合业务”的方案,差点合进主干。后来我们给Agent定了硬约束:最大迭代次数3次、只允许改指定的文件、每次修改必须附带目的说明。超出约束就停下来等人。
4.5 把AI输出当圣旨,跳过评审
最危险的坑不是AI写得差,而是人放弃判断。有团队为了让开发“提速”,AI生成的代码直接合入,代码质量以肉眼可见的速度下滑。我建了个评审SOP:AI生成的代码必须过两道关,第一道是技术负责人做结构性审查,第二道是任务发起人做业务符合性审查。多花30分钟,省掉后面几天的返工,这笔账怎么算都划算。
下面是一个问题速查表,方便团队对照自查:
| 现象 | 根因 | 解法 |
|---|---|---|
| AI生成代码越改越乱 | 上下文喂太多,模型注意力分散 | 建立AGENTS.md,按任务裁剪上下文 |
| 测试全绿但线上出问题 | 测试与实现同源自洽 | 关键路径测试人写,测试先行 |
| AI顺手改了业务逻辑 | Prompt缺少行为红线 | 显式声明禁止无关改动,Diff审查重点盯 |
| Agent无限循环改代码 | 缺少迭代边界 | 限定文件范围、最大迭代次数 |
| 团队质量下滑 | 过度信任AI输出、跳过评审 | 建立AI代码评审SOP,两道审查关 |
5. 团队落地Harness Engineering的路径和对未来的判断
5.1 从个人技巧到团队规范
Harness Engineering的落地点不在个人,在团队。要让这套方法真正产生规模效应,需要把“个人经验”升级成“团队规范”。
我的建议是三步走。第一步,选择一个核心模块做试点,把AGENTS.md写起来,把任务拆解模板跑起来,积累一个迭代周期的数据。第二步,把试点期间的经验固化成团队的模板和脚本:任务卡模板、Prompt模板、AI代码评审清单、Eval集维护流程。第三步,把这些规范接入CI流水线,让AI生成的每个合并请求自动过护栏检查、自动触发Eval集回归。到了这一步,Harness Engineering才真正变成了团队的基础设施。
5.2 和AI Agent、AI Infra的分工关系
现在业界说的AI Agent,解决的是“让AI动起来”的问题——能自己调用工具、自己写代码、自己跑测试;Spring AI这类框架解决的是“让应用接上大模型”的基础连接问题。但Agent和框架解决的是“能做”,Harness Engineering解决的是“能放心做”。一个Agent如果没有边界约束和结果评估机制,就是个淘气的实习生,能干活也能闯祸。
未来的技术栈分层会越来越清晰:底层是AI Infra,负责算力、模型、数据;中间是Agent框架和AI编程工具,负责执行;上层是Harness治理层,负责定义任务边界、评估产出质量、沉淀团队经验。越往上走,越考验工程团队自己的积累——这也是为什么同一个工具在不同团队手里效果天差地别。
5.3 对软件工程未来的判断
我自己判断,未来两三年,软件工程会慢慢变成一门“目标定义科学”加“结果仲裁科学”。人类工程师的核心技能不再是“怎么写代码”,而是“怎么把需求定义到AI能精确执行的程度”“怎么快速判断AI产出是否符合业务意图”。这跟过去几十年软件工程重心的迁移方向是一致的——从个人手艺到过程管理,从过程管理到反馈速度,从反馈速度到智能治理。
对你个人来说,现在最值得做的准备工作,不是追最新最强的模型或工具,而是选一个正在维护的核心模块,给它在项目里写下一份清晰的AGENTS.md,把团队积累的边界约束、常见坑、测试规范都沉淀进去。这件事投入不大,但它是你从“用AI写代码”走向“用Harness Engineering管理AI产出”的第一步,也是未来所有AI协作效率的起点。
我始终相信,AI不会取代工程师,但会用AI的工程师会取代不会用AI的工程师。而真正拉开差距的,从来不是谁把Prompt写得更好,而是谁能更快地建立起一套驾驭智能产出的工程体系。Harness Engineering,就是这套体系的起点。
