乐于分享
好东西不私藏

我们把 AI 的记忆层建在了 1970 年代的文件系统上

我们把 AI 的记忆层建在了 1970 年代的文件系统上

为什么我们把 AI 记忆层建在 1970 年代的文件系统上,以及为什么它会比每一代云端向量库活得更久。

上一篇我论证了:向量搜索在结构上不适合做记忆。
合理的下一个问题写在脸上,那不用向量,用什么?
诚实的回答不流行到我几乎不想发。
Markdown 文件。YAML 元数据。SQLite。Tantivy。一个 1970 年代的文件系统,一个 1991 年的标记格式,一个 2000 年的内嵌数据库,一个安静地驱动着半个开源世界的搜索索引。这里没有任何东西是奥巴马第二个任期之后发明的。没有任何东西拿过 Series C 融资
我们选这套技术栈,不是因为它聪明。是因为它全部都通过了软件世界唯一真正重要的考试 —— 时间
技术债的最危险形态,不是建在老技术之上。是建在还没被时间清洗过的新技术之上,一套还没公开失败过、被迫 fork 过、被维护方默默 deprecated 过、被恐慌迁移过的技术栈。向量数据库作为一个产品类别,大约三岁。Markdown 三十五。SQLite 二十六。纯文本比 UNIX 还老。我们把记忆层押在已经证明自己杀不死的那一层上。
三个理由。任何一个都够了。

一 · 精度:确定性 vs 概率性

一个 SQL SELECT 是确定性操作。同样的查询、同样的表,连续运行一万次,返回完全相同的结果集。字节级一致。没有舍入、没有 temperature、没有模型版本、没有 embedding 漂移。这一行要么在,要么不在
向量相似度查询,是一个披着确定性外衣的概率性操作
同一个 cosine query 跑两次,经常得到一样的 top-k。但经常 ≠ 始终。不同版本的 embedding 模型对同一段输入文本会产生不同的向量。不同的 ANN 索引实现 —— HNSW、IVF、Annoy —— 对同一个 query vector 会返回不同的邻居。哪怕在单一索引内部,多线程探测顺序也会让 ranking 在不同 run 之间漂移。系统在「同样的输入返回略不一样的结果」时没有撒谎。它只是诚实地承认了它从来就是的东西:一个估算(an estimate)
在搜索任务里,估算就是正确答案。用户在钓鱼,他们会调整 query。他们问的不是「我写过什么?」,他们问的是「有什么看起来像我现在在想的事?
在记忆任务里,估算就是渎职
当你问自己的系统「我上季度怎么评估那家公司的?」,唯一可接受的答案是你真写过的那段话,带着真实的时间戳、在真实的文件里。不是最近邻不是缝合的近似是那个东西本身,与你手指敲下的那一刻字节相同

“In search, an estimate is helpful. In memory, an estimate is a lie.”

搜索里,估算是帮助。记忆里,估算是谎言。

这就是为什么我们记忆层的 substrate 是 SQLite 索引的 Markdown,而不是向量库。向量没错。它只是不该被用来做这件事。这件事是对已写下内容的召回,只有确定性结构才能返回它。

二 · 主权:文件系统作为开放协议

文件系统是计算世界里最接近宪法文件的东西。
它在 1970 年代被设计为开放协议。没有任何公司控制它没有任何许可协议管制它。没有 V2 schema 升级会反过来破坏 V1 写下的文件。磁盘上的字节就是磁盘上的字节。Apple 不能让你的.md文件在他们调整产品方向的那天到期Microsoft 不能在下一版操作系统里把它弃用Anthropic 不能某天醒来决定你的记忆是上季度的算力预算
向量数据库不具备这个属性。它做不到
每一个商用向量库都是一个专有 schema,藏在专有 API 后面,跑在某家公司的基础设施上,而那家公司的商业模式要求你持续依赖它。Pinecone 关停不是抽象风险,是某个不由你控制的时间尺度上的运营必然性。基础模型供应商悄悄修改它记忆库的 schema 也不是假设,是任何一个保留策略由季度财报决定的系统的默认状态。Bug report 会很客气。迁移工具会半残。你的过去会带着你不会立刻察觉的微妙扭曲到达新 schema。直到第一次你问系统一个具体问题,看着它满怀信心地编出一段东西。
当 substrate 是租来的,你的过去就是租来的
这不是技术选择。这是伦理选择。把你积累的思考,每个决定、每个洞察、每段记录你六个月前是谁的痕迹,放进一个你不拥有的格式、一个你无法导出的服务,就等于把你的内在生命转化成一份长期租约,签在你没起草的条款上,对方的利益与你不一致。
过去五百年里所有认真的记录者都坚持亲自掌握档案是有原因的。银行、法庭、家族、宗教秩序。这个原则完美地缩放进数字时代。形式只是变了。今天它的形式是一个你磁盘上的纯文本文件夹,由你机器上的软件索引,用你掌握的密钥加密,备份到你能撤销的存储
其他都是与拥有云的人之间的租约。

