文章

BM25 是什么?理解搜索系统里最经典的「关键词匹配」算法

从三个问题拆解 BM25 的核心设计:词频收益为什么该递减?稀有词怎么加权?长文章是否天然占便宜?看懂这些,就理解了搜索系统里最经典的『关键词匹配』算法。

BM25 是什么?理解搜索系统里最经典的「关键词匹配」算法

最近在学习搜索和 RAG 的过程中,一个非常经典的方法反复出现在我面前: BM25。如果你接触过搜索引擎、信息检索,或者最近比较火的 RAG,大概率都会遇到两个词: 稀疏检索(Sparse Retrieval)稠密检索(Dense Retrieval)

对于 Dense Retrieval,我们现在已经比较熟悉了——把文本转成 Embedding,再用向量相似度去找到“语义上相近”的内容。而 BM25,基本可以看作 Sparse Retrieval 里最经典、最有代表性的算法。

简单来说:

BM25 做的事情,就是判断一篇文档和你的搜索关键词到底有多匹配。

但它并不是简单地“看看关键词出现了几次”。真正有意思的地方在于: BM25 对“一个词出现多少次”“这个词有多稀有”“文档有多长”这几件事,都做了更合理的处理。 把这几点理解了,BM25 的核心也就掌握得差不多了。

这篇文章会从一个最简单的关键词搜索说起,顺着三个问题一步步引出 BM25 的核心设计,最后再聊聊它在今天的搜索和 RAG 系统里扮演什么角色。


一、🔍 先从最简单的关键词搜索说起

假设我们有三篇文章:

文章内容
文章 A苹果公司今天发布了新款 iPhone,苹果公司表示新产品将在下个月上市。
文章 B苹果是一种常见水果,苹果富含维生素和膳食纤维。
文章 C微软发布了新的人工智能产品。

现在用户搜索:

苹果公司

最简单的搜索方法是什么?直接数就行了: “苹果”和“公司”这两个词,在每篇文章里各出现了多少次。 显然文章 A 的匹配程度最高。

这其实就是关键词检索最核心的思想:用户输入了一些词,我们去寻找包含这些词的文档。

这种表示方式通常非常“稀疏”——假设整个词表有 10 万个词,一篇文章可能只覆盖其中几百个,那么绝大多数位置都是 0。所以这一类方法通常被称为 Sparse Retrieval,稀疏检索

但问题来了:如果只是简单地统计关键词出现次数,很快就会遇到几个问题。接下来,我们就顺着这三个问题,一步步走近 BM25。


二、❓ 问题一:一个词出现 100 次,真的比出现 10 次重要十倍吗?

假设我们搜索“人工智能”,有两篇文章:文章 A 中“人工智能”出现了 3 次,文章 B 中则出现了 100 次。如果单纯按照词频计算,文章 B 的相关性可能是文章 A 的几十倍——但现实显然不是这样。

想想看:一个关键词在一篇文章里出现 1 次和出现 0 次,区别很大;出现 5 次和出现 1 次,也有一定区别;但出现 100 次和出现 50 次,通常就没那么大区别了。换句话说:

关键词频率带来的收益应该逐渐递减,而不是无限线性增长。

这就是 BM25 非常重要的一个设计: Term Frequency Saturation,词频饱和。你可以把它理解成——BM25 会奖励一个关键词在文档中多次出现,但这个奖励会越来越小,大致可以理解成:

出现次数加分效果
0 次0 分
1 次明显加分
2 次继续加分
5 次还有提升
20 次提升已经很有限
100 次不会因此获得 100 倍的优势

这比单纯统计词频要合理得多。


三、❓ 问题二:所有词的重要程度一样吗?

显然也不是。比如用户搜索:

如何使用 Python 训练神经网络

这里面“如何”“使用”这样的词,区分度其实很弱,因为几乎所有文档里都会出现;而“Python”“神经网络”这些词就重要得多。更关键的是:如果一个词在整个文档库里非常少见,那么当它出现在某篇文章里时,往往就携带了很强的信息量。

这就是信息检索里另一个非常经典的概念: IDF,Inverse Document Frequency,逆文档频率。它背后的思想非常直观:

一个词越稀有,搜索价值通常越高。

举一个例子。假设我们有 100 万篇网页,不同词的出现情况和搜索价值差别非常大:

出现在多少篇文章中搜索价值
“的”约 90 万基本无法帮助筛选文档
Transformer约 1 万区分能力较强
BM25几千搜索价值更高

所以 BM25 会给不同关键词不同的权重,粗略理解就是:

1
2
3
非常常见的词 → 权重低
比较少见的词 → 权重高
非常稀有的词 → 权重更高

这也是 BM25 比普通关键词计数效果好很多的重要原因。


四、❓ 问题三:长文章是不是天然更容易命中关键词?

还有一个很容易被忽略的问题。假设有两篇文章,都出现了 3 次 BM25:

文章字数“BM25” 出现次数
文章 A200 字3 次
文章 B2 万字3 次

哪一篇和 BM25 更相关?很可能是文章 A。因为 200 字里出现 3 次 BM25,说明整篇文章大概率就是围绕这个主题展开的;而一篇 2 万字的文章里出现 3 次 BM25,可能只是在某个角落顺带提了一下。如果只按词频统计,这两篇文章得分可能一样——更糟的是,长文章天然包含更多单词,反而更容易命中用户的 Query。

所以 BM25 还做了一件事: Document Length Normalization,文档长度归一化。也就是说,BM25 会考虑文档到底有多长,如果一篇文章特别长,其中关键词的出现次数就不会被给予过高的权重。这实际上是在修正长文档天然占便宜的问题。

