结论先说:OpenAI 用 10 周时间重写了服务端的 Git 存储层,新系统 Pando 把中位 push 延迟降低接近 80%,每天可交付接近 1 PB 的 Git 数据,单机缓存命中超过 99%。
2026 年 11 月 2 日,OpenAI 在官方博客发布了一篇名为 Scaling Git at OpenAI 的工程长文,第一次完整公开了 Pando 的架构。事情的起点很朴素:过去一年,随着 Codex 让工程师能并行处理更多工作,OpenAI 的 monorepo 在分支数、push 频率、merge 次数、CI 里的 fetch 与 clone 数量上都暴涨。到去年年底,原有 source control 系统开始变慢,merge 失败,某些时期可靠性低于 90%。
Git 协议本身没有问题,撑不住大规模并发操作的是承载 Git 服务的架构。下面按官方披露的实现细节,把三种架构的取舍、Pando 的核心机制和它付出的代价拆开讲。
问题从哪来:Codex 放大了 monorepo 的写放大
官方把负载增长的来源列得很具体。Codex 让工程师并行完成更多工作,由此产生了更多分支和 push、更多 merge、开发环境与研究任务和 CI 中更多的 fetch 与 clone、同一工程师同时准备多个 CI 变更,以及多个 push 同时触发任务去获取同一个 commit。
这些现象叠加起来指向同一个结论:Git 存储服务的瓶颈在服务端,不在客户端。传统做法是每个仓库保留完整副本,用协调器让所有副本对 ref 更新达成一致。这个模型在中小规模下很干净,OpenAI 的规模把它推到了尽头。
值得先说清楚的是,Pando 完全兼容 Git 协议和现有 Git 客户端,工程师和智能体的分支、push、fetch、clone、merge 工作流都没变。OpenAI 还基于自己的 Git fork 向 upstream Git 持续贡献补丁,其中一部分改进已经进入主线。这条路径与 GitHub Copilot Fusion 的三档编排 指向同一个问题,当代码由多个智能体并行产出时,协作层的扩展能力比单次生成质量更早触到天花板。这决定了它是一次可被外部复用的工程实践,而非只能在 OpenAI 内部跑的定制系统。
三种架构的取舍:3PC、对象存储 WAL 与 Pando
官方在文中给出了两种传统架构的建模分析,并提供了交互式模拟器做对比。
三阶段提交(3PC)的流程是:任一服务器收到 push 后,把 packfile 复制并并行发送到所有副本,协调器等待多数副本接受 ref 更新,每个副本锁定对应 ref 并检查它是否仍指向客户端预期的旧 commit,协调器发出 pre-commit 消息,获得多数确认后通知副本执行更新。好处是完整副本可就近服务读取,客户端连到哪个副本都能拿到一致的 refs 视图。代价同样明显:ref 更新必须逐个完成,每次 push 都需要协调器与副本之间多轮网络往返,等待 quorum 把副本磁盘性能和通信延迟直接放到 push 的关键路径上。模拟结论是负载增加时 3PC 的磁盘趋于饱和,写入延迟显著更高。
对象存储 WAL 的做法是把 incoming packfile 上传到 blob storage,在本地副本准备 ref 更新,然后向共享 manifest 追加一条含 ref 更新与 packfile 位置的记录,用 compare-and-swap 原子更新 manifest。它允许多个写者并行上传 packfile,manifest 提供明确的全局更新顺序。但即便 push 的是毫不相干的分支,也必须竞争更新同一个 manifest,成功 CAS 的往返延迟限制了仓库发布新 manifest 的频率。batching 可以一次发布多个 ref,却会引入排队和更高延迟。更根本的问题是,每个副本仍需从 blob storage 读取并索引 pack 才能在本地提供读取,写入速度一旦超过副本索引速度,副本就会落后,客户端 fetch 新 commit 的时间随之增加。模拟结论是 WAL 系统读取延迟显著更高。
Pando 重新审视了传统 Git 服务的两个默认假设,然后各自做了替换。
| 维度 | 三阶段提交 | 对象存储 WAL | Pando |
|---|---|---|---|
| ref 更新顺序 | 全局协调,全序 | 共享 manifest 全序 | 因果一致性,按分支独立 |
| pack 生成方 | 副本本地打包 | 副本从 blob 读取并索引 | push 时生成一次,多方复用 |
| 写入扩展方式 | 加副本,协调器成为瓶颈 | 加存储,manifest 仍竞争 | 加 Pando 服务、扩 metadata 与 blob |
| 模拟表现 | 写入延迟显著更高 | 读取延迟显著更高 | 数千客户端并发 push 性能不受明显影响 |
| 仓库级时间点快照 | 提供 | 提供 | 不提供 |
官方特别注明,这个模拟是合成的教学模型,不是生产基准测试。在真实 monorepo 测试和模拟中,Pando 都能支持数千客户端并发 push。
核心机制一:因果一致性与 ref version
第一个被放弃的假设是仓库级全局一致快照。如果所有 ref 更新都通过同一个协调点排序,不同分支上的 push 就会互相争用,即使它们毫无关系。Pando 选择放弃这一点。
替代方案是一套基于因果一致性的写入模型。客户端 push 时,Pando 把 incoming packfile 存为 blob storage 中的不可变对象,每次分支移动就记录一个新的 ref version。一个 ref version 包含新的分支 tip、提供该 tip 的 packfile,以及该 pack 依赖的早期 ref versions。blob storage 与 metadata store 都支持水平扩展。
fetch 时的流程是:找到需要重放的 ref versions,找到对应的 packfiles,把这些 packfiles 提供给客户端,客户端据此重建创建目标 ref version 时的状态。一致性保证落在四个层面:全仓库范围的因果一致性、单个 ref 更新的可串行化、单次 push 的 read-your-own-write,以及只有同一 ref 上的并发 push 才可能产生冲突。
不提供的也很明确。Pando 不提供 Git 操作期间所有 refs 的统一时间点快照,也不提供 clone 或 fetch 内所有 ref 更新的全局顺序。官方给的例子是:完整 clone 协商期间 foo 和 bar 都可能发生更新,一个客户端可能看到 foo@1、bar@2,另一个可能看到 foo@2、bar@1。OpenAI 的判断是,用户和智能体通常依赖单个 ref 上的更新顺序,而不是所有 refs 的全局更新顺序。
元数据操作的数量被刻意压平。Push 路径需要 O(1) 次 metadata 读和写,无论 push 的体积多大,所需元数据操作数保持常数级。Fetch planning 的复杂度是 O(log Δ),Δ 是客户端当前状态与目标状态之间的最短 ref-version 距离。
这里也有一个反直觉的取舍。传统 Git 服务会向客户端展示几乎所有 refs,因为展示越多,客户端能排除的服务器已有对象就越多,生成的 pack 也就越小。Pando 出于两个原因只 advertise 部分 refs。成本上,仓库有几百万分支时,完整 ref advertisement 本身可能超过 100 MiB。更重要的是可复用性,只允许客户端排除明确依赖的对象,服务端才能证明哪些依赖已被持有、哪些历史可以安全省略,进而在后续 fetch 中直接复用同一个 packfile。默认情况下,客户端 push 新 feature branch 时,Pando 只 advertise 一个指定的 trunk 分支。
代价写得很坦白:对同一分支连续 push 多次,或者在另一个 feature branch 上继续堆叠分支,客户端可能需要重新发送 trunk 之外的全部内容。OpenAI monorepo 的实际数据是,中位 packfile 小于 20 KiB,第 99 百分位小于 3 MiB。
核心机制二:服务端不维护本地仓库副本
第二个被放弃的假设是为每个客户端生成唯一 packfile。不同客户端持有的本地历史不同,传统服务会为每个客户端单独生成 pack 以避免发送对方已有的对象,代价是大量 CPU 消耗和磁盘 I/O,而且在高并发读取下难以扩展。
Pando 的做法是把生成环节前移到 push 时。服务端收到 push 后,在流式传输到 blob storage 的同时用单次 pass decode 验证 pack,不把 pack 解包到本地仓库,也不维护 loose 或 packed objects。fetch 时根据客户端已有历史选择已存储的 packfiles,返回这些 pack 的 URI,客户端直接下载。
结果是这个服务端主要执行三件事:协议协商、pack 选择、元数据操作。它不需要频繁执行昂贵的 unpack、repack 和本地 Git 对象库维护,因此可以运行在普通云 VM 上,不依赖高端专用硬件。这一点和行业里常见的重型自研方案形成对比,站内关于 OpenAI Habitat 500 PB 存储与 10 毫秒读取延迟 的拆解提到过类似权衡。
读取路径:packfile-uri 与区域缓存
fetch 侧依赖 Git 协议的 haves 与 wants。客户端声明自己已拥有哪些 commit、希望获得哪些 commit,Pando 把这两组输入映射到 ref versions,找到包含目标 commit 的版本及其历史 packfiles,计算出能覆盖客户端所需对象的 pack 集合,再补齐 side branch 缺失的 trunk 依赖。依赖规划是这里的关键,一个想要 side branch 的客户端,隐含地需要它依赖的 trunk 历史。
传输机制上,Pando 用上了 Git 协议里的 packfile-uri 特性。普通 HTTP clone/fetch 响应只允许发送一个 packfile,packfile-uri 允许服务器返回额外 pack 的下载地址。Pando 在 HTTP 响应里内联返回空 packfile,通过 packfile-uri 返回多个实际 packfile URI,客户端并行下载独立 packs。OpenAI 为 packfile-uri 向 upstream Git 贡献了多项改进,包括并发下载、中断传输后的清理、已完成下载被再次恢复,以及 fetch 接受已有 pack 时的额外校验。客户端侧还增加了 packfile-uri 下载 tracing 和 pack 生成字节数统计,用来区分慢 fetch 的时间花在生成 pack 还是传输 pack 上。这类可观测性的思路与 AKV 缓存工程开源 的处理方式一致,先把成本分布量出来再动结构。
分发层面用了两层缓存。Express 是 pack delivery service,缓存 blob storage 并返回 packfile URI,对 packfile 使用一致性哈希路由,缓存命中率超过 99%。另有独立的 metadata cache 服务缓存 metadata store。区域集群在完全命中本地缓存时可以处理 commit ID 查询和特定 ref 读。
最终的网络数字是:配合 packfile-uri、区域本地缓存和标准云厂商 VM,clone 与 fetch 可以跑满 10 Gbps 的客户端到 Pando 网络链路。部署后的整体成绩是中位 push 延迟降低接近 80%,每天交付接近 1 PB 的 Git 数据,单小时曾服务超过 57 TB 的 Git packs,其中超过 99% 的字节来自本地磁盘缓存,且只需少量 CPU 核心。合并可靠性同时获得提升。
分层 Compaction:L0 到 L4 的 pack 覆盖层
如果每次 push 都保留为一个独立 pack,客户端落后较多时可能需要下载数万个小包。在快速变化的 monorepo 里,这会显著增加文件数量、请求数量、协商开销和首字节延迟。
Pando 的做法是建立分层结构。每次 push 产生一个 L0 packfile,代表可传输的最小数据单元。后台 worker 把多个 L0 pack 聚合为覆盖连续 ref versions 的更高层 cover,形成 L0 到 L4 的层级。OpenAI 当前 monorepo 最多用到 L4。
compaction 承担两个作用。覆盖足够满时,worker 重新组织 packfile 内部对象生成单一 packfile,提升对象压缩率。没有重新打包的 cover 则作为 ref versions 之上的 skip list,扫描各层索引时跳过大量中间版本,以对数时间选出所需 packs。cover 因此分为 repacked cover 与 unrepacked cover 两种,分别对应压缩与规划性能。
有一处与多数 Git 服务不同。Pando 保留所有层级的 packs,不依靠垃圾回收删除旧 pack,而是根据客户端的 haves 和 wants 持续使用各层 pack。对通过 Pando API 读取任意对象的客户端来说,从 L0 读取通常比从 L4 读取需要更少数据,原因是小 pack 中的对象通常压缩得更少。
| 生产指标 | 数值 |
|---|---|
| 切换到 Pando 后中位 push 延迟 | 降低接近 80%(约 5 倍改善) |
| 每日 Git 数据交付能力 | 接近 1 PB |
| 单小时 Git pack 交付量 | 超过 57 TB |
| 本地磁盘缓存命中字节比例 | 超过 99% |
| Express 缓存命中率 | 超过 99% |
| clone 与 fetch 可跑满带宽 | 10 Gbps |
| OpenAI monorepo 中位 packfile | 小于 20 KiB |
| OpenAI monorepo packfile 第 99 百分位 | 小于 3 MiB |
| 从启动到生产的开发周期 | 约 10 周 |
用 Codex 造 Codex:Lean 与 TLA+ 的形式化验证
开发方式本身就是这套系统的一部分。Pando 使用 Codex 开发,从启动到生产只用了 10 周。职责分工是一名工程师设计核心架构,多个 agent 团队负责实现,少数工程师负责部署。技术选型是 Rust,作为全新项目不依赖历史遗留依赖。
验证手段分四层。一层是 Git 行为一致性测试套件,让 agent 能自动验证改动是否符合标准 Git 行为。一层是确定性模拟测试工具,用于检查系统不变量、验证系统属性、找出并修复协商中的微妙 race condition、防止 pack 规划回归。第三层最特别,OpenAI 用 GPT-6 Astra 让 agent 编写 Lean 和 TLA+ 代码,建立了一套 Pando 理论,对系统属性做形式化证明,并借此发现和修复实现缺陷。第四层是持续运行,多个 agent 连续运行数百小时寻找边缘情况,配合具备 Daybreak 能力的模型全天候 red-team Git 和 Pando。
Anthropic 用 Claude 自建代码系统取代 Git 走的是另一条路线,两者的共同点在于都要把版本控制从瓶颈变成可扩展的基础设施。迁移过程采用无停机方案。Pando 最初以 read-through 与 write-through proxy 的形式部署在旧系统之前,与旧 source control 系统保持同步,逐步把流量迁移过去,全程不停机。代理层还能去重重复请求、合并请求,在转发给旧后端前降低负载。随着更多工作负载迁移到 Pando,push 逐渐填充 Pando 缓存,旧后端因缓存命中而改善可靠性。客户端侧则通过内部 Git CLI wrapper 分阶段迁移到公开 Git 构建,覆盖开发者机器和 ChatGPT 桌面应用,同时为变更请求、代码评审和自动化 API 建设专门工具,Codex 也直接参与迁移准备工作。
常见问题
Pando 和 GitHub 托管的代码托管服务是同一类东西吗?
不是同一个层级。GitHub 这类服务是完整的代码托管平台,包含仓库管理、评审、CI 等功能。Pando 解决的是其中最底层的存储与分发问题,即在一个超大 monorepo 上如何高并发地写入和读取 Git 对象。OpenAI 保留既有的托管与协作工具,只替换了最下面的存储服务层。
放弃仓库级全局快照会带来什么实际影响?
在一次 clone 或 fetch 的协商期间,不同 refs 可能处于不同的逻辑时间点,两个客户端可能看到不同的 refs 组合。对依赖单个分支更新顺序的工作流没有影响,但如果业务逻辑要求所有分支严格对齐,就需要额外的协调层。OpenAI 的判断是用户和智能体通常不依赖这种全局顺序。
只 advertise trunk 会不会让 push 体积变大?
会,但幅度可控。客户端能排除的对象变少,pack 就更大,OpenAI monorepo 的中位 packfile 是小于 20 KiB,第 99 百分位小于 3 MiB。连续向同一分支 push 或堆叠分支的场景下,客户端可能需要重发 trunk 之外的内容,这是官方明确承认的代价。收益是服务端能够证明依赖关系,从而让同一个 packfile 被多个客户端直接复用。
相关阅读
- Anthropic用Claude自建代码系统取代Git:日合并3万次、12倍增长
- GitHub Copilot Fusion:60 分、Token 减半与三档编排
- OpenAI Habitat 深度:500 PB 存储与 10 毫秒读取延迟
- AKV 缓存工程开源:智能体成本降 27.7%,分数升 1.7 分
小结
Pando 的价值在于把一组被默认接受的假设逐个拆掉,仓库级全局快照、每客户端唯一 packfile、全局有序的 ref 更新,然后用手感更好的机制替换。代价写得很清楚,放弃时间点快照、同一 ref 仍有写冲突、依赖证明更复杂,这三点都摆在台面上。10 周从零到生产、80% 的 push 延迟降幅、每天 1 PB 的交付量,这些数字最终来自一次架构判断而非一次硬件升级。
延伸阅读
- OpenAI伦敦分部人均薪酬231万英镑:堪比英超球星3 周前
- OpenAI 赏金上限提至 17.2 万美元 核心漏洞 3 万美元起4 小时前
- Claude 30分钟破译26年NSA椭圆曲线悬案:种子源自1997年Unix时间戳3 周前
- OpenAI 推训练安全新规:高官手握否决权,警报超时自动停训1 月前
继续读
同一批更新里这几篇值得一看:
- OpenAI LifeVal 基准:3995 人样本与 90.4% 最低分2026-11-03
- ChatGPT 记忆 96% 由模型自写:2050 条实测拆解2026-11-03
- Claude Ultra 取消 5 小时限制:周额度 10 倍与 Max 对比2026-11-02
