返回 文章 build CMS 文章

Anthropic 如何用 Scion 重构源代码控制:从 Git 到智能体规模

当 AI 让代码量爆炸,Anthropic 用自研 Scion 替换 Git,为智能体规模的软件开发重建源代码控制。

源代码控制ScionGitAnthropic
成长分 / 100 74 综合收获、行动、留存与影响

Anthropic 如何用 Scion 重构源代码控制:从 Git 到智能体规模
为什么值得读了解 AI 编码如何将瓶颈从写代码转移到源代码控制等开发者基础设施。

学习 Scion 针对始终在线客户端、水平扩展、廉价提交等原则的设计与实现。

关键洞察
  1. Anthropic 的日均合并代码变更从 2026 年 5 月的约 2,500 项增长到 9 月的超过 30,000 项,Git 的分布式设计在超大 monorepo 下成为扩展瓶颈。
  2. Scion 基于客户端始终在线、客户端-服务器不对称、全面 API 驱动、水平扩展、提交廉价无锁、工作副本可选且稀疏等原则构建。
  3. Scion 以变更集为核心,服务器端创建提交,通过派生数据支持追溯、路径历史等查询,并采用分层缓存架构实现高吞吐。
转成行动

深入阅读

正文与原文对照

原文保真覆盖:全文原文字符:22475

获取开发者通讯

产品更新、操作指南、社区聚焦等。每月发送至您的收件箱。

在 Anthropic,编码不再是构建系统或进行研究的瓶颈。Claude 能够自主迭代研究循环、对复杂程序进行微优化,并以我们前所未见的速度和规模从零开始构建新服务。如今,瓶颈变成了所有为人类规模构建的开发者基础设施:源代码控制、构建和 CI。

2026 年 5 月,Anthropic 平均每天合并约 2,500 项代码变更;截至 9 月,我们每天合并超过 30,000 项。我们预计这一增长速度短期内不会放缓;合并代码的潜在需求几乎是无限的,我们每消除一个瓶颈,都会立即导致我们产生的代码量进一步增加。

为了支持这种增长,我们构建了 Scion——一个内部版本控制系统,并在五个月内将我们的 monorepo 从 git 完全迁移过来。我们还在同一时间段内构建并发布了代码审查界面(称为 Antique)、代码搜索、丰富的源代码控制 IAM 系统、管理并落地大量已审查代码的新方法等。在本文中,我们将重点介绍我们具体是如何构建 Scion 的。这是一个有趣的案例研究:Claude 编写代码的能力既是最初让我们陷入这种局面的原因,也是我们能够快速构建高质量、可扩展系统来应对它的原因。

在探讨我们构建了什么之前,我们应该承认我们的工作负载有多么不寻常。不出所料,Anthropic 使用 Claude 编写软件的程度远超几乎所有其他公司,因此我们往往是第一个看到为人类规模构建的工具开始吃紧的地方。源代码控制只是其中一个例子。虽然我们预计近期内不会有太多组织遇到这些问题,但我们怀疑用不了多久,其他使用 AI 编码工具的人也会经历这些同样的压力点,这就是为什么我们想分享我们构建了什么以及学到了什么。

Git 是一个去中心化系统:每个克隆都是一个完整、自包含的仓库,可以计算差异、读取历史和追溯(blame),并在完全离线的情况下检出任何修订版本。对于绝大多数仓库来说,这是正确的设计,也是 git 成为标准的重要原因。

随着我们的 monorepo 增长,它越来越不符合这种设计空间。仅主分支的历史就接近 100 GB,而压缩后的工作副本超过 25 GB。我们每天为 CI 执行约 2,500 万次代码检出,这还不包括开发者环境、代理沙箱和研究任务。如果天真地获取,那将是每天超过 600 PB 的 git 流量。

Git 提供了处理仓库部分内容的工具,例如浅克隆、稀疏检出和 promisor 远程。除此之外,还有针对大型 monorepo 的标准变通方法,例如内部 git 镜像和保存在 blob 存储中的仓库快照(种子)。我们全都用过——在高峰期,我们运营了数百个内部 git 镜像来应对负载。这为我们赢得了时间,但随着合并率的提高,它们变得越来越难以运营。种子在刷新之间离主分支顶端越来越远,而且要让依赖历史记录的操作(如 diff 和 blame)在部分克隆上正常工作,需要越来越多的细心维护。

