AI Coding 的下一步不是写得更快,而是可验收:蚂蚁数科 Harness 工程实践


随着大模型能力增强,AI Coding 正从代码补全走向由 Agent 独立执行完整任务。研发团队面对的问题也随之改变:当代码产出速度成倍提升,原有的需求约束、Code Review 和测试验收机制还能否跟上?如果验证能力没有同步升级,AI 带来的可能不只是效率,还有更集中、更难控制的质量风险。


在 AICon 全球人工智能开发与应用大会上,蚂蚁数字科技资深技术专家魏长征结合两个真实项目,分享了团队对这一问题的探索:在一个 40 多万行的 Rust 新项目中,从第一天开始将 Harness 内建进研发流程;在一个超过 60 万行的 C++ 存量项目中,先重建事实源和质量门禁,再让 Agent 参与仓库升级。经过改造,后者的代码缺陷率从 20% 以上降至个位数。


在魏长征看来,AI Coding 并没有创造全新的软件工程问题,而是以更高的产能,将需求模糊、目标漂移、事实冲突和验证不足等旧问题集中放大。Harness 也不是某一种具体技术,而是一套围绕约束、验证和验收建立研发闭环的思路。本文将沿着演讲的逻辑,呈现这套体系如何从实际问题中逐步形成,以及它在新项目和存量工程中的具体落地过程。


AI Coding 最近被频繁提起,但使用大模型辅助编程并不是刚刚发生的事情。


大模型出现不久后,很多团队已经开始尝试让模型写代码。那时还没有成熟的 Agent 工具,大家主要在对话框里提问、粘贴代码,让模型帮忙编写脚本、处理繁杂任务或者分析错误,确实可以节省不少力气。


随后,Cline 等工具开始以插件的方式嵌入 VS Code,大家逐渐在 IDE 中使用 AI。再往后,我们集中采购了 Cursor 一类的 AI IDE,开发者的使用方式从“在 IDE 中安装插件”,变成使用一整套内嵌 Agent 的开发环境。那一阶段,大家使用最多的能力还是 Tab 补全。


到了后来,Claude Code 等终端形态的工具出现,Cursor 的产品形态也发生变化。我们逐渐发现,IDE 可能已经不再是主要战场,对话框反而成为人与 Agent 协作的主要入口。


随着模型越来越强、工具可以完成的工作越来越多,我们交给它的任务也越来越完整。最初只是让 AI 写几行代码,后来则希望它独立完成一项任务,最后由人来验收。


因此,检验标准也在变化。过去,我们关心的是代码写得好不好;后来,需要判断功能是否正确;当 Agent 开始处理工程级任务时,仅仅判断某个模块能不能运行已经不够,还要看它放进整个项目以后,能不能在完整链路中稳定工作。


AI Coding 的产能提升得非常快,但研发团队的验证标准、验证方法和验证工具是否同步跟上了,这是目前最核心的矛盾。


一旦验证能力没有跟上代码生产能力,项目就很容易失控。Harness 工程之所以受到关注,正是因为大家开始意识到,只让 Agent 高速生产代码是不够的,还必须围绕它建立完整的验证闭环。


从早期的 Prompt 工程,到上下文工程、Harness 工程,再到最近讨论较多的 Loop 工程,不同概念反映的是同一个趋势:AI Coding 在研发工作中承担的角色越来越重要,处理的任务也越来越复杂。我们希望 Agent 做更多事情,同时又希望它把这些事情做好。



 AI Coding 新范式挑战:从传统研发范式到 AI Coding Loop


AI Coding 经常被称为一种新的工作范式。它的新,首先体现在开发者角色的变化上。


原来我们自己写代码,是代码的生产者;现在代码越来越多地由 AI 完成,我们逐渐变成代码和结果的评判者。再从更大的范围看,有了 AI 工具以后,一个人能够处理的任务跨度、涉及的知识面以及跨角色协作的范围,都会明显扩大。


但我也一直在思考:AI Coding 到底带来了哪些过去从未见过的挑战?


仔细想一想,很多问题并不是 AI 带来的,它们过去一直存在于软件研发过程中。


我很多年前在外企做软件工程师时,一个 Feature 可能并不复杂,但从开发到 Release 需要半个月,其中甚至有一周都在和国外同事做 Code Review,反复讨论实现细节。即使经过这么长的流程,软件仍然难免出现 Bug,但整体发布质量相对稳定。


后来,很多业务进入高速发展阶段。产品经理可能今天提出一个需求,要求三天以后上线。研发人员会觉得很多地方没有写清楚,但为了赶上发布时间,只能根据自己的理解补全。等功能上线以后,产品经理却发现,这并不是他想要的功能。


