AI 编码合并前风险登记:merge 之前要追踪的条目
专门给 AI 生成代码准备的合并前风险登记册:LLM 不会主动提示的七类风险、每个 PR 一行的风险备注,以及什么情况阻塞合并、什么情况只是警告。
我为什么开始给 AI 代码单独记一份风险登记
我不想再多一个模板。我只想在生产环境里别再被吓一跳。在第三次出事之后——某个 AI 生成的 PR 上线了我自己手写绝不会上线的东西——我终于接受一个事实:助手和我对"风险"的权衡完全不是同一套。助手优化的是"看起来像样、能编译通过"的代码;我要优化的是"合并之后我晚上还能不能睡着"。
于是我开始在每一个 AI 协作过的 PR 上写一行风险备注。不是文档,就是一句话:这次改动可能破坏什么,我为此做了什么。这一句话就是整份登记册。它写在 PR 描述里,被 CI 强制要求,也是我做评审时最先读的那一行。
模型不会主动标出的七类风险
七个分类。每个 PR 在写风险备注之前,都要对照这七类逐一过一遍:
- 安全(Security)。密钥被注入泄露、不安全的
eval、未经校验的输入跑到 shell 里、鉴权被某个辅助函数绕过。模型在本该用 parser 的地方,顺手就伸向了exec。 - 数据丢失(Data loss)。数据库写入、破坏性迁移、没带
WHERE的DELETE、文件覆盖、schema 被 drop 掉。数据是一扇单向门。 - 性能(Performance)。N+1 查询、没有上界的循环、热点路径上的同步调用、没做分页。演示数据集上很快,真实数据集上是灾难。
- 正确性(Correctness)。悄无声息的错误结果。差一错误、正负号写反、舍入规则错、异常被吞掉。代码照样跑,结果微妙地不对。
- 依赖(Dependency)。新引入的包、陌生的包、每周下载量只有十次的包。助手几乎什么都敢 import。
- 合规(Regulatory)。PII、GDPR、HIPAA、PCI,凡是碰到支付的一切。模型并不知道你在哪个司法管辖区。
- 运维(Operational)。新队列、新 cron、新 webhook——任何现在就需要被监控、但目前还没人盯着的东西。
那一行风险备注到底长什么样
这是我实际使用的格式。它故意写得很无聊。无聊,才能在赶时间时一眼读完。
Risk: 新增一个接收用户输入 ORDER BY 的 GET 接口——SQL 注入类风险。Mitigation: 对列名做白名单。
就这么一句。一个分类提示、具体可能出什么事、为此做了什么。如果我写不出这一句,这个 PR 就还没准备好。如果缓解措施写的是"无",这个 PR 同样还没准备好——"无"是一个信号,不是一条捷径。
绿、黄、红:合并门禁矩阵
每个 PR 根据七类风险被打上一个颜色,颜色决定接下来会发生什么:
- 绿色。七类里一类都没踩中。在有测试覆盖的模块里做纯重构、改日志、改文档。正常合并。写一行 Risk: none 仍然欢迎。
- 黄色。踩中一到两类,有明确的缓解措施。写好风险备注,走正常评审。大多数真实 PR 都属于这一档。
- 红色。任何破坏性的数据操作、任何新增的鉴权面、任何触碰合规的改动,或者一次性踩中三类及以上。阻塞合并。重新设计、拆分、或者升级上报。红色绝不允许在评审行内直接豁免。
作者写备注,评审者负责质疑
不可谈判的一条:是谁对着 AI 下的 prompt,就由谁来写风险备注。不是评审者,不是模型,不是机器人。作者才有上下文——他向模型要了什么、模型返回了什么、他又基于信任接受了哪些部分。评审者的工作重心也随之转变:从"挑出 bug"变成"质疑风险备注"。作者是不是漏了一类?缓解措施是真做了,还是只是口头理想?标成黄色的是不是其实该是红色?
这个翻转很关键。从风险备注读起的评审者,比从 diff 读起的评审者抓到的问题更多——因为备注把作者的推理过程暴露出来了。备注写得敷衍,代码通常也敷衍。
让 AI 自己先把风险说出来
在我让它写实现之前,我会先让它写风险。prompt 是这样:在写任何代码之前,列出这次改动最高的三个风险,以及你会怎么缓解每一个。它给出的答案质量不稳定,但这个动作迫使模型去审视这次改动,而不是一上来就开始吐代码。我把它给的这三行贴在草稿注释里,然后在旁边写我真正的那一行风险备注。
这里有一个陷阱,也正是这份登记册存在的全部理由。AI 生成的代码看起来往往风险很低。变量名温和、注释礼貌、函数短小。人类读者会根据"语气"去模式匹配。这份登记册就是对抗这种偏见的强制机制:不管代码看起来多友好,风险备注照写不误。
一个真实例子:没做租户隔离的用户搜索接口
最近有个 PR 新增了一个 GET /api/users/search?q= 接口。代码写得很干净,测试全部通过,助手用了参数化的 LIKE 查询,看起来挺像样。作者包了一层薄薄的 wrapper 就把 PR 提上来了。
是写风险备注这个动作抓住了它。先是踩中安全,接着是性能,然后是合规——作者在第三类上停了一下,才意识到这个查询根本没按租户做作用域隔离。任何登录进任何账号的人,都能搜到系统里的每一个用户。代码严格按照写的那样运行着,同时也是一起随时会爆发的跨租户数据泄露。风险备注把它标成了红色。修复只有两行。那起没有发生的事故,才是我在意的东西。
给登记册本身写 Given/When/Then 验收标准
这份登记册只有作为 CI 检查才管用,作为"礼貌建议"是没用的。我把它规格化如下:
Given an AI-assisted pull request is opened When the PR description does not contain a line matching "Risk:" Then CI fails with a message pointing to the risk register policy Given a PR is marked red by the risk matrix When the author attempts to merge without a linked redesign issue Then the merge is blocked until a reviewer with the risk-gate role approves Given a PR passes all seven category checks with no trips When the author writes "Risk: none" Then the PR may proceed through normal review at yellow-equivalent speed
这个检查本身故意写得很笨。它只是在 PR 正文里查字面字符串 Risk:。判断本身仍然由人做。这扇门只是拒绝让你跳过做判断这件事。
每周一次横扫:把登记册当成数据集来读
每周五我会扫一遍本周的所有风险备注——不是 PR,是备注本身。规律出现得很快。如果本周黄色备注里有一半都写了"N+1",那说明我们有的是查询层问题,而不是评审问题。如果"新依赖"反复出现,就该有人来搞一个包选型策略了。如果某个团队的合规类风险从来没出现过,他们要么是运气好,要么就是没在看。这样一来,登记册就不再只是文书工作,而变成了一个弱信号传感器。它的价值也正是在这里兑现——不在任何单个 PR 上,而在聚合视角里。我对登记册的原则和我对它所守护的代码的原则是同一条:如果它不能帮我决定什么事,它就不该存在。
可以直接放进 PR 模板的风险登记
风险登记不需要长。它只要逼着作者把“哪里可能出事”写成一句可检查的话。AI 生成的 PR 最需要这一格,因为模型通常会解释自己做了什么,却不会主动说自己没验证什么。
AI risk register: - Scope risk: touched files outside src/billing/**? no - Data risk: migration changes existing rows? yes, backfill dry-run attached - Contract risk: public response shape changed? no, schema diff attached - Rollback risk: feature flag billing_proration_v2 can disable new path - Evidence gap: load test not run against production-size invoice table
边界:不要把低风险文案 PR 也塞满风险表。只要改动碰到数据、权限、钱、外部 API、迁移、后台任务或用户可见契约,就必须登记。
可复制产物:AI 编码评审包
在 AI 生成 diff 进入代码评审前使用。它把提示词范围、允许变更和证据要求合并成一个可审查产物。
AI 编码评审包:AI 编码合并前风险登记:merge 之前要追踪的条目 本次要做的决策: - 确认 AI 只在批准范围内生成变更,并为每条验收标准提供证据。 责任人检查: - 产品责任人: - 工程责任人: - QA 或运维评审: 范围边界: - 本次包含: - 本次不包含: - 仍需确认的假设: 验收证据: - 测试或 fixture: - 日志、指标或截图: - 人工复核步骤: AI 边界:生成变更必须留在书面范围内,每条验收标准都要能找到证据。 评审追问: - 没参加需求会的人还会误解哪里? - 哪个证据能证明这次改动足够安全,可以发布?
编辑复核记录
复核日期:2026-04-28。本次补充了可复用产物,按相关主题 Hub 检查了文章定位,并收紧下一步链接,让页面更像可操作参考,而不是孤立长文。
专题阅读路径
这篇文章归入 AI 编码治理 主题。先读 Hub,再结合下面的清单、模板或工具落到具体项目里。
继续阅读
编辑说明与免责声明
最近复核:2026-04-28。编辑部检查了示例、内链和可复制评审片段,确保内容更适合真实项目使用。
本文用于软件工程教学与实践参考,不构成法律、税务或投资建议。示例场景用于解释规格方法,不对应真实客户数据。
- 作者信息:Spec Coding 编辑部
- 编辑政策:编辑与事实核查政策
- 联系方式:联系页面