跳转到主要内容

合并队列成了新的瓶颈

阅读需 1 分钟Tian PanTian Pan

你的编程智能体(Coding agents)刚刚让编写代码成为了交付软件中最廉价的部分。但它们并没有让代码落地变得更便宜。AI 采用率高的团队合并的 Pull Request (PR) 数量几乎是以前的两倍——而他们的交付指标却几乎没有变化,因为每一个 PR 仍然必须挤进同一个代码评审流水线、同一个 CI 集群以及同一个合并队列(Merge Queue),而这些设施当初是按人类打字速度设计的。约束并没有消失,而是向后移动了,移到了系统中那个最窄的管道:从“已批准”到“进入主分支(main)”之间的串行化路径。

这是一个经典的约束理论(Theory-of-constraints)故事,大多数工程组织目前正身处其中却尚未察觉。当一名开发者可以在并行工作树中指挥 5 到 10 个智能体时,PR 的体量就不再与员工人数挂钩。但合并吞吐量仍然取决于一些更为死板的东西:你的 CI 每小时能验证多少个 main 分支的候选状态。这个数字受限于测试套件的时长、执行器(Runner)容量、抖动率(Flake rate)和队列机制——而这些都没有随着智能体变快而变快。

悄然失效的容量数学题

合并队列的存在是为了强制执行一个不变性:main 分支永远是绿的(测试通过状态)。它通过针对 main 的“未来”状态(当前末端加上队列中排在前方的所有变更)来测试每个 PR,而不是针对编写 PR 时那个陈旧的分支点。这种保证正是你在几十个并发变更可能产生交互时所需要的,但也正是它让吞吐量的成本变得昂贵:正确性是用串行化换来的。

算一算串行队列的账。如果你的合并组 CI 端到端需要 30 分钟,那么一个严格排序的队列每小时最多只能合并 2 个 PR——如果没有任何失败,每天最多 48 个。一个 50 人的团队,如果每人每天产生 2 个 PR,就已经超过了这个上限。现在让每个开发者运行几个智能体,请求到达率翻了三倍,而服务率却保持不变。排队论在这里是残酷的:当到达速度接近处理容量时,等待时间不再是线性增长,而是呈爆炸式增长。上个季度只增加了 10 分钟延迟的队列,在这个季度可能增加 4 小时,而 CI 的任何环节都没有变慢。

分批处理(Batching)是标准的避风港,而且确实有效:将 5 个 PR 放在一次 30 分钟的运行中进行测试,你就获得了 5 倍的吞吐量——只用了 30 分钟的算力,而不是两个半小时。GitHub 自己的单体仓库(Monorepo)就是一个参考案例。超过 500 名工程师通过合并队列每月合并约 2,500 个 PR;从旧的部署列车模型迁移到动态合并组后,平均交付时间缩短了三分之一,同时安全并发部署的变更量翻了一番。但分批处理也有失败模式,而智能体异常擅长触发这种模式。

智能体是抖动放大器

当一个批次失败时,队列必须找出罪魁祸首。简单的策略是剔除整个批次并重新测试所有内容;更聪明的队列会采用二分法(Bisect),但这仍然需要 O(log n) 次完整的 CI 运行。无论哪种方式,只要有一个红色测试结果,就会导致后面所有 PR 赖以测试的投机状态失效,队列必须从失败点重新开始。这种级联失败(Cascade)是合并队列运行中成本最高的操作——而它的发生频率是由你的“抖动测试(Flaky test)”率决定的,而非代码质量。

Uber 的数据让这个利害关系变得具体:在他们建立专门的抖动管理之前,他们的 iOS 主线仅有 52% 的时间是绿色的,他们最终在单体仓库的 600,000 个测试中识别出了大约 1,000 个抖动测试。仅仅千分之几的不稳定测试就足以堵塞所有人的队列。

智能体让情况显著恶化,原因有三个复合因素:

  • 更多的条目,更多的掷骰子机会。 如果每 200 次运行会出现一次抖动,而你的队列每天处理 40 个批次,那么你每周都会发生级联失败。当每天处理 120 个批次时,你每天都会发生级联失败。抖动率没变,但暴露在风险下的次数变了。
  • 智能体无休止地重试。 人类看到偶然的失败会叹口气,点击重新运行,并在 Slack 上提一句。但一个被指示为“完成 PR 合并”的智能体会反复将同一个变更重新排队,每次尝试都会烧掉完整的 CI 运行时间,并为排在后面的所有人重新触发同样的级联失败。在人类操作频率下只是轻微浪费的重试循环,在智能体频率下变成了拒绝服务攻击(DoS)。
  • AI 编写的变更带有更多的潜在破坏性。 跨工具研究发现,AI 辅助编写的 PR 包含的问题大约是纯人工 PR 的 1.7 倍。其中一些问题仅在合并组中才会暴露——这意味着更多的合法失败与抖动交织在一起,使得寻找罪魁祸首变慢,也让乐观策略变得更冒险。

这种复合效应才是关键。每个因素单独看都是可控的;但加在一起,它们会让一个原本每月出一次状况的队列变成持续震荡的状态。团队的感受是“CI 变抖动了”,但测试并没有变——变的是流量。

会员专享

余下内容仅对会员开放。

会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。

  • 完整文章,包含未公开存档的部分
  • 可落地的工作框架,附带权衡与决策依据
  • 新文章抢先看,先于公开发布

随时取消 · 一次订阅,畅读全部

参考资料

保持联系,关注我获取更多内容

阅读需 10 分钟

那些在本地通过但在 CI 中失败的编程智能体

编程智能体会继承你笔记本电脑中已配置好的环境,并提交在本地通过但在 CI 中失败的补丁。解决方案是建立仓库级的环境契约、进行预检一致性检查,并根据本地与 CI 的差异进行评分。

insider
ai-engineering
阅读需 8 分钟

你在廉价模型上测试,却在昂贵模型上部署

在廉价模型上运行 CI 和评估,而生产环境却使用尖端模型,这在最关键的地方破坏了开发与生产环境的一致性。本文将探讨为什么层级差距会使你的评估门控失效,以及缩小这一差距的预算计算方法。

insider
llm
阅读需 10 分钟

你的智能体幻觉出的软件包现在已存在 —— 而且它是恶意的

LLM 会反复幻觉出相同的虚假软件包名称 —— 43% 的名称在每次重新运行时都会重复出现 —— 而攻击者正在注册这些名称。本文探讨了为什么拥有安装权限的智能体会将幻觉演变为供应链攻击,为什么 Diff 审查无法捕捉此类问题,以及能够防御此类威胁的 lockfile、白名单和冷却期防御机制。

insider
ai-engineering
阅读需 10 分钟

万档代码转换:在机械式代码迁移中运行智能体集群

确定性的代码转换工具可以完成迁移中简单的 80%,但在长尾问题上会停滞不前 —— 而这正是单个文件编码智能体大显身手的地方。但在集群规模下,问题不再是提示词工程,而是变成了批量操作:分片、验证网关、隔离以及针对其 Mapper 具有随机性的 MapReduce 作业的合并策略。

ai-engineering
coding-agents
阅读需 9 分钟

你的内部框架是一种低资源语言

编程智能体可以写出完美的 React,却会对你公司内部的 ORM 产生幻觉。本文探讨了为什么内部框架表现得像低资源语言,如何衡量这种能力断层,以及何时应该让你的技术栈顺应模型的训练分布。

insider
ai-engineering