别把 AI 代码审查 API 当同步函数:CI 里最容易漏掉的 5 个状态
GitHub 在 10 月 2 日宣布:Copilot code review 可以通过 REST / GraphQL API 请求,单次请求还能选择 review effort。自动化入口一旦打开,AI 审查就不再是开发者点一下按钮,而是 CI 中一个会重试、并发、过期的异步任务。
最危险的实现,是调用 API 后看到 2xx 就把检查标成成功。它遗漏了五个必须显式处理的状态。

1. requested:只代表平台接受了请求
请求成功与结果完成之间可能隔着排队和执行。CI 需要先生成内部 job_id,保存仓库、PR、当前 head_sha、规则版本和审查强度,再保存外部回执。
type ReviewJob = {
id: string
repo: string
pr: number
headSha: string
policyVersion: string
effort: "lite" | "balanced"
state: "requested" | "running" | "completed" | "superseded" | "failed"
}
这样,外部 API 临时超时也不会让任务凭空消失。
2. running:重复事件不能重复创建任务
PR Webhook 会重放,工作流也会人工重跑。幂等键至少要包含:
repo + pr + head_sha + effort + policy_version
数据库给这个键加唯一约束。再次收到相同事件时返回原任务,而不是再发起一次审查。只用 PR 编号不够,因为新提交和新规则都应产生新任务。
3. completed:结果必须绑定代码快照
审查完成时重新读取 PR 的最新 SHA:
if (result.headSha !== pullRequest.headSha) {
await jobs.markSuperseded(result.jobId)
return
}
旧结论可以留作证据,但不能再阻塞或放行当前提交。否则慢任务会把新任务的状态覆盖掉,这是典型的“最后返回者获胜”竞态。
4. superseded:过期不是失败
把过期任务记成失败,会制造无意义告警;把它记成成功,又可能误导门禁。superseded 应是独立终态:保留结果,标明对应 SHA,不参与当前合并判断。
如果 PR 更新频繁,还可以设置短暂防抖:新提交到达后等待几十秒再创建任务。但防抖不能替代 SHA 校验。
5. failed:失败要区分“可重试”和“需人工”
网络超时、限流可以指数退避;权限拒绝、配置不支持、覆盖范围未知则不该盲目重试。失败记录至少包含:失败阶段、错误类别、已尝试次数、下次重试时间和是否需要人工介入。
证据包比评论更重要
开发者最终看到的是行内评论,流水线真正需要的是结构化证据:
- 审查对应的
head_sha; - 实际生效的强度,而不是模糊的
default; - 规则版本与触发原因;
- 已检查和跳过的文件;
- 发现的严重度与位置;
- 完成、过期、失败或部分完成的终态。
官方更新还提到 Balanced 已成为 Default 对应的默认强度,且不同管理层级可以覆盖设置。因此,“使用 default”不是足够的审计信息,回执里应固化最终解析出的值。
一个最小接入顺序
- 先只对高风险目录、跨服务修改或大 PR 触发审查。
- 第一阶段保持非阻塞,统计重复率、过期率和失败率。
- 固化状态机和证据包,再把明确的阻塞发现接入门禁。
- 任何覆盖范围未知或结果过期的情况,回退人工复核。
AI 审查 API 的价值在于可编排,但可编排也意味着必须面对分布式系统的基本问题。先把幂等、快照绑定、终态和回执做好,才谈得上让它稳定进入 CI。
来源
- GitHub Changelog:Copilot code review: API support and new default effort level(2026-10-02)
- GitHub Changelog:Dynamic workflows in Copilot CLI and the Copilot app(2026-10-01)