---
layout: post.njk
source: https://yage.ai/share/anthropic-scion-agent-scale-infra-20261018.html
web_feed:
  articleId: cmvftsjob0003ye46zbkkq557
  feedSourceId: webfeed_yage_ai
  guid: https://yage.ai/share/anthropic-scion-agent-scale-infra-20261018.html
  sourceUrl: https://yage.ai/share/anthropic-scion-agent-scale-infra-20261018.html
speaker: yage.ai
title: |-
  为 agent 重造地基：Anthropic 的 CI 与
  Scion，哪些判断能复用、哪些不必照搬
date: '2026-10-18'
summary: Anthropic 针对其内部源码控制系统 Git 在面对高频运行的 Agent 任务时遇到的存储和性能瓶颈，重写了源码控制系统 Scion。Scion 采用了“轻客户端、重服务端”的架构，通过内容寻址替代传统 packfile，引入三层缓存机制，并优化了写操作（Changeset 机制）和合并流程，以适应永远在线、生命周期短的机器集群的需求。文章总结了重构过程中对研发流程、人与系统边界的工程判断，强调了流程优化、意图审查以及对成熟开源设计先例的借鉴。
area: tech-engineering
category: architecture
tags:
  - source-control
  - ai-agent
  - content-addressable-storage
  - caching-strategy
  - system-design
people: []
companies_orgs:
  - Anthropic
products_models:
  - Scion
  - Git
media_books: []
draft: true
status: evergreen
---

## 用户变了：从偶尔离线的人，到机房里永远在线的
agent

2026年10月13日，Anthropic发布了一篇文章，介绍他们内部的新一代源码控制系统Scion。促使他们改造源码控制系统的动力是，他们的规模在4个月内突然暴涨。2026
年 5 月，Anthropic 的大仓库每天平均有 2,500 个变更合并到主分支，到 2026
年 9 月涨到了每天超过 30,000
次。短短四个月，每天合入的变更次数涨了十倍不止。越来越多的 agent
和自动化任务在提交代码，那些按人类规模设计的研发基建也就顶不住了，源码控制、构建和
CI 系统率先出现瓶颈。

从存储和带宽的角度看，git 系统已经撑不住了。Anthropic
主分支的历史大小接近 100GB，即便压缩后每个工作副本也有 25GB+。再加上 CI
和自动化任务每天要拉取约 2,500 万次代码，如果每次都完整
clone，内网每天搬运的代码就超过 600PB。为了支撑 git，Anthropic
曾部署几百个内部 git mirror 节点，并用对象存储的仓库快照做 seed
再同步增量。即便如此，系统仍然经常挂掉。

那为什么经过时间考验的 git 在这里失灵了呢？这是因为 git
从诞生起，它的核心用户就是人。git 2005
年诞生时，一个核心目标就是让开发者即使离线也能照常工作：背着笔记本在断网的十几个小时里，照样可以提交、切分支、翻几年前的历史、比较任意两个版本之间的差异。为了支撑这种偶尔离线的场景，git
选择了客户端和服务端对等的架构：每次 clone
一个仓库到本地的时候，默认要把整个仓库的提交历史和文件对象图从头到尾都下载下来，所有的历史追溯、差异计算、分支合并都在本地完成。只要屏幕前坐着的是每天只拉几次代码、守着同一个工作目录写上一整天的人，这种离线对等的设计就非常优雅。

但到了今天的 Anthropic
内部，源码控制系统的头号用户已经换了。每天发起两千多万次检出、提交三万多次变更的主力，不再是坐在飞机上敲键盘的程序员，而是机房里永远在线的
agent 和自动化 CI
任务。这批机器客户端有两个跟人正好相反的特征：第一，它们永远连着高速数据中心网络，根本没有离线办公的需求；第二，它们的生命周期极短，经常为了修一个
bug、跑一次测试就临时拉起一个沙盒，干完活便销毁，不少任务甚至只需要看一眼两次提交之间的差异，连本地工作目录都不用建。

