Codex 时代的 Git 不够用了:Pando 做了什么

OpenAI 用 Pando 换掉了 monorepo 的 Git 后端,保留协议和客户端,放弃仓库级一致和每客户端打包。中位 push 延迟降到原来的约五分之一,每天近 1 PB。拆开瓶颈、取舍,以及不重写 Git 的团队今天能做的三件事。

Delta

Delta

2026-11-04

Codex 时代的 Git 不够用了:Pando 做了什么

OpenAI 把自家 monorepo 的 Git 后端换了,工程师和 Agent 仍然用原来的 git clone、git fetch、git push。新后端叫 Pando,2026 年 4 月开始承载生产流量,现在支撑 OpenAI monorepo 的全部开发。按 OpenAI 公布的数字,中位 push 延迟降到原来的约五分之一,每天要送出近 1 PB Git 数据。

值得看的不是“OpenAI 又造了个轮子”,而是它承认了两个默认假设变了:所有 ref 更新要按一个全局顺序排队,每个客户端都要单独生成一份 packfile。Agent 并行提交时,先顶不住的是这两处,不是模型。

下面按 OpenAI 原文拆三件事:瓶颈在哪一层,Pando 保留了什么、放弃了什么,不重写 Git 的团队今天能做什么。前提是:下面的数字来自 OpenAI 的生产环境,不是给中小团队画的及格线。

先坏的是读路径,不是模型

OpenAI 写得很具体:Codex 让一名工程师可以同时准备多个改动等 CI,每次 push 又会触发多个 job 去 fetch 同一个 commit。分支、push、merge、clone 和 fetch 一起涨。

Git 的 fetch 不是把文件传过去这么简单。客户端告诉服务端自己有哪些 commit、想要哪些,服务端要算出对象差集,再压成一个 packfile。不同客户端的本地历史不同,服务端往往要为每个客户端单独算一份。读取方越多,CPU 和磁盘 I/O 越重,这种结果也很难缓存。

第二处是 ref 广告。push 时服务端要告诉客户端自己有哪些分支,客户端才能少传对象。分支到百万级时,OpenAI 说单是 ref advertisement 就可能超过 100 MiB。这个开销跟分支数成正比,不跟代码量成正比。

2025 年底,OpenAI 的 monorepo 开始出现慢 fetch、慢 push 和 merge 失败,可靠性有时低于 90%。加磁盘或加副本只能缓一口气,因为瓶颈在“每个请求都要重新算”和“所有写入都要排一个序”。

3PC 和 WAL 为什么不够

OpenAI 动手前模拟了两种常见的分布式 Git 做法。

第一种是三轮提交(3PC)。每个副本保存完整仓库,push 的 packfile 复制到所有副本,多数接受后,协调者再走预提交和提交两轮通信。读可以本地读,所有 ref 也能给出一致快照;代价是每次 push 都要等副本磁盘和网络,ref 一次只能更新一个。

第二种是预写日志(WAL)。packfile 可以先并行上传到对象存储,但所有 push 都要更新同一个 manifest,用 compare-and-swap 决定谁先谁后。上传能并行,发布仍然串行;批量合并能少更新几次 manifest,但会把更新排进队列,延迟反而上去。副本还得把 pack 读回来建索引,写入一快就落后。

两种设计的共同点,是把“仓库级一致”当成不能动的约束。Pando 的起点是先拿掉这条约束。

Pando 保留什么,放弃什么

保留的是协议和客户端。工程师和 Agent 继续用原来的 Git 命令,现有工作流不用改。OpenAI 还维护了一份自己的 Git 客户端构建(openai/git),客户端可并行下载和索引独立的 pack;部分改进已进入上游 Git。

放弃的是三样东西。

仓库级的时点一致。Pando 改成因果一致:每次 push 的 packfile 作为不可变对象进 blob store,元数据里记一个 ref version,包含新 tip、这次用的 pack 和它依赖的旧版本。读分支时,按 ref version 回放需要的 pack。单个 ref 的更新仍然串行,也支持 read-your-own-write;但一次 clone 或 fetch 读到多个分支时,它们可能不在同一个时间点。

每个客户端一份 packfile。Pando 把 push 上来的 pack 直接存下来,fetch 时按客户端已有的 commit 选一组现成 pack 返回,不再解包重打。push 的元数据读写是 O(1),fetch 是 O(log Δ),Δ 是客户端落后多少个 ref version。代价是客户端可能下载一些自己已经有的对象。

完整的 ref 广告。默认只把一个指定的 trunk 分支作为 base 广告给客户端。广告大小不随分支数增长,客户端生成的 pack 只依赖 trunk 历史,同一个 pack 可以被其他有 trunk 的客户端复用。代价是连续 push 同一分支或 stacked branch 时,要重复发送 trunk 之外的对象。OpenAI 说他们 monorepo 里这样生成的 pack,中位数不到 20 KiB,P99 不到 3 MiB,他们认为这个交换划算。

读路径靠缓存和 packfile-uri。Git 协议一次 HTTP 响应只能带一个 packfile,Pando 返回一个空的内联 pack,再用 packfile-uri 给出多个下载链接。区域缓存服务 Express 用一致性哈希路由,命中率超过 99%,用标准云主机就能把 10 Gbps 网卡跑满。后台还有一个类似 LSM 的 compaction,把大量 L0 pack 合成 L1 到 L4 的 cover,避免客户端为了追上 trunk 下载几万个 pack。

这些细节说明 Pando 不是“更快的 Git”,而是把 Git 的存储和传输拆成可水平扩展的两层:不可变 pack 放对象存储,ref 版本放元数据存储,服务节点只做协商和选 pack。

