混合检索与重排序
关键词 + 向量、Top K 与 Reranker 如何提升命中率。
一句话理解:关键词检索擅长“字面精确”,向量检索擅长“意思相近”,混合检索把两者的候选合在一起;重排序再用更精细的模型从候选中挑出真正最相关的几段。
用户问:“工单 TK-2291 里这笔企业版订单已经开了发票,退款要怎么走?”
只用向量检索,可能找回一堆关于“发票”“退款”的通用片段,却漏掉专门提到“TK-2291”这张工单的历史处理记录;只用关键词检索,能找到包含“开发票”和“退款”的片段,却漏掉写成“已开票订单需先完成发票作废”的相关条款。
生产级的 RAG 很少只用一种检索方式。这一课讲“先广召回、再精排序”的两阶段检索结构,以及其中每个参数对产品效果意味着什么。
两种检索与混合检索
关键词检索与向量检索
| 关键词检索 | 向量检索 | |
|---|---|---|
| 原理(直觉) | 看查询中的词在片段里出现得多不多、这些词稀不稀有 | 看查询和片段在语义空间里离得近不近 |
| 典型算法 | BM25 等 | Embedding + 近似最近邻 |
| 擅长 | 订单号、错误码、条款编号、专有名词、内部缩写 | 同义表达、口语提问、换一种说法 |
| 不擅长 | 同义词、换个说法就找不到 | 精确字符串、否定、数字、版本差异 |
| 知识库例子 | “E-4031” 精确命中错误码说明 | “为什么钱没退回来” 找到“退款失败原因” |
BM25 的直觉可以简单理解为:一个词在这个片段里出现得越多、在整个知识库里越少见,这个片段对该词的得分就越高。“退款”到处都有,权重低;“E-4031”只在一处出现,权重高。
两者的强弱恰好互补,这就是混合检索的出发点。
混合检索:把两份名单合并
整体结构是“先广召回、再精排序”:
两份名单的分数口径不同,BM25 分数和余弦相似度不能直接相加。常见的融合方法是 倒数排名融合(RRF):不看原始分数,只看每个片段在各自名单里的排名。
片段得分 = Σ 1 / (k + 该片段在某份名单中的排名)
(k 是一个常数,用于平滑,常见取值为 60)
例:片段 X 在关键词名单排第 1、在向量名单排第 5
得分 = 1/(60+1) + 1/(60+5) ≈ 0.0164 + 0.0154 = 0.0318
片段 Y 只在向量名单排第 1、关键词名单中没有
得分 = 1/(60+1) ≈ 0.0164
直觉是:在两种检索里都靠前的片段,更可能真的相关。 实际系统中也可以给两路结果设置不同权重,比如包含编号的查询更偏向关键词检索。这些都需要用评测数据来调,而不是凭感觉定。
重排序:从“找得全”到“排得准”
第一阶段检索要在几万甚至几百万个片段中快速找候选,必须用计算便宜的方法。它能保证“正确答案大概率在前 50 里”,但不能保证“正确答案排在第 1”。
重排序模型(Reranker)做的是第二阶段的精细判断:把 问题和每个候选片段一起 交给模型,直接打一个相关度分数。
因为要逐对阅读,重排序比向量检索慢得多、贵得多,所以只用于第一阶段筛出的几十到上百个候选。
Anthropic 在 Contextual Retrieval 的实验中,在上下文化片段、混合检索的基础上再加入重排序,检索前 20 个片段的失败率合计降低了 67%(仅用上下文化向量检索时为 35%)。具体数字取决于数据,但“重排序有明显增益”是 RAG 实践中比较一致的结论。
重排序模型可以用专门的 Reranker 服务,也可以用一个较小的大模型来打分。前者通常更快更便宜,后者更灵活,能加入业务规则(例如“同等相关时,优先生效中的最新版本”)。
Top K 与检索前的准备
Top K:每个数字都是取舍
一条检索链路里有好几个“K”,每一个都对应一个产品取舍:
| 参数 | 含义 | 调大 | 调小 |
|---|---|---|---|
| 第一阶段 K | 每路检索取多少候选 | 召回更全,重排序成本上升 | 更快,但正确片段可能根本没进入候选 |
| 重排序后 N | 最终放进上下文的片段数 | 信息更全,干扰项增多、成本上升 | 更聚焦,但多文档问题可能缺信息 |
| 相关度门槛 | 低于多少分的片段丢弃 | 更严格,更多“找不到” | 更宽松,更多噪音 |
几个经验:
- 第一阶段宁可多取,第二阶段宁可少放。 召回阶段漏掉的,后面无法弥补;上下文里多放的,会引发 上下文腐化。
- N 应该随问题类型变化。 “E-4031 是什么意思”一段就够;“对比三个版本的退款时限”可能需要六到八段。可以由查询分类决定,或者交给 Agent 自己判断是否再检索(参见 Agentic RAG 与联网搜索)。
- 门槛比 N 更重要。 如果最相关的片段得分也很低,说明知识库里可能没有答案,应该让 Agent 明确说“没找到依据”,而不是硬凑三段给模型。
检索之前:查询改写与过滤
混合检索和重排序处理的是“怎么找”,但“拿什么去找”同样重要:
- 补全指代:多轮对话中用户问“那个人版呢?”,要改写成“个人版订单开具发票后如何退款”。
- 拆分复合问题:“开票后的订单怎么退款,时限是多久?”拆成两次检索。
- 识别精确实体:从问题中抽出
TK-2291、E-4031这类编号,交给关键词检索,或转为元数据过滤条件。 - 术语映射:把“挂起”“二退”这类内部说法映射为文档中的正式术语。
查询改写通常由一次轻量的模型调用完成,要注意把改写结果记录进日志,出问题时才能判断是“改写改错了”还是“检索没找到”。
常见误区
- “向量检索已经很智能了,不需要关键词检索。” 业务问题里充满编号、代码和专有名词,这些恰恰是向量检索的弱项。
- “Top K 越大越保险。” 第一阶段可以大,进入上下文的数量要克制。多放的片段是干扰项,不是保险。
- “加了重排序就不用管切块和元数据了。” 重排序只能在候选里排序,候选里没有正确片段,排得再好也没用。
产品经理检查清单
- 用户问题中包含编号、错误码、专有名词的比例有多高?是否启用了关键词检索?
- 两路检索如何融合?权重是否基于评测数据确定?
- 是否有重排序?增加的延迟与成本是否可接受?
- 第一阶段 K、最终 N、相关度门槛分别是多少?依据是什么?
- 检索前是否有查询改写?改写结果是否记录在日志中?
- 最相关片段得分过低时,Agent 的回复是什么?
练习
用企业知识库的 10 个真实或模拟问题做一次手工对比:
- 问题中至少 3 个包含编号或错误码,3 个是口语化提问,其余是普通问题。
- 对每个问题,分别写出你预期关键词检索和向量检索各自能找到的片段(可以用知识库自带的搜索功能模拟关键词检索)。
- 标出哪些问题只有一种方式能找到正确片段。
- 为这 10 个问题设计查询改写,写出改写后的查询以及应附加的元数据过滤条件。
延伸阅读
- Anthropic:Introducing Contextual Retrieval(混合检索与重排序的组合实验)
- Claude 文档:Embeddings(包含重排序模型的介绍)
下一步
找到了正确的片段,还要让用户相信答案。下一课「引用与可追溯」讲如何让每个结论都能指回原文。