2026年9月21日,Linear的CTO Tuomas Artman在项目管理工具里指派了一个任务给工程师Mufeez Amjad,标题很直白:“CI costs are high”。这个看似普通的运维需求背后,藏着一个让很多工程团队头疼的真相:AI代理生成代码的速度远超预期,但负责验证这些代码的CI/CD系统还在按人类节奏运转。Linear的代码库主要基于TypeScript,但他们这次对CI基础设施的重构思路,对于使用其他语言栈的团队同样有参考价值。
过去几年,大家默认AI编程代理只是让写代码变快了。写代码快了一倍,测试也得跑得快一倍,这逻辑听起来没毛病。但现实情况更糟。当代理开始并行工作,或者一个代理同时开多个Pull Request(PR)时,CI不再只是“检查对不对”的守门员,它变成了整个交付链路里最昂贵的阻塞点。Linear在这篇博文中提到,代理让发布代码的速度呈指数级增长,但验证这些变更的环节并没有跟上同样的节奏。每个PR依然要穿过CI的关卡,结果就是基础设施成本飙升,开发者和代理都在排队等反馈。
这跟我们也比较像,CI实际上要跑的东西很多,虽然很多都是自动再跑。
为了看清这个问题有多严重,Linear团队没有凭感觉优化,而是盯住了两个核心指标:一个PR在CI上排队等待的时间,以及单次测试消耗的Runner机器时间。从年初到现在,他们的测试套件数量近乎翻了四倍。注意,是四倍。在这种压力下,他们硬是把PR的等待时间从6分钟以上降到了5分钟出头,同时把单测Runner时间砍了一半。这在直觉上有点反常识:活儿多了两倍,时间反而少了?这就是重构基础设施带来的红利。
Linear的解法没有涉及什么黑魔法,而是拆成了四个层面的工程改造,从最底层的硬件到最上层的测试逻辑。
第一层是搬离GitHub Actions,换到第三方高性能Runner。这一步带来的提升纯粹是物理层面的。他们新用的Runner有更快的CPU、更高性能的存储和更好的缓存基础设施。对比切换前后两天的数据,同样的Pipeline在新机器上平均快了34%。有些工作负载甚至在20倍左右。听起来像是“花大钱买快机器”,但这其实是必要的基础投入。当代码吞吐量增加400%时,原来慢吞吞的默认环境就成了硬伤。Mufeez Amjad之前在做Meta的Buck2构建系统时就有处理大规模编译的经验,这次他把类似的思路用在了CI基础设施上,让机器本身不再是限速瓶颈。
第二层是精简关键路径上的任务。CI里有很多Job,但不是所有Job都同等重要。有些Job一旦完成,其他的阻塞任务才能开始。Linear重新梳理了依赖关系,把那些拖后腿的、反复执行的验证步骤识别出来,要么并行化,要么直接砍掉冗余部分。这里有个细节很有工程味:他们优化了Checkout行为。你可能觉得Checkout就是拉个代码,有什么好优化的?但在高并发场景下,Git操作如果没处理好,会引发锁竞争或者网络开销,导致整个Job卡住。Linear把这块卡点找出来解决了,减少了无意义的等待。
第三层是去重与缓存。依赖安装是每个CI Job都要干的事,也是最费时间的环节之一。如果每个Job都重新下载一遍node_modules或者pip packages,那时间和带宽都浪费在重复劳动上。Linear加强了缓存机制,确保依赖只在真正变化的时候重新解析和安装。同时,他们把原本分散的依赖设置进行了整合,减少因为配置不一致导致的版本冲突或下载失败。这一步看似琐碎,但在每天成百上千次构建中,省下来的时间累积起来非常可观。
第四层,也是我觉得最见功夫的一层,是测试执行效率的优化,特别是针对Vitest的隔离策略。当测试套件数量激增时,简单的并行跑起来可能会导致资源争抢,甚至因为测试之间的状态污染导致结果不可信。Linear调整了Job分组逻辑,让相关联的测试在一起跑,不相关的分散开。更关键的是,他们加强了测试隔离。Vitest本身支持模块隔离,但默认配置可能不够激进。Linear通过调整隔离粒度,避免了不必要的模块重新加载,同时确保了测试之间的独立性。这使得单测Runner时间减半成为可能,而不是因为砍掉了测试用例,而是因为跑得更快了。
这套组合拳打下来,效果不仅体现在速度上,还体现在成本上。Linear在文中特意提到,随着测试套件增加,机器时间的消耗曲线原本会大幅上扬,但通过上述优化,他们把这条曲线压平了。对于一家ARR(年化经常性收入)刚刚突破1亿美元的公司来说,CI账单每个月能省下多少钱,这笔账不用算太细也知道有多重要。
这件事之所以值得在整个行业范围内讨论,是因为它暴露了一个普遍性的错位。Megaport和RuntimeWire在评论中都提到,AI Coding正在把软件工程的瓶颈从“写代码”转移到“验证代码”。以前我们觉得瓶颈在人脑子里的构思,后来觉得瓶颈在打字员的手速,现在瓶颈在服务器的队列里。
Anthropic最近的动态也在印证这种趋势。他们在The Decoder的报道中提到,Claude Code重构了Projects功能,引入了协调器(Coordinator)机制,将任务拆分到并行的云线程中。这些线程独立打开PR并运行测试,所有线程共享内存。想象一下,如果每个线程都在往CI里塞PR,而CI还在按串行思维调度,那结果就是彻底的拥堵。Linear的做法实际上是在为这种“多代理并行”的工作流做基础设施铺垫。
AWS Machine Learning Blog在9月20日的一篇文章里也提到了类似的观点。部署一个Hugging Face模型需要十几个决策,如果让没有引导的编码代理去干,容易生产出脆弱或昂贵的端点。这说明验证环节不仅仅是跑测试,还包括对环境配置、资源分配的校验。如果CI不能快速反馈这些“非代码类”的错误,代理就会一直犯错。
还有一个数据支撑了这个趋势的普遍性。Ramp公司最近披露,他们内部的编码代理负责了75%的合并PR。每四个合并的代码变更里,有三个是AI写的。在这种比例下,如果CI的平均反馈时间还是10分钟,那就是代理每分钟都在等待,而人类开发者也在等待这些代理完成工作。反馈延迟直接决定了迭代速度。
这里有个观点来自Botonomous.ai,我觉得挺戳中痛点的:“当你的工具成为瓶颈,你曾经是否测量了正确的指标?”以及“修复瓶颈不会消除拥堵,只会重新分布它”。Linear解决了CI慢的问题,但下一步拥堵会分布到哪里?可能是代码审查(如果人类还要Review AI的代码),可能是部署流水线,或者是甚至更上游的需求澄清。AI Coding带来的不只是效率提升,而是整个研发流程权重的重新分配。
对于正在大规模引入AI Coding的团队,我的建议是别把CI当作静态的配置列表。YAML文件写好了,不代表系统就健康了。你需要把它当成一个动态系统来运维。关注两个核心指标:“每PR成本”和“反馈延迟”。前者控制你的云账单,后者控制你的迭代节奏。
Linear的这篇博文虽然是以TypeScript栈为背景,但里面的方法论是通用的。无论你的后端是Go、Rust还是Java,只要你的测试套件在增长,且你引入了并行的代码生成能力,你就会遇到Checkout卡顿、依赖缓存失效、测试隔离不彻底这些问题。基础设施的演进必须跑在应用层创新的前面,至少是同步。如果验证的速度慢了半拍,前面所有的生产力提升都会被等待时间抵消掉。
现在,瓶颈已经转移了。接下来的问题是,你的CI架构准备好了吗?是继续忍受慢速的验证循环,还是像Linear一样,花点时间重新审视从Runner硬件到测试隔离的每一个环节?在AI代理全天候工作的未来,这道题没有标准答案,但答错代价很高。