对普通团队意味着什么

对使用者,clone、fetch、push 没变;对托管方,换掉的是服务端实现。这意味着 Git 的瓶颈不一定是它本身,很多时候是托管服务选了“全局有序加每客户端打包”的架构。

Pando 不是现成产品。OpenAI 只说在探索把这项技术分享给用户,截至原文发布,没有公布开源计划、价格或时间表。它也不是唯一遇到问题的一家:HN 讨论里有人列了 Cursor、GitHub、Anthropic 的同类文章。

原文没有披露仓库体积、提交量和成本。能确认的只有结果数字:中位 push 延迟降近 80%(OpenAI 另一处表述为降到原来的约五分之一,两个口径指同一组数据),每天近 1 PB Git 数据,单小时送出超过 57 TB pack,其中 99% 以上来自本地磁盘缓存。

不重写 Git,今天能做三件事

下面三条是通用做法,不是 Pando 的配置说明。目标一样:减少服务端重复计算,减少同时抢一个 ref 的写入者。

第一,减少每个 clone 和 fetch 要算的对象。CI 里用 git clone --depth 1 只取最近一次提交;需要历史时用 --filter=blob:none 做 partial clone,按需再取 blob。多个 job 共用一份本地镜像,用 --reference 指向它,别让每个 job 都从远端全量拉。这些做法不能消除服务端计算,但能减少重复读取方和传输。

第二,控制 ref 的数量。合并后自动删分支,给长寿命分支设上限,别让每个 Agent 任务都永久留一个分支。文章里 100 MiB 的 ref 广告是百万分支规模,普通团队离得很远;但如果一个仓库已有几千个活跃分支,先清理再谈扩容。仓库大到一定程度,拆成多个仓比优化单仓更便宜,代价是跨仓变更和依赖管理变复杂。

第三,把 trunk 的更新串起来。用 merge queue 或批量合并,让多个 Agent 的改动按队列进 main,而不是同时抢同一个 ref。合并前 squash 掉 Agent 产生的调试提交,减少无意义的 ref 版本。CI 侧按 commit 缓存依赖和构建产物,避免每次 push 都让多个 job 重新 fetch 同一份历史。

如果 Agent 已经在并行改代码,仓库层的压力和任务层的隔离要一起看。HiFox 的做法是每个任务独立 checkout 一个 worktree,不同任务在同一个仓库的不同工作区里跑,结果提交到带任务编号的分支,执行记录留在任务上。它不替代托管层改造,但能让“哪个任务改了哪条分支、谁触发的”有据可查。机制见 代码仓库 和 Agent 如何执行任务。

什么时候才值得换后端

先量六个指标:push 的 p50 和 p95、fetch 的 p95、merge 失败率、CI 里 clone/fetch 占总时长的比例、单仓活跃分支数、服务端 pack 生成的 CPU 占用。前三个看开发者是否已经感到痛,后三个看痛是不是来自架构,而不是机器不够。

如果 push 和 fetch 的 p95 还在秒级,merge 失败主要是冲突,先做上面三件事,别为了“Agent 规模”提前重写。反过来,如果加了机器、清了分支、上了 merge queue,fetch 仍随读取方数量线性变慢,才说明每客户端单独打包成了瓶颈。

原文还提到,Pando 从 kick-off 到生产只用了 10 周。这个数字也容易被误读:这次重写用 Codex 推进,核心由一名工程师设计,多个 Agent 团队实现,少量工程师部署。前提是 Rust 重写、无历史依赖、有 Git 一致性测试和确定性模拟测试。这不是普通团队换后端的工期承诺。

结论

Git 没有死。死的是两个默认假设:所有 ref 必须按一个全局顺序更新,每个读取方必须拿到一份为自己定制的 packfile。Pando 的价值在于把这两个人为约束拿掉,同时保留协议和客户端,让工程师和 Agent 不用改工作流。

对多数团队,今天最划算的动作不是重写 Git,而是把 CI 的 clone/fetch 和分支数量管起来。先打开 CI 配置,统计 clone 和 fetch 占总构建时间的比例;如果它已经排在依赖安装前面,就从浅克隆、partial clone 和共享镜像开始改。

资料来源: Scaling Git at OpenAI;HN 讨论;openai/git;git-clone 文档。

Explore more

你关掉的 Codex 数据共享,可能被悄悄重新打开

你关掉的 Codex 数据共享,可能被悄悄重新打开

OpenAI 尚未确认 Codex 数据共享开关为何被重新打开。本文拆开个人账号、企业工作区和 API 的数据边界,给出一套可截图、可复核、可处置的团队检查流程。

2026-11-05

OpenAI 收购 Pierre:Codex 补代码审阅

OpenAI 收购 Pierre:Codex 补代码审阅

OpenAI 收购 Pierre 指向 Codex 的代码理解与审阅工作流。公告确认了方向,却未公布整合时间表。团队现在可从任务验收、运行证据和独立审阅入手,检验 Agent 写完代码后能否被可靠接手。

2026-11-05

DeepSeek Search 与 Fetch API 上线:每千次成功请求各 0.75 美元

DeepSeek Search 与 Fetch API 上线:每千次成功请求各 0.75 美元

DeepSeek 在官方 API 文档中新增 Search 与 Fetch 两个独立接口:Search 用于网页搜索,Fetch 用于抓取网页内容。两项能力都按成功请求计费,每 1000 次分别收费 0.75 美元。对正在搭建 RAG、研究…

2026-11-05