Keyword-Search
1922 字约 6 分钟
domain/aiai/rag
2026-07-24
Keyword Search(关键词检索)是 RAG 系统中与向量检索互补的基础检索方式。在 Hybrid Search 架构中,BM25 承担精确字面匹配的角色,是向量检索天然不具备的能力。
一句话解释
通过将用户查询分解为关键词,在文档中匹配这些关键词的精确出现,利用词频和逆文档频率计算相关性得分,返回最匹配的文档。
核心问题
为什么向量检索不够,还需要关键词检索?
- 精确匹配场景:错误码
ERR_5021、SKUX-200Pro、条款号第 1043 条——向量模型从未见过或无法区分这些精确符号 - 语义混淆:向量检索可能被语义相近的词带偏,到达不了"精确相等"的匹配
- 可解释性:BM25 能直接看到哪个词得分,向量检索是黑盒
基础概念
BM25(Best Matching 25):TF-IDF 的工业级升级版,通过词频饱和惩罚和文档长度归一化解决 TF-IDF 的核心缺陷。
TF-IDF 缺陷:词频线性增长无上限,长文档天然占优。
BM25 改进:非线性饱和(参数 k1)+ 动态长度归一化(参数 b)。
RRF(Reciprocal Rank Fusion):将 BM25 和向量检索的排名融合的算法,无需归一化,即插即用。
BM25 算法原理
核心公式
score(D,Q)=w∈Q∑IDF(w)×tf(w,D)+k1×(1−b+b×avgdl∣D∣)tf(w,D)×(k1+1)
其中:
- IDF(w):逆文档频率,词越罕见得分越高
- tf(w, D):词 w 在文档 D 中的词频
- |D|:文档长度(词数),avgdl:所有文档平均长度
- k1:词频饱和度参数(默认 1.2~1.5)
- b:文档长度归一化参数(默认 0.75)
公式直觉
当 tf 趋近无穷大时,该词对得分的贡献趋近于 (k1 + 1) 的饱和值,而非无限增长——这就是"词频收益递减"效应。一个词出现 2 次 vs 出现 10 次,在 BM25 中得分差距远小于 TF-IDF。
IDF 计算(BM25 变体)
IDF(w)=ln(df(w)+0.5N−df(w)+0.5+1)
N 是文档总数,df(w) 是包含词 w 的文档数。+0.5 平滑处理防止除零。
BM25 参数调优
k1 — 词频饱和度
| k1 值 | 效果 | 适用场景 |
|---|---|---|
| 0 | 退化为二值模型(出现/不出现) | 极短文档,一词出现就够 |
| 0.5~1.0 | 词频快速饱和,出现 2 次和 10 次差异不大 | 短文档且主题集中(新闻、FAQ) |
| 1.2~1.5(默认) | 适中饱和,绝大多数场景表现良好 | 通用场景 |
| 2.0~3.0 | 词频影响更接近线性 | 长文档且主题多样(小说、综合类书籍) |
b — 文档长度归一化
| b 值 | 效果 | 适用场景 |
|---|---|---|
| 0 | 完全忽略文档长度 | 所有文档长度不重要 |
| 0.3~0.5 | 轻度长度惩罚 | 高度专业化文档(工程规范、专利、学术论文) |
| 0.75(默认) | 适中长度惩罚,通用场景 | 大多数场景 |
| 0.7~0.9 | 较重长度惩罚 | 多主题混合文档(新闻、用户评论) |
调参优先级
Elastic 官方建议:优先优化查询语句(bool query、phrase match、boost)、添加同义词和模糊匹配,最后才考虑调 b 和 k1。默认值在绝大多数场景足够好。
常见问题诊断
症状:长文档总是搜不出来,排在前面的都是短文本。
诊断:系统对长文档的"长度惩罚"过于严厉。
解决:调小参数 b。极端情况下 b=0 会完全无视文档长度差异。
关键词检索 vs 向量检索
| 维度 | BM25(Sparse) | 向量检索(Dense) |
|---|---|---|
| 匹配机制 | 精确关键词匹配 | 语义相似度匹配 |
| 擅长 | 错误码、SKU、专有名词、条款号、代码 | 同义表达、意图匹配、概念相关 |
| 不擅长 | 同义改写、跨语言语义 | 精确符号、罕见名词 |
| 向量形态 | 50000+ 维,>95% 为 0 | 256~1536 维,全部非零 |
| 推理延迟 | 毫秒级 | 10~100ms |
| 可解释性 | 强(能看到哪个词得分) | 弱(黑盒) |
一句话选型原则:"只要关键词就能搞定,千万别上神经网络。只要用户会'人话'提问,就用 Dense。"
关键词检索不可替代的场景
| 场景 | 示例 | 为什么 BM25 不可替代 |
|---|---|---|
| 错误码检索 | ERR_5021、NullPointerException | 向量模型从未见过这些词,embedding 四不像 |
| 产品 SKU/型号 | X-200Pro、RTX-4090 | 向量模型容易将不同型号混淆 |
| 法律条款编号 | 《民法典》第 1043 条、GDPR Article 17 | 向量检索完全无法区分条款号差异 |
| 代码搜索 | def authenticate_user、import torch.nn | 精确 API 名称和函数签名必须字面匹配 |
| 内部项目代号 | "雷达计划"、"凤凰项目" | 预训练语料中不存在,向量模型无法理解 |
| 新闻版权去重 | 用 5 个核心实体词搜索疑似抄袭 | 10ms 内返回,准确率 98%[1] |
Hybrid Search 融合策略
标准架构(2026 年业界共识)
[用户查询]
|
├── 向量检索 (Dense, top-K)
├── BM25 检索 (Sparse, top-K)
|
└── RRF 融合 (k=60)
|
└── Cross-Encoder Rerank (精排)
|
└── 最终结果 Top-N混合检索负责"召得全",Rerank 负责"排得准"。
RRF 融合公式
RRF_score(d)=r∈R∑k+rankr(d)1
- k = 60(论文中经验常数,削弱头部名次碾压效应)
- 完全不碰原始分数,只用名次
- 被两路同时命中的文档分数自动叠加,自然被顶到前面
其他融合策略
| 策略 | 原理 | 适用场景 |
|---|---|---|
| 线性组合 | 两路分数归一化后加权求和 | 对召回特性有明确预期,需精细控制 |
| 级联过滤 | BM25 快速粗筛 → 向量检索精排 | 超大规模语料库,降低向量检索计算量 |
| 动态权重 | 根据查询类型自动调整权重 | 错误码查询→BM25 权重高,自然语言→向量权重高 |
中文分词(关键工程实践)
中文必须先用分词器分词再喂给 BM25,直接按字符 BM25 效果很差:
- 使用 Jieba 等分词器
- 挂载领域自定义词典,确保"图神经网络""并发接入"等专业术语不被切碎
- Chunking(宏观切块)和 Tokenization(微观分词)是两个独立步骤
常见误区
- 只上向量检索不上 BM25:遇到错误码、专有名词查询时必然召回失败
- BM25 直接按字符处理中文:不经过分词器,效果极差
- 盲目上混合检索:如果场景就是日常语义问答,纯向量+rerank 可能就够了
- 两路分数直接相加:BM25 得分和向量余弦相似度量纲完全不同,必须用 RRF 或归一化
- 忽视 IDF 更新:新增大量文档后 IDF 值过时,应在空闲时批量重建
进阶方向
- Hybrid Search:BM25 + 向量检索 + RRF 融合 + Rerank 的完整流水线
- SPLADE:学习型稀疏嵌入,BM25 的神经网络升级版
- Multi-Vector(ColBERT 风格):为每个 Token 生成独立向量,实现词-词细粒度匹配
- Query Rewrite查询改写:改写后同时执行 BM25 和向量检索,效果更佳
关联笔记
- Hybrid Search
- Rerank重排序
- Query Rewrite查询改写
- RAG基础
- 向量与Embedding
- 文档切分策略
来源:BM25 基准测试(新闻去重场景),具体数值取决于语料规模与实体词选择策略 ↩︎