[控场AI]
· 9 分钟阅读· 4,885 字

Copilot能批准PR了,但AI审批需要职责分离

Copilot能批准PR了,但AI审批需要职责分离

Copilot 可批准 PR 引发治理问题:AI 批准应保守,需职责分离与敏感路径人类专属。

GitHub Copilot 代码审查新增“批准”功能,使 AI 能够计入拉取请求的必需审批数,这改变了合并协议的威胁模型。文章指出,AI 批准不应被视为更好的审查体验,而应作为证据的一部分,并严格限制在低风险路径。敏感路径(如认证、支付、CI 工作流、密钥管理)必须保留人类专属批准。内容排除策略直接影响批准质量,CI 的独立性取决于其不可被 PR 廉价破坏。Agent 不应批准同类 agent 编写的 PR,否则构成自动化洗白。建议采用策略阶梯:从仅评估信号开始,逐步放开低风险路径,要求可解释的策略证据,设定例外到期日,并保留部分纯人类仓库。核心原则是让 AI 激进地审查,但保守地批准,将其视为安全和治理功能而非生产力功能。

GitHub 发布了一条看似不起眼的变更日志:Copilot code review 现在可以批准拉取请求。不是评论,不是总结,不是委婉地说"看起来没问题"——是批准。在分支保护、代码所有权、审计日志和部署门禁构成的合并协议中,这是一个完全不同的动词。

评论是建议,批准是协议的一部分。当 AI 的"批准"可以计入必需审批数时,问题就不再是"AI 该不该审查代码",而是:当 AI 审查被允许"算数"时,它必须与哪些职责分离?

批准不是更好的审查体验

AI 代码审查作为 linter、静态分析和依赖告警的加强版,价值很明确:在人类浪费注意力之前过滤噪音。Copilot 的审批评估在这个语境下是有用的信号——它可能没发现阻塞性问题,可能只看到低风险编辑,可能帮人类更快地分类队列。

但一旦这个批准能计入必需审批,它就从"信号"变成了"能把代码从提议状态移到可合并状态的东西"。这改变了威胁模型。团队花了很多年教育开发者:合并按钮不只是按钮,它是一条受控边界。围绕它设规则,是因为代码审查不只关乎代码质量,更关乎问责——谁看过?谁有足够上下文接受这个风险?批准者是否独立于变更作者?

如果 Copilot 现在能参与这个协议,它就必须被当作协议参与者来治理。把它当成"又一个审查者"是懒惰的架构。它是一个新的合并原语。

分支保护(Branch Protection) 是 GitHub 等代码托管平台提供的一项仓库管理功能,它允许管理员为特定分支(如 main、release)设定一系列合并规则。常见的规则包括:要求至少 N 个批准、要求特定代码所有者(CODEOWNERS)的批准、要求状态检查(如 CI 测试)通过、禁止强制推送、要求线性历史等。分支保护的核心作用是防止未经审查或未通过验证的代码直接进入关键分支,从而将合并过程从“个人操作”转变为“受控协议”。当 AI 批准可以计入必需审批数时,它实际上是在与分支保护的计数逻辑交互——平台需要明确 AI 批准是否被视作满足“至少一个批准”的合法来源,这直接决定了 AI 在合并协议中的法律地位。

代码所有权(CODEOWNERS) 是 GitHub 提供的一种机制,允许仓库维护者为特定文件或目录指定“所有者”(通常是团队或个人)。当拉取请求修改了这些路径下的文件时,系统会自动请求相应所有者的审查,并且可以配置为必须获得所有者批准才能合并。代码所有权的设计初衷是确保变更由最了解该领域风险的人来审查,它体现了职责分离原则。如果 AI 批准被允许替代或补充代码所有者批准,就会削弱这种基于专业知识的审查保障。因此,在讨论 AI 批准时,必须明确它不能绕过代码所有权规则,尤其是在敏感路径上。

有用的版本是狭窄的

Copilot 审批真正有价值的场景并不难想象:生成的文档、测试夹具更新、纯格式化变更、编译器与测试给出强证据的机械重构,以及生成过程本身受控且可复现的低风险生成代码。对于这些变更,AI 批准可以减少人类审查拖累——没人应该花高级工程师的注意力去给一个确定性工具产生、CI 已验证的千行 diff 盖章。

