Scion 和 AI 时代的版本控制
当大量 AI Agent 同时写代码,版本控制的成本会怎样变化?从变更记录、派生索引、分层缓存到主干协调,结合三张原理图理解 Anthropic 的 Scion,以及它的意义与边界。
写代码的速度越来越快,软件交付却未必同步变快。一个 AI Agent(智能体)几分钟就能改完代码,但它仍要准备工作目录、读取历史、提交修改、等待测试,再与其他变更整合。Agent 数量越多,这些步骤产生的总开销就越值得关注。
Scion 是 Anthropic 为这种负载构建的内部版本控制系统。理解它,可以从一个问题开始:当代码的主要使用者是大量在线、短暂存在的任务时,版本控制应该如何分配工作?
Scion 给出的方向,是让客户端按需取数,让服务端承接版本计算,并尽可能复用数据和计算结果。它把版本控制推进为一种在线基础服务。沿着这条线索,我们也能看清它的收益、技术先例和适用边界。
Agent 如何放大版本控制的成本
Anthropic 在 2026 年 10 月 13 日的文章中披露,其每天合并代码超过 3 万次,CI 每天进行约 2500 万次 checkout,也就是把指定版本的代码准备成任务可用的工作目录。Anthropic 原文
这两个数字换算成日均值,约为每秒 0.35 次合并、289 次 checkout。平均值不能代表峰值,却提示我们:扩展难度需要结合仓库体积、任务重复度和每次操作的成本一起判断。
设想一座图书馆。一位研究者长期坐在固定书桌前,可以慢慢积累自己的资料;如果每天有大量短暂到访的读者,每人只看几页,为每个人准备整套资料就很不划算。
传统完整克隆适合让开发者持有一份可独立操作的仓库。长期使用同一工作目录时,初始化成本能够被摊薄。临时沙箱则会不断重复初始化,一些公共数据和公共计算也可能随之重复。
可以用一个粗略模型理解这种压力:
总成本 ≈ 任务数量 ×(代码传输 + 版本计算 + 工作区维护)
优化的重点因此变得明确:减少无关数据,复用相同对象,复用相同查询结果。
这里也要准确理解 Git。Git 已支持部分克隆,可以省略暂时不需要的对象,在需要时再获取。采用哪种版本系统,应比较真实工作流中的成本,不能把 Git 一概等同于每次完整下载。Git 部分克隆文档
先保存变更事实
版本系统至少要回答两个问题:这个版本是什么,以及怎样快速找到其中的信息。这两个问题可以由不同的数据结构解决。
Scion 的 changeset,即变更集,记录相对第一父节点发生变化的文件,并引用相应内容。设计说明
假设我们修复支付逻辑,修改两个文件、删除一个旧文件。用简化格式表示:
变更 C1
父版本:C0
文件变更:
pay.py → 新内容 H1
test.py → 新内容 H2
old.txt → 删除
H1、H2 可以理解为由内容计算出的标识。记录保留路径与新内容之间的关系;文件内容则单独存储。对这个单父节点例子,把这些文件变更应用到 C0 上,就能得到 C1。
图 1:变更记录与派生数据的教学模型。字段为示意;同类设计可见 Meta 的 Bonsai。
文件级变更与文本补丁是两层概念。 “这个路径现在对应哪份文件内容”,不等于“底层只能存储增加或删除的几行文字”。文件内容如何压缩、两个版本如何计算 diff,都可以另行设计。Meta 的公开 Bonsai 模型展示了路径变更列表和独立文件内容存储的组合。Bonsai 数据模型
Git 的快照模型也不意味着每次复制整仓。Git 的提交引用目录树,目录树再引用文件和子目录,未改变的对象可以复用。比较这些模型时,关键在于提交过程中必须构建什么数据,以及相应计算由谁承担。Git 对象模型
再为读取建立索引
如果只保留一连串变更,查询历史就可能很慢。例如,要找出某个文件在第十万次提交时的内容,最朴素的方法是沿历史不断寻找。
数据库解决类似问题的方法,是建立索引和物化视图。版本控制也可以把查询需要的结构预先或按需算出来:
| 想回答的问题 | 可以使用的派生数据 |
|---|---|
| 某版本有哪些文件 | 目录树和文件清单 |
| 谁改过这个路径 | 路径历史索引 |
| 某一行来自哪次修改 | blame 数据 |
| 两个版本有什么祖先关系 | 提交图索引 |
所谓派生数据,就是能够从基本记录重新计算出来的信息。它承担查询加速的任务,不必全部成为提交事实的一部分。
可以把它的计算方式理解成:父版本已经有结果,当前版本只需根据本次变更更新相应结果。计算完成后,其他任务就能复用。
Meta 的 Mononoke 公开文档展示了这一机制:派生数据可以由后台处理,也可以在查询缺失时按需生成。这样,写入与查询就能分别优化,新增索引也能改善新的查询需求。Mononoke 派生数据
这项选择有明确代价。提前计算能降低查询等待,却可能算出无人使用的数据;延迟计算能减少无用工作,却可能让第一次查询变慢。系统需要根据负载作出取舍。
让代码读取复用缓存
另一项关键设计,是如何把代码分发给大量任务。
Git 的 fetch 协议可以让客户端告诉服务端自己想要什么、已经有什么,再由服务端确定传输哪些对象,返回 pack 数据。响应因此与客户端的已有状态有关。Git 协议文档
围绕不可变对象组织读取时,请求可以更接近下面这种形式:
给我标识为 H 的对象。
如果 H 对应的内容不会改变,相同请求就可以反复使用同一个缓存结果。不同任务读取相同代码时,便有机会共享已经获取的数据。
Scion 公开的对象读取路径包括节点缓存、区域缓存和源控服务,见下图。架构来源
图 2:只展示树与文件对象的读取。箭头表示缓存未命中后继续向上游请求,不代表所有版本查询都走同一条路径。
这条链路让我们容易理解共享的价值:同一节点上的任务复用节点缓存,不同节点还有机会复用区域缓存。任务越频繁读取相同对象,重复搬运数据的机会就越少。
按需读取还可以分成两个层次。稀疏工作区只选择需要的目录;虚拟工作区则进一步推迟文件内容的获取,在真正读取文件时才准备它。Meta 的 Sapling、Mononoke 和 EdenFS 也展示了延迟获取与虚拟工作区的设计方向。Sapling 扩展设计
实际收益仍取决于任务访问模式。大量零散请求会带来网络往返,冷缓存也需要重新填充。Git 的 packfile 还能通过增量压缩节省空间,因此对象式读取与打包传输各有成本,不能只凭“是否使用 packfile”判断优劣。Git packfile 原理
分开创建版本与推进主干
现在考虑两个 Agent 同时工作。它们都从版本 P 开始,一个修改支付逻辑,另一个修改测试,分别产生 CA 和 CB。
CA、CB 可以同时存在。但主干 main 最终指向哪里,是另一件事。
图 3:版本创建可以并行;主干更新和组合行为验证仍需要协调。示例省略了评审等步骤。
一种安全更新方式是:仅当 main 仍然等于预期的 P 时,才把它改为 CA。这种“比较旧值,再尝试替换”的操作叫 compare-and-swap,简称 CAS。
Scion 把 changeset 创建与引用更新分开,并用 Spanner 单行 CAS 更新引用。设计来源
如果 CB 随后仍以 P 为旧值尝试推进主干,就会发现 main 已经变化。系统必须先处理新的整合关系,再决定如何更新。
CAS 已是成熟技术,Git 的 update-ref 同样支持先检查旧值再更新引用。Git update-ref 文档
这里值得记住的原则是:让大量不可变版本的产生尽量并行,把必要协调集中在少量可变状态上。 这会降低协调范围,却不会让并行修改自动兼容。文件冲突和跨文件的行为冲突,仍然需要解决。
验证会成为更突出的难题
代码存储和分发加快之后,交付链路还剩一个更难的问题:这些变更组合起来,是否正确?
沿用每天 3 万次合并这个量级,假设变更均匀到来,一轮 10 分钟的测试期间,约有 208 次合并发生。这是便于理解的计算,不代表真实峰值或测试时长。
测试通过,只能说明某个明确版本通过了这些测试。主干继续前进后,需要重新判断旧的测试证据适用于哪里。
传统合并队列可以把变更组合起来验证,也能够并发构建;GitHub 的实现已经支持这些方式。GitHub 合并队列
Anthropic 提到,他们增加了合并后、部署前的自动化测试投入。来源
这意味着验证工作可以分布在不同阶段,但每个阶段的责任必须清晰:哪些检查是合并门槛,哪些问题可以在合并后快速发现和回退,哪些验证必须在部署前完成。
一个版本系统可以保存代码、计算差异、支持回滚。正确性的证据,仍需来自针对明确版本的测试、评审和运行结果。
Scion 的意义与适用边界
这条技术路线有清晰先例。Google 在 2016 年介绍过服务巨大单一仓库的自研基础设施;Meta 的 Mononoke 也采用精简核心数据、派生索引、无状态服务和外部存储等设计。Google 论文、Mononoke 架构
我更关注 Scion 带来的一个信号:过去由庞大工程师团队产生的基础设施压力,可能被大量 Agent 集中到人类成员更少的组织中。组织人数没有那么多,计算任务和变更活动却仍然可以很大。这是从负载特征出发的推论,不能直接推广到所有使用 AI 编程的团队。
Anthropic 报告,源控基础设施的 CPU 和内存占用约降至旧 Git 镜像方案的 1/200。这个数字对应特定基础设施对比,不能解释成整体开发效率或总成本改善 200 倍。性能数据来源
对于多数团队,首先应该测量:时间花在 checkout、构建、测试,还是等待整合?如果重复取数占比很高,可以研究部分克隆和共享缓存;如果版本查询反复计算,可以考虑服务端查询;如果瓶颈是验证,就需要改善测试选择和反馈周期。更换版本系统本身未必解决主要问题。
Scion 展示了一种有价值的设计思路:把可共享的数据和计算提升为公共服务,把每个任务必须完成的工作压到更小范围。当 Agent 持续提高代码产出速度,工程系统更需要关注的指标,是每个经过验证、能够安全交付的变更需要付出多少成本。