合并 AI 生成代码之前:非技术创始人的变更证据包
一套面向非技术创始人的实用验收框架,用明确范围、风险分级测试、独立复核与恢复计划判断 AI 生成代码能否安全合并。
一个 AI 编程智能体修复了结账故障,顺手升级了三个依赖、修改了一个环境变量,并提交了一条 Pull Request。变更说明写得很完整,测试全部显示为绿色。另一个 AI 审查工具提出了两处小问题,智能体逐一修改后,合并按钮亮了起来。
这次变更已经可以上线了吗?
未必。测试可能只覆盖了智能体改动的函数,却遗漏了退款流程;依赖升级可能引入新的安装脚本;环境变量可能被错误打进浏览器代码;AI 审查工具也可能沿用了生成代码时的相似假设。解释越流畅,越容易让一项证据不完整的变更显得可靠。
非技术创始人不需要在一夜之间变成资深工程师。更可行的做法,是为合并设置一个小而明确的变更证据包:它要说明这次改动想解决什么、可能影响什么、哪些检查在最终版本上实际运行过、风险部分由谁复核,以及线上表现不符合预期时如何恢复。
证据包不能证明代码绝对没有缺陷,任何审查流程都做不到。它建立的是一条可辩护的决策边界:一边是“智能体说任务完成了”,另一边是“团队已经获得足够独立证据,可以承担发布决定”。
这是 Y Build AI 应用上线质量审查中的变更控制层。合并后,还要使用AI 构建界面状态审查验证用户真正看到的结果,尤其是涉及等待、权限、重复操作和恢复的改动。
Pull Request 是变更提案,不是安全证明
现在的编程智能体可以编写代码、解释改动、回复审查意见,再继续修改同一分支。这套流程很高效,却也可能把多个本应相互制衡的角色压缩进同一个系统。
代码作者声称改动范围很小;它生成的测试验证了自己的理解;AI 审查工具检查同一份可见 diff,又接受了同一个不完整需求。三方结论完全一致时,真实用户流程仍可能失败。
GitHub 官方文档对这个边界说得很明确:Copilot 代码审查不能保证发现 Pull Request 中的所有问题,也可能出错,因此应当仔细验证其反馈,并补充人工审查。文档还说明,部分文件类型不在其审查范围内,其中包括依赖管理文件。这不代表 AI 审查没有价值,而是说明:AI 审查意见是决策输入,不是决策本身。
同样的原则也适用于人工编写的代码。人也会误解需求、写出无效测试,或因为变更看起来熟悉而快速批准。AI 改变的是工作条件:它可以更快地产生更大的 diff,生成很有说服力的解释,并以极低成本继续修改。因此,验收流程必须依赖绑定到最终变更的证据,而不是依赖对作者的信心。
先写一份“变更契约”
查看代码文件之前,先用日常语言写出五项变更契约。创始人即使不读代码,也应当看得懂。
- 用户结果: 改动上线后,用户应该能够完成什么?
- 明确不做什么: 哪些相邻行为必须保持不变?
- 影响范围: 可能涉及哪些页面、API、数据存储、权限、定时任务、第三方服务和配置?
- 失败条件: 即使正常路径成功,出现什么情况仍意味着改动不安全或不完整?
- 验收证据: 看到哪些可观察结果,才足以支持合并?
用户可以重试一次失败的银行卡付款,同时不会生成第二张订单。本次改动不改变定价、税费、退款与订阅续费。验收必须包括付款失败测试、重试测试、重复提交测试、客户端不包含密钥的确认,以及经过核验的恢复路径。
这段话比“修复结账”有用得多。它给审查者设定了边界,也会暴露需求漂移:如果 diff 改到了退款逻辑,或新增了支付依赖,那么实际变更已经超出原来的描述。
变更契约应当在接受最终实现之前写好。如果代码和契约都由同一个智能体在完工后补写,它很容易描述“自己做成了什么”,而不是“产品原本需要什么”。
组成一份可检查的合并证据包
证据包可以直接放在 Pull Request 描述中。普通改动可以很短,高风险改动则需要更深入。以下六部分构成最低限度的有效记录。
1. 意图与范围
写入变更契约、被修改的用户流程,并链接原始 issue、客服反馈、设计稿或决策记录。如果没有来源明确的需求,要说明是谁批准了目标行为。
明确列出非目标。“不做数据库迁移”“不把新数据发送给第三方”“不修改授权规则”都是可以验证的边界;“顺手做点小清理”不是。
2. 按产品后果绘制 diff 风险图
不要把每一行改动视为同样重要。可以让智能体先按产品风险对文件分组,再由审查者确认分组是否合理。
| 风险区域 | 合并前必须回答的问题 |
|---|---|
| 登录与权限 | 用户是否能读取、修改或删除过去无权接触的内容? |
| 支付与权益 | 重试会不会重复生成订单、扣款、退款或授权? |
| 数据与迁移 | 改动是否向后兼容?能否在不丢数据的前提下恢复? |
| 密钥与配置 | 仅限服务端的值会不会进入日志、构建产物、截图或浏览器代码? |
| 外部动作 | 邮件、发布、删除或 API 写操作是否可能执行两次? |
| 依赖与构建脚本 | 哪些包、版本、许可证、传递代码或安装行为发生了变化? |
| 用户可见状态 | 加载中、空数据、失败、重试时分别会发生什么? |
这张风险图刻意使用产品语言。创始人未必理解抽象类层级,但可以追问:一次重试会不会产生两次扣款?错误状态会不会保留用户已经填写的内容?
如果智能体无法解释某个文件为什么发生变化,应当暂停合并。如果大量 diff 中夹着生成产物、锁文件、数据库迁移或基础设施配置,要把这些文件单独拿出来审查。
3. 绑定最终版本的可执行证据
“测试通过”信息不完整。至少要记录:
- 被测试的 commit 标识;
- 实际运行了哪些检查;
- 每项检查是通过、失败还是被跳过;
- 使用了什么环境;
- 每项关键检查覆盖了哪个场景;
- 哪些预期检查没有运行。
面向用户的改动不能只提供单元测试,还要提供场景证据。例如预发布地址、一段简短录屏、可访问性结果、移除敏感值后的 API 记录,或前后对比截图。证据既要展示被修改的行为,也要覆盖至少一个失败或边界状态,而不能只展示最理想的演示路径。
智能体生成的测试本身也需要审查。要看它是否验证了有意义的产品结果,还是仅仅重复实现细节。一个只确认“函数返回成功”的测试,可能看不出系统生成了两张订单、改错了账户,或向用户显示了并不真实的完成状态。
4. 供应链与数据路径证据
依赖改动要单列。记录所有新增、移除或升级的直接依赖,说明为什么需要它,锁文件和安装行为是否变化,以及已知漏洞与许可证检查是否运行。
GitHub 的依赖审查正是为这条边界设计的。它可以在 Pull Request 中显示新增、删除与升级的依赖,并通过检查阻止引入已知漏洞的新依赖。该功能是否可用取决于仓库类型与套餐,小团队也可以使用其他扫描器或人工审查锁文件。关键不是供应商,而是这项控制本身。
接着追踪数据流。改动是否新增了分析服务、AI 供应商、错误上报、远程存储或新的 API 调用?哪些用户数据会离开你的系统?其中是否包含提示词、上传文件、用户标识或密钥?数据目的地是否符合隐私说明与产品承诺?
一项代码改动可能通过所有功能测试,却因为悄悄改变了客户数据的接收方而不应被接受。
5. 独立复核与责任人
为合并指定一名人类责任人。这个人不必检查每个语法细节,但必须对“现有证据与产品风险相匹配”这一判断负责。
登录、支付、破坏性动作、数据库迁移、密钥、生产基础设施和敏感数据相关改动,需要独立技术复核。“独立”意味着审查者不能只是回头问写代码的同一个智能体“你确认安全吗”。换一个模型可以扩大问题搜索范围,但它依然是自动化辅助,不是承担责任的批准者。
GitHub 受保护分支可以强制 Pull Request 审查,在出现新 commit 时使旧批准失效,要求代码所有者复核,并阻止最后一次推送者批准自己的改动。小团队不必在每个仓库里启用所有规则,但必须有一道控制,防止高风险的 AI 生成版本绕开实际负责人。
审查意见处理完毕后,还要再次核对最终 commit。智能体为回应评论所做的“小修复”仍然是一次新变更,早期版本上的测试和批准不应自动授权后续版本。
6. 发布与恢复证据
批准合并与批准生产发布是两个不同决定。合并前要记录:
- 是否可以通过功能开关或逐步放量启用;
- 哪个生产信号表明改动按预期工作;
- 哪个信号会触发回滚或关闭;
- 由谁观察这些信号、观察多久;
- 具体的回滚、revert 或向前修复路径;
- 是否存在不可逆的数据操作。
不要只写“必要时回滚”。风险较高时,要实际验证恢复机制。数据库迁移、后台任务、Webhook 或外部通知已经改变状态后,简单 revert 可能无效。此时恢复方案可能是向前迁移、紧急开关、对账任务或人工修复。
让证据深度与后果匹配
如果修改错别字与重写支付流程都要经历相同流程,人们迟早会绕过规则。可以用简单的风险等级控制成本。
| 等级 | 常见改动 | 最低证据要求 |
|---|---|---|
| 低 | 文案、样式、独立文档 | 范围说明、预览、相关构建或链接检查 |
| 中 | 用户流程、API 行为、分析埋点、常规依赖升级 | 变更契约、风险图、自动检查、场景证据、明确责任人、恢复说明 |
| 高 | 登录、支付、权限、迁移、密钥、敏感数据、破坏性动作 | 完整证据包、独立技术复核、安全检查、预发布演练、受保护部署、验证过的恢复方案 |
风险取决于后果,而不是代码行数。一行权限改动可能是高风险,大型测试夹具可能是低风险。要问的是:如果假设错了,真实用户、真实数据或真实资金会发生什么?
如果暂时无法确定风险等级,先按更高一级处理,直到有人能够清楚解释为什么可以降低。
非技术创始人可以执行的审查顺序
面对一项中风险改动,可以依次完成下面七步:
- 先读变更契约,不打开 diff。你能否复述承诺的用户结果与明确非目标?
- 查看文件列表。是否意外出现支付、登录、数据、配置、依赖或部署文件?
- 打开最终 commit 的检查结果。预期检查是否真的运行,结果是否来自可信系统?
- 在预发布环境走一遍被修改的流程,测试正常路径、一个失败路径,以及一次重复或重试。
- 阅读未解决和已解决的审查讨论。新 commit 是否已经让旧批准或旧测试失效?
- 确认发布责任人、生产成功信号、停止条件与恢复动作。
- 只批准已经核对过的 commit。如果分支继续变化,重新收集受影响的证据。
让薄弱审查看起来很可靠的失败模式
智能体只审查了自己的需求理解
代码、测试、说明和审查都来自同一个不完整需求。加入独立产品场景,或让能够质疑前提的人参与复核。
绿色检查对应的不是最终版本
CI 或预发布证据收集后,智能体又为审查意见提交了新修改。每项结果都要绑定最终 commit,重要分支还应让旧批准自动失效。
diff 很小,影响半径却很大
配置、权限、路由或迁移中的一行改动可能影响所有用户。按后果分级,不能按 diff 大小分级。
正常路径掩盖了状态错误
演示第一次可以成功,但双击、重试、刷新、会话过期或超时后返回就会破坏流程。证据必须包含边界与恢复状态。
大量 AI 评论制造了“审查很充分”的观感
一长串风格建议可能遮住权限、数据与恢复问题。审查覆盖面比评论数量重要。
回滚只存在于文档里
revert 代码无法撤回邮件、扣款、已删除记录、已改变的数据结构或已经泄露的密钥。发布前必须写清不可逆影响和恢复责任人。
这套框架不能替代什么
变更证据包不是安全审计、渗透测试、合规评估,也不能替代有经验的工程判断。NIST 的安全软件开发框架把代码审查与分析放在更完整的安全开发流程中;OWASP 同样强调,人工安全代码审查应与自动扫描配合,而不是提供万能保证。
如果涉及受监管数据、资金流转、医疗、安全关键系统、密码学、身份基础设施或重大迁移,应当引入合格专家。如果团队里没有任何人理解相关代码或失败模式,不要用检查清单制造信心。应当缩小范围、推迟发布,或取得专业技术复核。
小团队也不必在尚无用户时就建立庞大审批体系。可以从受保护的主分支、最终 commit 检查、日常语言变更契约、明确合并责任人和恢复说明开始,再根据真实风险与重复发生的问题逐步增加控制。
合并前检查清单
合并 AI 生成代码之前,确认:
- 用户结果与非目标已经用日常语言写明。
- 变更文件符合声明的范围。
- 高风险区域被明确标注。
- 测试与检查绑定最终 commit。
- 跳过、缺失或不稳定的检查已经披露。
- 至少验证了一个失败或边界状态。
- 依赖与数据路径改动经过单独审查。
- AI 审查意见得到验证,而非自动接受。
- 有人类责任人承担合并决定。
- 高风险代码得到独立技术复核。
- 新 commit 会让相关旧证据失效。
- 已经明确生产成功信号与停止信号。
- 回滚或恢复方案具体且可行。
- 部署前已经理解不可逆影响。
智能体可以在几分钟内生成一条很有说服力的 Pull Request,信任应当多走一步:先写契约,再检查风险;把证据绑定最终版本;把代码审查与生产发布分开;提前知道如何恢复。做到这些之后,合并按钮代表的是团队能够解释并承担的决定,而不只是智能体任务的终点。