alitrack

他让17个AI Agent同时写代码,两周重写了PostgreSQL

有人在两周内把 PostgreSQL 重写成了 Rust。

不是 mock。不是 demo。

他叫 Michael Malisper,前 Heap 工程师,运维过 PB 级 Postgres 集群。他在 2026 年 4 月启动了一个叫 pgrust 的项目——用 Rust 从零重写 PostgreSQL。

结果:2 周通过 33% 回归测试(16,000+ SQL 查询),3 周 67%,目前已 100%。GitHub 2190 stars。盘兼容——能直接启动现有 Postgres 18.3 数据目录。最新的未发布版本声称事务负载比 Postgres 快 50%,分析负载快 300 倍。

我花了一晚上研读了他的三篇长文和 GitHub 仓库。这篇文章要讲的不是 pgrust 本身,而是他用的那套方法——一套和我之前踩过的坑形成鲜明对比的方法。

● ● ●

为什么你的 C→Rust 翻译总是失败

如果你试过用 AI 把 C 代码翻译成 Rust,你可能已经有这种体验:前 200 行看起来还行,然后 ownership 报错开始堆积,你让 AI 修,它开始加 .clone() 和 unsafe,逻辑开始扭曲,最后你得到一堆能编译但完全不可维护的东西。

这不是你的问题。也不是 AI 的问题。问题是"翻译"这个 paradigm 本身就是错的。

C 和 Rust 是两种完全不同的设计哲学。C 的裸指针、手工内存管理、宏系统,跟 Rust 的 ownership/borrowing/lifetime 不是一个维度的东西。你让 AI 做"逐行翻译",等于让它同时做两件事——理解原始语义,再映射到目标语言。这两件事互相干扰。

更致命的是,逐行翻译会把原始项目的架构债原样携带过去。Postgres 的进程模型、32-bit 事务 ID、VACUUM 机制——这些都是 40 年历史积累的设计决策,有些已经明显过时。逐行翻译到 Rust,只是换了一种语法表达同样的债。

Malisper 也考虑过"逐步替换 C 组件"的方案,然后放弃了。他的原话:"I never actually looked at the [Postgres C] code for these."(我根本没看过那些 C 代码的实现。)

● ● ●

他做了什么

他的做法可以总结为一句话:行为驱动重写,回归测试做 oracle。

具体流程:

  1. 01让 AI 用自然语言解释 Postgres 某个组件的行为(不读代码实现)
  2. 02基于行为理解,从零用 Rust 写一个最小化版本
  3. 03跑 Postgres 的 50,000 条回归查询作为正确性验证
  4. 04始终保持系统可运行——Day 1 就支持 CREATE/SELECT/INSERT

Day 1 他只用了 3 小时就做出了能跑 SQL 查询的最小系统。然后每天叠加更多组件。

● ● ●

Phase 2:工厂模式

到第三周,他的开发方式变了。不再是"人写代码,AI 辅助",而是"人设计系统,AI 工人执行"。

他把自己比作 Factorio 玩家——角色从写代码变成了设计生产线、消除瓶颈。

具体配置:

  • 8 个 Codex 账号,每个 $200/月
  • 10-20 个并行 AI agent,每个负责一个独立 feature
  • 用 Conductor 管理 git worktree(每个 agent 独立工作目录)
  • 共享 Rust build target 目录(否则 100GB+ 构建产物)
  • CI merge queue 自动合并

他不再读大部分代码。"给定 pgrust 还这么早期,更重要的是做出能用的东西,而不是写出最好的代码。信任 agent,出问题再修——这比一开始就追求完美更快。"

他用过的一个类比:当 CEO 管 120 人团队时,你的工作不是读每一行代码,而是设置 guardrail、确保你有足够的 visibility。管 agent 团队是一样的。

● ● ●

他踩过的两个坑,恰好验证了对的方向

坑 1:Feature 级提交 → 合并冲突噩梦。 最初让每个 agent 完成整个 feature 再合并。3 小时写出几万行代码,然后花了 2 小时手工解决合并冲突。虽然 feature 是正交的,但它们都碰了 parser、planner、executor 这些共享组件。

修正:小切片提交。 每个 agent 做完一个 test-passing 的切片就提交合并。代码漂移最小化,合并几乎零摩擦。

