engineering deep-dive

ZeroClaw 混合记忆揭秘:SQLite + FTS5 + 向量为什么打得过专用向量数据库

ZeroClaws.io

ZeroClaws.io

@zeroclaws

2026年3月7日

8 分钟

ZeroClaw 混合记忆揭秘:SQLite + FTS5 + 向量为什么打得过专用向量数据库

大多数 AI 智能体框架实现记忆的时候,第一反应是上向量数据库。Pinecone、Weaviate、ChromaDB、Qdrant——选择多且文档齐全。存嵌入向量,按相似度查询,获取相关上下文喂给下一个 prompt。

ZeroClaw 一个都不用。它的记忆系统是一个 SQLite 文件,把 FTS5 全文搜索和向量相似度搜索组合在一起。没有外部数据库。没有独立服务。没有网络往返。整个记忆系统包含在 3.4MB 的二进制里。

这不是限制——这是刻意的架构选择,性能数据撑腰。

为什么纯向量搜索对智能体不够用

向量搜索找语义相似的内容。问"怎么部署到 Kubernetes?",向量搜索会返回过去关于 Kubernetes 部署、Docker 容器和云基础设施的对话。有用。

但智能体记忆的访问模式跟知识库不同。智能体需要召回的东西:

  • 精确术语。 "测试服务器的 API 密钥是什么?"向量搜索可能返回关于 API 密钥的泛泛而谈。你需要的是那次具体提到测试密钥的对话。
  • 近期上下文。 "我们刚才聊了什么?"对保持对话流来说,时间近比语义相似更重要。
  • 结构化查询。 "上周所有关于数据库迁移的对话。"这是过滤,不是相似度搜索。

纯向量记忆能搞定第一类,后面两类搞不好。全文搜索搞得定精确术语和结构化查询,但会漏掉语义关联。最优解是两者结合。

ZeroClaw 的混合搜索怎么工作

ZeroClaw 把每条记忆存在一个 SQLite 表里,带三种搜索机制:

1. FTS5 全文搜索(BM25 评分)。 SQLite 的 FTS5 扩展提供快速全文搜索,带 BM25 相关性评分——跟传统搜索引擎用的算法一样。"测试 API 密钥"这样的查询瞬间找到精确提及,按词频和文档长度评分。

2. 向量相似度搜索。 每条记忆包含一个在写入时计算的嵌入向量。相似度查询用余弦距离找语义相关的内容,即使精确的词不匹配也能找到。

3. 元数据过滤。 时间戳、会话 ID、频道来源和自定义标签支持结构化查询,在搜索运行前缩小结果范围。

当 ZeroClaw 为 prompt 检索上下文时,它并行运行两种搜索并合并结果:

  • FTS5 结果按 BM25 相关性评分
  • 向量结果按余弦相似度评分
  • 分数归一化后以可配置的权重组合(默认:60% FTS5,40% 向量)
  • 元数据过滤(时间近度、来源频道、会话 ID)作为前置过滤器应用
  • Top-K 结果成为智能体的上下文窗口

这种混合方式捕获了单独任何一种搜索会漏掉的内容。精确术语"测试 API 密钥"通过 FTS5 浮出来。语义相关的"部署凭据"讨论通过向量浮出来。智能体两者都拿到。

性能:SQLite vs 专用向量数据库

基准测试数据集为 100,000 条记忆条目(一个重度使用的个人智能体半年的典型量):

  • ZeroClaw SQLite:0.3ms
  • ChromaDB(本地):2.1ms
  • Weaviate(本地):4.8ms
  • Pinecone(云端):15-50ms(取决于网络)
  • ZeroClaw SQLite:1.2ms
  • ChromaDB:8.5ms
  • Weaviate:12ms
  • Pinecone:30-80ms
  • ZeroClaw SQLite:45MB(磁盘文件大小,内存映射)
  • ChromaDB:380MB RSS
  • Weaviate:1.2GB RSS
  • ZeroClaw SQLite:<1ms(文件按需打开)
  • ChromaDB:2.3s
  • Weaviate:8-12s

ZeroClaw 的 SQLite 方案在每项操作上都更快,内存只用一小部分。性能优势来自三个因素:

  1. 1.**零网络开销。** SQLite 是进程内的。没有序列化,没有 TCP 往返,没有连接池。读写操作直接是内存映射文件访问。
  1. 2.**没有服务器进程。** ChromaDB 和 Weaviate 作为独立服务运行,有自己的内存分配器、垃圾回收器和线程池。SQLite 共享智能体的进程空间,零开销。
  1. 3.**为访问模式优化。** 智能体记忆主要是写操作(每轮对话都写)和偶尔的读操作(上下文检索)。SQLite 擅长这种模式。专用向量数据库为跨百万向量的大规模相似度搜索优化——对智能体规模的数据来说大材小用。

嵌入策略

ZeroClaw 用打包在二进制里的轻量模型计算嵌入。默认是一个量化的 sentence transformer 变体,产生 384 维向量。不是最高质量的嵌入模型,但小到可以在进程内不用 GPU 就跑。

想要更高质量嵌入的用户可以把嵌入计算委托给 Ollama 或任何兼容 OpenAI 的嵌入端点。代价:写入延迟略高(嵌入 API 调用),换来更好的语义搜索质量。

实际上,打包的模型对大多数智能体场景够用了。智能体记忆召回不需要研究级嵌入的细微差别——它需要的是当你问容器部署时能找到之前关于 Kubernetes 的对话。轻量模型可靠地搞定这个。

为什么不直接用向量数据库?

专用向量数据库的论据假设了一个智能体记忆达不到的规模。

Pinecone 在跨数十亿向量的复杂过滤查询上很强。一个个人 AI 智能体重度使用一年大概积累 10 万条记忆。团队共享的智能体可能到 100 万。在这个规模下,SQLite 比任何外部数据库都快,因为外部服务的开销超过了计算上的节省。

损益平衡点——专用向量数据库超过 SQLite 的地方——大约是 1,000 万条目加复杂的多向量查询。没有个人或小团队 AI 智能体会达到这个阈值。

确实需要大规模的用户可以换:ZeroClaw 的记忆接口是一个 trait。把 SQLite 实现换成 Postgres+pgvector 后端或专用向量数据库,不改任何其他东西。但先用 SQLite 开始。你大概率永远不需要换。

单文件优势

有一个容易被忽略的实际好处:整个智能体的记忆就是一个文件。

  • 备份: `cp memory.db memory.db.backup`
  • 迁移: 把文件复制到新机器
  • 审查: 用任何 SQLite 客户端打开,对智能体的记忆跑 SQL 查询
  • 清空: `rm memory.db`,智能体回到白纸一张
  • 加密: 用 SQLCipher 做静态加密

不用管理数据库服务器。没有连接字符串。没有 schema 迁移。没有需要运行服务的备份脚本。文件就是数据库,数据库就是记忆。

在树莓派上做边缘部署,这就是"能跑"和"我还得跑一个数据库服务"的区别。在 4GB 的 Pi 上,ChromaDB 需要的 380MB 直接判死刑。SQLite 需要的 45MB 根本不算事。

简单的事情应该简单。智能体记忆就是简单的事情。SQLite 让它保持简单。

开始用 ZeroClaw 构建 AI Agent

获取新版本、集成和 Rust 驱动的 Agent 基础设施更新。不发垃圾邮件,随时退订。