一、为什么是 SQLite ?

1. 零运维成本:无需部署 Elasticsearch、PostgreSQL。一个 .sqlite 文件随 Agent 启动,随系统备份。

2. 极致的 I/O 性能:利用 better-sqlite3 的同步特性,在本地单机场景下,其读写延迟远低于通过网络访问的向量数据库。

3. 数据主权:所有的记忆、向量、索引都存储在本地,解决了用户数据泄漏风险。

二、核心架构设计:四表驱动的记忆引擎

与以往依赖庞大云端向量数据库的理念不同,OpenClaw 选择了一条更轻量、更直接的路径:将完整的 RAG 系统压缩进一个 SQLite 文件中。这不仅为了节省成本,更是为了速度与安全。

OpenClaw 数据库核心由四张表构成,分别承担元数据管理文件追踪内容存储向量缓存四大职能。

具体代码查看源码的 ensureMemoryIndexSchema

1. meta 表

meta 表作为一个 k-v 表,可以存储一些配置相关的数据,使得配置数据与业务数据进行解耦,可以让系统在不重启、不重构的情况下适应新的策略。通过 k-v 记录 Agent 层都处理过哪些操作,具体来讲:在 Gateway 层,将每个可能产生副作用的操作(如发送邮件、修改文件)都附带唯一键,然后经由 Agent 层在存储层 SQLite 记录已处理的键,防止网络重传导致的重复执行。

2. files 表

这是实现高效增量索引的关键表。OpenClaw 并不盲目地重新扫描所有文件,而是通过三级过滤机制,file 表主要负责前两级过滤,最后一级过滤由 chunks 表和 embeddingCache 表实现。三级过滤机制如下:

1. 元数据快速筛选:比对字段 mtime(最后修改时间)和 size(文件大小)。如果这两个值与数据库中记录的完全一致,极大概率文件是没有发生变化的,文件扫描过程结束。如果根据这两个值未能从数据库中查询得到相关数据,那么就会进入第二级过滤。

2. 内容哈希精准校验:当第一级过滤失败后,说明时间变动了(只要修改文件就会更新时间),程序才会真正的首次读取文件内容并计算其 hash 值。若计算得到的 hash 值与数据库中的记录 hash 一致,说明内容未变,文件扫描过程结束。如果根据 hash 值未能从数据库中查询得到相关数据,那么就会进入第三级过滤。

3. 文本块级去重与缓存命中:在 RAG 中会将文件进行分块处理,第二级过滤进行内容哈希计算时未能成功匹配到数据只是说明文件内容有变动,但并不代表文件中的每一行内容都变了。将待检测的文件进行切分,得到多个文本块,对每个文本块进行计算得到 hash 值。根据 块hash + 模型名model 查询 embeddingCache 表,如果命中,说明这段文本在其他文件或之前已经计算过向量了,直接复用缓存中的向量embedding,跳过向量计算的 API 调用;如果未命中,需要调用 Embedding API 计算新向量,并存入缓存中。然后再根据该 path + 块hash 查询 chunks 表是否已经存在该记录,如果未存在,需要将该记录插入表中;如果存在,则无需重复插入。

直观流程图如下所示

3. chunks 表

4. embeddingCache 表

三、为什么需要三级过滤?

可以看出,openclaw 采用这种漏斗式的过滤机制,在处理文件的时候,第二次及以后的索引速度会得到非常大的提升,同时也将向量计算 API 的调用成本降至最低。

Categories:

Tags:

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注