用给长生命周期、经常离线的人类设计的对等系统来伺候短生命周期、永远在线的机器集群，原来的设计优势全都成了包袱。为此，Anthropic
抽调了 7 名工程师，花了 5 个月时间从头写出了 Scion，把整个单体大仓从 git
全量迁了过去，同时把代码评审工具
Antique、代码搜索、源码级权限管控，以及自动二分定位与回滚管线等半打配套系统全都重做了一遍。

左右对照：2005
年为人设计的客户端会离线、每台机器存完整仓库、本地算历史与差异；2026
年为 agent
设计的客户端永远在线、只留少量本地缓存、重计算收回服务端，两者的客户端假设正好倒置

## 当重写变便宜，先凑合打补丁的账本已经算不平了

看到 7 个人在 5
个月里换掉整套版本控制底座，很多人的第一反应都是为什么要造这么重的轮子，在老系统上继续加缓存、打补丁难道顶不住吗？这笔账我们不久前在姊妹篇《CI
的第二层红利：重写变便宜之后，补丁不再回本》里，已经用 Anthropic
自己的 CI 测试筛选服务算过一次：agent
一让仓库流量涨起来，旧架构上打补丁能买到的平稳窗口就迅速变短；另一边，AI
辅助编程又把重写一套系统的工期和人力门槛压得很低。一头是补丁的保质期越来越短，另一头是重写的固定成本越来越低，以前那种先凑合打补丁、实在撑不住再重写的盈亏平衡点已经明显往前挪了。Scion
只是把同一本经济账从外围的 CI
服务一路往下算，算到了最底层的版本控制系统头上。

## 当读写代码的主力变成机器，Scion
换掉了 git 的前提

既然头号用户是永远内网的机器，客户端自然不必像人类笔记本那样把整座仓库背在身上。Scion
干脆拆掉了客户端与服务端对等的设计，让两边完全分工：服务端握全量历史、做所有费
CPU
的重计算；客户端只留一块有界的本地对象缓存，自己几乎不做计算，很多时候连本地仓库都不检出，直接调服务端
API
完成工作。顺着读代码、写与查、主干合入以及人的分工这四个关键场景去看，就可以看见这套”轻客户端、重服务端”的思路怎么落地。

git 的四个假设逐个失效：读的 packfile
现场打包、写与查的全树快照加锁、合入的排队全绿全局锁、人的逐行读代码，分别被按内容寻址加三层缓存、追加日志加服务端派生数据、合入后测加自动回滚、只审意图加架构护栏替换

### 读：别每次现场打包整座仓库，缺哪个文件直接按地址去拿

具体来看，对于最频繁的拉取代码操作，我们平时用电脑进行git操作的时候，git客户端需要和服务端进行协商，汇报自己的本地有什么提交，然后服务端再根据提交图现场比较计算，得出客户端需要哪些文件和目录对象，临时压缩打包成一个专属的大文件发送过来，这个现场打包的文件叫packfile。人一天拉几次码没啥，但一天
2,500 万次从零启动的检出，每次都要跟服务端对账、由服务端现场挑对象打包成
packfile，这套流程很快就把几百台内部 git 镜像节点的 CPU
和内存吃满了。更麻烦的是，每次打包的结果因为客户端当时的本地状态不同，也会不一样，所以中间层没法做像缓存静态文件那样的通用缓存。

要想成千上万的机器共享缓存、不用每次都重新打包，前提是每个文件都要有固定的地址。Scion
直接用文件内容的哈希值当存储地址：相同的内容会算出来一样的地址，改一个字就会变成新地址，因此相同的内容会自动只存一份，自动去重。而且同一个地址指向的内容不会变，所以任何中间缓存节点只要存过这个地址，就可以直接告诉客户端不用再问服务器是否有过期。这种用内容算出的哈希当地址的机制叫内容寻址。靠内容寻址，Scion
直接废了 packfile，它的客户端工具 scn
和服务端协商时不汇报自己有什么，而是从根目录树开始往下走，缺哪个目录/文件的哈希块就直接递归去要，传了一半断了也可以随时恢复。

