AI 编码合并前风险登记:merge 之前要追踪的条目

AI 编码合并前风险登记:merge 之前要追踪的条目
Spec Coding 编辑部 · Spec-First 工程实践内容

专门给 AI 生成代码准备的合并前风险登记册:LLM 不会主动提示的七类风险、每个 PR 一行的风险备注,以及什么情况阻塞合并、什么情况只是警告。

发布于 2026-03-10 · ✓ 已更新 2026-05-06 · 阅读约 7 分钟 · 作者:Spec Coding 编辑部 · 审校:编辑与事实核查政策

我为什么开始给 AI 代码单独记一份风险登记

我不想再多一个模板。我只想在生产环境里别再被吓一跳。在第三次出事之后——某个 AI 生成的 PR 上线了我自己手写绝不会上线的东西——我终于接受一个事实:助手和我对"风险"的权衡完全不是同一套。助手优化的是"看起来像样、能编译通过"的代码;我要优化的是"合并之后我晚上还能不能睡着"。

于是我开始在每一个 AI 协作过的 PR 上写一行风险备注。不是文档,就是一句话:这次改动可能破坏什么,我为此做了什么。这一句话就是整份登记册。它写在 PR 描述里,被 CI 强制要求,也是我做评审时最先读的那一行。

模型不会主动标出的七类风险

七个分类。每个 PR 在写风险备注之前,都要对照这七类逐一过一遍:

那一行风险备注到底长什么样

这是我实际使用的格式。它故意写得很无聊。无聊,才能在赶时间时一眼读完。

Risk: 新增一个接收用户输入 ORDER BY 的 GET 接口——SQL 注入类风险。Mitigation: 对列名做白名单。

就这么一句。一个分类提示、具体可能出什么事、为此做了什么。如果我写不出这一句,这个 PR 就还没准备好。如果缓解措施写的是"无",这个 PR 同样还没准备好——"无"是一个信号,不是一条捷径。

绿、黄、红:合并门禁矩阵

每个 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 代码评审 · 合并前风险登记 · AI 生成代码安全 · PR 风险备注 · 合并门禁

专题阅读路径

这篇文章归入 AI 编码治理 主题。先读 Hub,再结合下面的清单、模板或工具落到具体项目里。

编辑说明与免责声明

最近复核:2026-04-28。编辑部检查了示例、内链和可复制评审片段,确保内容更适合真实项目使用。

本文用于软件工程教学与实践参考,不构成法律、税务或投资建议。示例场景用于解释规格方法,不对应真实客户数据。