退一步看,我们注意到,像大多数公司一样,我们把 git 当作一个集中式系统来使用,只有一个权威副本,但我们的客户端几乎都是代理和作业,它们按定义是在线的。让 git 在分布式、离线工作中表现出色的那些特性,随着仓库的增长,反而在积极削弱我们的扩展能力。于是我们问自己:如果我们从一开始就设计源代码控制,考虑到代理始终在线这一事实,它会是什么样子?

在代理式编码中,许多关于软件开发方式的常见假设正在演变。在构建 Scion 时,我们拥抱了这些变化,这使我们能够在几个核心原则上采取与 git 根本不同的方法。针对大型单体仓库的源代码控制已有先例,尤其是谷歌的 Piper 和 Meta 的 Sapling,因此我们能够借鉴它们来之不易的经验来构建 Scion。我们的原则是:

客户端始终在线。 Git 假设客户端离线工作,并且需要仓库的完整副本。由于我们的客户端几乎都是代理和作业,我们围绕一个始终可访问的服务器来设计 Scion 的客户端和协议,并让客户端在需要时获取数据。

客户端-服务器不对称。 在 git 中,每个客户端都能成为功能完备的服务器。在 Scion 中,服务器负责回答关于文件历史和 blame 的问题、创建提交、执行合并和变基等。客户端维护一个有界的本地对象缓存,在磁盘上布置工作副本文件,监控文件系统变化,并为用户提供一种符合人体工程学的方式与服务器交互。它自身能计算的东西很少,但作为交换,它在本地需要的数据也少得多。

一个全面的源代码控制服务可以驱动许多新颖的应用。 使用 git 时,一个需要询问仓库相关问题的 CI 作业或工具,例如谁最后修改了某一行或两个提交如何关联,必须维护仓库的本地副本,或者寄希望于供应商特定的 API 提供答案。使用 Scion 时,客户端使用的所有源代码控制查询也通过 API 暴露,因此在许多情况下,作业根本不需要本地仓库。许多内部工具,例如我们自动化的 bisect 和 revert 流水线,如果没有这种廉价、程序化的源代码控制访问,就无法大规模实用。

一切都必须可水平扩展。 在高峰期,我们运行了数百个 git 镜像,这严重消耗了容量,并且一旦仓库超出镜像的磁盘或内存限制,就不再能扩展。在 Scion 中,仓库的数据是分布式的,每个组件都可独立扩展;任何地方都没有仓库的完全物化副本,即使在服务器上也没有。没有类似 packfiles(git 的压缩对象包)的东西,因此不需要仓库维护。

提交必须廉价、增量且无锁。 在 git 中,你在本地提交,然后推送以分享你的工作。在 Scion 中,每次提交、变基或合并都发生在服务器上,因此无需推送,但每一项操作都需要快速完成。创建提交并更新其下游数据结构的成本必须随变更的大小而扩展,而不是随仓库的整体大小扩展,否则服务器将无法跟上。Scion 中的开发生命周期不鼓励使用引用(指向提交的指针,例如分支和标签),除了主引用或发布分支,因为每台服务器都必须达成一致的全局状态是一个迫在眉睫的扩展问题。

工作副本是可选的,并且按设计是稀疏的。 由于我们的 monorepo 非常庞大,而且我们每天为 CI 检出代码数千万次,我们希望尽可能避免检出。例如,在 Scion 中,需要某个提交与其合并基之间差异的 CI 作业可以向服务器请求它。写入也是如此:许多写入工作负载也可以跳过检出,完全通过 API 运行。Scion 的协议以稀疏检出为中心,稀疏检出只包含客户端请求的目录,以及虚拟化检出,它按需物化文件,因此当作业确实需要磁盘上的文件时,客户端只需为其实际读取的内容付费。