有了内容寻址做基础，所有文件和目录都成了永不过期的静态块，那几百台各自维护整座仓库、现场算包的
git
镜像节点就可以全撤掉，换成三层缓存。为什么要分三层，是因为机房里每时每刻都有大群任务在读同一批代码，离任务越近的地方越快但装得越少，离全量数据越近的地方装得越全但路也越远。Scion
的思路是先在宿主机本机找，找不到再去机房共享内存找，实在没有才去云端存储拿，一层比一层更靠近全量真数据。第一层是跑在每台宿主机上的本机守护进程
scion-daemon。同一台机器上先后拉起的短期 agent
容器直接共用这份本机缓存，前一个任务刚拉过的文件，后一个任务在本机就能直接读。要是本机没有，请求就往上问第二层的区域缓存
scion-cache。它把大家常读的热数据直接按磁盘格式常驻内存，命中后流式下发，省掉了解包开销。只有前两层都没命中的冷数据，才会走到第三层的权威服务端
scion-server，回源去云端存储里读取。这三层对外是接口一致的同构
RPC 服务，彼此故障域严格隔开，整条读取链路就像 CDN 一样逐层回源。

一旦缓存通路理顺，客户端也就自然不用再做全量克隆，而是支持两种按需拉取模式：一种是在事先知道只涉及哪些模块的情况下，直接把当前任务需要用到的子目录拉取到本地硬盘，其他目录一概不碰，也就是稀疏检出；另一种是先只在本地挂一个空目录骨架，看上去文件都在，实际还没下载，等进程真的去读某个文件时，在后台按需拉取，也就是虚拟化检出。对于只看一眼代码差异的
CI 任务，连目录都不用建，直接调用服务端 API 拿 diff 就行。Anthropic
实测报告说，这套三层缓存每一层的命中率都超过 99%，整套源码控制基建占用的
CPU 和内存相比原来的 git 镜像集群缩小了 200
倍。单次检出从分钟级降到秒级，还顺手给整个 CI 省了 25% 的
CPU，客户端和缓存层也都免去了定期维护仓库的活。

### 写与查：每次提交只记改了哪几个文件，查历史也交给服务端去算

写代码查历史也一样，日常改动代码除了直接提交，还要把两条改动线接到一起（合并），或者把自己的改动挪到最新主干后面重接一遍（变基）。git
每次提交都要存一个指向整棵目录树的快照指针，仓库一大，提交、合并或变基的开销都会跟着受拖累，服务端接收
packfile
和挪动大量分支指针又得加锁协调。到了查询环节矛盾更突出：研发工具经常要逐行追溯某行代码是谁写的（blame
查询），或者在合并前顺着历史往上找两个分支的最近共同祖先（merge
base）。要是让一个个临时拉起的 agent 容器在本地遍历 100 GB 历史去算
blame 和 merge base，根本跑不动。

Scion 的做法是写入和重查询都放到服务端去做，每次提交的基本单位是一个
changeset。一个 changeset
不会去存储整个目录树的指针，而只会记录这次相对于第一个父提交具体改动了哪些文件，以及指向这些文件内容的内容寻址指针。服务端在保存
changeset
的时候，也不会原地去改复杂的树形结构，而是像记流水账一样，每次只在日志的末尾顺序追加一条新记录，这种只追加不改写的预写式日志机制一般叫做
WAL。不论是提交、合并还是变基，都在服务端直接生成 changeset
追加到末尾，写入后即处可见。因为不用改整棵树、也不用原地改旧数据，每次写入的开销只和这次改动了多少个文件成正比，整个仓库有多大和它没有关系了。

