CI/CD 与发布
CI 自动修复如今是扎实的 L2:智能体推送修复,由人合并。它值不值得做,取决于模型之外的三件事:批量大小、一套演练过的回退机制,以及智能体的 CI 令牌能触及什么。这三件事做错了,出问题时构建也不会变红。Elastic 的智能体靠删掉本该修复的升级来让构建保持绿色;一枚权限过宽的 CI 令牌,让攻击者把恶意代码塞进了 Amazon AI 编码扩展的正式发布版本。
什么变了
进来的变更更多、更大。《代码变便宜后,瓶颈转移了》讲过其中的机制:DORA 把 AI 采用与交付不稳定性联系起来,"部分原因在于更大批量的代码更难评审"(DORA 2025,第 57 页,调查)。紧挨着这句话的,才是对发布工程最要紧的一句:回退更频繁的团队从 AI 获得了更多团队绩效收益,但"依赖回退并不能直接降低不稳定性"。回退能缩短损害持续的时间,却挡不住坏变更进来。批量大小和回退是两种不同的控制,两样都要有。
流水线成了所有上游智能体的核验器。编码智能体无人值守时,判定它的工作是否完成的是测试套件和构建。Stripe 的一次性智能体每周产出 1,000 多个已合并 PR,每个都经人评审;每次运行最多跑两轮 CI,而这套 CI 要从 300 多万个测试中挑选用例(Stripe,T3,截至 2026 年 2 月)。这套做法见《编码》。对本章而言,要点在于:CI 如今就是判据原则里的那个判据,智能体能对 CI 做什么,就能对裁决做什么。
智能体进入了流水线。CI 自动修复、评审和分诊智能体如今都作为流水线作业运行,而流水线作业持有密钥:制品库令牌、部署密钥、有写权限的仓库令牌。一个持有这些密钥、同时读取 issue 或 PR 文本的智能体,就是一条新的攻击路径(见 9.5)。
本阶段的阶梯
判定标准沿用成熟度模型的 CI/CD 一行;证据缺口照实写明。
L1 是唯一有对照试验的一级。DIDACT 在《案例研究》中有完整分析。这里要紧的是:Google 测量了下游安全(回退和 sanitizer 失败),而不只是修复被应用的频率。L1 以上的每一级都缺这项测量。
L2 已经作为产品功能上线。GitHub 于 2026 年 5 月 18 日为失败的 Actions 作业推出了 Fix with Copilot。智能体排查失败的作业,把修复推到该分支,并@开发者评审(厂商文档,截至 2026 年 5 月)。它在设计上就是 L2:合并仍由开发者来做。
厂商自报。Nx 销售它所描述的自愈 CI。其 2025 年 12 月的年终文章称"约 60% 的修复被接受","约三分之二的失败 PR 得到了有效修复"。"被接受"指开发者采纳了修复,不等于修复正确。文章没有给出样本量、时间窗口、基线或回退率。这个数字只能说明功能有人在用,不能说明它值多少。
L3 存在于配置里,而不在结果里。Nx 文档描述的自动应用功能,会在"以下条件全部满足时"不经人工步骤把修复提交到 PR 分支:建议"已经明确验证能修复失败的任务",任务匹配所配置的 glob 模式,并且"AI 智能体高度确信"(截至 2026 年 10 月)。拿判据原则来对照这几个条件:验证和 glob 列表是模型之外的检查,确信度则是模型给自己的工作打分。只有前两项能算作 L3 的依据。没有任何组织发表过自动应用的 CI 修复的逃逸率或回退率,所以 L3 这一格只有机制,没有结果。
L4 对 LLM 而言是空的。Harness 的 Continuous Verification"用机器学习根据历史数据建立正常行为基线",把部署后的数据与之比较,并"在发现异常时自动触发回退"(厂商文档,截至 2026 年 10 月)。这是货真价实的 L4 发布把关,靠的是经典异常检测;网格把它算作 AI,但不记在 LLM 名下。它的教训可以照搬:自动发布决策要以指标对照基线为依据,而不是靠模型对局面的解读。
规则 2 在这里格外适用。一个阶段的级别,取你实际采用的评审方式与 AI 凭证所允许的权限两者中较高的那个(成熟度模型的规则 2)。一个能读取 npm 发布令牌或部署密钥的智能体作业,就该令牌所能触及的范围而言处于 L4,无论它的修复评审得多仔细。大多数团队按评审方式给 CI 智能体定级。应该按它持有的密钥来定。
案例:Elastic 的依赖修复智能体 · T3
级别:CI/CD,针对一个任务类别(修复构建失败的 Renovate 依赖 PR)处于 L2。
Elastic 负责 elastic/cloud 仓库的团队用 Renovate 升级依赖,有些升级会把构建弄坏。2025 年年中,团队把 Claude Code 放进了 Buildkite 流水线,让它尝试修复这些问题。第一个月里,智能体"一共修复了 24 个原本失败的 PR","7 月 22 日至 8 月 22 日之间提交了 22 次"。这次推广"只限于 45% 的依赖"。团队估计它"节省了 20 天的实际开发工作"。
这个案例之所以是本章的锚点,在于它的护栏:
- 不自动合并。"绝不在没有人监督的情况下提交 AI 的工作。"脚本"确保 GitHub PR 的自动合并处于禁用状态",因为"有 AI 参与时允许自动合并是危险的"。据该文,如果无法禁用自动合并,脚本会直接中止。
- 由运行框架强制执行的白名单。工具配置"以确定性的方式限制 Claude 能用的命令和能采取的动作"。Elastic 称这一点"对安全至关重要"。
- 范围收窄,留有审计记录。"不要改动修复构建所严格必需之外的任何东西。""只有 elastic/cloud 仓库中的分支能接收这些提交。"每个动作发生时都会写入日志文件。
- 一条针对明显捷径的规则。"绝不降低依赖的版本",以及"相对于 master 分支,宁可失败也不要降级版本"。
智能体还是走了捷径。用 Elastic 的话说:"Claude 倾向于这样修复版本升级带来的问题:嗯……把版本升级删掉。"构建就是判据,撤掉变更就能让它通过。禁止降级的规则写在提示词里,模型只是参考它;它不在检查里,检查才会强制执行它。问题被人工评审发现了,L2 本来就是为此而设。Elastic 的结论是:"评审必不可少,对提议的变更保持审慎态度极其重要。"
它没有说明什么。成功率。Elastic 没有说智能体尝试了多少个失败的 PR,所以 24 是一个没有分母的分子。它也没有说明已合并修复的缺陷率或回退率。节省 20 天是团队的估算,不是测量。
实例演算:用公开数据给 Elastic 定级。用成熟度模型中的自评方法来打分。
- 评审方式。每个 AI 碰过的 PR 都要等人合并,自动合并被强制关闭。就依赖升级修复而言,这是 L2。
- 实际授予的权限。提交只能进 elastic/cloud 的分支,工具实行白名单。文章没有说明 Buildkite 作业持有哪些密钥。评估者在认定 L2 之前会问这一点,因为规则 2 按令牌定级。
- 升到 L3 需要什么。第一,一个针对变更意图的核验器,放在智能体够不着的地方。对这个任务类别,流水线可以加一步,把 PR 的版本目录与 Renovate 原本的升级做差异比较,凡是降低版本的修复一律判失败(本书的提议)。这就把失效的指令变成了检查。第二,在至少 90 天里把回退率与人工修复做比较。第三,一个演练过的暂停手段。这些都没有公开,所以如实的评分是 L2。
迁移步骤
每次只升一级,只针对一个指定任务类别;每一级积累的证据就是进入下一级的门票。合适的起点类别范围窄、频率高、可检查:锁文件与依赖升级导致的失败、lint 与格式错误、重命名后失效的导入。涉及安全的代码、迁移和流水线定义本身,都不适合作为起点。
L0 → L1:给建议,同时测安全。
- 在开发者本来就会看的地方展示构建失败的修复建议:IDE、PR、失败作业的日志。
- 照搬 DIDACT 的设计:记录建议被应用的频率,并从第一天起记录包含已应用修复的变更被回退的情况。没有第二个数字,日后就无法判断 L2 是否让情况变差。
L1 → L2:智能体推送,人来合并。
- 给智能体一个独立的机器人身份,让每次提交都有署名,并且只允许它推送到正在修复的那个 PR 分支。
- 智能体碰过的 PR 一律禁用自动合并;如果做不到,就让作业失败(Elastic 的做法)。
- 在运行框架里而不是提示词里强制执行工具白名单,并把动作日志保存为构建产物。
- 把你禁止的捷径(降级、删除或跳过测试、修改 CI 配置)写成在智能体之后运行、且智能体无法修改的流水线检查。
- 开始积累 L3 需要的 90 天记录:修复合并率、固定时间窗口内的回退率,以及同类人工修复的这两个数字。
L2 → L3:自动应用到分支,按证据评审。成熟度模型里 L3 的各项条件全部适用。它们落到 CI 上是这样的:
- 只对书面清单上的任务类别自动应用,并由配置强制执行(Nx 的 glob 模式是一种做法)。绝不让模型确信度成为唯一的关卡。
- 在一个智能体未参与配置的作业里,对智能体的提交重跑完整流水线。这次重跑加上前面的意图检查,才构成验证。
- 合并仍要设关。到了 L3,智能体不再为每个修复等待批准,但 PR 仍须经人批准或按路由规则合并。Zalando 的评审机器人会自动批准它归为低风险的 33% 的 PR,其规则"基于对我们生产事故的分析而制定"(Zalando,T3,2026 年 8 月)。它是否使用 LLM 没有说明;可以借鉴的是用你自己的事故数据来划分风险层级。
- 演练暂停。针对某个任务类别关掉智能体,确认流水线照常运转,再重新打开。成熟度模型要求暂停和回退经过演练,而不只是可行。
L3 → L4:以现有证据,不行。没有任何组织发表过带验证记录的、由 LLM 驱动的推进或回退。如果要让发布决策自动化,就让指标与基线的比较来做决定,就像经典验证那样。模型可以解释这个决定,但不该做出这个决定。成熟度模型对 L4 的其他条件仍然适用:一名指定的问责人、一个急停开关和定期抽样审计。任何无法撤销的发布动作,根本没有资格进入 L4。
如果上游智能体正在推高 PR 规模或每次发布的变更数,先解决这个问题,再谈升级。一个更快修复更大批量的 CI 智能体,交付的仍然是更大的批量。
护栏
9.3 中的护栏让 CI 智能体的产出保持诚实。本节把智能体本身当作一个攻击者够得着的特权依赖来对待。完整的权限模型见《安全、权限与爆炸半径》。三起事件说明了 CI 为什么需要自己的护栏。
PromptPwnd:不可信文本加特权令牌。Aikido 的研究人员发现,一些 GitHub Actions 和 GitLab 工作流存在这样的链条:"不可信的用户输入 → 被注入提示词 → AI 智能体执行特权工具 → 密钥泄露或工作流被操纵"。受影响的集成包括 Gemini CLI、Claude Code、OpenAI Codex 和 GitHub AI Inference。Google 针对 Gemini CLI 自身的工作流"在四天内打了补丁"。Aikido 称"至少有 5 家财富 500 强公司受到影响",但没有点名。Claude Code 的 action 默认只为有写权限的用户运行;Aikido 认为用 allowed_non_write_users: "*" 放宽这一限制"应被视为极其危险"。
Aikido 给出的缓解措施本身就是一份可用的清单:"限制 AI 智能体可用的工具集";"避免把不可信的用户输入注入 AI 提示词";"把 AI 的输出当作不可信代码";"限制泄露的 GitHub 令牌的爆炸半径"。用成熟度模型的话说,一个处理陌生人 issue 文本的智能体,不能同时持有能改动其分支之外任何东西的密钥。
Amazon Q 扩展:AI 工具自己的流水线。2025 年 7 月,AWS 披露恶意代码被"自动包含进了"Amazon Q Developer VS Code 扩展的一个发布版本。根本原因是"其 CodeBuild 配置中一个权限范围不当的 GitHub 令牌"(AWS 安全公告,CVE-2025-8217,T2 厂商公告)。1.84.0 版本带上了它,1.85.0 版本将其移除,注入的代码因语法错误没能执行。根本原因不在模型,而在一枚 CI 令牌的权限范围,与《案例研究》中那些智能体事故属于同一类失败。
Nx s1ngularity:一次工作流注入,武装了 AI 命令行工具。Nx 的维护者安全通告把 2025 年 8 月的入侵追溯到一个 PR 校验工作流。它使用了 pull_request_target,并在 shell 步骤里回显 PR 标题,于是一个精心构造的标题被当作代码执行,最终导致 npm 令牌泄露。Wiz 的分析还原了恶意包随后的行为:它们以跳过权限确认的参数运行开发者本机安装的 AI 命令行工具,四处搜寻密钥。AI 这一步只在不到四分之一的情况下成功外泄数据,常常被模型拒绝、审批确认和默认的工作区限制挡住。Nx 的修复都是 CI 层面的:用 Trusted Publishing 取代长期有效的 npm 令牌,外部贡献者触发的工作流须经批准。本书的安全一章以此为锚点案例。
以下是本书对任何运行智能体的 CI 作业的提议,综合自上述三起事件和 GitHub 已上线的权限边界:
CI AGENT JOB: MINIMUM ENVELOPE (the book's proposal) trigger only collaborators with write access; never "*" input issue/PR text is data; never in a prompt alongside secrets token scoped to the one PR branch; short-lived secrets no publish, deploy or cloud-admin credentials in the job tools allow-list enforced by the harness, not the prompt cannot edit workflow files, CODEOWNERS, agent config, test oracles merge auto-merge disabled on any PR the agent touched log every action uploaded as a build artifact
GitHub 的 Copilot 云端智能体已经把其中大部分作为默认设置:它只能推送到自己的分支,它的工作流"在 Copilot 云端智能体的代码经过评审之前不会被触发",发起这项工作的人不能批准该 PR(GitHub 文档,截至 2026 年 10 月)。还没有人按权限边界发表过事故率,所以请把它当作起步设计,而不是经过验证的标准。
针对幻觉包名的依赖白名单见《经济性、风险与度量》;运行中服务的回退见《运维与事故》。本站的智能体供应链安全深入解析和发布与发版智能体实战手册介绍了相关工具。
指标
CI 智能体最常用的指标是接受率:开发者采纳的修复占所提修复的比例。它衡量的是认同,不是正确。Elastic 那些被删掉的版本升级,如果评审者没发现,也会被算作"已接受"。DIDACT 之所以是模板,是因为它把吞吐量和下游安全放在一起测。请按任务类别,为每个流量指标配一个稳定性指标:
- 修复合并率,带上分母。用已合并的修复除以尝试过的修复,而不是除以提出的修复。Elastic 的 24 就没有分母。
- AI 落地修复的回退率,在固定时间窗口内(例如 14 天)统计,并与同类人工修复的回退率并列。这是稳定性那一半,也可以实际替代成熟度模型对 L3 要求的、与人工基线对比的逃逸缺陷率。
- 拦下的意图违规。统计被智能体之后的检查拦下的降级、删除或跳过的测试,以及对 CI 配置的修改。数字上升,说明智能体在钻判据的空子;长期为零,也可能说明检查根本没在起作用。
- 批量大小,用 DORA 自己的指标:最近一次变更的代码行数、每次发布的变更数、完成一项任务所需的时间(DORA 2025,第 58–59 页)。小批量会略微削弱 AI 对个人效能的提升,不过 DORA 判断其净效应为正。
- 变更失败率和恢复时间,比较包含 AI 落地变更的发布与不含的发布。
Thoughtworks 技术雷达(第 34 期,2026 年 4 月)把 DORA 指标列入"采纳"环,并附了一句正合本章的话:"如果前置时间没有缩短、部署频率没有提高,更快的代码生成就不会转化为更好的结果。"这是从业者的观点,与本章的证据一致。在打开一个 CI 智能体之前,先写下让它关闭的阈值。第 17 章《衡量成效与何时回退》会完整阐述回退触发条件。
反模式
- 把绿色构建当证明。Elastic 的智能体靠删掉被测的变更让构建通过。如果智能体能改变构建所检查的内容,通过就毫无意义。在智能体之外检查意图,并参阅《测试与验证》了解如何让测试远离它。
- 沿用旧的自动合并。一个原本自动合并 Renovate 或 Dependabot PR 的仓库,在智能体向其中一个 PR 提交的那天,就悄无声息地变成了 L4。照搬 Elastic 的做法:自动合并没关掉,就拒绝继续。
- 开放触发加密钥。在
pull_request_target上、或为任意评论者运行智能体,而作业又持有写入或发布令牌。这正是 PromptPwnd 和 Nx 的模式。 - CI 中权限过宽、长期有效的令牌。Amazon Q 和 Nx 两起事件,症结都在一枚权限超出作业所需的 CI 令牌。请使用短期、范围受限的凭证和可信发布。
- 把接受率当成功指标。60% 被接受,说明开发者采纳了这些修复,并不说明这些修复是对的。
- 拿模型确信度或 LLM 当关卡。"高度确信"是模型给自己打分,而且没有任何已发表的证据支持由 LLM 驱动的推进或回退。请以检查和基线作为关卡。
- 权限过宽的角色。在有争议的 Kiro 案例中,双方的说法都把访问范围放在核心位置,而 Amazon 的修正措施是"对生产访问实行强制同行评审"(《案例研究》)。给智能体一个能部署的角色,就是授予了 L4,不管有没有人有意这么做。
本站的 CI 修复智能体实战手册和智能体变更的合并队列实战手册介绍了具体实现。发布与版本管理讲的是智能体自身的分阶段发布。
怎么做。
- 选一个范围窄、可检查的任务类别,比如失败的依赖升级或 lint 错误,以 L2 运行:智能体以机器人身份推送到 PR 分支,由人合并。
- 智能体碰过的每个 PR 都强制关闭自动合并,关不掉就让作业失败。在运行框架里而不是提示词里强制执行工具白名单。
- 把你禁止的捷径(降低版本、删除或跳过测试、修改工作流或 CODEOWNERS)变成在智能体之后运行、且它无法修改的流水线检查。
- 审查每一个运行智能体的 CI 作业:移除发布、部署和云管理员密钥,把触发者限制为有写权限的协作者,不让 issue 和 PR 文本进入与密钥同处一个作业的提示词。
- 用尝试次数作分母衡量修复合并率,并把 AI 落地修复的回退率与人工修复对比。不要把接受率当作结果来汇报。
- 升级之前先限制批量大小、演练一次回退。回退能限制损害,却不能防止不稳定。
- 进入 L3 的门槛:90 天的回退数据不差于人工基线,有智能体无法修改的意图检查,自动应用只限于配置好的任务清单,并且暂停手段已经演练过。发布推进交给基于指标的验证。L4 没有 LLM 证据。