Skip to content

Q37 · 混合检索的稠密 + 稀疏融合策略有哪些? ​

用户问:“耳机 E20 签收后 20 天,还能按普通退货走吗?”知识库的一段现行政策写着“E20 无理由退货须在签收后 7 天内且未拆封”。另一段使用更口语的“超过申请时限无法办理普通退货”,没有写 E20。只按字面找,能抓住型号,却可能漏掉换了一种说法的条款;只按语义找,能懂“还能退吗”与“申请时限”的关系,却可能把其他耳机型号或旧版政策排在前面。

混合检索常把两条路线同时跑起来:一条擅长精确词项,例如 E20;另一条擅长语义近似,例如“还能退吗”与“申请时限”。问题不只在“开两条搜索”,还在于两张结果表怎样合并、去重、排序。不同系统的原始分数不能随手相加;正确片段若一开始被某条路线截掉,后面的融合也救不回来。我们先把这些词讲清,再用一组数字亲手排一次。

术语与符号 ​

词或符号初学者可以这样理解本文对应物
RAG搜资料取得依据,再让模型根据依据答复查售后政策后回答 E20
稀疏检索资料以“哪些词出现了、各自有多重要”等大量大部分为零的特征表示,用词项匹配找资料用 E20、签收、退货去找条款
BM25常见的词项相关性打分方法,会考虑词出现情况和该词在全库有多常见型号 E20 很罕见,命中它通常有用
稠密检索用较短、几乎每个位置都有值的数字向量表示一句话的含义,按向量相近程度找资料“还能退吗”找“申请时限”
Embedding / 向量把文字变成一串数的表示;数的每个位置通常不能直接读成某个汉字政策句子和用户问题各有一个向量
召回 / 候选搜索初步取回一批可能相关的文档块两路分别取前 3 条政策片段
文档块 / chunk原文中可独立搜索的一段,需能回到来源E20 政策的完整一条规定
doc_id / chunk_id文档和块的稳定编号,用来合并相同结果P09 文档的第 2 个条款块 P09-2
top-k从一路初始搜索取排名前 k 的结果,k 是数量稀疏、稠密各取前 3 条
原始分数 / score某一路搜索给出的相关性数值,数值范围依算法而异BM25 的 9.0;向量搜索的 0.75
排名 / rank在某一路列表中的名次,从 1 开始P09-2 在关键词结果排第 1
融合把两路候选合成一张可供后续使用的结果表同一块只留一份,再决定最终次序
RRFReciprocal Rank Fusion,倒数排名融合:只用各路名次来算合并分两路都靠前的块得到两份贡献
cRRF 公式中的平滑常数,控制名次差距的影响;本文取 60与 top-k 里的 k 不是同一个数
归一化把不同搜索器的分数映射到可比较的范围把 BM25 9.0 和向量 0.75 分别换到 0~1
alpha分数加权时偏向稠密结果的比例,本文约定 0~10 只看稀疏;1 只看稠密
重排序融合产生候选后,再用更细的模型或规则重新排列审阅候选原文后选最适合回答的块

本文用 BM25 做稀疏路线的例子,便于理解精确字词匹配;“稀疏”并不只等于 BM25,一些系统也能使用学习得到的稀疏向量。稠密路线常使用向量相似度,但不同模型和搜索服务返回的分数定义可能不同。先比较同一路内部的顺序,再讨论如何跨路线融合。Azure AI Search 的混合搜索概述同样把词项检索和向量检索并行、再合并结果作为基本流程。

先固定一份可以算清的资料 ​

以下订单、条款和分数均为教学假设,不是现实商家政策或某个搜索产品的实测结果。设今天为 2026 年 9 月 26 日,E20 订单于 9 月 6 日签收,因此已过 20 天。现行政策 P09 自 9 月 1 日生效;旧政策 P06 已于 8 月 31 日失效。P09 第 2 条写:“E20 无理由退货须在签收后 7 天内且未拆封。”用户是否拆封未知,但 20 天已经超过了 7 天,因此至少不能按现行规则声称它仍在无理由退货期限内。

我们把一次查询里可能找到的块缩写如下:

代号这段资料是什么对本问题的作用
A = P09-2现行 P09 的 E20 七天条款必须找到的主要依据
B = P09-3现行 P09 对“普通退货申请时限”的解释能补充说法,但不能取代 A 的具体条件
C = P06-2已失效旧政策中的 E20 三十天条款文字相关,但不能用于当前结论
D = P09-8现行政策中另一款耳机的退货条款话题相近,型号不对

