夜雨聆风学习资料网

ARTICLE · 1185045

Anthropic重做源码管理,更多测试放到合并后

Anthropic重做源码管理,更多测试放到合并后

要查询一项变更什么时候并入主干,有些系统让Claude逐条翻提交记录。工程师要求它停下:这件事应该问代码审查工具。

这个小例子来自Anthropic的《Redesigning source control at Anthropic》。Anthropic源码管理团队的Nick G.等人在10月13日发布的复盘里说,七人团队用五个月建成源码管理系统Scion、审查工具Antique和一组相关系统,并完成单一大仓库从Git的迁移。

Anthropic源码管理团队

本文采用其工程复盘了解自家系统的负载、设计和迁移经验,性能数字均按公司自报阅读。

公司称,每天合并的代码变更从5月约2500次增至9月超过三万次。Claude既增加了待处理的代码,也帮助他们重做处理这些代码的工具。

这些工程师制止的,是一种不合适的查询方式。查询该由谁回答、测试该在哪一步做,都影响后续工作。

每天两千五百万次检出,先要把文件准备好

有了完整Git克隆,用户离线也能查看历史、比较版本和取出代码。对大多数仓库,这仍是很好用的设计。Anthropic却发现,自己几乎都在为始终在线的Agent和自动任务服务。

它的主干历史接近100GB,压缩后的工作副本也超过25GB。仅持续集成,也就是自动运行构建与测试的CI,每天就要检出约2500万次代码;开发环境、Agent沙箱和研究任务还没算进去。

这里的“检出”,是把指定版本的文件准备到任务能读取的地方。写一小段代码之后,若测试任务还得反复获取、准备庞大的仓库,写代码节省的时间就可能被后续工作占去。

原文估算,朴素地获取这些工作副本会产生每天超过600PB的Git流量。这是假设方案的量级,不是公司实际每天传了这么多数据。他们此前已经采用浅克隆、稀疏检出、内部镜像与快照,最多运行数百个Git镜像。

这些办法争取了时间,但变更越来越密,快照离最新主干越来越远,部分克隆上的历史查询也更难维护。继续加镜像,并不能无限解决单个镜像的内存与磁盘限制。

我的理解是,团队此时需要重新问:这个任务究竟要读哪些文件、回答什么问题?如果只是查一次差异,没必要先准备一份能独立回答所有问题的本地仓库。

查历史交给服务器,文件用到再取

Scion把历史查询、逐行追溯和合并等操作交给服务器。客户端主要维护有限的对象缓存、把需要的文件放到磁盘,并监测本地修改。

例如,CI任务想知道两个版本有什么差别,可以直接调用服务接口。自动定位引入问题的变更、执行回退的工具,也能通过接口查询,不必各自维护完整仓库。需要实际运行程序时,客户端仍会准备文件,只是默认支持按目录取用,或读到文件时才把它生成到磁盘上。

这里舍弃的,是客户端独立离线工作的能力;得到的,是更少的本地数据和统一的查询服务。历史查询的计算仍然要做,只是主要交给了服务器。

服务器自身也没有一份完整展开的大仓库。Scion将一次变更记入日志,记录相对第一个父版本,也就是作为比较基准的旧版本,改动了哪些文件,再以内容地址指向文件数据。相同内容对应相同地址,存下后就不再变化。

只记录改动,有利于快速接收变更,却不能直接高效回答“这一行谁改过”。因此系统另建逐行追溯、路径历史和提交关系等派生结构。需要的索引可以提前计算,也可以等查询到来再算。

这部分设计有个很实用的分工:接受一项改动,不必同时完成所有未来查询需要的计算。查询方式可以继续演化,客户端也不需要知道服务器内部如何换索引。

同一节点上的任务,不再各搬一遍相同内容

减少整仓检出之后,真正需要的文件仍然很多。Scion为这部分设置了分层缓存:同一机器上的任务共用节点缓存,节点再向所在区域的缓存请求;区域缺失的对象,才交给上游权威服务查存储。

内容不变,缓存就能放心复用。区域缓存按客户端能直接读取的格式流式返回对象,不必每次重新计算缺了什么,再生成一个巨大的压缩包。客户端请求的是自己尚缺的具体对象,中断后也能继续取。

