AI 编程:从生成到验证,工程闭环的关键挑战
Info
AI 编程首先降低了编写代码的门槛。
然而,这迅速引出了一个新的难题:当代码生成得又快又多时,谁来确保这些实现是符合预期的?
许多团队最早遇到的并非代码生成环节的问题,而是在代码审查(Review)阶段。
AI 能快速生成大段代码,但如果每一次都需要研发人员逐行审阅、判断其质量和可合并性,这种体验会相当不轻松,甚至违背直觉。
这意味着,AI 编程的第一阶段是实现代码的生成和采纳。而其第二阶段,则是确保生成结果的可验证性、可修正性,并最终融入稳定的工程流程。
许多团队在应用 AI 编程时,会首先从代码审查、差异解读、风险检测等方面着手。
这一选择并不令人意外。
因为代码审查本身就是研发流程中固有的验证环节。
它关注的焦点并非“AI 是否能写代码”,而是“本次代码变更是否可以被接受”。
当 AI 承担了越来越多的实现工作后,人的角色并未消失,而是从“亲手编写代码”转向“评估 AI 所写代码的可用性”。
过去,研发人员在编写代码时,理解、实现与检查是同步进行的。
他们一边编写,一边判断逻辑是否符合需求;一边修改文件,一边确认是否破坏了原有逻辑;一边调试,一边补充边界场景的代码。
但 AI 的介入,将这一过程进行了拆分。
AI 负责生成代码。 人负责确认代码。
如果确认环节仍主要依赖人工逐行阅读代码、逐段理解差异、逐个评估风险,那么 AI 编程带来的效率提升,很可能在代码审查、测试和返工环节被抵消。
这就是验证问题开始凸显的时刻。
AI 编程最容易被察觉的变化是生成速度的提升。
过去需要研发人员花费半天时间编写的页面逻辑,现在可能通过几轮对话即可生成主体代码。过去需要反复查找的组件用法,现在 AI 可以根据仓库上下文直接补全。过去需要手动串联的状态、接口、页面交互,现在 AI 也能提供一套实现方案。
这些变化带来了直接的价值。
但在实际的研发流程中,代码的编写仅仅是任务进入下一步的开始。
它还需要被确认。
确认它是否准确理解了需求,是否在正确范围内进行修改,是否符合团队规范,是否保留了历史逻辑,是否覆盖了关键边界场景,以及是否能够顺利进入审查、测试和发布流程。
这些判断,并不会因为代码是由 AI 生成就自动消失。
相反,当 AI 能够一次性生成更多代码、修改更多文件、覆盖更多逻辑时,验证的压力反而会更加突出。
因为此时,人面对的不再是自己刚刚编写的代码,而是一组由 AI 生成的变更结果。
人需要重新理解它、评估它、确认它。必要时,还需要指出问题,引导 AI 进行修正。
因此,AI 编程的一个真实变化是:在生成成本降低后,验证成本变得更加显性化。
这也是为什么仅仅讨论“AI 能否编写代码”已不足够。
下一阶段更关键的问题将是:AI 生成的实现结果,如何被确认为可接受的?
在某些 AI 编程的实践场景中,团队会使用“出码率”来衡量 AI 代码的采纳程度。
即,在最终提交或合并到仓库的代码中,有多少比例来自于 AI。
这个指标是有价值的。
它能表明 AI 是否真正参与了实现过程,而不仅仅停留在建议、补全或对话阶段。
如果 AI 代码最终未能被提交,它更多地扮演了辅助角色。而如果 AI 代码大量被采纳,则说明它已开始承担一部分实际的研发工作。
然而,“出码率”主要衡量的是“采纳”,它不能替代“验证”。
因为代码被采纳,仅仅意味着它成为了本次实现的一部分;而一个需求是否可验收,还需要看它是否满足了任务目标、业务语义、交互预期、工程规范和回归要求。
例如,一个看似简单的列表筛选需求。AI 可能已经完成了主要的代码修改:增加了筛选选项、补充了状态值、调整了接口参数、更新了列表请求逻辑。
从代码层面看,它已经产生了实现结果。但进一步审视,仍会存在许多问题需要确认。
这个新增的筛选选项是否与已有的筛选条件保持一致?状态值是否与后端约定完全对齐?切换筛选条件后,分页和搜索状态是否符合预期?在数据为空时,是否沿用了团队统一的空状态组件?这些修改是否影响了其他筛选条件或历史逻辑?
这些问题最终决定了这个需求是否可以被验收。
因此,出码率越高,验证就越显重要。
并非出码率不重要,而是当越来越多的实现由 AI 完成时,团队就越需要一套机制来确认:这些变更是否可被接受,哪些问题可以被自动化发现,哪些风险必须由人工判断。
否则,出码率可能演变成一个孤立的数字。
它能说明 AI 编写了大量代码,却无法说明这些代码是否可靠、是否可交付、是否适合规模化复用。
在之前的探讨中,我一直强调一个观点:当 AI 开始承担执行任务时,研发任务不能仅停留在需求文档、设计稿、接口文档和自然语言描述等层面,而需要被转化为更稳定的任务表达形式,即 Task IR。详见:为什么 Spec 不是终点,而只是中间产物?软件研发正在从 Spec 驱动,走向表示驱动(RDD)
本文对验证的讨论,实际上是在这一基础上更进一步。
任务表达不仅是为了让 Agent 能够执行,也是为了让系统能够判断执行结果是否满足既定目标。
如果一个任务仅停留在原始输入阶段,Agent 或许能凭借模型能力猜测一部分实现路径。但系统很难稳定地判断其实现结果是否符合任务目标。
这是因为系统不清楚任务的目标是什么、修改范围在哪里、哪些行为是必须遵循的、哪些边界是不能被破坏的、哪些验收条件是可以被检查的、哪些地方允许 Agent 自主决策,以及哪些地方必须回归人工判断。
因此,任务建模不仅仅是为了让 Agent 执行。它还具有另一层重要作用:任务表达让 Agent 明确知道要做什么,而自动化验证则让系统知晓是否满足了任务目标。
这两者实际上是一体两面。
缺乏清晰的任务表达,Agent 的执行会变得发散。缺乏可检查的验收标准,验证只能依赖人工最终的审阅。缺乏结构化的边界和约束,许多判断就无法从经验判断转化为系统能力。
这也是为什么端到端自动化不能被简单理解为:原始输入 → AI → 代码。无论这些输入是需求文档、设计稿、接口文档,还是仓库上下文,中间都需要一层更稳定的任务表示。
它不仅是代码生成的输入,也是验证的依据。
过去我们讨论 Task IR、需求理解和任务建模,更多是在回答:如何让 AI 更稳定地执行任务?
现在进入验证问题的讨论,实际上是在继续回答另一个问题:如何让系统更稳定地判断任务是否完成?
从这个角度看,验证并非任务表达之后额外增加的环节。
它是任务表达能否构成一个完整工程闭环的关键一环。
在传统的研发流程中,测试是验证最常见且最容易被感知的部分。
但在 AI 驱动的研发自动化中,验证不能简单等同于测试。
测试更多地回答:“代码运行后,某些用例是否通过?”
而验证则需要回答:“这个任务是否已经满足了可验收的条件?”
这两个问题虽然有交集,但并非完全一致。
以列表筛选为例。如果 Agent 完成了代码修改,页面能够正常打开,构建也能通过,这仅仅说明它在工程层面没有立即失败。
但这还远远不够。
我们还需要确认:选中筛选选项后传递的参数是否正确,列表数据是否真的被过滤,分页和搜索状态是否符合预期,空状态和加载状态是否沿用了原有规范,以及是否对其他筛选条件造成了影响。
这些问题中,有些可以通过自动化测试来覆盖,有些则需要结合任务语义、页面状态、设计规范和历史实现来综合判断。
因此,AI 时代的验证,不是在代码生成之后简单地增加一个测试工序,而是需要贯穿整个任务执行和结果确认的全过程。
在本文中,我将首先将其收敛为两类:执行中验证和交付后验证。
如果不考虑完整的层级划分,端到端自动化中的验证至少可以关注两个关键节点:一类发生在 Agent 执行过程中,另一类发生在开发结果形成之后。
前者更侧重于过程纠偏,后者则更侧重于质量的把关。
执行中验证,发生在 Agent 执行过程中,或每一轮执行完成之后。
它关注的重点并非最终交付物是否满足发布要求,而是本轮执行是否朝着正确的方向推进。
例如,Agent 是否正确理解了任务目标,修改是否在正确范围内,是否引入了不相关的变更,关键行为是否已实现,验收标准是否基本满足,以及是否需要进一步反馈给 Agent 进行修正。
这类验证更贴近任务本身,也更贴近 Agent 的执行过程。
其作用在于尽早发现偏差,避免 Agent 沿着错误的方向走得太远。
如果没有执行中验证,Agent 可能在误解任务目标后继续生成大量代码。
直到最后审查时,人工面对的将不再是小问题,而是一整套需要重新理解、重新评估、重新修正的变更。
这也是为什么 AI 编程的验证不能仅仅放在最后。
越早发现偏差,越容易修正。越晚发现偏差,越容易导致返工。
交付后验证,发生在开发结果已经形成,准备进入测试、审查或发布流程时。
这里的“交付后”,并非指在发布之后才进行验证,而是指对已形成的实现结果,进行工程质量和交付可接受性的检查。
它更接近工程交付体系中的质量保障环节。
例如,构建过程是否通过,类型检查和代码风格是否满足要求,单元测试和覆盖率是否达标,端到端测试是否覆盖了关键路径,视觉回归是否发现明显偏差,现有功能是否受到破坏,以及是否具备进入测试或发布流程的条件。
执行中验证解决了“Agent 本轮执行是否完成、是否偏离、是否错误”的问题。
交付后验证解决了“本次开发结果是否能够进入工程体系”的问题。
这两类验证的位置不同,作用也不同。
执行中验证更像是过程的纠偏。交付后验证更像是质量的闸口。
前者降低了 Agent 沿着错误方向继续执行的可能性。后者降低了问题进入后续研发流程甚至线上环境的概率。
如果说 AI 编程的上半场,是让 AI 承担更多的实现工作,那么下半场就必须解决:这些实现结果,如何在过程中被纠偏,在交付前被确认。
验证不仅仅是发现本次哪里出了错。更重要的是,发现问题之后,这些错误要有明确的去向。
当验证发现任务未完成,它应该反馈给 Agent,触发下一轮修正。当验证发现某类错误反复出现,它应该被沉淀为规则、约束或技能。当验证发现输入信息不足,它应该反向推动输入检查。当验证发现 Task IR 的表达不完整,它应该补充相应的字段和验收标准。当验证发现某类需求无法自动判断,它应该被明确为人工验收点。当验证发现一个失败的样本具有代表性,它应该被纳入后续的 Benchmark 样本库。
这样,验证就不再是最后的“检查一下”。它将成为整个链路持续改进的机制。
这也是端到端自动化与普通 AI 编程的根本区别。
普通的 AI 编程可以依赖人工经验进行反复的对话修正。
但端到端自动化追求的是:将这些经验、判断和反馈,尽可能地沉淀到系统中。
只有这样,在下一次遇到类似任务时,整个链路才有机会变得更加稳定。
越深入真实的研发流程,越会发现一个普遍问题:代码可以由 AI 生成,也可以被团队采纳,但它是否可接受,不能仅凭人工最后凭借经验来判断。
什么是“完成”?什么是“可验收”?什么是“符合规范”?什么是“未破坏已有逻辑”?什么是“可以进入交付流程”?什么情况下需要重新执行?什么情况下必须交由人工判断?
这些问题过去主要由研发人员承担。
现在,如果希望 AI 不仅仅是辅助个人,而是能够融入研发流程,承担一类可复用、可衡量、可规模化的工程任务,那么这些判断就必须逐步显性化。
这也是验证问题真正核心价值所在。它并非讨论测试工具的多少,也不是在说要不要增加一些端到端测试。
它真正探讨的是:当执行者从人转变为 Agent 时,研发体系如何重新构建其判断能力。
如果说 AI 编程的上半场,让我们看到了代码可以由 AI 生成并被团队采纳。
那么下半场则需要证明:AI 生成的实现结果,能否被稳定地确认、持续地修正,并被纳入工程流程。
这一步比生成本身更具挑战性。
因为它要求我们重新梳理研发过程中那些过去依赖人脑完成的判断:需求是否清晰,边界是否明确,上下文是否充分,任务是否被正确表达,执行是否偏离目标,结果是否满足预期,失败是否能够回流,经验是否能够复用。
这些问题相互关联,共同构成了真正的端到端自动化。
因此,在后续审视 AI 编程时,不能仅仅询问:“它生成了多少代码?”
还需要进一步追问:“它生成的代码如何被验证?验证失败后如何修正?修正的经验如何沉淀?下一次遇到同类任务时,链路是否会变得更好?”
当这些问题开始得到认真解答时,AI 编程才会从单纯的工具提效,走向系统层面的整体提效。
也只有在达到这个阶段,端到端自动化才不再仅仅是一次成功的演示(Demo),而会演变成一套可评估、可复用、可规模化推进的工程能力。
本文首先回答了:为什么 AI 编程进入下一阶段,验证会变得日益重要。
然而,验证本身还需要进一步细分。
它不是一个单一的动作,而是一组发生在不同阶段、针对不同对象的一系列检查机制。
在下一篇文章中,我将继续深入探讨:在端到端自动化框架下,验证到底应该如何分层?从执行中验证到交付后验证,中间需要设置哪些检查点,哪些环节可以实现自动化,哪些部分仍然需要人工参与判断?