你以为向量检索万能,其实漏了一半
很多人聊RAG,上来就是Embedding、向量数据库、语义匹配,好像关键词检索已经是上个时代的产物。
但真实情况是:你问大模型"2024年第三季度营收",向量检索可能给你召回一堆聊"财务分析方法论"的文档,而BM25精准命中含"2024"“第三季度”"营收"这三个词的段落。
这不是向量检索不行,是它天然不擅长精确匹配。BM25在这个场景里,至今无可替代。 Elasticsearch、Lucene、OpenSearch这些搜索引擎的底层排序算法,用的都是它。RAG框架里做混合检索(hybrid search),BM25负责稀疏检索那一半。
今天把BM25从分词到打分的完整链路拆清楚,不讲废话。
第一步:分词——检索的起点
BM25的第一步不是算分,是把文本切成词。
英文分词简单,按空格切就行。"machine learning"切成 machine、learning,再做个词干还原(stemming),learning 变回 learn,就算完事。
中文麻烦得多。“自然语言处理"这个词,可以切成"自然/语言/处理”,也可以切成"自然语言/处理",甚至不切当一整个词。切法不同,检索结果天差地别。
# jieba 分词示例import jiebatext = "自然语言处理是人工智能的重要方向"# 精确模式words = jieba.lcut(text)# 输出: ['自然语言', '处理', '是', '人工智能', '的', '重要', '方向']# 搜索引擎模式(更细粒度)words_search = jieba.lcut_for_search(text)# 输出: ['自然', '语言', '自然语言', '处理', '是', '人工', '智能', '人工智能', '的', '重要', '方向']搜索引擎模式会额外切出子词,保证"自然语言"作为整体词被检索到的同时,单独搜"语言"也能命中。RAG场景里,文档分词和查询分词必须用同一套分词器,否则词对不上,等于白搭。
分词之后,停用词(的、是、在、了)通常会被过滤掉。这些词在每篇文档里都出现,没有区分度,留着只会增加噪音。
第二步:倒排索引——为什么能秒回
分完词,下一步是建倒排索引。
正排索引是从文档找词:文档A包含[苹果, 手机, 评测]。倒排索引反过来,从词找文档:苹果→[文档A, 文档C, 文档F],手机→[文档A, 文档B]。
搜"苹果 手机"的时候,系统不需要遍历所有文档,直接在倒排索引里查这两个词,取交集,瞬间拿到候选文档列表。这就是搜索引擎能在毫秒级返回结果的原因。
倒排索引结构示意:词项 → 文档列表(含词频)─────────────────────────────────苹果 → [文档A:2, 文档C:1, 文档F:3]手机 → [文档A:1, 文档B:2]评测 → [文档A:1, 文档D:1]自然语言处理 → [文档B:1, 文档E:2] ``` 有了候选文档列表,接下来就是核心问题:怎么给每篇候选文档打分?BM25登场。 --- BM25的打分公式:三个变量决定一切 ------------------ BM25的全称是 Best Matching 25,由 Robertson 等人在1994年提出,至今仍是信息检索领域的标准排序算法。 核心思路:一个词在当前文档出现越多,分数越高;但这个词在所有文档里都出现的话,重要性就低。再加一个文档长度归一化——短文档里出现的词,比长文档里出现的词更值钱。 公式长这样: ```plaintext score(q, d) = Σ IDF(qi) × TF_term(qi, d)其中:TF_term = f(qi, d) × (k1 + 1) / (f(qi, d) + k1 × (1 - b + b × |d| / avgdl))IDF(qi) = log((N - n(qi) + 0.5) / (n(qi) + 0.5) + 1)看着复杂,拆开就三个部分:
「词频饱和」——出现次数不是越多越好
f(qi, d) 是词 qi 在文档 d 里出现的次数。朴素想法是出现越多越相关,但BM25加了个饱和机制:词频增长到一定程度后,分数增益迅速衰减。一篇文档里"苹果"出现3次确实比出现1次更相关,但出现30次不一定比3次相关30倍。
k1 控制饱和速度,默认值1.2。k1越大,饱和越慢,词频影响越大;k1越小,饱和越快,词频很快就不怎么加分了。
「IDF逆文档频率」——烂大街的词不值钱
N 是文档总数,n(qi) 是包含词 qi 的文档数。一个词在所有文档里都出现,n(qi) ≈ N,IDF趋近于0,这个词几乎不贡献分数。“的”"是"这种停用词的IDF就是0,被自动过滤。
反过来,一个词只在少数文档里出现,IDF很高,命中时分数暴涨。这就是为什么专业术语比通用词更能精准定位文档。
「文档长度归一化」——短文档里命中更值钱
|d| 是当前文档长度,avgdl 是所有文档的平均长度。b 控制归一化强度,默认0.75。
直觉上理解:一篇10个词的文档里命中了查询词,说明这篇文档跟查询高度相关;一篇10000个词的文档里命中同样的查询词,可能只是顺带提了一嘴。BM25通过这个机制惩罚长文档,让短而精的文档排在前面。
参数怎么调
k1 和 b 是BM25仅有的两个可调参数,理解了它们的含义,调参就有方向了。
k1(默认1.2):控制词频饱和速度。文档内容差异大、词频分布不均匀时,适当调大(1.5-2.0);文档长度均匀、内容相似时,调小(0.5~1.0)。大多数场景默认值就够用。
b(默认0.75):控制文档长度归一化强度。文档长度差异大时保持0.75;如果文档长度都差不多,b可以调小甚至设为0,不做事长归一化。如果发现长文档总是排在前面,适当调大b。
# 用 rank_bm25 库快速实现from rank_bm25 import BM25Okapi# 文档库(已分词)corpus = [ ["苹果", "手机", "评测", "续航"], ["华为", "手机", "拍照", "评测"], ["苹果", "电脑", "性能", "评测"], ["小米", "手机", "性价比", "评测"]]bm25 = BM25Okapi(corpus)# 查询(同样要分词)query = ["苹果", "手机", "评测"]scores = bm25.get_scores(query)# 输出: [2.14, 0.0, 1.07, 0.0]# 文档0得分最高,因为同时命中"苹果""手机""评测"三个词# 获取最相关的文档top_k = bm25.get_top_n(query, corpus, n=1)# 输出: [['苹果', '手机', '评测', '续航']]文档0得分最高不难理解:三个查询词全部命中,且文档长度短,归一化后得分更高。文档2只命中了"苹果"和"评测",少了"手机",IDF贡献少了一块,分数自然低。
在RAG里怎么用BM25
单用BM25做RAG检索,能解决精确匹配问题,但搞不定语义相似。用户问"营收增长",文档里写的是"收入提升",BM25对不上。
所以现代RAG系统普遍采用混合检索(hybrid retrieval):
# 混合检索示意defhybrid_search(query,top_k=5):# 稀疏检索:BM25 bm25_scores=bm25.get_scores(tokenize(query))# 稠密检索:向量相似度 query_vec=embedding_model.encode(query)vec_scores=cosine_similarity(query_vec,doc_vectors)# 分数融合(简单加权或RRF) final_scores=0.5*normalize(bm25_scores)+0.5*normalize(vec_scores)returntop_k_indices(final_scores)BM25负责捞精确匹配,向量检索负责捞语义相近,两路结果融合后送进大模型生成回答。目前LangChain、LlamaIndex、Dify这些主流RAG框架都内置了混合检索支持。
权重分配没有标准答案。查询偏向精确匹配(代码搜索、专有名词、数字日期)时,BM25权重调高;查询偏向语义理解(开放问答、概念解释)时,向量权重调高。实际项目里建议用RRF(Reciprocal Rank Fusion)做融合,比简单加权更稳。
别让检索环节拖后腿
RAG系统效果不好,90%的问题出在检索环节,不在大模型。召回不到正确的文档,再强的模型也只能一本正经地胡说。
BM25的价值在于:它简单、快、可解释、不需要GPU。向量检索再火,精确匹配这件事,BM25做得比谁都好。两者搭配,才是RAG检索的正确姿势。
搞懂分词、倒排索引、TF-IDF打分这三件事,BM25的核心就吃透了。剩下的参数调优,拿真实数据跑几轮对比,比看十篇博客都管用。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~