顺便说一句:BM25 的前身是经典的 TF-IDF。TF-IDF 只做了“词频 × 稀有度”这两件事,BM25 又补上了词频饱和和长度归一化——所以它经常被称作“更成熟的 TF-IDF”。


五、📐 如果一定要看公式,BM25 大概长这样

到这里,我们已经可以不借助公式理解 BM25 了。如果你还想更进一步,看看它在数学上到底怎么表达,最常见的形式是这样的:

\[\text{Score} (D,Q)=\sum_{q_i\in Q}\text{IDF} (q_i)\cdot\frac{f (q_i,D)\, (k_1+1)}{f (q_i,D)+k_1\left (1-b+b\cdot\frac{|D|}{\text{avgdl}}\right)}\]

第一次看到可能会觉得复杂,但拆开来看,它其实就是前面几节内容的数学版:最外层的 $\sum$ 负责把 Query 里每个词的得分加起来,剩下的部分正好对应前几节讲的三个思想。

$\text{IDF} (q_i)$:这个词有多稀有。 对应第三节讲的 IDF——词越稀有,这一项越大,这个词的权重就越高。

$f (q_i,D)$:这个词在文档 D 里出现了多少次。 也就是词频。有意思的是,它同时出现在分子和分母里:分子让它得分更高,分母又把它往回拉,一推一拉之间,收益就逐渐饱和了——这正是第二节讲的词频饱和。

**$D/\text{avgdl}$:文档的相对长度。** 当前文档长度除以整个语料库的平均长度。文档越长,这一项越大,词频带来的加分就会被“稀释”——这正是第四节讲的文档长度归一化。

所以这个公式看着唬人,其实就是在说:每个词的得分 = 稀有度 × 打折后的词频 × 长度修正。


六、⚠️ BM25 最大的问题:它“不懂语义”

看到这里,BM25 好像已经非常聪明了,但它有一个非常明显的限制:

BM25 本质上还是关键词匹配。

比如用户搜索“如何提高大模型回答的准确性?”,而文档写的是“降低 LLM hallucination 的几种方法”。从人的角度看,两者显然高度相关,因为我们知道:大模型 ≈ LLM,回答不准确 ≈ hallucination。但 BM25 并不真正理解这层语义关系——如果 Query 和 Document 没有共享足够多的词,它的得分可能就不会很高。

这也是为什么后来 Embedding Search 会这么流行。Embedding 做的是另一件事:

把文本映射到一个向量空间中,根据语义距离寻找相似内容。

所以即使 Query 是“苹果手机”、Document 是“iPhone 16 使用体验”,两者没有一个完全相同的词,Embedding 模型仍然能判断出它们在语义上高度相关。


七、🤔 既然有了 Embedding,为什么 BM25 还没有消失?

这是一个非常有意思的问题。如果 Dense Retrieval 可以理解语义,那是不是直接用 Embedding 就好了?实际上并不是——BM25 到今天依然被大量使用。

原因在于: 关键词匹配和语义匹配,擅长解决的问题并不完全一样。 比如用户搜索下面这些内容:

场景例子
网络报错ERR_CONNECTION_RESET
订单号202608140031
产品版本GPT-5.2
函数名getUserById

这种 Query 最大的特点是什么?它们需要的是 精确匹配。Embedding 有时候反而会把一些“语义差不多”的内容找出来,但用户真正想找的,可能就是那个字符串本身。而 BM25 在这种场景下往往非常强。

所以在现实系统里,一个非常常见的方案是 Hybrid Search,也就是 BM25 + Vector Search:一个负责关键词匹配,一个负责语义匹配,最后把两边的结果融合起来。


八、🚀 这也是为什么 BM25 在 RAG 时代重新变得很重要

如果你最近在学习 RAG,就会发现很多系统并不是“用户问题 → Embedding → Vector Database → Top K”这么简单。真实生产环境里的检索管线(Retrieval Pipeline)往往要复杂得多,比如:

RAG 检索管线中的 BM25

BM25 在这里的角色很清楚—— 负责找出“字面上高度匹配”的内容;Vector Search 负责找出“语义上高度相关”的内容;Reranker 再进一步判断,到底哪些内容真正和用户的问题最相关。

所以 BM25 并不是一个已经被 Embedding 淘汰掉的老算法。恰恰相反,在今天很多搜索和 RAG 系统里,它依然是 Retrieval 层非常重要的一块。


九、💡 我现在怎么理解 BM25?

如果让我现在用一句话解释 BM25,我可能会这样说:

BM25 是一个基于关键词的相关性排序算法,它会综合考虑关键词出现频率、关键词稀有程度以及文档长度,从而判断 Query 和 Document 在字面层面有多相关。

再简单一点: BM25 = 更聪明的关键词匹配。

它不理解真正意义上的语义,但它非常擅长: 精确、稳定、高效地找到那些“确实包含你要找的东西”的文档。 而这恰恰也是现代搜索系统里非常重要的一种能力。

所以当我们今天讨论 RAG、Embedding、Vector Database 的时候,也许不应该把 BM25 看成一个“上一代技术”。更准确的理解是: BM25 和 Embedding,其实是在解决检索问题的两个不同侧面

 BM25Embedding
关注你写了什么词你想表达什么意思
擅长精确匹配、稳定高效语义相近、同义表达
短板不懂语义对精确字符串不敏感

而一个好的搜索系统,往往两者都需要。

本文由作者按照 CC BY 4.0 进行授权