只有当证据证明目标用户结果在最终环境中成立,AI 生成的代码才算可以发布。Agent 的总结、干净的 diff 和通过的单元测试都很有用,但没有任何一项可以单独成为通用完成标准。

实用做法是建立一条证据阶梯:依次验证源码、最终生成物、集成运行时、用户动作和真实交付结果。

从用户结果开始

先写一句可观察的话:

这次改动后,用户可以完成 X,并得到 Y。

再列出不变量:URL、权限、数据归属、价格、状态和既有行为中,哪些不能改变。

没有这一步,验证很容易转向“什么最好测”,而不是“什么最重要”。

使用证据阶梯

  • 静态有效:类型、语法、lint、schema 和配置可以正确解析。
  • 聚焦行为:被修改的函数或组件通过最窄测试。
  • 集成成立:注册、依赖注入、路由、持久化和错误路径能协同工作。
  • 最终生成物:模板、脚本、metadata 和配置在生成后被直接检查。
  • 用户旅程:真实动作在有代表性的渲染环境中完成。
  • 交付结果:目标发布、URL、事件或产物可以从最终消费者读回。

验证到哪一层取决于风险和影响,但绝不能停在最终用户实际消费层的下方。

直接检查最终生成物

很多 Agent 错误藏在源码与输出之间:

  • 模板生成了无效 JavaScript;
  • Markdown 语法被原样显示在页面上;
  • 路由模块存在但没有注册;
  • 配置本身合法,却引用不存在的脚本;
  • metadata 更新了,页面正文仍然是旧版。

真正的验证对象,是浏览器、运行时、应用商店或客户最终收到的东西,而不只是源模板。

增加负向检查

Happy path 无法证明边界。请覆盖用户真实可能遇到的失败:

  • 无效输入;
  • 没有权限;
  • 旧状态;
  • 重复重试;
  • 上游超时;
  • 空数据;
  • 移动端布局;
  • 旧缓存。

幂等动作要用同一个身份重试,并证明逻辑上只落一次。Last-known-good 页面要模拟上游失败,并证明旧成功版本仍然可用。

分开 Builder 与 Reviewer 的证据

Builder 应报告执行命令和已知缺口;Reviewer 应独立对照原始目标、真实 diff 和最终输出。

有效复核至少回答三件事:

  • 硬事实:改动和检查真的发生了吗?
  • 意图:结果仍然符合用户目标和不变量吗?
  • 判断:选用的路径是否适度、可维护?

一条开发者复盘准确指出了核心错误:把 Agent 最后的自然语言回复当成完成。纠正方式是接受“done”前先要求证据:相关讨论

发布检查清单

产品结果

  • 目标用户动作成功。
  • 既有用户动作保持预期行为。
  • 文案和界面没有实现说明或模板残留。

代码与产物

  • 类型、测试和构建通过。
  • 最终生成物可以解析。
  • 最终路由或 bundle 包含改动。
  • 浏览器输出和日志不包含 Secret。

运行与交付

  • 部署身份对应目标版本。
  • 真实 HTTP 状态、页面 metadata 和正文一致。
  • 重试与失败行为不会破坏已有状态。
  • 临时测试对象已明确保留或清理。

会话交接

  • 证据绑定精确版本或命令。
  • 已知缺口明确。
  • 下一个会话不需要猜测发布了什么。

什么时候必须人工验证?

如果功能依赖布局、焦点、动画、登录、供应商状态或用户感知,就应该使用真实浏览器、设备或账号。自动化的作用是减少重复,而不是抹掉最终用户视角。

核心原则

不要问 Agent 是否完成了;要问最终消费者是否证明承诺的结果成立,以及失败场景能否继续保护这个结果。