在 RAG 系统中,单一的检索方式经常出现盲区:纯向量检索擅长捕捉语义相近的内容,但可能在精确关键词匹配上力不从心;传统的 BM25 等关键词检索对术语、缩写、编号非常敏锐,却无法理解同义改写和上下文语义。混合检索正是为了复用二者的优势,将稀疏检索(如 BM25)和密集检索(向量相似度)的结果进行融合,最终给出一个综合排序。
然而,混合之后最常见的问题就是:两种检索的打分不在同一量级,直接合并往往效果很差。 向量相似度通常是 0 到 1 之间的余弦值,而 BM25 得分受文档长度、词频影响,数值范围可能从 0 到几百。如果不做归一化和权重调整,其中一种检索方式很容易“淹没”另一种,使混合检索名存实亡。
1. 归一化:让分数先站到同一条起跑线上
在调权重之前,必须先解决分数尺度不同的问题。最实用的归一化方法是 Min-Max 归一化,对每个检索结果列表分别处理:
对于一组原始得分 \( s_1, s_2, ..., s_n \),归一化后的得分为:
\[
s'_i = \frac{s_i - s_{min}}{s_{max} - s_{min}}
\]
这样处理后,所有分数都被压缩到 \([0, 1]\) 区间,向量检索和 BM25 的得分在数值上具备了直接比较的基础。在实践中,为避免少量极端值影响,也可以先截断取前 k 个结果再归一化,或使用基于排名的倒数归一化(RRF,Reciprocal Rank Fusion)作为替代方案,RRF 不依赖具体分数,只关心排名:
\[
\text{RRFscore}(d) = \sum_{r \in R} \frac{1}{k + r(d)}
\]
其中 \( r(d) \) 是文档 \( d \) 在某个检索列表中的排名,\( k \) 是常数(通常取 60)。RRF 天然对分数尺度不敏感,是快速融合的好选择。不过当需要精细调节语义匹配和精确匹配的侧重时,加权求和的归一化方法更灵活。
2. 权重调优:找到最佳的 \(\alpha\)
归一化之后,混合检索的最终得分可以表示为:
\[
\text{score}_{\text{hybrid}} = \alpha \cdot \text{score}_{\text{dense}} + (1 - \alpha) \cdot \text{score}_{\text{sparse}}
\]
其中 \(\alpha\) 是密集检索(语义)的权重,取值 0 到 1。\(\alpha = 1\) 退化为纯向量检索,\(\alpha = 0\) 则为纯关键词检索。
如何确定这个 \(\alpha\)? 理论上没有完美值,它高度依赖你的数据特点和问题类型。一个务实的方法是:在准备好的测试问题集上做网格搜索。
操作步骤:
- 准备评估集:收集至少 50–100 个真实的用户问题,并为每个问题人工标注出期望召回的文档片段(或者至少标注应该出现的关键知识点所在的文档 ID)。如果没有标注资源,也可以用历史高满意度问答日志来近似。
- 设定评价指标:常用的是召回率(Recall@K),例如看前 5 或前 10 个检索结果中是否包含正确答案。也可以结合答案端的端到端准确率。
- 网格搜索:以 0.1 或 0.05 为步长遍历 \(\alpha\) 从 0 到 1,分别执行检索并计算指标。
- 选择最佳权重:找出使评估指标最高的 \(\alpha\),记录下来作为默认配置。
真实经验:在很多企业文档场景(如内部知识库、技术手册)中,关键词匹配需求较重(像型号代码、错误码等),\(\alpha\) 常在 0.3–0.5 之间,即更侧向稀疏检索。而在 FAQ 或客服对话等语料口语化、同义表达多的场景,密集检索权重可能需要调到 0.6–0.8。没有一刀切的数字,必须根据实际数据定。
3. 动态权重:更进一步(可选)
如果业务场景下问题类型差异明显,固定权重可能不够精细。可以引入一个轻量级的分类器或规则,根据查询特征动态调整 \(\alpha\)。例如:
- 当查询包含明确的关键词、编号、日期等,提高稀疏检索权重;
- 当查询是完整的自然语言问句、较长句子,提高密集检索权重。
这种方法可以在固定权重已经调优的基础上再获得 2%–5% 的召回提升,但会增加少许系统复杂度。建议先用固定权重跑出可接受的基线,再视需要迭代。
4. 上线后的验证与再调优
权重调优不是一劳永逸的。当知识库发生重大变化(如大量新增文档、切块策略调整),原有的 \(\alpha\) 可能不再最优。可以每隔一段时间,用新的真实查询日志抽样标注,重新跑一次网格搜索来校准。
混合检索权重调优的目标,始终是让最终回答的准确率、召回率满足业务要求。这个过程技术含量不高,但细致和数据驱动,每一次有效调整都直接作用于终端用户的体验提升。