实际系统应在检索前就按权限、商品范围和政策生效期过滤,至少不让 C 混入当前可用证据。为了展示融合算法的行为,下面的算例故意暂时保留 C:这样才能看到“融合分高”也不等于“能用”。算完后还要把业务有效性检查补上。相关性排序与规则有效性是两个不同判断,Q32把权限、版本和引用放进了完整链路。

假设两条路线各自取前 3 个块,顺序是:

名次稀疏路线:BM25稠密路线:语义向量
1A:型号与条款都匹配B:说法与问题最接近
2D:含“耳机”“退货”A:意思也匹配
3B:有“申请时限”C:旧政策文字也谈能否退货

两路合并的候选是 A、B、C、D 四个块;A 和 B 虽在两路都出现,按稳定的 chunk_id 去重后仍各算一条。两路命中相同文档的不同条款时,不能仅因 doc_id 相同就糊成一段;这会丢掉哪一条具体支撑结论。图只表达“两路候选汇合再排序”,不表示桌面上第一张卡天然就是合法的现行证据。

关键词与语义两路检索结果汇入同一候选清单后排序

第一种:只合并候选,随后再判断 ​

最直观的做法是取两路结果的并集:稀疏前三条和稠密前三条全部进入候选池,按 chunk_id 去重。它的好处是减少“只搜一种方式导致正确片段完全缺席”的风险。此时尚未回答“哪条排第一”,可以后接业务过滤、重排序器或一个确定性的优先级规则。若只取两路交集,A、B 会留下,D 和 C 被去掉;噪声可能更少,但任何只被一路找到的正确证据也会被错杀。因此交集适合做很严格的候选条件,不宜默认把它当“更准”。

例如用户写出精确型号“E20”,而向量路线没把型号保留下来,A 可能只在稀疏列表里。若强制交集,A 会从最终候选消失。这也解释了为何融合开始前要先看每路的召回情况:两路都没找到 A,并集、RRF、加权分数都无法凭空制造 A。

一种产品可能用“稀疏命中型号才放行、稠密结果只负责扩展说法”,另一种产品可能先把两路取并集后交给重排序器。它们并非同一个公式的参数变化,而是候选准入方式不同。需要编号或法律条款精确命中的场景,可设置硬过滤;普通问答可以让两路提供更宽的候选,再做证据核对。

第二种:按名次做 RRF 融合 ​

BM25 的分数可能是 9、3、1;向量搜索可能是 0.91、0.83、0.77。把 9 与 0.91 直接相加,词项路线会仅因数值尺度大就支配结果。RRF 不看这些原始分数,只看每条资料在各路的名次。对某个块,若它在一路排第 rank 名,就加上 1 / (c + rank);没出现在该路,就不加。本文取 c=60,它是常见示例值,不是所有产品必须使用的常量,也与“每路取前几条”的 top-k 无关。Elasticsearch 的 RRF 文档给出了同样的按各路名次求和公式,默认 rank_constant=60,且说明每个子检索器参与融合时权重相等。

把上表代进去,保留五位小数即可:

块稀疏贡献稠密贡献RRF 合分
A第 1 名:1/61≈0.01639第 2 名:1/62≈0.01613≈0.03252
B第 3 名:1/63≈0.01587第 1 名:1/61≈0.01639≈0.03227
D第 2 名:1/62≈0.01613未出现:0≈0.01613
C未出现:0第 3 名:1/63≈0.01587≈0.01587

所以融合次序是 A → B → D → C。A 在两路都靠前,合分最高。B 的语义名次第一,也得到较高分。D 在关键词路线第二,却只拿到一路贡献;C 同理。RRF 的优点是无需为两种不同尺度的原始分数设计换算方法,因此适合先做一个可靠基线。Azure AI Search 在混合查询中使用 RRF,并区分 RRF 的常数与向量检索中表示近邻数量的 k。Azure AI Search 的 RRF 说明

但 RRF 也丢掉了名次之间的分差。假如 A 与稀疏第二名相差极大,B 与稠密第二名几乎打平,RRF 只知道“一、二名”,不知道“远远领先”与“几乎相同”。又如一条旧政策 C 在两路都排前面,它也能拿到高融合分;公式不会读取“已失效”这个业务条件。因而业务过滤要先做,必要时再用能读原文与元数据的重排序器。若产品提供加权 RRF,也要看清哪个权重乘在哪一路贡献上;基础 RRF 公式不自动体现业务偏好。Azure 的 RRF 文档介绍了向量查询权重,但这属于具体产品配置。