但关键词是"作为证据的一部分"。危险的版本更宽:一个 agent 写变更,另一个 agent(或同类工具换个帽子)审查它,CI 因为测试薄弱或变更改动了测试工作流而通过,批准计入,合并按钮亮起,所有人假装存在独立审查。

这不是职责分离,这是自动化洗白。

敏感路径应保留人类专属

第一条策略应该无聊且明确:Copilot 批准不应计入敏感路径。建议从一份拒绝清单开始:

  • 部署工作流
  • 认证与授权代码
  • 支付与计费代码
  • 账本、对账与资金流转逻辑
  • 密钥处理
  • CI 与发布自动化
  • 依赖清单与 lockfile
  • 基础设施即代码
  • 包发布配置
  • 生产事故工具
  • 安全策略与代码扫描配置

这不是因为 Copilot 在这些领域无用。它仍可评论、解释、指出可疑模式、帮人类审查者问出更好的问题。但它的批准不应满足合并规则。用工具改善判断,和把控制决策委托给工具,是两回事。 敏感路径正是这个区别最重要的地方。如果一个 PR 改动了 GitHub Actions 工作流,我不希望将要执行该工作流的同一平台被视为独立的批准者。

基础设施即代码(Infrastructure as Code, IaC) 是指用代码文件(如 Terraform、CloudFormation、Kubernetes 清单)来定义和管理计算、网络、存储等基础设施,而不是通过手动控制台操作。IaC 文件通常与部署工作流紧密集成,一旦合并便可能触发基础设施的创建、修改或销毁。因此,IaC 的变更审查需要评估其对生产环境的潜在影响,包括资源权限、网络暴露面、成本和安全配置。AI 批准若计入合并规则,必须确保审查者(人或 AI)能够理解这些文件所代表的真实基础设施状态,并且有足够的上下文判断变更是否安全。由于 IaC 经常涉及云凭证和敏感配置,它应被列入拒绝清单,仅允许 AI 提供评论而非批准。

上下文排除现在更重要了

一个容易被忽视的细节:GitHub 同时让内容排除(content exclusions)在 Copilot app 和 CLI 中正式可用。企业需要把敏感文件排除在 agent 上下文之外,这很好。但如果 agent 被允许批准代码,排除策略就成了批准策略的一部分。

一个不被允许读取相关文件的审查者给出的批准,是更弱的证据。想象一个人说:"我批准这个认证重构,但我无权打开策略文件、集成测试或部署工作流。"你不会把这当成强审查。同样标准应适用于 agent。批准策略需要知道的不只是哪些文件变了,还有工具在形成批准时被允许检查哪些文件。

CI 不会自动变得独立

简单的答案是:只在 CI 通过时让 Copilot 批准。这必要,但不充分。只有当 PR 无法廉价地破坏那些本应约束它的检查时,CI 才是独立证据。如果变更编辑了工作流文件、可复用工作流引用、构建脚本、依赖安装、测试选择或产物发布,那么 CI 结果本身就是被改动对象的一部分。

这也是 GitHub 近期收紧 Actions 信任边界的一系列变更的意义所在:CodeQL 对 Actions 问题的更精确检测、更清晰的可复用工作流身份上下文、最小权限、不可信触发器的只读缓存令牌。正确的思维模型是:自动化不是一团信任,它有边界。AI 批准应继承这些边界,而不是漂浮其上。

OIDC(OpenID Connect) 是一种基于令牌的身份验证协议,在 CI/CD 场景中用于让工作流临时获取云资源访问权限,而无需长期存储静态密钥。GitHub Actions 支持 OIDC 与云提供商(如 AWS、Azure、GCP)集成,工作流可以请求一个短期有效的 JWT 令牌,云平台验证该令牌的签发者和声明后授予最小必要权限。这种机制减少了密钥泄露风险,但也引入了新的信任边界:如果工作流定义文件本身可被 PR 修改,攻击者可能篡改 OIDC 令牌的请求范围或目标角色。因此,当讨论“CI 作为独立证据”时,必须考虑 OIDC 配置的完整性和不可篡改性。AI 批准若依赖 CI 通过,就需要确保 CI 工作流及其 OIDC 配置不受被审查变更的直接影响,否则 CI 结果可能被操纵。

Agent 编写的代码需要独立审查