理解这些原则在构建 Scion 时如何在实践中结合在一起是很有帮助的。这些见解可以应用于其他源代码控制系统,或者更广泛地应用于软件开发生命周期的其他阶段。

在 Scion 中,工作单元是“变更集”,即预写日志中的一项条目。变更集存储了你在 git 提交中预期的大部分内容。但是,git 提交存储指向树的指针,而变更集存储相对于其第一个父提交发生更改的文件列表,1 以及指向 blob 存储中压缩文件内容的内容寻址指针。变更集在服务器端创建,并且立即可在所有地方使用。

这种结构使我们能够以非常高的吞吐量接受变更集,因为没有要接受的 packfile,没有锁定或跨服务器协调,也没有要移动的引用。Scion 在技术上支持引用,但由于创建和获取提交都不涉及引用,移动引用是对单个 Spanner 行的比较并交换,与创建变更集分开进行。

变更集只记录已更改的内容,因此仅凭它自身,无法快速回答诸如谁最后编辑了某一行或哪些提交影响了某个文件之类的问题。为了回答这些问题,Scion 从变更集构建额外的数据结构,包括用于文件追溯和路径历史的专用结构,以及用于提交图的跳表。我们将所有不直接属于变更集的内容称为“派生数据”,并且我们通过一个通用机制来计算所有这些数据。每种类型的派生数据都是递归定义的,因此某个变更集的派生数据值是根据该变更集的父提交的派生数据值计算出来的。

这种机制有三个好处。首先,当新的数据结构能使某些操作更快时,我们可以轻松添加一种新的派生数据类型。其次,对于每种类型,我们可以选择是急切计算还是推迟工作,从而避免物化我们不需要的数据。第三,由于客户端永远看不到这些数据结构的内部细节,我们可以在不改变客户端的情况下对它们进行优化。随着系统的发展,我们已经多次添加了新的派生数据类型,例如用于执行复制检测或基于路径的文件搜索的新索引。

一小队 Scion 服务器为客户端所需的任何操作提供源代码控制 API,例如获取变更集、计算差异、查找合并基础以及获取 blob。所有源代码控制数据都是内容寻址的,因此一旦存储,数据就不会改变,任何服务器都可以缓存它而无需与其他服务器核对。因此,这些服务器可以水平扩展,并且几乎不需要协调。它们本质上是大缓存,也可以即时计算派生数据并将结果写回 Spanner。

Scion 的众多消费者不再需要维护自己的本地仓库。获取和维护仓库曾经是 CI 作业或需要询问源代码控制问题(特别是关于提交祖先和追溯)的工具的重大维护负担。在迁移初期,在我们拥有自己的客户端、仓库格式或协议之前,Scion 只回答这些“元数据”查询。获取文件内容和物化工作副本是数据密集得多的操作,它们需要自己的设计。

Scion 的 scn 客户端在几个重要方面偏离了 git 的获取协议,因此,它适用于高度可扩展的架构,所需的 CPU 比 git 服务器少得多。Scion 的协商不告诉服务器客户端已经拥有什么;相反,它仅对客户端想要的树和 blob 进行操作。从根树开始,客户端检查其本地存储中缺失的树并递归请求它们,然后对 blob 重复该过程。每个请求都是针对一个永不改变的特定对象,因此任何缓存都可以回答它,并且该架构与传统分层缓存非常相似。该过程也很高效且可恢复,因为没有单个多 GB 的包文件响应。稀疏甚至虚拟化的检出不需要特殊支持,因为客户端根本不会请求它不想要的树。

在集群中,客户端通过套接字与守护进程 scion-daemon 通信,该守护进程为整个节点存储对象。我们的大多数节点需要访问 monorepo,同一节点上的作业重用大多数相同的对象。每个守护进程从定期刷新的快照开始,然后只与其区域中的树和 blob 缓存服务器(称为 scion-cache)通信。这些缓存服务器直接从内存中以守护进程将使用的磁盘格式流式传输对象,因此它们不需要花费时间计算客户端缺失的对象或执行增量压缩。当缓存缺少对象时,它会询问权威的 scion-servers,后者根据需要从 Spanner 或云存储中读取。