三 · 流动性:格式作为联邦

Markdown 是计算世界里最滥交的格式。它对什么都张开。
在 Obsidian 里打开它。在 Logseq 里打开它。在 VS Code、iA Writer、Typora、vim、nano、TextEdit、macOS Finder 预览面板里打开它。用 grep、awk、sed、ripgrep、fzf 处理它。用 git 追踪它。通过 Dropbox、iCloud、Syncthing、rsync、U 盘、邮件附件同步它。在手机上读、在 2008 年的 Linux 笔电上读、在还没被发明的设备上读。把它交给下一代语言模型,它们原生解析。因为 2020 年之后的每个模型都是在跑 Markdown 的网络上训出来的。
这不是巧合。这是六十年的计算范式更替在一个赢遍每一层栈的格式上留下的产物。
向量嵌入有完全相反的属性。一旦生成,它们就冻结在生成它们的模型上。text-embedding-3-large 产出的 embedding,与 Gemini 产出的不互通。两者都与下个季度发布的下一代 embedding 模型不互通。换供应商不是改个配置 —— 是对整段历史做一次重新 embedding job,按新供应商的每 token 价格付费,加上一次索引迁移,加上下游系统从未被设计来检测的语义关系漂移的隐性风险。

“Plain text is forward-compatible with every AI that hasn’t been invented yet. Vector embeddings are barely backward-compatible with last quarter’s model.”

纯文本,向前兼容所有还没被发明的 AI。向量嵌入,连上个季度的模型都向后兼容不了。

正确的解读视角是联邦(federation)。Markdown 是一个联邦协议,每个编辑器、每个模型、每个脚本读它都不需要任何人许可。向量库是被囚禁的格式。联邦只在你真想要行动自由时才有意义。我们想要。我们假设我们的用户也想要。

四 · 组合(The Composition)

这是大多数架构文章塌陷成教程的段落。那种博文我不写。机制不是论点。但层叠的形状是论点,所以形状是我会给你的。
Markdown 是内容层。用户真写下来的句子,字节级保存。
YAML frontmatter 是结构层。标签、来源、AI 完整性标记、created-at 与 modified-at 时间戳、与其他笔记的交叉引用。这些元数据把一条笔记从「数据团块」升格为「记录」
SQLite 是索引层。「所有标 X 的笔记,写于 Y 与 Z 之间,引用 Q 的」,这种向量库语焉不详地做手势的查询,关系数据库瞬间返回,全精度,从你拥有的单个文件里出来。
Tantivy 是全文召回层。BM25、自定义 CJK tokenizer、跨语料的精确短语搜索。在「搜索」变成「vibes」之前搜索引擎用的那种东西。
向量搜索,在这个架构里不是地基。是最顶端的一层薄薄的层,只在模糊语义表面匹配真的是正确操作时才被用,开放浏览、意图消歧、跨语言相似性。它是调味,不是基底
结果是一个底部知道真相、顶部友好地猜测的记忆系统,就这个顺序。绝大多数云端 AI 记忆产品反过来,模糊检索是承重墙,结构是事后栓上去的。那个反转就是 bugMonolithos 是拒绝把它发货的架构

任何一年里最流行的技术栈,几乎从来不是十年后还站着的那个。Markdown 比今天发布 AI 产品的大多数工程师的职业生涯还老SQLite 比他们当中一半还老。纯文本比这门学科还老。
我们没选最先进的栈。我们选的是不会过期的那一个。

“Future-proof is not a feature. It is an architecture.”

经得起未来,不是功能,是架构。


下一篇预告(5/4 上线):《From Tool Calling to Cognitive Federation,为什么 MCP 选错了抽象层级》
英文原文同步上线:silasyu.substack.com