还有一个容易漏掉的参数是每路候选深度。如果稀疏只取前 1 条,B、D 就不在稀疏列表里,RRF 分数会改变;如果稠密只取前 1 条,A 失去来自稠密路线的贡献。融合器只能看各路提供给它的“窗口”,不能替搜索器回头遍历全库。Elasticsearch 把这个窗口称为 rank_window_size,窗口变大可能改善候选覆盖,也会增加成本。Elasticsearch RRF API

第三种:分数归一化后按权重相加 ​

当原始分数的差距本身有价值时,可以先把各路分数转到可比较范围,再做加权。常见示意是每条路线独立做 min-max 归一化:该路候选的最低分映射为 0、最高分映射为 1,中间值按比例换算。然后约定稀疏权重为 1 − alpha、稠密权重为 alpha:

text
归一化分数 = (该块原始分数 − 该路最低分) / (该路最高分 − 该路最低分)
融合分数 = (1 − alpha) × 稀疏归一化分数 + alpha × 稠密归一化分数

公式里的“该路”很关键:先在 BM25 那张表内部算最大最小,再在向量那张表内部算最大最小,不能把 BM25 的 9 和向量的 0.95 放到同一个最大最小值里。某块只在一路出现时,该路以外的贡献如何处理,必须由实现明确定义;下表假设未出现的贡献记为 0。若一路的最高分与最低分相同,分母会变成 0,也须设置稳定的处理规则。Elasticsearch 的 linear retriever就提供先归一化、再按权重线性组合的实现,并提醒不归一化可能使某一路因分数尺度而偏置结果。

仍看 A、B、D、C,另设这次两路的原始分数如下。数字是另一个教学样本,不要把它误认成上面 RRF 必须使用的输入:

块稀疏原始分稠密原始分
A9.00.85
B2.00.95
D1.0未命中
C未命中0.75

稀疏一路在 1.0~9.0 之间:A 变成 (9−1)/(9−1)=1,B 变成 (2−1)/(9−1)=0.125,D 变成 0。稠密一路在 0.75~0.95 之间:B 变成 1,A 变成 (0.85−0.75)/(0.95−0.75)=0.5,C 变成 0。若 alpha=0.5,两路各占一半,则 A 的合分是 0.5×1+0.5×0.5=0.75,B 是 0.5×0.125+0.5×1=0.5625,D 与 C 在这个很小且只取到几条候选的示例里变成 0。A 排第一。若把 alpha 改成 0.8,则 A 为 0.2×1+0.8×0.5=0.6,B 为 0.2×0.125+0.8×1=0.825,B 会反超。调权重确实能改变顺序,却不保证新的第一名更适合回答 E20 的具体条件。

这个极小样本也暴露了 min-max 的弱点:某一路尾项会被压成 0;一条异常高分会改变整张列表的映射;取回候选数量变化,最大最小值也可能变化。归一化让分数能按同一尺度参与计算,不等于它们拥有跨查询可比较的“概率意义”。Weaviate 的混合搜索文档区分按名次的融合与按相对分数的融合;其 alpha 可调关键词与向量路线的占比,但具体默认值、归一化细节以所用产品版本为准。Weaviate 混合搜索概念、查询接口

分数加权适合已经有标注样本、希望细调“精确编号”和“语义近似”重要性的场景。若真实问题几乎都含可靠的产品编号,可以尝试更偏稀疏;若用户常用与文档完全不同的说法,可以试更偏稠密。但 alpha 应通过同一批问答数据验证,不应因为“0.5 看上去公平”就固定。对混合有精确型号与口语描述的场景,也可按问题类型动态选权重,不过动态规则同样要评测,防止模型错误分类后选错路。

融合之外,还有三道必须独立处理的关口 ​

权限和版本。 本文故意把失效 C 放进算法表。若 C 在两路都排第一,RRF 或加权分都可能把它排在 A 前面。排序公式不认识“此政策已过期”,所以要按身份、商品、地区与生效期限制候选范围。权限过滤尤其不能等生成完再做:不该看的资料一旦送入模型,就已经突破了访问边界。版本规则也不能简单写成“只取最新”:历史订单可能适用当时版本,须按业务时点判断。Q32有完整展开。