为了解决写入时的争用问题，Scion 还大幅度削减了分支指针的数量。在 Git
中，分支指针是一个名字，它指向当前最新的提交，比如主干叫
main，或者开发时随手建立的特性分支名，这些名字指针统称为
ref。如果有几千个工程师和成群的 agent
在仓库里建立分支的话，就会有成千上万个这样的名字。问题的关键在于，这些名字是全局共享状态：服务端得协调好每个名字此刻指向哪里，一旦有成千上万个改动并发地挪动它们，协调本身就成了瓶颈。Scion
平时尽量避免使用 ref，仓库中几乎只有 main
和发布分支，开发过程中的提交不需要注册成全局分支名。因此在创建 changeset
的时候，既不收 packfile，也不需要跨节点加锁或者移动
ref。只有在合入主干、必须更新 main 这个全局名字的这一刻，服务端才会去
Google 的全球分布式强一致数据库 Spanner
中对单行记录进行一次原子操作：先看一眼旧提交号是否改变，没改变才写新提交号，也就是常见的
CAS 操作。

而用于查历史的
blame、路径历史、提交图的跳表等查询数据则没有新增任何事实——只要有基本的changeset流水账，就可以随时像从银行流水算余额一样把它们推算出来，不需要人手动提交维护。Scion把这类可以从基础提交记录中随时递归推算出来的二级索引统称为derived
data。服务端用同一个通用的机制来计算derived
data，可以提前算好，也可以按需推算。因为客户端只能调API，看不见内部结构，所以在工程团队在后台升级索引的时候，客户端完全无感。目前已经陆续加入了复制检测和按路径搜索的索引。开发期间，Claude
还发现祖先查询漏用了一个已有索引，顺手做了一处算法优化。

### 合入：排队等测试跑完会堵死全仓，改成先合入主干再自动测试和回滚

写完能读能写以后，第三块撞墙的地方是主干合入关卡。大型工程团队一般会在主干前放一道自动化门禁，让所有待合入的改动排成一队，挨个基于最新主干跑完完整测试、确认全绿才放进主干，这个排队机制叫merge
queue。

每天只有几百次人类提交的时候，merge queue
运转良好；但当合入量冲到每天 30,000 次、主力变成全天候运行的 agent
时，正经的 merge queue
就不通了。每次合入都要先排队跑测试，队头的改动跑测试要好几分钟，后面成千上万个改动只能干等；而且单体大仓只有一个
main，这支队伍没法拆到多台机器上并行合入——高并发下等于给整个仓库加了一把慢速的全局排他锁。为此，Anthropic
转向合入后、部署前的自动化测试，先把代码合进主干，再配合自动二分定位与自动回滚管线把有问题的提交摘出去。高并发直接合入确实会让代码冲突变多，但团队试下来发现，让
Claude 自动修冲突的速度比人类工程师识别出冲突还要快。

### 人：写代码的比审代码的快，人类只审改动意图和系统边界

第四个瓶颈落在人身上。这 7 个人一边要把 Scion
和半打配套系统写出来，一边还得守住代码质量，对系统本身的每一个改动都做人工审查；而与此同时，全公司的合并量已经涨了
10 倍，靠逐行读完 AI 写的代码根本不现实。可要是完全放手让 agent
自写自审，又会踩中两个反模式：一个是 agent
会照抄老代码里本不该存在的坏模式而违反架构约束，比如内部以前有好几个系统为了查提交合入时间，不去调评审工具接口，而是直接从头到尾线性扫描整条提交日志，agent
写代码时就会顺着这种坏习惯继续写；另一个是对抗式代码审查视野短浅，负责挑刺的
agent 会没完没了地抛出假想风险，逼着 Claude
过度工程化、一层层叠加过量的防御校验。

在摸清这两个脾气之后，团队决定只对每个改动的意图和系统边界做审查，而不是逐行阅读具体实现。工程师的主要责任是提供高层的系统理解，做出设计决策，很多时候就是跟
Claude
说不。底层正确的实现由不依赖外部环境、可以精确模拟并发顺序的密闭确定性仿真，以及随机输入异常输入的模糊测试和限流来保证。安全方面通过仓库级和目录级的权限控制，并在评审工具
Antique 中加入复杂的语义审批。日常维护则由一组基于 Claude Tag
创建的专门巡检实例负责，内部戏称它们为
superfans，每个实例只负责一个组件，比如
scion-daemon、scion-cache 或 Antique
合并队列的健康状况。

