端到端自动化中的验证分层:不是写完再测,而是从输入开始就要验证
当 AI Coding 开始从“生成代码”走向“参与交付”,验证就不能再被理解为最后加上的一道测试关卡。
在端到端自动化里,验证需要被拆成一套分层系统:前面验证输入是否可执行、任务是否被稳定表达;中间验证 Agent 是否真的完成了目标变更、代码是否能进入工程体系;后面再验证交互、视觉、回归风险与人工验收点。
只有当这些验证层次被组织起来,AI 研发自动化才可能从“能生成代码”,走向“能稳定交付结果”。
一、验证不是写完代码之后才开始#
很多团队做 AI Coding 到一定阶段后,都会遇到一个相似的问题:
代码确实生成出来了。
PR 也能被采纳。
局部功能看起来也跑通了。
但到了真正准备 Review、提测、验收、发布时,问题才开始集中暴露:
需求边界有没有理解对?
页面路径是不是真的可用?
设计稿有没有还原?
有没有破坏已有逻辑?
这些结果到底能不能算作一次可交付?
上一篇文章里《AI Coding 的上半场是生成,下半场是验证|AI 代码被采纳,不代表需求可验收》,我们讨论过一个判断:
AI 代码被采纳,不代表需求已经可验收。
AI Coding 最先降低的是写代码成本。
当 Agent 能越来越快地生成代码,甚至生成的代码能够被团队采纳之后,新的问题就会浮出来:
这些实现结果,如何被确认是可接受、可验收、可进入真实工程流程的?
但继续往前走,会发现问题还不止于此。
如果我们只把验证理解成“代码生成之后再做 build、lint、单测、E2E”,其实已经晚了一步。
因为在真实的端到端自动化链路里,很多问题并不是发生在代码实现阶段,而是更早就已经埋下了。
可能是 PRD 没有说清楚边界。
可能是 API 字段、状态和异常分支不完整。
可能是设计稿只覆盖了主态,没有覆盖空态、异常态和交互状态。
可能是仓库上下文没有被正确拉进来,Agent 不知道应该参考哪个页面、哪个组件、哪个历史实现。
也可能是任务还没有被稳定表达,就已经被送进了执行阶段。
这时,后面的工程验证再严,也只能验证一个已经偏掉的结果。
所以,端到端自动化中的验证,不能只被理解为“写完之后再测”。
它首先要回答的是:
这个任务从一开始,是否已经具备被 Agent 稳定执行的条件?
这也是我现在越来越明确的一点:
端到端自动化中的验证,不是一个尾部动作,而是一条贯穿输入、表示、执行与验收的链路。
二、为什么验证必须前移#
在传统研发流程里,我们习惯把验证放在实现之后。
需求来了,研发理解,开始开发,开发完成后再进入联调、测试、验收和发布流程。
这套流程之所以能够运行,是因为中间有大量隐性的人工判断。
研发会在脑子里补齐需求边界。
会根据经验判断应该改哪里。
会知道哪些组件不能乱用。
会知道哪些状态需要兼容。
也会在写代码过程中不断做细小的取舍和修正。
但当 Agent 开始成为执行者,这些隐性判断就不能再完全依赖人的经验自然发生。
如果输入不完整,Agent 可能会自己补。
如果边界不清楚,Agent 可能会扩大修改范围。
如果仓库上下文缺失,Agent 可能会绕开团队已有实现。
如果验收标准不明确,Agent 可能会生成一份“看起来相关”的代码,但不一定真的完成了任务。
更关键的是,当执行成本下降之后,越上游的偏差,越容易被后续执行放大。
这张图想表达的不是“代码实现不重要”。
而是:当 AI 已经能够较快完成单点代码实现时,真正影响结果稳定性的因素,会更多转移到更高杠杆的位置上。
任务是否被正确表达。
上下文是否足够。
执行路径是否被组织。
验证闭环是否存在。
这些因素一旦出错,后面很容易出现“局部看起来完成了,但整体结果不可验收”的情况。
所以,验证必须前移。
它不只是为了在最后判断结果对不对,更是为了在执行链路中不断防止偏差被放大。
三、一个更适合端到端自动化的验证框架#
如果把验证放进完整的端到端自动化链路里,它至少可以拆成四个阶段、八个层级。
这几个层级不是彼此替代的关系。
输入验证不能替代工程验证。
工程验证也不能替代黑盒验收。
黑盒验收不能覆盖所有回归风险。
自动化验证也不应该取消所有人工判断。
它们分别回答不同问题。
越靠前的验证,越是在帮助 Agent 执行收敛,防止任务从一开始就跑偏。
越靠后的验证,越是在判断结果是否可以进入真实工程流程和业务验收。
如果不拆开,我们很容易把所有问题都混在一起。
比如 build 通过了,就以为需求完成了。
比如页面看起来能用,就忽略了已有链路被破坏。
比如 Agent 写了很多代码,就误以为它真的理解了任务目标。
比如人工验收指出问题,才发现前面根本没有明确 acceptance。
端到端自动化要往前走,验证就不能只是一个笼统的“测一下”。
它需要被设计成一套分层系统。
为了便于后面展开,可以先把这套分层整理成下面这张表:
| 阶段 | 层级 | 验证对象 | 核心作用 |
|---|---|---|---|
| 前置验证 | 输入验证 | PRD / API / 设计稿 / 仓库上下文 / 团队规范是否足够 | 防止输入不完整导致后续执行失真 |
| 前置验证 | 表示验证 | Task IR / Manifest / Acceptance 是否完整、边界是否清晰 | 防止任务还没表达清楚就进入执行 |
| 执行结果验证 | 实现验证 | 代码是否完成目标变更,是否改在正确范围内 | 判断 Agent 是否真的做完 |
| 执行结果验证 | 工程验证 | lint / typecheck / build / unit test / CI | 判断代码是否能进入工程体系 |
| 黑盒验收验证 | 交互验证 | 页面行为、状态流转、异常分支、用户路径 | 判断用户侧功能是否成立 |
| 黑盒验收验证 | 视觉验证 | 设计稿还原、组件规范、布局一致性 | 判断 UI 结果是否符合设计和业务页面预期 |
| 黑盒验收验证 | 回归验证 | 已有逻辑、相邻场景、核心链路是否被破坏 | 防止局部正确、整体破坏 |
| 人工验收 | 人工验收 | 复杂判断、业务语义、风险取舍、发布决策 | 保留必要的人类判断 |
四、第一阶段:前置验证——先判断任务能不能被执行#
端到端自动化里的第一类验证,不发生在代码生成之后,而发生在任务进入执行之前。
这部分可以称为前置验证。
它包含两层:
一层是输入验证。
一层是表示验证。
这两层看起来不像传统意义上的“测试”,但在 AI 研发自动化中非常关键。
因为很多失败不是 Agent 写错了,而是任务还没有准备好,就已经开始执行了。
1. 输入验证:输入是否达到可执行状态#
输入验证要解决的问题是:
PRD、API、设计稿、仓库上下文和团队规范,是否已经足够支撑 Agent 执行?
这件事在人工研发时代经常被低估。
因为人可以通过沟通、经验和上下文记忆补齐很多信息。
但 Agent 不一样。
如果 PRD 只说“新增一个筛选项”,但没有说明筛选项对应的状态值、默认状态、空态表现、和已有筛选条件的组合关系,Agent 很可能只能按字面完成一个控件。
如果 API 文档只给了字段名,没有说明枚举值、异常状态、分页逻辑和权限边界,Agent 可能会把一个局部字段展示做出来,但无法保证完整交互成立。
如果设计稿只提供了主页面截图,没有补充弹窗、空态、错误态、加载态,Agent 也许能还原一个静态页面,但无法覆盖真实业务操作路径。
如果仓库上下文没有准备好,Agent 不知道应该参考哪个历史页面、哪个公共组件、哪个 service 层封装,最后就可能写出一套看起来能跑、但不符合团队工程体系的实现。
所以输入验证不是检查“代码对不对”。
它首先检查的是:
这个任务的输入,是否已经达到可执行状态。
在我们的内部端到端自动化实践里,这一点非常明显。
很多时候,Agent 执行效果的差异,并不是模型能力差异,而是输入准备程度的差异。
同样一个需求,如果只给一句自然语言描述,Agent 很容易做成一个“能看”的结果。
但如果把 PRD、API、设计稿、仓库上下文、历史相似实现、团队组件规范都组织好,Agent 不只是更容易完成任务,也更容易生成符合团队工程习惯的实现。
这就是输入验证的意义。
它不是为了增加流程负担,而是为了避免后面所有执行都建立在不完整输入之上。
2. 表示验证:任务是否被稳定表达#
输入足够,并不代表任务已经可以直接执行。
因为 PRD、API、设计稿、仓库上下文,本质上仍然是分散输入。
它们来自不同角色、不同系统、不同表达方式。
真正进入 Agent 执行之前,还需要把这些输入收敛成一个更稳定的任务表示。
在我们的实践里,这一层通常会落到 Task IR、Manifest、Acceptance 这类中间表示上。
表示验证要检查的是:
任务目标是否明确。
改动范围是否清楚。
交互行为是否被描述。
数据模型是否被说明。
工程约束是否进入上下文。
验收标准是否可检查。
不确定项是否被显式暴露。
换句话说,表示验证关心的是:
这个任务是否已经从“人类能大概理解”,变成了“Agent 可以稳定执行、系统可以继续验证”的结构化对象。
这是 AI 研发自动化里很关键的一步。
在人写代码的时候,很多边界可以隐含在人的脑子里。
但当 Agent 成为执行者,这些隐性边界就需要被显式化。
比如一个需求写着“待发货列表增加状态筛选”。
人类研发可能自然会想到:
筛选项放在哪里;
和已有筛选条件如何组合;
默认值是什么;
接口参数怎么传;
列表为空怎么展示;
切换筛选时是局部刷新还是整页刷新;
是否影响其它 tab 或其它状态列表。
但对 Agent 来说,如果这些内容没有被表达,它就可能只完成其中一部分。
所以 Task IR 不是为了多写一份文档。
它的价值是把任务从自然语言、设计稿、API 文档、仓库上下文的混合输入中,收敛成一个可以被执行、被检查、被复用的表示对象。
表示验证就是在判断:这个表示对象是否足够稳定。
如果表示本身不稳定,后面的实现验证、工程验证、黑盒验收都会失去参照系。
这也是为什么在端到端自动化中,表示验证应该被视为第一类验证,而不是文档整理的附属动作。
五、第二阶段:执行结果验证——判断 Agent 有没有真的做完#
当前置验证完成之后,任务才真正进入执行阶段。
但 Agent 执行完成,并不意味着任务完成。
生成代码,也不意味着目标变更已经成立。
所以第二阶段的验证,重点是判断:
Agent 有没有真的完成任务,并且这个结果是否能进入工程体系。
这一阶段包含两层:
实现验证。
工程验证。
1. 实现验证:代码是否完成目标变更#
实现验证关心的不是代码有没有变化,而是 Agent 是否完成了目标变更。
这层要看的问题包括:
它是否改在了正确的页面、模块和组件里。
是否覆盖了 Task IR 里的核心目标。
是否实现了 acceptance 中的关键行为。
是否遗漏了边界条件。
是否引入了无关改动。
是否绕开了团队已有组件、工具函数和历史实现。
是否用一种“看起来完成”,但实际不可维护的方式解决问题。
在 AI Coding 场景下,这一层很重要。
因为 Agent 很擅长生成“相关代码”。
但“相关”不等于“正确”。
“看起来实现了”也不等于“完成了目标变更”。
比如它可能新增了一个筛选控件,但没有把筛选参数真正传到请求里。
可能改了页面展示,但没有处理空态。
可能完成了主流程,但遗漏了异常分支。
可能实现了当前页面,但破坏了同一组件在其它页面的复用。
也可能为了快速完成任务,绕开了团队已有的组件封装和状态管理方式。
这些问题,很多时候不是 lint 或 build 能发现的。
实现验证的核心,是拿执行结果反向对照任务目标:
这次变更到底有没有做完?有没有做在正确范围内?有没有覆盖关键行为?
上一篇文章里提到的“执行中验证”,在这一层会具体落到任务完成度、变更范围和关键行为覆盖上。
如果发现偏差,Agent 还可以继续获得反馈并修正。
所以实现验证不只是一个最终判断,也是一种执行收敛机制。
2. 工程验证:代码是否能进入工程体系#
实现验证之后,才进入大家更熟悉的工程验证。
这一层包括:
lint
typecheck
build
unit test
基础 CI
必要的覆盖率和静态检查。
工程验证很重要,但它的位置需要被放准确。
它不能证明需求已经完成。
它只能证明这次改动没有突破工程系统的基本约束。
build 通过,不代表业务路径正确。
typecheck 通过,不代表状态流转正确。
lint 通过,不代表实现方式符合需求意图。
单测通过,也不代表页面最终可以被验收。
但反过来,如果这些基础工程验证都过不了,代码也很难进入后续 Review、提测和发布流程。
所以工程验证是必要条件,但不是充分条件。
在端到端自动化里,这一层的价值,是把 Agent 的输出纳入现有工程体系,让代码至少满足团队的基础质量门槛。
它回答的问题不是:
需求是否已经完成?
而是:
这份代码是否具备进入工程流程的基本资格?
这个边界必须清楚。
否则,我们很容易把“工程通过”误认为“业务可验收”。
六、第三阶段:黑盒验收验证——从代码完成走向结果可用#
当代码完成目标变更,也通过基础工程验证之后,问题还没有结束。
因为端到端自动化真正要交付的不是一段代码,而是一个可用的结果。
这时验证视角要从代码和工程系统,转向用户路径、业务流程、视觉结果和整体回归风险。
这一阶段可以称为黑盒验收验证。
它至少包含三层:
交互验证。
视觉验证。
回归验证。
1. 交互验证:用户路径是否成立#
交互验证回答的是:
从用户视角看,这个功能能不能用?
它关注页面行为、状态流转、异常分支和关键路径。
比如:
页面能否正常进入。
筛选、提交、弹窗、跳转是否符合预期。
状态切换是否正确。
接口请求是否被正确触发。
返回数据是否正确展示。
空态、异常态、权限态是否被处理。
主链路是否闭环。
这和实现验证不是一回事。
实现验证是站在任务和代码角度看结果。
交互验证是站在用户路径和业务流程角度看结果。
对很多 B 端研发需求来说,真正的可验收性往往首先体现在交互链路是否闭环。
一个列表筛选需求,不只是页面上多了一个下拉框。
还要看选择状态之后,查询参数是否正确变化,列表是否局部更新,空结果是否展示空态,重置条件是否符合预期,是否影响其它筛选项。
一个弹窗新增需求,不只是弹窗能打开。
还要看打开条件、关闭行为、提交校验、接口异常、成功反馈、数据刷新是否完整。
这些东西很难只靠代码静态检查判断。
它们必须回到用户路径里验证。
所以在端到端自动化里,交互验证是从“代码完成”走向“结果可用”的关键一层。
至于黑盒验证具体如何落地,背后其实会涉及浏览器自动化、覆盖率采集、DevTools 调试协议、用例生成与执行编排等一整套工具链。
这些能力并不是孤立存在的。
浏览器负责真实页面执行。
调试协议负责状态获取与行为控制。
覆盖率负责判断路径是否真正被触达。
Agent 负责组织验证任务、分析结果并继续反馈修正。
执行编排则负责把这些能力串成一条真正可运行的验证链路。
这部分后面我也会单独展开。
2. 视觉验证:实现是否符合设计意图#
视觉验证处理的是另一类问题:
页面实现是否符合设计意图、组件规范和业务页面的信息组织方式。
过去很多人会把视觉验证理解成“像不像设计稿”。
但在真实业务系统里,视觉问题并不只是美观问题。
它可能影响信息密度。
影响操作路径。
影响页面结构。
影响组件一致性。
影响用户对状态和优先级的判断。
尤其是在 B 端页面里,字号、间距、对齐、表格密度、按钮层级、状态颜色、弹窗布局,都不是纯粹的样式细节。
它们背后往往承载着业务信息组织方式。
在我们最近的实践里,设计稿验证这一块也出现了新的变化。
一种比较有效的方式,是把设计稿转成图片,再让多模态模型理解目标页面。
首轮生成结果可能会出现字体偏大、间距不准、布局细节偏差等问题。
但当我们把当前实现截图和目标设计稿一起给到 Agent,让它做对比修正时,Agent 往往能够很快把视觉问题收敛掉。
这说明随着多模态能力提升,设计稿到页面结果之间的验证和修正,会越来越具备自动化可能。
但这里也有现实问题。
大图、多页面、多状态会占用大量上下文。
有些 Coding Agent 的子 Agent 不一定能直接读取图片。
设计稿中的交互状态、组件语义、业务规则,也不一定能从单张截图中完整恢复。
所以视觉验证不应该只停留在“把图扔给模型”。
它还需要和前面的输入验证、表示验证结合起来。
设计稿提供视觉目标。
Task IR 提供任务边界。
仓库上下文提供组件规范。
当前实现截图提供对比基准。
多模态模型提供差异识别和修正建议。
这些合在一起,视觉验证才更可能稳定工作。
3. 回归验证:有没有破坏已有系统#
交互验证和视觉验证更多关注当前需求是否成立。
但端到端自动化还必须关注另一个问题:
为了完成这次需求,有没有破坏已有系统?
这就是回归验证。
在 AI Coding 场景下,回归风险会更突出。
因为 Agent 可能会为了完成当前目标,做出一些超出预期的修改。
它可能改动了一个公共组件。
可能调整了一个 service 封装。
可能改变了一个状态流转。
可能影响了相邻页面。
可能让某个历史场景失效。
也可能引入了一个全局副作用。
当前任务看起来完成了,但系统整体稳定性下降了。
这就是“局部正确、整体破坏”。
回归验证关心的不是“这次需求有没有完成”,而是:
这次变更有没有破坏已有逻辑、已有路径和已有约束。
它和工程验证不同。
工程验证更多判断代码是否符合基础工程约束。
回归验证判断的是业务系统是否仍然稳定。
这也是为什么历史用例、历史需求回放、核心业务路径、关键页面快照,在后续会变得很重要。
它们不仅是测试资产,也会成为端到端自动化系统的评价基准。
如果没有回归验证,Agent 可能每次都能完成一个局部任务,但系统整体会在不断修改中变得越来越不可控。
七、第四阶段:人工验收——保留必要的人类判断#
端到端自动化并不意味着取消人工验收。
更准确地说,它是在重新定义人工验收应该出现在哪里。
过去,人可能要花大量时间看代码、改细节、补实现、查低级问题。
当 Agent 能承担越来越多执行工作,自动化验证也能覆盖越来越多机械判断之后,人的位置应该上移。
人不应该消失。
但人也不应该继续停留在所有低层细节上。
人工验收要保留在更高语义、更高风险、更需要业务判断的位置。
比如:
需求意图是否真的被满足。
业务规则是否符合真实场景。
某个边界是否可以接受。
某个实现风险是否值得进入后续流程。
是否可以进入 Review、提测、灰度或发布。
是否需要补充新的验证用例。
是否需要反过来调整 Task IR 或验收标准。
这些判断,很难完全交给自动化系统。
不是因为 AI 一定做不到,而是因为这里涉及的不只是“对不对”,还包括“是否合适”“是否值得”“风险是否可接受”。
所以人工验收不是自动化失败后的兜底。
它是端到端自动化体系里必须保留的一类高层判断。
真正成熟的自动化系统,不是让人完全消失,而是让人的判断被放在更高杠杆的位置上。
八、验证分层之后,Benchmark 才有基础#
回到这篇文章的核心。
端到端自动化里的验证,不是一道最后关卡。
它是一套贯穿输入、表示、实现、工程质量、黑盒行为、视觉回归和人工验收的分层系统。
前置验证,防止任务从一开始就跑偏。
执行结果验证,帮助 Agent 收敛到正确实现。
工程验证,让代码进入团队工程体系。
黑盒验收验证,判断用户路径和业务结果是否成立。
回归验证,防止局部正确、整体破坏。
人工验收,保留高语义、高风险、高取舍的判断。
当这些层次被拆清楚之后,验证就不再只是一次任务的检查项。
它还会变成后续 Benchmark 的评价维度。
也只有先拆清楚应该验证什么、如何验证、验证到什么程度,Benchmark 才有可复用、可比较、可度量的基础。
否则,我们很难回答这些问题:
不同 Agent,到底谁更适合完成这类任务?
不同输入组织方式,是否真的提升了执行质量?
Task IR 是否比直接 Prompt 更稳定?
仓库上下文、历史实现和团队规范,对结果有多大影响?
视觉验证、交互验证和回归验证,分别能覆盖哪些风险?
一次端到端自动化结果,究竟应该如何被判定为“成功”?
这些问题,都不是简单看出码率就能回答的。
出码率可以说明 AI 生成了多少代码。
但端到端自动化真正要回答的是:
这些代码是否完成了任务,是否符合工程体系,是否通过黑盒验收,是否没有破坏已有系统,是否能够被人接受并进入真实交付流程。
所以,验证分层不仅是端到端自动化的执行保障,也是后续 Benchmark 的前提。
下一步,问题会继续往前推进。
当我们已经知道应该验证哪些层次之后,如何把这些层次转成可复用、可比较、可度量的评估体系?
这是 Benchmark 要解决的问题。
但另一个同样现实的问题也会出现:
这些验证能力,具体应该如何真正跑起来?
比如:
黑盒验收如何自动执行?
浏览器自动化如何组织?
覆盖率如何采集?
页面行为如何回放?
DevTools 调试协议如何进入链路?
多 Agent 如何协同完成验证任务?
这些问题,已经不只是“验证理念”,而会进入真实的工程工具链设计。
后面我也会单独展开:
一套端到端自动化中的验证链路,究竟是如何通过 E2E、浏览器自动化、覆盖率采集和调试协议真正跑起来的。
前者决定我们如何评估端到端自动化的真实效果。
后者决定这套验证体系能不能真正运行。