RAG 向量搜索 vs 关键词搜索:小规模知识库的检索策略

每一个用 Obsidian 积攒了几十篇技术笔记的人,迟早都会动一个念头:能不能让 AI 自己翻笔记,替我记住那些踩过的坑?

念头一起,RAG 就到了嘴边。向量化、embedding、语义检索,这些词汇自带一种工程上的庄严感,仿佛不上向量数据库就对不起自己的笔记。但在真正动手之前,值得先算一笔账。

关于"RAG 效果不如关键词搜索"的说法

这句话在特定场景下有事实基础。不是 RAG 不好,是它解决的问题和你遇到的问题之间,可能隔着一道规模的鸿沟。

向量检索的语义漂移

Embedding 模型把文本映射到向量空间,"语义相近"的文本距离近。但"语义相近"不等于"你想要的"。

搜"chezmoi apply 没有拉取远程":

  • 关键词搜索:直接命中包含 chezmoi apply 的笔记
  • 向量搜索:可能返回一篇关于"git pull 同步远程仓库"的通用文章,语义相近但答非所问

向量空间里的"近",有时候是一种礼貌的误解。

技术术语是天然的精确锚点

技术笔记里的关键词不是自然语言,而是精确的标识符。stat -f %m 就是 stat -f %mpromptStringOnce 就是 promptStringOnce。它们不需要被"理解",只需要被匹配。关键词搜索在这种场景下天然精准,向量化反而是绕路——用一个复杂的模型去"理解"一个不需要理解的字符串。

Chunking 的信息损耗

RAG 需要把文档切成 chunk。切太小,上下文丢失——一段代码和它的解释被拆到两个 chunk 里,各自漂流。切太大,噪音淹没信号。而关键词搜索返回整个文件,上下文完整,LLM 拿到的是一篇结构完整的笔记,不是被肢解后的碎片。

BM25:一个难以超越的老对手

BM25 是几十年前的关键词排序算法。业界做 RAG 评测时经常发现一个尴尬的事实:精心调教的向量检索只是勉强打平 BM25,有时还不如。这也是为什么现在主流方案转向 hybrid search(关键词 + 向量混合)——承认单纯向量搜索的短板,用老办法补新技术的漏洞。

规模效应

向量搜索的优势在大规模语料(几千篇以上)中才显现。几十到几百篇的规模,关键词搜索的结果集本身就很小——搜一个关键词命中三篇,不存在"结果太多需要排序"的问题。

场景对比

场景关键词搜索向量搜索
技术文档、代码、报错信息强(术语精确)弱(语义漂移)
模糊问题("如何提高性能")弱(不知道搜什么词)强(语义匹配)
小规模(< 500 篇)够用杀鸡用牛刀
大规模(> 5000 篇)结果太多需要排序有优势

实际方案:Grep + LLM

最终在 Claude Code + Obsidian 的工作流中采用的检索链路:

Grep(关键词过滤) → Claude(判断相关性) → Read(读原文)

对比 BM25 的经典链路:

关键词过滤 → 词频统计排序 → 返回 top-K

区别在于"排序器"。前者用 LLM 理解上下文和问题意图,后者用词频公式。在小规模数据上,LLM 作为排序器严格优于 BM25。52 篇技术笔记搜一个关键词,命中 1-3 篇,LLM 读一眼文件名就知道该看哪篇。BM25 能做的事,LLM 顺手就做了。

至于向量化——搭建 embedding 服务,维护向量数据库,每次笔记更新重新索引。这些代价换来的收益是:在 52 篇笔记中做语义模糊匹配。这笔账算不过来。

结语

五十二篇笔记,不需要向量数据库,不需要 embedding 模型,不需要 BM25。一个 Grep,一个 LLM,足矣。

技术选型中最难的部分,往往不是选择用什么,而是承认不需要什么。向量化是好工具,留给几千篇以上的场景。在那之前,简单、精准、零依赖的方案,就是最好的方案。