这就是研发过程中常见的目标漂移。


今天,我们把一项 Coding 任务交给 Agent,最后发现它实现的功能与预期不一致,很容易把原因归结为大模型的幻觉。但在责怪模型之前,也需要先问一句:我们自己的需求是不是也存在“幻觉”?目标、边界和验收标准真的说清楚了吗?


类似的问题在由人完成的软件开发中一直存在。AI Coding 带来的巨大变化,并不是创造了这些问题,而是它的速度太快、产能吞吐太高,所以把问题集中暴露了出来。


一个 Agent 可能在一天之内完成过去三个月才能完成的代码量。原本分散在几个月中的问题突然集中爆发,自然会让人觉得项目里到处都是问题。


本质上,AI Coding 放大的是研发流程中原本就存在的需求模糊、认知偏差、事实冲突和质量欠账。


过去,我们站在开发者的角度,可能会抱怨产品需求写得不清楚,需要自己不断脑补。今天,当 Agent 努力理解我们的任务时,我们实际上站到了类似产品经理的位置。


看清这个底层逻辑之后,解决问题的方向也就比较清楚了。Harness 工程要处理的很多挑战,在过去的软件研发流程中都能找到相应的解决办法。传统研发会做需求评审、架构评审、接口定义、Code Review、测试准出和任务拆解。进入新的工作范式后,我们需要思考的是,如何把这些经验迁移到与 Agent 协作的过程中。


AI Coding 的问题首先是“太快”。既然如此,我们也可以用同样快的方式进行验证。Agent 可以生成代码,也可以参与质量检查和 Code Review。


可以理解为“用魔法打败魔法”:当代码生产速度和验证速度能够匹配,再加上相应的 Harness 机制,就有可能形成类似传统研发的质量闭环,并在这个基础上提高整体效率。



 Harness 架构:来源于真实工程实践


AI Coding 的下一步不是写得更快,而是可验收:蚂蚁数科 Harness 工程实践


在我们的实践中,Harness 并不是一种具体技术,更像是一套验证闭环的思想。


至于 Harness 架构是不是一定要分成某几层,每个项目是不是都要采用同样的 Reviewer,其实没有那么重要。不同项目面对的问题并不相同,很难把一套做法原封不动地搬过去。


即使在我们自己的项目里,这套体系也不是一开始就完整设计出来的。最初并没有想清楚需要多少个 Reviewer,也没有预先决定每个 Reviewer 应该检查什么。更多时候,是随着项目暴露的问题越来越多,团队不得不寻找新的约束方法,最后才逐渐形成一个体系。


因此,从方法论角度所说的五层,更像是一种“马后炮”式的总结:项目跑了两个月,感觉效果不错,再回过头看,发现这些实践大致可以归为五层。它们背后的逻辑并不陌生,因为基本都能在传统软件开发中找到对应。


传统开发在编码前会进行需求评审和架构评审,也会编写架构设计文档和接口定义文档,提前明确任务目标、软件边界和设计约束。这些工作对应的就是约束层。


对抗验证对应的是 Code Review。在高速迭代中,Code Review 本来就可能流于形式,AI Coding 进入以后,这个问题更加突出。过去,一个 PR 超过 2000 行,人工审查已经很困难;现在,Agent 一次可能提交四五千行代码。如果因此直接放开限制,负责 Review 的人很快就会不堪重负。代码提交者自己都没有完整看过,其他人又怎么可能逐行看完?


但 Code Review 本身非常重要,不能因为代码量变大就放弃。我们需要考虑的是,怎样在 CI 流程中让 Agent 参与 Code Review。


证据层对应的是交付验收和质量准出。一次任务能否交付,需要有相应的报告和测试结论,不能只是 Agent 告诉我们“已经完成”。


另外两层围绕状态写入和目标对齐展开,与传统研发中的任务拆解和阶段性评审很相似。比如,把一个任务拆成十个 Sprint,明确每个 Sprint 要做什么,再写入 Backlog。即使中间休假一周,回来以后仍然知道任务进行到了哪里。Agent 也面临同样的问题:如果没有持续记录任务状态,它就可能发生漂移,或者因为上下文丢失而忘记之前做过什么。


具体到约束层,一个项目通常需要规定几类文档。


AI Coding 的下一步不是写得更快,而是可验收:蚂蚁数科 Harness 工程实践


首先是任务目标和非目标:要做什么必须写清楚,不能做什么也要写清楚;其次是事实源,必须明确以哪一份文档或定义为准,不能同时存在多个彼此冲突的数据来源,否则 Agent 也会困惑。