坑 2:单 Agent 模式 → CPU 空转。 一个 agent 干 5 分钟活,他在旁边等着。切到 17 个 agent 并行后,他的 CPU 飙到 100%,但时间利用效率飞升。

这里有一个有意思的细节:他的代理瓶颈从"等 AI 推理"变成了"等编译和测试"。所以他花大量时间做的是——优化 parser 编译单元独立性(从 60 秒 → 36 秒)、共享 target 目录——这些都不是代码质量优化,是流水线吞吐优化。

● ● ●

这套方法论如何映射到 Hermes

pgrust 的成功证明了范式有效,但它的工具链是外挂拼凑的:Conductor 管 agent、手工切换 8 个账号、个人经验驱动决策。

Hermes 的架构天然能做得更系统:

Phase 1 — Understand(不要碰代码,先建模)

Malisper 靠 10 年 Postgres 经验做架构判断。如果你没有这种深度怎么办?

用 CodeGraph 自动建调用图:

codegraph_context(task="理解整体架构和模块边界")
      → 文件/模块树
      → 调用关系图(谁调用谁)
      → 数据流路径

这比"让 AI 用自然语言解释代码"更结构化。自然语言解释会丢失精确的调用关系。CodeGraph 给你的是可查询的图。

Phase 2 — Plan(决定什么要改)

pgrust 在这一步靠的是 Malisper 的个人判断——他知道进程模型该换成线程、正则引擎该换 SIMD、JSON 统计该加。但如果你做的是不熟悉的项目,这一步需要一个结构化的过程:

  • 提取回归测试,按模块分组
  • 列出每个模块的"行为契约"(输入→输出,不是代码结构)
  • 标记哪些设计决策要在重写时改变,以及为什么

这一步最容易被跳过,也最致命。没有这一步,你就会在重写到一半时发现"等等,这个模块和那个模块耦合太紧,需要一起重写"——然后就回到逐行翻译的陷阱里。

Phase 3 — Execute(始终保持可运行)

Hermes 做这一步比 pgrust 的方案简洁得多:

delegate_task(goal="重写 buffer cache 模块")
  ├── context: 行为规格 + oracle 测试 + Rust 写法规范
  ├── 工作方式: 基于行为理解从零重写(不读 C 代码实现)
  ├── 验证: cargo test -- regression
  └── 提交: 小切片 PR

不需要 Conductor,不需要 git worktree。delegate_task 原生隔离,自动管理上下文。

Phase 4 — Iterate(加速循环)

pgrust 有一个反直觉的数据:越到后期,每通过一个测试所需的 token 数越少。 原因是基础设施(planner、buffer cache、PL/pgSQL 等)建成后,剩余工作是精细化的、AI agent 擅长的小修小补。

这恰好是 reflection loop 的价值。跑通一批 → 更新 skills(沉淀"这类模块怎么重写最好")→ 下一批更快。

● ● ●

什么时候用,什么时候别用

这套方法论不是万能药。

适用的场景:

  • 大型 C/C++ 项目 → Rust/Go,语义差异大,重写收益高
  • Python → Go,性能驱动重写
  • 原始项目有可运行的回归测试套件(oracle 是刚需)
  • 你有领域专家或者至少能在 Phase 1 投入足够理解时间

不适用的场景:

  • 1,000 行以下的小项目(方法过重)
  • 同语言重构(不需要完整方法论)
  • 没有测试的项目(先补测试,否则盲人摸象)
  • 你不能承受"先跑通再优化"的阶段性混乱

● ● ●

最后

你在问题里说的"用 codegraph 先把代码树建起来再用另一种语言实现",方向完全对——但这套方法论往前多走了一步:代码树帮你理解架构,回归测试帮你验证行为,但最终的代码应该从行为规格出发从零写,而不是"翻译"任何东西。

pgrust 告诉我的不是"AI 可以写数据库"。而是换了范式之后,AI agent 能做的事远超直觉。前提是你得扔掉"翻译"的惯性思维,用 oracle 驱动而不是源码驱动。


pgrust 仓库: github.com/malisper/pgrust

Malisper 的原始博客: malisper.me/pgrust-rebuilding-postgres-in-rust-with-ai/

67% 更新: malisper.me/pgrust-update-at-67-postgres-compatibility-and-accelerating/