Git 基础设施重建:智能体规模开发下的读写解耦
原文:GitHub Blog - 《Building Git infrastructure for agent-scale development》(https://github.blog/engineering/architecture-optimization/building-git-infrastructure-for-agent-scale-development/)
写 Agent 的人平时关心模型、提示词和工具设计,很少有人往下再看一层:Agent 每跑一步都要 commit 或 checkpoint,这些写请求最后落到了哪里。GitHub 在 10 月 6 日发布的这篇技术博客把这件事讲透了------它们落在 Git 的存储层,而且所有写入都要挤过同一条需要达成一致的路径。作者 Brian Celenza 是负责 GitHub 存储与核心服务的首席工程师。这篇文章拆解三件事:规模数字说明了什么、"读好扩、写难扩"在智能体场景下具体卡在哪、新架构用什么方法把两者解开。
一、三组数字:Agent 把写负载推到了什么量级
原文给出的数字不多,但每一组都指向同一个方向。
| 指标 | 变化 | 时间口径 |
|---|---|---|
| 月度 Git 事件量 | 218.2 亿 → 473.3 亿 | 2025 年 9 月 → 2026 年 8 月,翻倍以上 |
| 月度 commit 量 | 73.8 亿次 | 2026 年 9 月,是一年前的 5 倍以上 |
| 月度 push 量 | 6.9 亿 → 33.5 亿 | 同比增长 4.9 倍 |
| PR 合并量 | 接近一年前的 4 倍 | --- |
| GitHub Actions 运行次数 | 32.6 亿次 | 2026 年 9 月,是一年前的 4 倍以上 |
顺手做个量级换算:按 30 天口径把上面的月度数字摊到秒,473.3 亿次 Git 事件约等于每秒 18 万次,73.8 亿次 commit 约等于每秒 2847 次,32.6 亿次 Actions 运行约等于每秒 1258 次。这不是峰值,是平均值。
原文还提到一个常被忽略的分布特征:8 月份 GitHub 上最忙的那个仓库,单月大约收到 10 亿次请求。也就是说,头部仓库和普通仓库之间的差距,比大多数人想象的要大得多------而智能体开发恰好集中在头部。
二、五个具体的瓶颈
规模本身不是问题,问题在于这种负载的形态。原文列了五条,每一条对应一个不同的压力点。
- 单次 push 的延迟变成智能体的速度上限。Agent 在一个紧循环里几乎每做一个动作就 commit 或 checkpoint,它的推进速度被"一次 push 要多久完成"卡住。人类完全感知不到的延迟,在这里成了限制因素。
- 写吞吐的需求涨了两个数量级。push 同比增长 4.9 倍,而同一个仓库里可能有几千个 Agent 各自在自己的分支上写,这些写入最终会汇聚到架构里的同一点。
- 合并争抢同一个引用。Trunk-based 开发、发布列车、合并队列,都会把全部工作挤到一个必须吸收每次合并的 ref 上。
- 一次 push 会放大成几千次读。CI 和代码扫描每分钟会反复 clone 或 fetch 同一个分支尖端,这个扇出必须足够廉价。
- 仓库维护本身也在变贵。为了保持操作快,GitHub 要持续做数据压缩和失效对象清理,而每一次新写入都会增加这份工作,成本随量级叠加。
这五条放在一起,能解释为什么"把 clone 做快"只解决了一部分问题:读相对容易扩,写难得多。读可以加缓存、加副本,把同样的字节发给更多客户端;写则必须先把数据持久化、并保证一致性可见,后面的人和 CI 才能在此基础上继续构建。
三、现在的架构为什么在头部仓库撞到天花板
理解新架构,得先理解旧架构的耦合点。
现在每个仓库由 Spokes 存储:它把一份完整的仓库副本放在若干台文件服务器的本地磁盘上,默认是 5 份。本地快盘让 Git 操作能以低延迟读到原生仓库数据,多副本既提供冗余,也把读负载分散到不同文件服务器上。当一次 push 更新引用时,用一个三阶段提交协议配合仲裁,保证 CI、Web 界面和 API 客户端看到一致的仓库状态。这套组合目前支撑着十亿量级的仓库。
问题出在一句话上:持久化机制和扩展机制是同一个机制 。磁盘上的那些副本就是事实来源,所以增加读容量就等于增加一个持久化副本;而每个副本都要参与每一次写,于是加读副本会让写更慢。极端情况下,加副本给写带来额外开销,丢副本会减少读容量,丢仲裁则直接停写。
对绝大多数仓库来说这个权衡完全可接受,只有活动量最高的那一小撮会撞到它。但智能体开发恰好都挤在那一小撮里。
四、新架构的两条原则
原文把方案归结为两条分布式系统设计原则。
第一条:最小化协调。
一次 push 里真正需要所有副本达成一致的,其实只有引用更新这一步。存储底层对象、校验对象连通性、密钥扫描这些工作量大得多,但它们大多可以和其他写入并行进行。把需要协调的路径压缩到最小的那一步,其余工作就不再拖慢响应。
配套的另一件事是把维护搬离服务路径。压缩和垃圾回收是仓库最重的工作之一,而现在它们和响应实时 Git 请求用的是同一批主机。新架构里,单独的 worker 直接对持久化存储做维护,繁忙仓库可以在后台持续被优化,不影响 push 和 fetch。
第二条:存储与计算解耦。
现在的架构里,本地磁盘上的完整副本同时扮演两个角色:既是持久化存储,又是响应 Git 请求的那一层。拆开之后各自独立扩展:
- 读容量来自轻量的缓存 worker,权威副本放在下面的持久化存储层。这样 CI 扇出、Agent 集群、大 clone 带来的读尖峰,不会给每次 push 增加额外工作。
- 权威数据放在 Azure Blob Storage,持久性和复制直接借用 Azure 的规模;计算层只管用最低延迟跑出最高吞吐。
- 故障恢复的形态变了。存储和计算耦合时,丢一台主机同时损失容量和持久性,恢复要重建完整仓库副本;拆开之后,丢一个计算 worker 更接近一次缓存未命中,替补 worker 立刻开始服务,边跑边从持久化存储填充缓存。
- 容量可以跟着流量走。发布或新 Agent 集群上线带来的突发,可以临时加容量,过去之后再释放,不用提前按峰值配置。
五、收益,以及"边跑边换"这个约束
原文给出的内部基准结果是:新架构实现了最高 35 倍于当前的写吞吐,读容量可以独立按需扩展。
这句话有个前提条件值得单独记一下------整套重建是在 GitHub 持续运行的状态下做的,没有维护窗口,也没有让用户改工作方式。原文的表述是"为最苛刻的工作负载而建,抬高的是所有人的下限":无论是受严格监管要求约束的企业、要给操作系统仓库落地一次改动的团队,还是跨时区评审志愿者贡献的维护者、提交第一个 PR 的学生,用的是同一套更快也更稳的地基。
同时新架构必须保留团队已经在用的控制:维护者需要分支保护和必需评审,确保未经审查的改动进不了默认分支;安全团队需要审计日志和仓库可见性;值班工程师需要有可依赖的自动化和足够的可观测性。原文把原则概括成三句:建立在开发者已经信任的工作流上、可靠性优先、让人保持对代码的控制。
六、这套思路对 Agent 开发者意味着什么
即使你不做 Git 平台,这篇文章里的两个模式可以直接搬进自己的 Agent 系统。
第一个模式是"识别哪些工作真的需要串行"。Agent 编排里常见的错误是把所有步骤都做成同步等待,而实际上真正需要集中一致的往往只有最终的状态提交。用一个很小的骨架来感受这种拆法:
python
# 自拟示意,非官方代码:把"必须协调"的部分压到最小
def handle_agent_step(state, action):
result = run_tool(action) # 可并行:无需所有副本同意
artifacts = persist_artifacts(result) # 可并行:内容写入对象存储
scan_secrets(artifacts) # 可并行:校验异步做
# 只有引用更新这一步需要达成一致,它是关键路径,所以越短越好
return commit_ref(state.ref, artifacts)
在这个骨架里,run_tool、persist_artifacts、scan_secrets 都能和其他步骤重叠执行,commit_ref 才是必须串行的那一小段。换句话说:不要因为"要保证一致"就把整条链路都串起来。
第二个模式是"Agent 的写入频率要有上限"。每步都 commit 看起来最安全,实际会把写吞吐乘以步数。更实际的做法是按"可恢复价值"而不是按"动作发生"来定 checkpoint 粒度------比如一个逻辑子任务完成、或累计改动达到某个规模时才落一次,中间状态留在内存或本地暂存。
小结
这篇文章的技术内核并不复杂:把持久化和扩展拆成两件独立的事,再把不需要协调的工作全部移出关键路径。难的地方在于它必须在线完成,且不能动用户已经依赖的评审、审计、分支保护这些控制。
对 Agent 开发者,最值得带走的一条判断是:当你说"系统变慢了",先分清慢的是读还是写。读慢通常加缓存就能缓解;写慢往往意味着有一处不该串行的协调卡住了吞吐,而这个瓶颈会随着 Agent 数量的增加被成倍放大。
文中数据、架构描述与引用来自 GitHub Blog(2026-10-06),Azure Blob Storage 的具体形态与 35 倍基准的测试条件以官方后续文章与文档为准,此处未验证最新版本。