为什么我用 Rust 重写了 Memoria
徐鹏 · MatrixOne 技术负责人
先说说我的背景
我是一个老程序员了,写了快二十年代码,过去将近十年一直在做数据库内核的开发。
2019 年 4 月,我遇到了一个以图搜图的需求。一开始的做法很朴素——用 Python 搭了一个应用,调 Faiss 做向量检索,能跑就行。但做着做着我意识到,向量相似度检索不是一个应用层的问题,它应该是一个数据库层面的基础设施。于是我从零开始设计和实现了 Milvus 的前几个版本。如果你去看 Milvus 仓库最早的 commits,整个内核的架构设计和核心实现基本都是我一个人完成的。Milvus 1.0 之前的内核全部是 C++ 实现的,而且不是普通的 C++——GPU 异构索引、多卡调度、混合过滤、动态索引的删除和更新,同时面对计算密集和 IO 密集的混合负载,这些问题放在当时,业界几乎没有现成的参考方案。后来 Milvus 成长为全球最知名的开源向量数据库之一,这是后话了。
之后我到了 MatrixOne,设计并实现了整个存储引擎。MatrixOne 整体是用 Golang 写的,我每天打交道的都是存储引擎、事务处理、查询优化。你可以说,我是一个活在编译器和类型系统里的人,习惯了所有问题在代码跑起来之前就被拦住。
说到 MatrixOne(https://github.com/matrixorigin/matrixone),可能很多人还不太了解。这是我们从 5 年前开始从零写的一个数据库内核项目,核心解决两个问题:一是用一套存储和计算引擎,同时支持 OLTP、OLAP、向量、全文的负载,不需要用户在不同数据系统之间搬数据。二是通过云原生和存算分离的架构,实现了 Git for Data 的能力——你可以对 TB 级别的数据进行跟 git 一样的快照、分支、Diff、Merge 操作。核心是我们在存储引擎层面实现了基于 Copy-on-Write 的数据版本管理:零拷贝分支、即时快照、任意时间点回滚,这对应用开发、数据开发和 AI 训练都非常有用。
今天聊的重点不是 MatrixOne,而是 Memoria——不过 Memoria 是完全基于 MatrixOne 构建的。
┌─────────────────────────────────────────────────────────┐
│ MatrixOne 架构 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ OLTP │ │ OLAP │ │ Vector │ │ FullText │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ └─────────────┴────────────┴─────────────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
│ │ 统一计算引擎 │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
│ │ CoW 存储引擎 │ ◄── Git for Data │
│ │ │ │
│ │ • 零拷贝分支 │ │
│ │ • 即时快照 │ │
│ │ • 任意时间点回滚 │ │
│ │ • Diff / Merge │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
│ │ 云原生 · 存算分离 │ │
│ │ (S3 / 对象存储) │ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────┘
被 AI 颠覆认知,然后开始做 Memoria
数据库内核的世界是确定性的、可控的。但从 2024 年下半年开始,AI coding 工具开始真正影响到我的日常工作。一开始只是用 Copilot 补补代码,后来发现 AI 能做的事情越来越多——不只是补全,而是能理解上下文、能重构、能写测试。作为一个系统程序员,我开始意识到一件事:AI 不只是在改变我们怎么写代码,它在改变什么样的项目值得去做。
这个认知的转变,直接把我推向了 AI 相关的项目。
MatrixOne 原生支持向量索引,我们一直在思考怎么让向量搜索的调优更智能——不是让用户手动调参数,而是让系统自己根据查询模式和数据分布去优化。这个想法需要一个"记忆层":系统要能记住过去的查询、记住哪些调优策略有效、记住用户的使用模式。
这就是 Memoria 的起点。它最初是为 MatrixOne 的向量搜索自动调优而设计的——一个能跨会话持久化、能语义检索、能版本管理的记忆系统。https://github.com/matrixorigin/Memoria
从数据库调优到 AI Agent 记忆:同一个问题
但与此同时,作为一个天天用 coding agent 的人,我发现了一件有意思的事:coding agent 对记忆的需求,和让 AI 给数据库做自动调优,本质上是同一个问题。 Agent 需要记住你的项目结构、你的编码偏好、上次调试到哪里了、哪些方案试过不行。这和数据库调优系统需要记住查询模式、记住哪些索引策略有效,在抽象层面完全一致——都是"跨会话的、可检索的、需要版本管理的持久化记忆"。
而我们手里恰好有 MatrixOne 的 Git for Data 能力。零拷贝分支意味着 agent 可以在不影响主记忆的情况下做实验性推理;即时快照意味着任何记忆变更都可以回滚;向量索引意味着语义检索是原生支持的。这些能力不需要从头造,MatrixOne 已经打磨好了。
数据库自动调优 Coding Agent
┌─────────────────┐ ┌─────────────────┐
│ 记住查询模式 │ │ 记住项目结构 │
│ 记住调优策略 │ │ 记住编码偏好 │
│ 记住数据分布 │ │ 记住调试进度 │
│ 回滚失败的尝试 │ │ 回滚错误的方案 │
└────────┬────────┘ └────────┬────────┘
│ │
│ 同一个抽象问题 │
└──────────┬─────────────────────────┘
│
▼
┌──────────────────────────┐
│ 持久化记忆层 │
│ │
│ • 跨会话持久化 │
│ • 语义检索 │
│ • 版本管理 (Git for Data)│
└──────────┬───────────────┘
│
▼
┌──────────────────────────┐
│ MatrixOne │
│ CoW · 向量索引 · 分支 │
└──────────────────────────┘
于是 Memoria 从一个数据库内部的调优工具,自然而然地演变成了一个通用的 AI Agent 记忆层。
如果你回头看,我的职业生涯里有一条反复出现的线索:从具体需求出发,发现通用问题,然后构建基础设施。 以图搜图 → Milvus,数据库调优 → Memoria,模式是一样的。而 Memoria 的核心——embedding、语义检索、混合索引——恰好是我做 Milvus 时积累了多年的领域知识在新场景下的延伸。
最初的版本是用 Python 写的。原因很简单:快。AI 生态里 Python 是默认语言,LangChain、sentence-transformers、各种 embedding 模型的 SDK 都是 Python first。作为一个原型,Python 让我们在几天内就跑通了从语义检索到 Git-style 分支的完整链路。
但随着 Memoria 从原型走向真正被我们内部要用起来的产品,Python 带来的问题开始一个接一个地冒出来。
Python 的问题:不是不能用,是越用越难受
动态类型语言有一个经典的痛点:bug 藏在运行时。
你写了一个函数,参数类型标注了 str,但 Python 不会在编译期检查这件事。某天一个 None 悄悄溜进来,程序在生产环境里炸了,堆栈指向一个你完全没预料到的地方。你加了 type hints,跑了 mypy,但 mypy 覆盖不了所有场景,尤其是涉及到动态反射和第三方库的时候。
这不是个别现象。我在开发 Memoria 的过程中反复碰到这类问题:
- 一个
Optional[str]没有被正确处理,导致 embedding 服务偶发性返回空向量 - 异步代码里的异常被静默吞掉,因为 asyncio 的错误传播机制和你直觉想的不一样
- 依赖管理是噩梦——不同用户的机器上,同一个
pip install装出来的东西可能完全不同 - 打包分发更是灾难,你要么让用户装 Python 环境,要么用 PyInstaller 打一个几百 MB 的包
这些问题单独看都不致命,但加在一起,它们构成了一种持续的摩擦力。每次我想加一个新功能,都要先花时间处理这些"基础设施层面"的麻烦。
我在做 MatrixOne 内核的时候有一个原则:能用编译型语言重写的,坚决不用 Python。 这个原则在 Memoria 上终于也到了兑现的时候。
为什么是 Rust,而不是 Go?
这是一个合理的问题。我写了好几年 Go,MatrixOne 整个内核都是 Go 写的,按理说 Go 应该是我的舒适区。
但我在语言选择上是有过教训的。做 Milvus 的时候,1.0 之前全部是 C++。C++ 给了我极致的性能和控制力,但代价是巨大的——内存安全问题防不胜防,开发效率低,新人上手困难。后来 Milvus 2.0 用 Go 重写,开发效率大幅提升,但在某些需要极致性能的场景下,GC 的存在始终是一个隐患。这两段经历让我对语言选择有了一个很实际的判断框架:不是哪个语言"最好",而是在具体场景下,哪个语言的 trade-off 最合理。
Memoria 的场景和数据库内核不太一样。Memoria 是一个需要被分发到用户本地机器上运行的服务。这意味着:
- 包体积很重要。 用户不会为了一个 memory server 去装一个几百 MB 的运行时。Rust 编译出来的二进制文件是自包含的,通常只有几 MB。
- 内存占用很重要。 Memoria 要常驻后台,和 IDE 一起跑。Go 的 GC 虽然已经很好了,但 Rust 的零成本抽象和无 GC 设计意味着内存占用可以低到几乎可以忽略。
- 性能天花板很重要。 语义检索涉及向量计算,分支合并涉及大量数据比对。Rust 在这些场景下的性能优势是实打实的。
从 C++ 到 Go 再到 Rust,我走了一条完整的弧线。C++ 教会了我性能和控制力的价值,Go 教会了我开发效率和工程化的价值,而 Rust 是我目前找到的最佳平衡点——它有 C++ 级别的性能,有比 C++ 好得多的内存安全保证,同时在 AI 辅助下,开发效率已经不再是瓶颈。
性能 ▲
│
极致 │ ★ C++ ★ Rust (+ AI)
│ Milvus 1.0 Memoria
│ · 极致性能 ✓ · 极致性能 ✓
│ · 内存安全 ✗ · 内存安全 ✓
│ · 开发效率 ✗ · 开发效率 ✓ (AI辅助)
│
│ ★ Go
│ MatrixOne
│ · 性能良好 ✓
│ · 内存安全 ✓ (GC)
│ · 开发效率 ✓
│
└──────────────────────────────────────────────► 安全性
更重要的是,2026 年的 Rust 和几年前的 Rust 已经不是同一个东西了——不是语言本身变了,而是学习它的方式变了。
AI 磨平了 Rust 的门槛
我要先声明一件事:我在开始重写之前,对 Rust 几乎一无所知。
我知道所有权、借用检查、生命周期这些概念,但从来没有真正用 Rust 写过一个完整的项目。如果是两年前,这可能意味着我需要花几个月时间去啃 The Rust Programming Language,和编译器搏斗,在 Stack Overflow 上搜索各种生命周期报错。
但现在不一样了。
今年 2 月份的时候,Anthropic 的研究员 Nicholas Carlini 发了一篇博客,讲他怎么用 16 个 Claude 实例并行工作,从零开始写了一个 Rust 实现的 C 编译器,能编译整个 Linux 6.9 内核,支持 x86、ARM 和 RISC-V 三个架构。10 万行 Rust 代码,花了大约 2000 个 Claude Code session,成本 2 万美元。
这件事对我的冲击很大。不是因为 AI 能写编译器——编译器本质上是一个规则明确的工程问题。真正让我震撼的是:AI 选择了 Rust 作为实现语言,而且写出来的代码质量足以编译 Linux 内核。 看完这篇博客,我就决定在 Memoria 上试一把。
这个案例说明了两件事:
- AI 对 Rust 的理解已经足够深,深到可以处理所有权、生命周期、trait 系统这些"Rust 最难的部分"
- Rust 的类型系统和编译器反而成了 AI 的优势——编译器会告诉 AI 哪里写错了,AI 可以根据编译错误自动修正
这和 Python 形成了鲜明对比。Python 的灵活性对人类来说是优势,但对 AI 来说反而是劣势——没有编译器兜底,AI 生成的 Python 代码更容易出现运行时才暴露的 bug。
差不多同一时间,Andrej Karpathy 在播客里说他从 2025 年 12 月开始就没有手写过一行代码了,从自己写 80% 的代码变成了 AI 写 80% 的代码。这个比例还在继续翻转。
我的体验和他类似。在用 AI 重写 Memoria 的过程中,我大概只需要做三件事:
- 定义架构——告诉 AI 我要什么样的模块划分、数据流、API 设计
- Review 代码——看 AI 生成的代码是否符合我的意图,是否有逻辑问题
- 处理编译错误——但大多数时候 AI 自己就能根据
cargo build的输出修好
Rust 的编译器在这个工作流里扮演了一个关键角色:它是 AI 和人类之间的"质量检查员"。每一次编译,编译器都在告诉你(和 AI):"这里有问题,具体是什么问题,应该怎么改。" 这种反馈循环在动态语言里是不存在的。
Rust + AI 的反馈循环 Python + AI 的工作流
======================== ========================
人类: 定义架构 / 需求 人类: 定义架构 / 需求
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ AI 生成代码 │ │ AI 生成代码 │
└──────┬──────┘ └──────┬──────┘
│ │
▼ ▼
┌─────────────┐ 编译错误 ┌─────────────┐
│ cargo build │ ──────────┐ │ 直接运行 │
└──────┬──────┘ │ └──────┬──────┘
│ 编译通过 │ │
▼ │ ▼
✅ 基本能跑 AI 自动修正 ❌ 运行时才爆炸
(精确的错误信息) (堆栈不知所云)
行业正在往这个方向走
我不是唯一一个这么想的人。
GitHub 的 Octoverse 2025 报告显示了一个有趣的趋势:AI 编码工具正在创造一种"便利循环"(convenience loop),重塑开发者的语言选择。TypeScript 在 GitHub 上以 66% 的增长率超越了 Python 和 JavaScript,成为使用最多的语言。原因之一是:静态类型给 AI 生成的代码提供了安全网。
同样的逻辑适用于 Rust。Stack Overflow 2024 年度调查显示 Rust 以 83% 的比率蝉联"最受喜爱"语言。State of Rust Survey 显示近半数受访企业已经在生产环境中使用 Rust。微软宣布了到 2030 年用 AI 辅助将 C/C++ 代码迁移到 Rust 的计划。
Python 在 AI 基础设施层的份额正在被编译型语言蚕食。Python 在 AI 研究和原型开发中仍然是王者,但在需要部署、分发、长期维护的系统软件中,编译型语言正在收复失地。
这和我在向量数据库领域看到的趋势完全一致。Milvus 最初的 Python SDK 是生态入口,但内核从来都是编译型语言。Qdrant 从第一天就选了 Rust,LanceDB 也是 Rust。在 AI infra 这个赛道上,"用 Python 做原型,用编译型语言做产品"已经不是个人偏好,而是行业共识。
对于需要嵌入到用户 IDE 中常驻运行的服务来说,零运行时开销、内存安全、单二进制分发这些特性不是锦上添花,而是刚需。Rust 正在成为这类场景的默认选择。
重写的收获
用 Rust 重写 Memoria 之后,我们得到了一些"免费"的提升:
Python 版 Rust 版
┌──────────────┐ ┌──────────────┐
二进制体积 │ ~300 MB │ → │ <10 MB │ ↓ 97%
├──────────────┤ ├──────────────┤
常驻内存 │ 200+ MB │ → │ ~20 MB │ ↓ 90%
├──────────────┤ ├──────────────┤
启动速度 │ 数秒 │ → │ 毫秒级 │ ↓ 99%
├──────────────┤ ├──────────────┤
分发依赖 │ Python + pip │ → │ 单个二进制 │ 零依赖
│ + venv + ... │ │ │
├──────────────┤ ├──────────────┤
运行时错误 │ 随时可能 │ → │ 编译即保证 │ ≈ 0
└──────────────┘ └──────────────┘
- 二进制体积:从 Python + PyInstaller 的几百 MB 降到了不到 10 MB 的单个可执行文件
- 内存占用:常驻内存从 200MB+ 降到了 20MB 左右
- 启动速度:从 Python 解释器的冷启动几秒,到 Rust 二进制的毫秒级启动
- 分发体验:用户下载一个二进制文件就能用,不需要装 Python、不需要管 pip、不需要虚拟环境
- 可靠性:编译通过基本就能跑,不会在运行时突然冒出一个
AttributeError: 'NoneType' object has no attribute 'xxx'
这些提升不是我通过精心优化得到的,而是换了一个语言就自然获得的。这就是我说的"免费提升"。
写在最后
我不是要说 Python 不好。Python 在 AI 研究、数据分析、快速原型开发中的地位短期内不会被动摇。但对于需要分发给用户、需要长期维护、需要在资源受限环境下运行的系统软件来说,Python 的短板正在变得越来越明显。
而 Rust 曾经最大的门槛——陡峭的学习曲线——正在被 AI 快速磨平。当 AI 可以帮你处理所有权和生命周期的细节,当编译器可以作为 AI 的实时反馈机制,Rust 的"难"就不再是一个有效的反对理由了。
作为一个写了多年 Go 的数据库内核程序员,我从来没想过自己会用 Rust 重写一个项目。但 AI 改变了这个等式。它让我可以把精力放在架构设计和产品思考上,而不是和语言的语法细节搏斗。
从 2019 年用 C++ 手撸 Milvus,到用 Go 构建 MatrixOne,再到今天用 Rust 重写 Memoria——每一次语言选择都是在当时的约束条件下做出的最优解。而 AI 的出现,让 Rust 从"想用但用不起"变成了"没有理由不用"。
系统瞬间有了内存安全、性能和分发体积的免费提升,而代价几乎为零。
这就是我用 Rust 重写 Memoria 的原因。
Memoria 是一个为 AI Agent 提供持久化记忆的开源项目,支持 Kiro、Cursor、Claude Code 等主流 AI 编码工具。底层存储基于 MatrixOne 云原生超融合数据库。