团队称,各层缓存命中率超过99%;Scion所需CPU和内存约为旧Git镜像系统的二百分之一。CI和研究任务检出代码由分钟级变成秒级,单是CI就获得25%的CPU容量收益。

这些数字支持的,是仓库分发与检出的改善,不能扩成公司整体成本下降25%。高命中率也依赖大量任务复用相同内容,换一种负载未必还能得到同样结果。

分层还带来一个容易忽略的约束:区域缓存出故障时,不能让所有请求直接涌向上游。团队严格限制层级关系,要避免局部故障拖垮全局服务。

评估集中化,也要检查区域缓存不可用时,怎样防止请求拖垮上游。客户端始终在线,就需要能持续访问源码服务。

测试还没跑完,主干已经变了

通常,合并队列会控制变更进入主干的顺序,并配合测试检查候选代码。当测试运行期间已有几百乃至几千项其他变更合并,维护一个全局顺序会越来越困难。

Anthropic说,自己未能有效复现行业常见的合并队列全仓锁做法,因此把投入转向合并后的自动测试和部署前测试。并发修改确实可能冲突,他们的经验是,Claude修复这类冲突,通常比人工识别出冲突还快。

这是接受一定冲突、再快速处理的工程选择,不是取消测试,也不是代码并入主干便立即交给用户。原文没有给出冲突率、故障恢复时长和生产缺陷率的完整比较,不能据此宣布合并后测试一定更安全。

我会把“允许进入主干”与“允许部署”分开看。检测后移时,后续发布检查必须能截住错误,回退与修复也必须可靠;否则等待测试省下的时间,会变成部署后的返工。

要借鉴这个安排,团队得先回答:测试跑的哪个版本,出错后能定位哪几项变更,以及谁能阻止有问题的版本发布。这些是我对验收条件的建议,不是复盘已经证明全部满足的结果。

工程师要判断,哪段代码根本不该写

复盘里,工程师仍审查每项变更请求,不过更关注变更意图,而非逐行阅读所有代码。

开头那种逐条翻日志的方案,看起来能得到答案,却忽略了系统里已有更合适的查询入口。另一次对抗审查担心内部服务不可信,Claude便增加了过量校验和复杂度。工程师需要制止这种由假想风险引出的过度设计。

一个实现跑通了,仍要判断它是否违反系统约束、重复已有能力,或者把维护成本留给了别的团队。只要求模型“继续检查”,也可能越查越复杂。

Simon Willison的解读在合并量图上标了模型公开发布日期,但他也提醒,这不是模型在Anthropic内部可用的时间。图上的同期增长,不能证明某个版本单独造成了效率提升。

我也不会用三万次合并来评判这七个人创造了多少业务价值。变更大小、返工、质量和最终被用户使用的结果,都没有被这个计数包含。它更适合说明基础设施承受了多大的工作量。

Anthropic明确说,Scion不适合普遍替代Git。超大仓库、密集在线Agent,以及远超一般公司的内部Token投入,都是这个案例的重要条件。迁移还牵涉审查、搜索和CI,不是换一个客户端命令就结束。

普通团队可以先借鉴服务器查询、按需取文件和节点缓存,不必连离线能力一起舍弃。至于合并后测试,应根据自己的发布风险另作判断。

工程师制止一次不合适的实现,有时比继续生成代码更能减少后续工作。

延伸阅读


《The Phoenix Project: A Novel about IT, DevOps, and Helping Your Business Win》
Gene Kim、Kevin Behr、George Spafford
用一部IT团队的工作小说理解瓶颈、工作流和跨部门协作。适合接着思考:写代码更快之后,哪一步仍在拖慢交付;它不证明Scion的性能或后移测试的安全性。
往期内容

OpenAI称模型协助查窃听,通报列出了监控和记录
六模型测试把粗鲁语气和短答要求分开了
Anthropic反蒸馏,Claude的旧思考要按条件复用
Maia 300:微软要提高每兆瓦的Token产出
Jev、OpenAI和微软,为何单独提供“判断”?
拾荒图书馆
看见技术,也看见它改变世界的方式

相关学习资料