scion-daemon、scion-cache 和 scion-server 在此协议下都响应完全相同的 RPC,因此客户端无需了解缓存拓扑。理论上任何一层都可以与任何其他层通信,但我们严格强制分层,以隔离故障域。我们希望避免出现这样的情况:某个区域性的 scion-cache 发生故障,压垮上游的 scion-server,进而拖垮整个系统。

该系统的每一层都保持超过 99% 的缓存命中率,且不需要长期存活的状态,因此按需扩容很容易。就 CPU 和内存需求而言,我们的 Scion 基础设施占用现在比之前的 git 镜像基础设施小 200 倍。CI 和研究任务检出代码的速度快了两个数量级(以秒计而非以分钟计),这在整个集群中释放出相当可观的容量;仅 CI 一项就实现了 25% 的 CPU 容量收益。客户端和缓存都不需要执行仓库维护,这简化了我们任务的生命周期管理。

我们开始构建 Scion 的时间,与 Claude Mythos Preview 和 Claude Tag 在内部可用大致相同。这两个发布同时放大了对 Scion 的需求* *,并显著加快了我们构建它的速度。

这里有一个特别引人注目的例子。今年早些时候,我们基本上是以手写方式完成了 git-to-Scion 摄取流水线第一版的原型。我们本以为它不错——直到我们拿到 Claude Mythos Preview 的一份早期内部快照。我们让它重写整个流水线,在没有任何进一步指示的情况下,它产出的版本内存占用减少了 20 倍、速度快了 4 倍,同时保留了围绕摄取顺序和数据结构的全部隐式不变量。

我们在构建和运营 Scion 过程中学到的东西,为构建智能体规模的软件可能是什么样子提供了一些有趣的启示。

小团队快速开发将变得更加普遍。 一个七人团队构建了 Scion 和 Antique(我们的代码审查工具,完全可以为此另写一篇博客文章),更不用说还有六个相关系统,并在五个月内完全迁移到这些系统上。我们完成这一切的同时,每天合并的代码量增加了 10 倍。过去,开发和部署这样一个源代码控制系统,需要一家公司花费数年时间迭代迁移,并投入多得多的工程师。我们认为这种快速、灵活的迁移在未来会变得更加普遍。

工程师的价值丝毫不减,但他们的工作正在发生变化。 所有参与这个系统的工程师现在都会认为 Claude 在编写代码方面比他们更强。但我们的工程师仍然提供了对高层系统间组件和设计层面权衡的宝贵理解,围绕我们想要解决的问题和我们知道需要达到的规模做出了明智的选择。很多时候,我们发现工程师的角色是告诉 Claude“不行”。智能体有时会为了满足一种本就不该被允许的模式而违反核心系统约束。这在我们迁移过程中尤为常见。例如,有多个系统试图通过线性读取提交日志来暴力查找某个变更何时合并到 main,而不是询问我们的代码审查工具。Anthropic 还大量使用对抗性审查,虽然这在许多方面非常有效,但也可能目光短浅,因此需要熟练的工程师引导 Claude 不要为了应对假设性的担忧而对系统某些部分过度设计。例如,有一次这样的审查对信任另一个内部服务过于防御,导致 Claude 添加了过多的验证和复杂性。我们的团队成员仍然审查该系统的每一个变更请求,但他们现在审视的是变更的意图,而不是逐行阅读代码。

我们能够大幅提升优化和质量。 凭借 Claude 能够以远超我们自身速度编写海量代码的能力,Scion 是我们参与过的最经过充分测试和充分防御的代码库之一。即使在我们紧张的时间表下,我们也能够为我们遇到过的每一个非平凡基础设施和源代码控制交互构建封闭模拟,以及模糊测试和复杂的速率限制。Claude 还随手发现了重大优化——例如,对祖先查询的一项算法优化,该查询遗漏了我们的一个索引——这本来需要专家花费数天或数周的分析和调优……然后第二天又把这一切重新做了一遍。

