最近在补 RAG 和检索系统的基础。刚开始看资料时,最容易混在一起的几个词就是:BM25、Embedding、SPLADE、Reranker,再加一个听起来很工程的词:多路召回。
单独看定义不难,难点在于把它们放进同一条检索链路里。复习时重点回答这些问题:
- 哪些方法负责“先找一批候选”?
- 哪些方法负责“把候选重新排好”?
- BM25 和 Embedding 明明都能搜,为什么还要一起用?
- Reranker 听起来更准,为什么不直接全库跑?
- SPLADE 到底是关键词检索,还是语义检索?
这篇笔记不铺满公式,重点讲清每种方法在检索系统里的位置、优势和边界。
速读版
先给一个压缩版结论:
| 方法 | 系统位置 | 主要解决 | 优点 | 短板 |
|---|---|---|---|---|
| BM25 | 关键词搜索 | 字面精确命中 | 快、可解释、对术语敏感 | 不懂同义表达 |
| Embedding | 语义近邻搜索 | 意思接近但字面不同 | 泛化强,适合自然语言问题 | 细粒度容易混 |
| SPLADE | 神经稀疏搜索 | 语义扩展后的关键词匹配 | 兼顾稀疏结构和语义扩展 | 模型和索引更复杂 |
| Reranker | 精排裁判 | 少量候选谁最相关 | 判断细,通常更准 | 慢,不适合全库扫描 |
一条典型链路大概是:
| |
多路召回要解决的是:不要让单一检索方法承担所有召回责任,而是让不同方法互相补盲区。
一、先分清召回和精排
搜索系统一般不会一开始就让最复杂的模型扫描整个文档库。文档量一大,成本会很高。
所以它会分成两步:
| |
召回阶段的目标是“尽量别漏掉相关候选”;精排阶段的目标是“在候选里排得更准”。
BM25、Embedding、SPLADE 通常更适合放在召回阶段;Reranker 通常更适合放在精排阶段。
二、BM25:最经典的关键词检索
BM25 是传统搜索里很经典的方法。它不理解深层语义,也不做推理,主要看一个问题:
query 里的词,在文档里有没有出现?出现的词有没有区分度?
比如用户搜:
| |
如果一篇文档里出现了“酒店”“住宿”“报销”,它就应该比完全没出现这些词的文档更相关。
BM25 可以先记成:
| |
复习时先理解这三个部分,再回到完整公式。
2.1 词频:命中 query 词,说明可能相关
如果 query 里有“住宿”,文档 A 出现了“住宿”,文档 B 没出现,那文档 A 大概率更相关。
但 BM25 不会让词频无限加分。一个词重复出现很多次,并不代表相关性可以无限升高。所以 BM25 会对词频做饱和处理。
2.2 IDF:越少见的词,越有区分度
有些词太常见:
| |
它们出现了当然有一点信息,但区分度不强。
有些词更具体:
| |
这些词更能帮助判断文档主题。
这就是 IDF 的直觉:一个词在全库里越少见,它越能区分文档。
2.3 文档长度修正:长文档不能天然占便宜
长文档词多,命中 query 词的概率天然更高。如果不修正,长文档会占便宜。
BM25 会考虑文档长度,让“短但精准命中”的文档也有机会排在前面。
2.4 BM25 的位置
BM25 特别适合这些场景:
- 搜索专有名词
- 搜索编号、代码、实体名
- 搜索业务词或固定术语
- 需要可解释的检索结果
比如:
| |
如果文档里明确出现这个词,BM25 的表现通常很稳。
它的短板也很明显:不太懂同义词。
| |
这些表达意思接近,但字面不完全一样。如果没有共同词,BM25 可能就会漏。
复习锚点:BM25 适合作为基础召回,尤其适合术语、编号、实体名;短板是同义表达和口语化改写。
三、Embedding:把文本放进语义空间
Embedding 的思路和 BM25 不同。BM25 看词有没有命中;Embedding 把文本编码成向量。
语义相近的文本,在向量空间里应该更接近。
比如:
| |
这些句子字面不同,但语义接近。好的 Embedding 模型会尽量把它们编码到相近的位置。
检索时通常是这样:
| |
最常见的相似度是余弦相似度:
| |
它关心的是方向,而不是文本长度。两个文本语义越接近,向量夹角通常越小,相似度越高。
3.1 Embedding 解决了 BM25 的一部分盲区
用户的问题往往很口语化:
| |
文档标题可能是:
| |
BM25 如果没有命中关键分词,可能不够稳;Embedding 更可能从整体意思上判断它们相关。
Embedding 适合:
- 同义表达
- 口语化 query
- 标题和问题表达方式不一致
- 需要整体语义理解的场景
3.2 Embedding 也会犯“语义太近”的错
Embedding 的问题是,它有时会太模糊。
比如:
| |
从语义上看都和“服务”有关,向量空间里可能靠得很近。但在实际业务里,它们可能需要被分到不同类别。
复习锚点:Embedding 擅长找“语义相近”的内容,但在术语边界、细分类别、编号实体上可能不够精确。因此它常和 BM25 搭配使用。
四、为什么需要多路召回
BM25 和 Embedding 的优缺点互补。BM25 负责词面命中,Embedding 负责语义相近;SPLADE 可以补充神经稀疏召回。多路召回就是同时跑多种召回方法,再合并候选:
| |
举个简单例子。
| |
BM25 可能找到:
| |
Embedding 可能找到:
| |
两路结果合起来,比单独用一路更稳。
4.1 分数不能直接相加
多路召回带来一个麻烦:不同方法的分数不是一个尺度。
BM25 可能返回:
| |
Embedding 的余弦相似度可能是:
| |
这些分数不能直接相加。
常见处理方法有两类。
第一类是分数归一化,例如 min-max normalization,把不同来源的分数压到相近区间,再加权融合:
| |
第二类是只看排名,比如 Reciprocal Rank Fusion。它不太关心原始分数,而是看一个文档在每一路里排第几:
| |
如果一个文档在多路召回里都排得靠前,它的融合分数就会更高。
RRF 的复习锚点:多路召回都排得靠前的文档,融合后应该获得更高优先级。
五、Reranker:候选少了以后,再认真判断
如果 BM25、Embedding、SPLADE 负责先找候选,Reranker 负责在候选变少后做细粒度比较。
Embedding 通常是 bi-encoder:
| |
这种方式快,因为文档向量可以提前算好。
Reranker 通常接近 cross-encoder 思路:
| |
例如:
| |
模型可以同时看到 query 和 doc,细粒度判断它们是否匹配。
5.1 为什么 Reranker 不直接全库跑
Reranker 通常更准,但也更慢。
如果文档库有 100 万篇,让 Reranker 对每篇都判断一次:
| |
成本太高。
所以它一般放在召回之后:
| |
复习锚点:召回阶段追求快和覆盖,Reranker 阶段追求细粒度相关性判断。
5.2 Reranker 适合处理候选之间的细微差别
比如 query 是:
| |
召回阶段可能找出:
| |
这些都相关,但最该排前面的可能是“发票作废与重开流程”。Reranker 就是在这种时候发挥价值。
六、SPLADE:神经网络版的关键词检索
SPLADE 是这几个方法里最容易混淆的一块,可以先这样理解:
SPLADE 试图把 BM25 的稀疏可解释性,和神经模型的语义扩展能力接起来。
BM25 在词项空间工作。文档里有哪些词,就在哪些词上有统计权重。
Embedding 在稠密向量空间工作。每个维度不一定有明确含义,但整体能表达语义。
SPLADE 也在词表空间里工作。假设模型词表有 30,000 个 token,那么一段文本会被表示成一个 30,000 维向量。
不同的是,这个向量很稀疏:
| |
比如用户输入:
| |
SPLADE 可能不只激活“酒店”,还会激活:
| |
这相当于模型自动帮 query 做语义扩展,但结果仍然落在稀疏词项空间里。
6.1 SPLADE 的激活直觉
很多 SPLADE 实现会对模型输出做类似这样的变换:
| |
拆开看:
ReLU(x):负数清零,只保留正向激活。log(1 + x):压缩过大的权重,让数值更稳定。
这样得到的是非负稀疏权重。
检索时可以直接做点积:
| |
如果 query 和 doc 在相同或相关 token 上都有权重,分数就会变高。
6.2 SPLADE 放在哪个位置
可以把它放在 BM25 和 Embedding 中间理解:
| |
SPLADE 吸引人的地方在于,它不像普通 Embedding 那样完全进入黑盒稠密空间,也不像 BM25 那样只依赖原始词面。它可以学习到一些扩展关系。
它的成本也更高:需要专门模型,向量维度很高,索引和部署比 BM25 更复杂。
七、一个完整检索链路可以怎么想
假设用户问:
| |
一条比较完整的检索链路可以这样组织:
| |
每一步对应一个具体问题:
- BM25:有没有明确命中关键词?
- Embedding:语义上像不像?
- SPLADE:能不能做更聪明的词项扩展?
- Reranker:候选里谁最贴合用户问题?
八、选型建议
如果只是做一个小型知识库,最简单的起点通常是:
| |
如果业务词很强,比如法规条款、财务科目、商品型号、错误代码,可以加上 BM25:
| |
如果发现 BM25 词面太死、Embedding 又容易把细分类别混在一起,再考虑 SPLADE:
| |
不要一开始就把所有东西都加上。检索系统越堆越复杂,调试成本也越高。更稳的做法是先跑通 baseline,再根据错误样本决定补哪一路。
小结
多路召回不是一个单独算法,而是一种系统设计思路:让不同检索方法从不同角度找候选,再用排序模型做最终筛选。
BM25 解决精确词面匹配,Embedding 解决语义泛化,SPLADE 尝试在稀疏词项空间里加入神经语义扩展,Reranker 负责最后的细粒度判断。
以后复习或设计检索链路时,优先问这些问题:
| |
这些问题比单独背概念更有用。检索效果通常不是由某个单点算法决定的,而是由整条链路的召回覆盖、候选融合、精排质量和阈值校准共同决定的。