记忆 RAG:不装向量库,也能做出像样的检索

phenix-fledgling Lv5

“做 RAG”在很多人心里等于”装向量数据库”。但看过 grok-build 的记忆检索源码后会发现:一条纯词法检索 + 精心设计的打分管线,在个人记忆这个规模(几千条以内)上完全够用,而且零外部依赖。

检索管线全景

查询 → 分词 → FTS5 BM25 取候选(3 倍量)
    → BM25 归一化到 [0,1]
    → 时间衰减(只衰减会话类记忆)
    → 来源权重(用户显式"记住"的最高)
    → 访问频次加成
    → 分数下限过滤
    → MMR 去冗余
    → top-K 注入系统提示

几个关键设计

中文分词不用 jieba。 SQLite FTS5 默认分词器不切中文(整句一个 token,什么都搜不到)。解法土但有效:英文按词切,中文按字符 unigram + bigram 切,拼成空格分隔的字符串存进 FTS。”pytest 测试”能命中”我偏好用 pytest”,标准库搞定。

时间衰减不是一刀切。 会话摘要类记忆按 30 天半衰期指数衰减(旧闻应该淡出),但用户显式”记住”的内容和导入的工作经验是长青的,不衰减。这一条直接来自”压缩即记忆”的分层:不同层的记忆有不同的生命周期。

来源权重表达信任。 显式记住 1.2 > 导入经验 1.0 > 会话沉淀 0.8。用户亲口说的话就是比系统自动总结的可信。

MMR 防止 top-K 全是近亲。 相关性再高,五条几乎一样的记忆也只该出现一条。用 Jaccard 相似度做多样性惩罚(lambda 0.7),不需要 embedding。

什么时候才需要向量

词法检索的死穴是同义改写:”我喜欢简洁的代码”搜不到”偏好极简风格”。当记忆库大到同义问题频繁出现,或者要做跨语言检索时,再把向量作为第二路召回加进来(混合检索),打分管线不变。生产上我会选 pgvector;个人档位 sqlite-vec 就够。

先把打分管线做对,向量只是候选源之一——这是 grok-build 给我的最大启发。

  • 标题: 记忆 RAG:不装向量库,也能做出像样的检索
  • 作者: phenix-fledgling
  • 创建于 : 2026-07-28 12:00:00
  • 更新于 : 2026-07-29 02:35:18
  • 链接: https://blog.xugua.xyz//post/记忆 RAG:不装向量库,也能做出像样的检索.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
记忆 RAG:不装向量库,也能做出像样的检索