粒度和去重。 一篇政策切成多个 chunk 后,可能同一文档的标题块与正文块都被召回。按 doc_id 全部去重,会丢掉具体条款;按 chunk_id 去重才知道两路命中的是不是同一段。反过来,若两块文字重复、只改了一个版本号,不去重会占据上下文。通常先保留文档 ID、版本和块 ID,按可追溯身份去重,再做相邻块合并或重排序。给模型的来源也要指向最终实际使用的块,而不是随便挑同文档另一页。

重排序和证据充足性。 融合输出的是候选顺序,仍可用能读取“问题 + 完整候选文本”的重排序器挑前几条;也要检查是否包含回答所需的全部条件。E20 的“20 天”与“7 天”能判断时间条件,但拆封状态不明,不能据此断言其他资格。重排序器若只看到截断的句子,可能漏掉“未拆封”;应让它拿到足以判断的完整条款。若正确块在任何初始列表都没有出现,再强的重排序器也无法修复漏召回。Q30按查询改写、召回与重排序的不同位置拆解了这件事。

怎样选策略并验证它真的有效 ​

先建立包含精确型号、同义表达、错别字、多轮指代、旧版条款、无权文档和根本无答案的问题集。每题标注必须找回的块和不可使用的块。固定同一知识库版本、同一权限身份与同一答案生成设置,依次跑四个基线:仅稀疏、仅稠密、RRF、归一化加权。再针对候选深度、c 和 alpha 做小范围调整。若一次同时改切块、Embedding 模型、权重与提示词,改善或退步都难以归因。

至少看三层结果:

层次具体问题可能暴露的错误
初始召回正确块是否出现在稀疏或稠密前 k 个?两路都漏掉 A,融合无能为力
融合排序A 在最终前几条吗?旧版与无权块是否被排除?RRF 算法没错,但版本过滤错了
最终回答模型是否按 P09 七天条款回答并正确引用?A 已找到,模型仍把“20 天”说成符合条件

可以记录 Recall@k(必需块是否进入前 k 个)、MRR(正确块越靠前越好)、最终答案正确与有据性,以及每路检索、融合、重排序的延迟和费用。单问“最后答对多少题”不足以定位问题;模型偶尔猜对,不代表检索链可靠。反过来,候选已经包含正确证据,答案错了,也不应盲目继续调 alpha。两路策略谁更好,必须由这些分层指标和业务错误成本决定。

落到 E20,合理的链路是:程序先确认订单与政策适用范围,关键词路线抓 E20 和“签收”,语义路线补充“还能退”与“申请时限”的表达;两路去重融合,再核对现行 P09 具体条款和来源,最终只回答有据可查的时间条件。用户若继续问质量问题、退款方式或其他地区规则,应另取对应证据,而不是把“混合检索成功”当成全部资格已查明。

面试时怎样回答 ​

可以这样说:“稀疏检索偏向精确词项,比如型号和编号;稠密检索用向量找意思相近的表达。混合检索先让两路各取一批候选,再按稳定块 ID 合并去重。简单做法是取并集后重排;常用的排名融合是 RRF,把每条资料在各路的 1/(常数+名次) 相加,避免直接混用 BM25 和向量分数;如果有标注数据要细调权重,也可以分别归一化分数,再用 alpha 做加权。两者各有边界:RRF 忽略分差,分数加权依赖归一化和权重;正确资料若没进入任何候选,融合无法补救。企业场景还要先过滤权限和有效版本,再验证最终答案有对应引用。选型时对比单路、RRF 和加权策略的召回、前列质量、答案正确率及成本。”

若面试官问“为什么不直接把 BM25 分数和向量相似度加起来?”,答:两者定义和数值范围不同,数值较大的一路会无故主导。问“两路都找到旧版政策,RRF 会识别它过期吗?”,答:不会,RRF只看名次,要先靠业务元数据判定可用版本。问“RRF 排第一就能给模型回答吗?”,答:还需检查原文是否完整覆盖问题、来源能否引用、权限和版本是否有效,必要时再重排或补查。

资料来源 ​

最后更新2026-09-26
难度P1
频率high
阅读22 min
主题rag / hybrid-search / bm25
觉得有帮助?把这个链接转给正在求职的朋友 · 用 Ctrl + K 全站搜索其它题