有一条规则应当不可谈判:agent 不应被允许批准由同类 agent 主要编写的 PR。 这不是说每个 AI 辅助的 PR 都需要委员会——开发者每天都在用补全和重构工具。关键在于 agent 做了实质工作的 PR:规划变更、编辑文件、编写测试并打开 PR。这种情况下,同一产品家族的 AI 批准不应算作独立审查。

翻译回人类语境就很清楚:我们通常不让作者做自己的独立审查者,不把"我检查了自己的工作"等同于另一个合格者的审查。AI 没有让这个原则过时,它只是让违反变得更容易。

自动化洗白(Automation Laundering) 是指利用自动化工具或 AI 系统为变更赋予虚假的合法性或独立性,从而绕过本应存在的人类审查或职责分离。在代码审查场景中,典型形式是:一个 AI agent 编写了代码,另一个同类 AI agent(或同一工具的不同实例)批准了该代码,使得合并请求看似经过了“独立审查”,但实际上审查者与作者同源,缺乏真正的独立视角。自动化洗白之所以危险,是因为它制造了一种合规的假象,可能让有缺陷或恶意的变更通过本该拦截它们的关卡。防范自动化洗白需要明确规则:AI 批准不能来自与代码作者相同的工具家族,且对于 agent 实质性编写的 PR,必须由人类或完全独立的审查者批准。

策略阶梯

不要一开始就在所有地方启用 AI 批准,然后指望仓库管理员自己摸索。建议用阶梯式推进:

底层:仅审批评估。 让 Copilot 表达它认为 PR 是否就绪,但不计入必需审批。观察信号质量,看哪里有用、哪里噪音大,调整指令和审查力度。

下一层:仅在明确低风险路径上允许计入批准。 文档、生成示例、纯格式化、仅测试变更、夹具更新、有强 CI 覆盖的机械重构。要求所有权规则和分支保护通过,要求新提交自动驳回批准。

再上一层:要求策略证据。 批准应当可解释:哪些文件变了?哪些路径被允许?应用了哪些内容排除?通过了哪些检查?PR 是人类、agent 还是混合编写?是否触发了敏感路径规则?

然后:让例外过期。 临时策略例外应有到期日,就像临时预算。迁移期间需要短期放宽可以理解,但永久例外会变成民间传说,民间传说变成生产风险。

顶层:保留一些纯人类仓库。 认证平台、支付系统、账本、基础设施模块、发布自动化、安全工具和受监管工作负载,仍可从 AI 评论中受益,但不让工具计为批准者。这不是反 AI,这是正常的工程判断。

发布系统提供了正确的类比

npm 的可信发布变更是一个好类比。现代发布体系正从长期令牌转向基于 OIDC 的工作流、独立配置、分阶段发布、恶意软件扫描和发布前的显式人工批准。模式很清晰:减少密钥蔓延,自动化无聊检查,保留有意义的关卡。

PR 批准应朝同一方向演进。如果 AI 审查成为合并路径的一部分,策略就应明确:工具能批准什么、只能评论什么、哪里必须保留人类或独立控制。成熟的答案不是"永远不让 AI 批准任何东西",而是"不要把便利和独立性混为一谈"。

真正的风险是假装什么都没变

有人会过度反应,说机器永远不该批准 PR。这太简单了。我们早已让机器以多种方式阻止和放行变更:测试、linter、扫描器、策略引擎、部署门禁和生成式证明都参与软件交付。问题不是机器参与,而是权限不清。

linter 失败时我们知道意味着什么;CodeQL 标记漏洞时我们知道它提供哪类证据;分支保护要求两个批准时我们知道自己意图的人类问责模型。AI 批准会搅浑这一切,除非我们仔细定义它。Copilot 批准意味着代码正确吗?不。意味着没有安全问题吗?不。意味着工具在其被允许使用的上下文和策略内未发现阻塞性关切吗?这更接近。

如果这就是它的含义,那么策略就需要说明:这种证据在哪里强到足以计入。

我的倾向很简单:让 AI 激进地审查,但保守地批准。 用它降噪、抓无聊错误、总结风险、让人类审查更敏锐。但当批准成为合并控制的一部分时,停止把它当生产力功能——把它当安全和治理功能。分离职责,命名路径,保留独立性,让审计追踪保持无聊。Agent 批准本身不坏,假装它只是"另一个审查者"才坏。

#Copilot code review#AI 代码审查#职责分离#Pull Request 审批#分支保护#AI 治理#GitHub Actions 安全
分享:

相关推荐