代码量 8 倍、测试量 10 倍、CI 作业半年 25 倍。三次权宜补丁分别只撑了 70 天、29 天和不到 1 天——这篇复盘讲清了 CI 该怎么按指数增长来设计。
一家做前沿模型的公司,工程师每季度交付的代码量涨到 2021–2025 年均值的 8 倍,其中 80% 由编码智能体写成。写代码不再是瓶颈,瓶颈转移到了合并前的门禁。
这家公司的工程博客公开了一手复盘,其中有四个数字值得放在一起看(原文复盘收录页):
这组数字解释了瓶颈为什么会转移。写代码和审 PR 被并行加速之后,合并前的门禁成了整条链路上唯一还在串行、且必须对每一次变更负责的环节。测试数量涨了 10 倍,而跑不跑、跑哪些,要由一个叫测试影响分析(Test Impact Analysis,下称 TIA)的服务来决定。
瓶颈转移不是孤例。更早的观察已经指出,AI 编码率上去了,交付周期并没有同步下降(卡点换到了验收环节)。代码写得快,验证跟不上,整条链路的实际吞吐由最慢的一环决定。
该服务在 2025 年 10 月就开始吃紧,连续两天触发告警。接下来是三次典型的"先止血":
| 补丁 | 做法 | 撑了多久 | 为什么失效 |
|---|---|---|---|
| 第一次 | 把核心数翻倍 | 70 天 | 核心变多,但记录测试结果的监听组件仍是单进程,PR 队列继续积压 |
| 第二次 | 按代码仓的包结构分片,每个包一个独立 worker | 29 天 | 指数增长再次打满;内存仍集中在单个实例里 |
| 第三次 | 每工作日定时重启进程 | 不到 1 天 | 中午前后即触达内存上限;重启后进度越落越多,滞后超过一小时的时段里大量结果没被记录 |
这里有两点容易被忽略。第一,权宜之计在今天买来的时间,往往只有一年前的几分之一——负载曲线本身变陡了。第二,换内存分配器、调垃圾回收这类"性能小手术"全部无效,说明问题在架构,不在实现细节。
最终的重构思路并不复杂,核心是让处理测试结果的节点变成无状态:
改造之后,处理节点可以随意增减——无状态意味着能水平扩展;那个曾经摇摇欲坠的单例,被拆成了一个日志加一个归并器。代价是分布式架构运行成本更高,换来的是可扩展、可做内存剖析。整个项目一名工程师花了三周完成,而按作者的判断,同样的工作在一年前大概要接近一个季度。
复盘里最值得抄进事故手册的一段,是关于监听组件滞后的描述。这个组件一旦落后,后果不是报错,而是选错测试:
按文中的估算,监听落后 20 分钟,就可能意味着数万条测试结果更新没能作用到选择器上。系统的正确性在没有任何告警的情况下悄悄退化——对智能体驱动的研发链路来说,这种降级比一次明确的宕机难排查得多。门禁一旦被证明不可信,审查者的第一反应往往是干脆关掉整个 PR(一次 1721 行 diff 的结局)。同类问题在安全侧也在出现:GitLab 的安全分析指出,把编码代理关进沙箱并不等于安全,因为白名单里的服务本身会构成攻击面(该分析的中文报道)。
要让审查真正前移,得先把它做成一条可度量的产线,而不是一次性的提示词技巧(多智能体代码审查的落地拆解)。
它是位于 CI 与测试用例之间的一层服务,根据代码变更涉及的文件、包依赖和用例的历史通过情况,判断这次变更需要执行哪些用例,而不是每次都跑全量。对测试量大的仓库,它直接决定流水线的实际时长。
用例总量在几百条以内、全量跑得动,就不必急着上。真正的触发信号是门禁时长:当合并前的等待开始让工程师绕开流程(比如跳过用例直接合并),说明测试分层或选择机制该补了——欠下的账通常按半年为周期集中爆发(AI 编程的技术债)。
重启只把内存清零,没有降低单位时间内的处理量。而且重启会打断进度,让组件重新开始落后——滞后累积到一定程度,部分结果就永久丢了。用重启对付内存压力,相当于用清空缓存掩盖设计问题。
单实例既无法水平扩展,也无法安全地做灰度或性能剖析——你不敢在一个已经满负荷的进程上动刀。把这层约束去掉,多数扩容动作才有执行空间。