我们为新型单体仓库安全奠定了基础。 在庞大的单体仓库中管理安全、安保和合规,与管理规模和体量同样重要。我们从一开始就在构建 Scion 时考虑了这些。它支持对仓库进行丰富的访问控制,以及将权限应用于单个目录的能力,以保护最敏感的代码,同时不失去单体仓库的优势。此外,我们构建的代码审查工具可以对审批表达复杂的语义约束,这让我们能够区分仅注释变更和敏感逻辑变更等简单事项,以便人工审查者能够专注于最重要的变更。

运营卓越可以达到一个全新的水平。 我们的团队大量使用 Claude Tag,这帮助我们监控系统的每个组件。例如,我们创建了 Slack 频道,让 Claude 专注于单个组件的健康状况。我们称这些 Claude 为“超级粉丝”。我们有 scion-daemon 超级粉丝、scion-cache 超级粉丝、Antique 合并队列超级粉丝等等。它们可以访问我们的遥测数据和日志,表现得像一位经验丰富的工程师,除了刷新图表和寻找任何异常之外无事可做。我们也有针对所有系统的传统警报,但相比之下,我们的超级粉丝能够检测到微妙而新颖的问题,让这些警报显得片面。

我们正在彻底重新思考我们的先验。 这个项目促使我们认真审视其他为人类规模设计的工作流程。例如,一个合适的合并队列在智能体规模下并不太合理。当数百甚至数千个变更可以在测试运行时合并,CI 到底意味着什么?我们尚未能够有效复制行业标准的合并队列全局仓库锁,因此,我们转而投资于合并后和部署前的自动化测试。这确实意味着并发变更可能会冲突,但 Claude 通常能够比人类识别冲突更快地修复这些冲突。

我们认为 Scion 只是解决日益强大的 AI 智能体所引发的扩展性问题的一部分答案。我们分享这些细节,作为团队如何应对类似挑战的一个例子,尽管我们并不期望我们的解决方案或我们的考虑适用于所有情况。

Scion 绝不是 git 的通用替代品。我们在这里概述的概念只适用于真正庞大的 monorepo,拥有数万名工程师或大量智能体疯狂编写代码。此外,Anthropic 的独特之处在于,我们为内部使用花费 token 的能力远远超过任何其他企业实际愿意花费的。我们这样做既是为了满足我们自己的软件开发需求,也是为了测试 Claude 的能力。

实际上,很难将 Scion 以对其他组织广泛有用的形式提供。它与 git 有显著差异,意味着公司需要迁移开发生命周期的每一个部分,并且它需要自己的代码审查、代码搜索和 CI。我们这些组件的内部版本高度定制,因此其他组织难以采用,我们担心试图构建一个试图取悦所有人的公共版本实际上并不会非常有用。

然而,我们预计这类问题在未来六到十二个月内会变得更加普遍,而让每一家使用 git 的公司都独自面对类似挑战,将是对工程资源的低效利用。有鉴于此,我们认为最有影响力的事情就是分享我们的思考,以便其他开发者能够在不偏离整体模型的前提下,将 Scion 中最成功的部分应用到 git 上。git 服务器不必以与 git 客户端相同的方式工作;已经存在能够带来显著扩展性改进的新颖服务器架构。Git 平台可以提供像 Scion 那样全面的服务端 RPC,甚至可能以标准化的方式跨各个代码托管平台提供,让 git 客户端学会与之通信。协商协议也不必与今天完全一样,而且 git 中各种稀疏和浅克隆特性也可以被很好地组合起来。

最后,我们要承认,git 社区已经花费了近二十年时间为数百万开发者扩展这一平台。我们的贡献要狭窄得多:分享我们对智能体软件开发如何与这些系统交互的早期看法,以便我们能够与 GitHub、GitLab 以及开源社区合作,支持开发者不断变化的需求。当软件开发生命周期与 AI 指数级增长相交汇时,我们都在同一条船上。

作者:Nick G. 以及源代码管理团队:S.G.、R.K.、Dan C.、Garrett H.、Ben L.、Colin M.、Joe P.。我们感谢 Vilas J. 和 Sergiu D. 在这段雄心勃勃的旅程中支持源代码管理团队,也感谢 Amir O. 对 Antique 的早期贡献。

产品更新、操作指南、社区聚焦等。每月发送到您的收件箱。