这些内容可以转化成不同形式的文档:有些方便人阅读,有些方便 Agent 获取上下文,还有一些适合机器直接检查。不同文档承担的作用不同,也会影响 Agent 的工作效率。


对抗验证也是一样。人做 Code Review 时,本来就会从不同角度检查代码:命名和格式是否规范,是否重复实现了系统中已有的能力,问题定位是否找到了真正的根因,还是只解决了当前的 Bug Fix Case,却没有覆盖其他同类问题。


因此,在 Agent 参与 Review 时,也需要让不同的 Agent 分别关注不同侧重点。


AI Coding 的下一步不是写得更快,而是可验收:蚂蚁数科 Harness 工程实践


证据层最重要的是可视化、可验证。在现在这种工作范式下,无论让人直接阅读大量代码,还是阅读大量 Markdown 文档,成本都很高。通过 HTML 验证报告以及架构图、流程图等可视化方式,人可以更快地看清测试过程、测试结果和最终结论。


中间过程同样需要被记录。我们现在有些 Agent 任务会连续运行十五到二十个小时。任务结束后,我们会担心它是否还记得最初的目标,执行过程中有没有跑偏。仅靠上下文压缩和模型自身的记忆,很难完全兜住这种长任务,所以通常会借助外部的工具,阶段性持久化它的工作状态。


任务完成以后,我们还会要求 Agent 重新复述:最初让它完成的到底是什么,任务目标是什么,它采用了什么方案,又是怎样达成目标的。每完成一个阶段都做一次这样的回溯,就能比较清楚地判断这一阶段的实现有没有跑偏。



  案例一:新项目构建——从第一天把 Harness 内建进研发流程


第一个案例是一个从零建设的 Rust 项目,代码规模超过 40 万行,基本由 Agent 从头参与开发。


项目开始时,我们首先考虑的是怎样建立初始仓库,而这件事也是从设计文档开始的。包括 AGENTS.md 在内的核心文档,首先要明确唯一事实源:哪些文件负责定义设计契约,API 应当以哪份文件为准,都必须说清楚,才能成为 Agent 后续开发时的可靠依据。


在项目级文档之下,每个模块还会有粒度更细的说明。我们不能把一份体量巨大的文档一次性加载进上下文,那样未必能取得理想效果。因此,文档需要分层,让 Agent 根据当前任务读取对应模块的信息。


每次发生变更时,我们还要求同步提交变更文档。从传统软件工程的角度看,这些事情并不新鲜,本来就是日常开发应该完成的工作,只是在实际执行中,人经常会偷懒。


有一个关于程序员的段子:程序员最讨厌别人的代码没有注释,也讨厌给自己的代码写注释。进入 Agent 时代以后,一个好处是 Agent 在这方面通常不会偷懒。只要团队把要求定义清楚,它就能够帮助维护相对完整的文档。


文档还需要与测试用例和代码持续对齐,并在每次变更时通过 CI 检查。只有这样,文档才能真正进入研发闭环,而不是写完以后便失去作用。


这个项目每天的变更很多,基本上每一个 PR,无论大小,都要有相应的变更文档。文档需要说明这次变更的动机和影响。一方面,负责 Code Review 的人可以先通过文档理解变更;另一方面,Agent 后续定位 Bug 时,也可以追溯到当时的变更记录。


项目运行一段时间后,如果出现问题,Agent 可能恰好检索到相关的变更文档,并从中发现当时遗漏的内容,从而更快地定位代码问题。


测试过程也需要可视化。Agent 可以快速生成大量测试,也可以把覆盖率做得很高,但人最终可能并不知道它到底测了什么,也无法判断测试路径是否有效,或者是否使用了大量无效 Mock。


单纯通过 Prompt 要求 Agent “认真测试”并不可靠。我们的做法,是把开发和测试过程做成可视化展示,并在每次发布时生成一套完整的可视化资产。


Reviewer 可以点开具体的测试路径,查看它覆盖了状态机中的哪些状态和跳转。如果一百个测试始终只覆盖两个状态之间的跳转,即使测试数量很多,质量也未必高,这种情况下就需要返工。


测试是否可信,不能只看数量和覆盖率,还要看它实际覆盖了哪些路径。


AI Coding 的下一步不是写得更快,而是可验收:蚂蚁数科 Harness 工程实践


Code Review 则通过 CI 门禁完成。CI 门禁是项目质量的重要兜底,也是最终的防线。我们把它分为硬门禁和软门禁。