### 系统边界：什么该学，什么不必搬

Anthropic 在博客最后也坦诚了 Scion 的定位与局限：它是沿着 Google
Piper 和 Meta Sapling 的路线发展出来的一套系统，并非用来取代通用
git，只在超大型单体库中才可能带来好处，并依赖于远超普通公司的内部 token
预算，因此并不打算开源为一个产品。对外而言，它给业界带来的启发主要在于几个架构层面的思路：git
服务端不必与客户端同构、把重计算放到服务端 RPC
里、拉取时可以使用不汇报本地状态的新协商协议，以及把少拉历史的浅克隆与少拉目录的稀疏检出更好地组合起来。

## 这是不是把 SVN 或
Mononoke 又发明了一遍

博客发出去以后，社区的第一反应是：这不就是把 SVN、Perforce 或 Meta
开源的 Mononoke 又发明了一遍吗？Scion 和 SVN/Perforce
只是看上去都是服务端集中，但底层的数据模型和水平扩展能力非常不一样。但是它的核心数据模型确实和
Meta 开源的 Mononoke (Bonsai) 非常接近。因为第一版博客没有提到
Mononoke，前 Meta 工程师 Rain 连发了第一篇、第二篇文章来质疑
Anthropic 没有提到 Mononoke 这个署名，并在 Hacker News
的讨论串上面展开了争论。10月15日，Anthropic 补充了脚注点名致谢了
Mononoke 和 Bonsai。

这更多是一个署名问题，而非代码抄袭或开源许可证违规。至于当初是否有意漏署，我们没法独立验证。但它至少提示了一个合理的解释：AI
之所以能快速重造一套底层系统，很可能正是因为前人已经把成熟的设计开源出来、又进了模型的训练集。

## 对别的团队意味着什么：哪些假设该重估，哪些只是
Anthropic 自己的仗

对普通工程团队的研发流水线而言，第一个应该放弃的想法是自己去实现一个版本控制系统。Anthropic
的对抗建立在百 GB 的历史库、每天 2,500 万次检出、30,000
次合入和远超一般公司的内部 token
预算上。对大多数团队来说，就算自己的仓库已经变慢，只要先把 Git
自带的三个减负开关配好——在 CI 和 agent
里只拉最近的一两层提交（浅克隆），先拉历史骨架、略过大文件（部分克隆），只把当前目录拉到本地（稀疏检出）——就能吃掉绝大部分痛点。在榨干这些原生工具前，自研版本控制只是在为不存在的规模买单。

在抛弃造轮子以后，这次重构里立刻能拿走的工程判断有三个，分别关于流程、人和账本。

第一，检查研发流程中默认用户是人的隐含假设。你不用等到日均三万次合入才开始优化，当流水线接入高频运行的
agent 时，每次任务全量拉取仓库的 CI
脚本、基于本地遍历提交图查元信息的周边工具、以及让所有提交排成一队等待测试完成的串行
merge queue
都会相继成为瓶颈。把一部分重测试从合入前移到合入后、部署前，并配置自动二分定位和回滚管线，往往比死抠单次测试几秒耗时更有用。

第二，把人的精力从逐行审语法转向守住意图和架构护栏。防止 agent
把老代码里的坏味道继续扩散，也别迷信 agent
之间的对抗式审查；人类工程师负责看清业务意图和模块边界，对模型过度工程化果断说不，同时把确定性仿真测试、目录级权限与自动回滚建扎实。

第三，重算老旧工具的修补与重写账本，但对开源先例保持敬意。要是内部老系统靠打补丁能买到的平稳窗口越来越短，而成熟的架构先例已经公开摆在社区里，抽两三个人借助模型花几周重写一套精简系统，这笔经济账现在完全算得平；只是动手时心里要清楚，省下的时间一半来自模型能力，另一半来自前人留在阳光下的开源设计。