Coding Agent 提交 PR 前的就绪清单
AI PR 的成本
根据 Opsera 2026 年的基准报告,AI 生成的 PR 在 review 阶段的等待时间是人工 PR 的 4.6 倍,引入的安全漏洞多出 15-18%。
AI 写得出语法正确、逻辑通顺的实现,但它提交的 PR 把所有理解成本都转嫁给了 reviewer。我见过典型的 AI PR:15 个文件的 diff,描述只有一句「实现 XX 功能」,没有截图、没有验证命令、没有风险说明。reviewer 要逐一判断哪些改动与需求相关、哪些是「顺手改的」,自己跑测试、自己评估影响——这些本该是作者在提交前就完成的工作。
AI 无法替 reviewer 思考。这份清单解决一个问题:提交前该做哪些自检,才能让 diff 被理解、被验证、被安全合并。
PR 是一份工程契约
Google 工程实践文档(eng-practices)对 code review 的定义是:「code review 的主要目的是确保 Google 代码库的整体健康度在持续改善。」重点在「系统是否变得更好」,而非仅仅「代码对不对」。
PR 是作者向团队做出的四项承诺:
- 改动范围清晰(diff 聚焦)
- 正确性可验证(证据完整)
- 风险已评估(风险说明)
- 出问题可撤回(回滚思路)
缺少任何一条,reviewer 就得花时间补全信息——这是 AI PR 审查等待时间远超人工 PR 的根源。
AI 带来的新挑战
AI coding agent 加快了 PR 产出速度,同时引入三个新问题:
Diff 膨胀。AI 没有「这个改动该拆成几个 PR」的直觉,50 行的需求可能产出 300 行的 diff——包括它认为「顺便优化」的部分。
验证缺失。AI 能写测试代码,但不会主动运行测试、截图浏览器、记录验收步骤。验证证据往往只有「已测试」三个字,reviewer 无法复现。
风险说明空白。AI 不了解你的部署流程、灰度策略和回滚机制。风险判断要么过于乐观(「无风险」),要么过于笼统(「可能影响其他模块」),缺乏可操作性。
SonarSource 2026 年调查显示,96% 的开发者不完全信任 AI 代码,但 42% 的代码已由 AI 生成或辅助。团队无法拒绝 AI PR,只能建立更严格的自检标准。
四个自检维度
基于上述分析,PR 就绪自检可以分解为四个维度,每个维度有明确的检查标准和好坏对照。
维度一:Diff 是否聚焦
Diff 聚焦指 PR 中每个文件改动都能被任务需求解释,不存在游离于目标之外的变更。
| 检查项 | 好的表现 | 坏的表现 |
|---|---|---|
| 改动文件数量 | 与任务范围匹配,通常 3-8 个 | 远超任务范围,15+ 个文件 |
| 无关改动 | 无格式化、无顺手重构、无调试代码 | 混入样式调整、注释修改、变量重命名 |
| 每个文件可解释 | 每个改动都能对应到具体需求 | 有些文件「说不清为什么改了」 |
| 提交结构 | 逻辑分组,commit message 清晰 | 一个巨大的 commit 或大量「fix」commit |
| 临时文件 | 已删除或被 .gitignore 排除 | 残留 console.log、.bak 文件 |
好的 diff(5 个文件,全部相关):
PR: feat: 实现文章分类筛选功能
├── features/article/ArticleList.tsx # 筛选 UI 和逻辑
├── features/article/useArticleFilter.ts # 筛选 hook
├── api/article.ts # tag 查询参数
├── tests/article-filter.test.ts # 筛选测试
└── types/article.ts # tag 类型定义
坏的 diff(15 个文件,仅 2 个相关):
PR: feat: 实现文章分类筛选功能
├── features/article/ArticleList.tsx # 筛选逻辑 ✓
├── types/article.ts # 类型定义 ✓
├── components/Header.tsx # 改了导航栏 ✗
├── styles/globals.css # 调了颜色 ✗
├── components/Footer.tsx # 改了间距 ✗
├── utils/date.ts # 加了格式化 ✗
├── ...还有 9 个「顺手改的」文件
reviewer 要逐一判断每个文件是否该保留,审查成本成倍增加。
维度二:验证证据是否可复现
验证证据是「我的改动是正确的」这一声明的支撑材料,关键在于可复现。
| 检查项 | 好的表现 | 坏的表现 |
|---|---|---|
| 验证命令 | 具体命令和输出 | 只写「已测试」 |
| 测试覆盖 | 说明新增/修改了哪些测试 | 「AI 说测试通过了」 |
| 浏览器验收 | 附截图,标注路由和视口 | 页面改动没有截图 |
| 边界情况 | 说明空状态、错误状态、极端输入 | 只覆盖 happy path |
| 性能数据 | 附 before/after 数据 | 声称「无性能影响」但无数据 |
好的验证证据:
验证命令:
- pnpm typecheck → 通过
- pnpm test -- --filter article → 12 tests passed
- pnpm build → 构建成功,无 warning
浏览器验收:
- http://localhost:3000/blog
- 桌面端 1440px(截图 1)、移动端 375px(截图 2)
- 状态:选 1 tag(3 篇)、选 2 tag(1 篇)、清除(全部 8 篇)
测试覆盖:
- article-filter.test.ts:有 tag / 无 tag / 空数组 / 多 tag 交集
坏的验证证据:「测试通过,页面正常。」——哪个测试?什么页面、什么状态?reviewer 无法判断覆盖范围,只能自己跑一遍。
维度三:风险说明是否真实
风险说明不必长,但必须具体到影响范围、触发条件和严重程度。
| 风险等级 | 特征 | 示例 | 审查要求 |
|---|---|---|---|
| 低风险 | 改动局部化,可安全 revert | 新增内部工具函数、修改文案 | 正常审查 |
| 中风险 | 涉及共享组件、API 接口或数据格式 | 修改共享 UI 组件 props | 检查下游影响 |
| 高风险 | 涉及权限、支付、数据库迁移、公开页面 SEO | 修改鉴权中间件、变更 schema | 需额外 reviewer + 回滚方案 |
好的风险说明:
风险:中
- 修改 packages/ui/Button.tsx padding(8px → 12px)
- 影响:所有使用 Button 的页面,视觉变化较小
- 已检查:23 处引用,无自定义 padding 覆盖
- SEO:无影响
回滚:直接 revert,无数据迁移
坏的风险说明:「无风险。」——改了什么、影响了谁、如何回滚,全部缺失。reviewer 要自己做影响分析。
维度四:回滚思路是否清晰
回滚思路是让 reviewer 知道:作者想过合并后出问题怎么办,并有基本可行的计划。
| 回滚策略 | 适用场景 | 恢复时间 |
|---|---|---|
| Git revert | 纯代码改动,无数据变更 | < 1 分钟 |
| Feature flag 关闭 | 有 flag 保护的新功能 | < 5 分钟 |
| 配置回退 | 环境变量或配置项变更 | < 5 分钟 |
| 数据迁移回退 | 数据库 schema 或数据变更 | 5-30 分钟 |
| 混合策略 | 代码 + 数据 + 配置组合变更 | 30+ 分钟 |
三个案例
案例一:好的 AI PR
AI 生成代码,作者提交前完成自检:
- 目标:实现文章列表 tag 筛选,点击 tag 后只显示含该 tag 的文章
- 改动:新增
useArticleFilterhook + 修改ArticleList组件 + API 支持tags参数 + 新增类型 + 4 个测试 - 验证:
pnpm typecheck通过,pnpm test --filter article12 tests passed;浏览器验收含桌面端和移动端截图 - 风险:低。API 新增参数向后兼容,未改共享组件
- 回滚:直接 revert
diff 5 个文件,每个改动都能在目标中找到对应说明。reviewer 15 分钟审查完,2 条建议性修改,当天合并。
案例二:差的 AI PR
同一个 AI agent 生成,作者没做自检直接提交:
- 描述:「feat: 实现文章分类筛选功能。已测试。」
- Diff:15 个文件,287 行新增
Reviewer 发现:筛选逻辑本身正确,但混入了 useEffect 依赖修改、卡片样式、CSS 变量、Button padding 等无关改动,还有 3 处 console.log 残留。40 分钟理清噪音,给出 Request Changes。作者又花 20 分钟修改、20 分钟复查,总计 80 分钟——比案例一多了 65 分钟。AI 代码本身没问题,代价出在提交前缺少自检。
案例三:从差到好的修复
初始状态:22 个文件、描述「优化了用户个人页面」、风险「无风险」、回滚未提及、验证「已测试」。
作者用清单逐项检查后:
- 拆分 PR:UI 优化(6 文件)、头像上传 bug fix(3 文件)、通知计数 bug fix(2 文件)各一个 PR
- 移除噪音:5 个纯格式化改动留到专门的 chore PR
- 补充描述:每个 PR 填写目标、具体改动文件、验证命令和截图、风险等级和回滚方案
拆分后每个 PR 审查不超过 15 分钟,总审查时间从 80 分钟降到 45 分钟,审查质量更高——reviewer 不用再在噪音中淘金。
PR 就绪自检流程
先检查 diff 范围,再检查描述质量,然后检查验证证据,最后检查风险和回滚。任何一步不通过,都应回到代码侧修复,不在 PR 描述里含糊带过。
PR 描述对比
| 维度 | 好的 PR 描述 | 坏的 PR 描述 |
|---|---|---|
| 目标 | 明确「做什么」和「为什么」 | 只写功能名 |
| 范围 | 列出文件和职责 | 不提及 |
| 验证 | 具体命令、输出、截图 | 「已测试」 |
| 风险 | 等级 + 影响范围 + 触发条件 | 「无风险」 |
| 回滚 | 具体策略和步骤 | 不提及 |
| 关联 | issue、设计文档链接 | 无关联 |
好的 PR 描述用结构化格式传递五个维度的信息,坏的 PR 描述几乎不传递任何有效信息。差距在信息密度,不在文采。
完整的 PR 就绪清单
以下清单涵盖四个维度共 18 项,提交前逐项检查。
Diff 聚焦(5 项)
- 改动文件都在任务范围内,没有「顺手改的」文件
- 没有残留的
console.log、调试代码、临时文件 - 没有混入无关的格式化、变量重命名、缩进调整
- 每个文件的改动都能在 PR 描述中找到对应说明
- 超过 10 个文件时,已考虑拆分为多个 PR
描述质量(4 项)
- PR 标题遵循团队 commit convention
- PR 描述包含「目标」:做什么、为什么做
- PR 描述包含「改动范围」:改了哪些文件、每个文件改了什么
- 关联了对应的 issue、设计文档或需求链接
验证证据(5 项)
- 包含实际运行过的验证命令和输出
- 涉及页面改动时,附浏览器截图或录屏,标注路由和视口
- 测试覆盖说明新增/修改了哪些测试,覆盖了哪些场景
- 边界情况有说明:空状态、错误状态、极端输入
- 涉及性能改动时,附 before/after 数据
风险与回滚(4 项)
- 风险评估真实具体,不写「无风险」(除非确实没有风险点)
- 说明是否影响共享组件、公开页面 SEO、权限、API 兼容性
- 回滚策略明确:git revert / feature flag / 配置回退 / 数据迁移回退
- 高风险改动已标记需要额外 reviewer
给 Coding Agent 操作者的建议
我在使用 AI coding agent 时总结了几条原则:
不要让 AI 产出直接变成 PR。 AI 生成代码后,我先本地审查 diff,删除或拆分无关改动,再提交。这一步通常 5 分钟,能省 reviewer 大量时间。
不要让 AI 写 PR 描述。 AI 写的描述往往是一句话。我自己写,或至少逐项填充清单内容。
不要让 AI 判断风险。 AI 不了解我的部署流程和回滚机制,风险评估由了解系统全貌的开发者来做。
验证必须自己跑。 AI 说「测试通过」不等于测试通过,我在本地运行后把实际命令和结果写进描述。
AI 是编码助手,PR 的质量由提交它的人负责。
结论
AI PR 的问题出在理解成本的转嫁。15 个文件的 diff、1 小时审查、3 个 PR 拆分——如果提交前做了自检,移除无关改动、补充验证证据、写明风险和回滚,审查时间可能只要 15 分钟。
好的 AI PR 是目标清楚、范围收敛、证据完整的 PR。下次提交前,花 5 分钟过一遍 18 项清单,reviewer 的审查更顺畅,我也对自己的改动更有信心。
参考资料
- The Standard of Code Review — Google Engineering Practices
- AI Coding PR Review Checklist — Spec Coding
- Code Review for AI-Generated Code: 2026 Standards Guide — Metacto
- 2025 was the year of AI speed. 2026 will be the year of AI quality. — CodeRabbit
- AI Coding Impact 2026 Benchmark Report — Opsera
- State of Code Developer Survey Report — SonarSource
- How I Validate Quality When AI Agents Write My Code — Dev.to
- Code Review Best Practices That Actually Scale — Augment Code