硬门禁通过机器脚本确定性地检查约束。例如,要求提交变更文档却没有提交,脚本可以直接发现并要求补充,这类问题没有必要浪费 Token。


软门禁主要由不同 Agent 执行 Code Review。我们会配置不同模型和 Prompt,让它们从不同侧重点审查变更。


有的 Reviewer 重点检查 Contract,核对变更目标、代码实现和规则是否一致;有的 Reviewer 专门做“减法”,不断追问代码是否多余、能不能简化;还有的 Reviewer 负责检查项目中是否已经存在可以复用的能力。


一个 40 多万行的项目,无论是人还是 Agent,都不可能了解全部代码以后再开始工作。但 Reviewer 可以借助文档和代码检索,发现某条路径是否已经有现成实现。如果重复造轮子,不仅会带来冗余,还可能在系统中造成二义性。


这些不同的 Review 视角,需要在实际暴露问题以后逐步沉淀到门禁中。它们共同构成了新项目中的 Harness:从文档和唯一事实源开始,经过测试证据和多视角 Review,最终形成可验收的研发闭环。



  案例二:存量项目改造——先补 Harness,再做仓库升级


AI Coding 的下一步不是写得更快,而是可验收:蚂蚁数科 Harness 工程实践


第二个案例是一个代码规模超过 60 万行的 C++ 存量项目。从一次大规模重构算起,这个项目已经持续开发了四五年,团队有几十人,期间人员也经历过多次变化,维护成本本身就很高。


一开始,团队并没有正式鼓励大家使用 AI Coding。后来我们发现,其实不需要鼓励,很多人已经在私下使用,因为它确实能够节省时间,至少不用手工输入那么多代码。


但开发者使用 AI 生成代码以后,未必会明确说明这部分代码来自 AI。任务完成速度变快了,提交的代码量也变大了。架构师做 Review 时非常痛苦,但发布日期又卡在那里,很难简单拒绝提交。


一旦审查稍有放松,问题很快就会出现。有一段时间,这个项目的代码缺陷率飙升到了 20% 以上


我们开始治理这件事时,首先确认了一点:不能退回到禁止使用 AI 的状态。大家已经用上了这个工具,再要求他们不用,基本不现实。即使强调存量项目风险高,也阻止不了开发者继续寻找使用方式。


唯一可行的办法,是让大家光明正大地使用 AI,同时让团队也能够光明正大地约束和拦截它。因此,我们开始对项目进行 AI 友好化改造,把 Harness 的思路应用到存量工程中。


改造完成后的一个月,项目代码缺陷率从 20% 以上降到了个位数,变化非常明显。


问题背后的原因并不复杂。由于团队人员不断变化,新成员很难完整理解这样一个复杂项目,也很难了解项目历史。更麻烦的是,历史文档和代码本身也可能存在错误。新人基于这些信息编写代码,容易出现问题,负责 Review 的人也未必能够识别所有偏差。AI Coding 提高开发速度以后,问题只会暴露得更多、更快。


这种情况在很多老项目中都很典型:事实源不固定,文档分散、缺失或者内容错误;不同文档之间相互矛盾,文档和代码也可能不一致;项目中还存在大量重复实现,而这些“轮子”之间同样可能互相冲突。


所以,改造的第一步不是让 Agent 修改代码,而是让 AI 扫描整个项目。


这个过程大约持续了一到两周。Agent 从项目整体开始,自顶向下进入各个模块和接口,一层层梳理文档、代码和实际行为,找出其中的不一致。


对于已经存在的历史错误,我们不可能立刻全部修改。代码即使有问题,仍然承载着现有业务,不能简单删除或重写。我们能做的是先订正事实,重新编写文档,建立唯一事实源。


以后 Agent 进入项目,无论处理什么需求,都必须先读取这套核心文档。系统再根据任务内容,把它路由到对应的模块文档。


例如,一个任务涉及网络模块,就让 Agent 继续读取网络模块的说明。文档会明确告诉它,旧代码与旧文档在哪些地方存在出入,哪些历史实现虽然暂时保留,但并不是后续开发应该遵循的正确路径。


Agent 可以暂时不修改那些历史错误,但必须知道它们是错误的,也必须知道以后应该沿着哪一条路径开发。


完成文档体系重建以后,我们再把前面提到的 Review 规则和 CI 检查逐步放进门禁。存量项目的 AI 友好化,要先补上 Harness,再让 Agent 进入具体改造。


面对大型存量工程,我们还担心 Agent 一次修改过多代码,把项目影响面扩大。因此,在任务开始之前,团队会先进行功能切片和任务拆分,把边界相对清楚、影响范围比较可控的部分交给 Agent