什么是多路召回?具体怎么做
1️⃣ 考察意图
面试官想考察你是否真正理解“多路召回”不是简单堆砌检索器,而是工程取舍的艺术。这是典型的系统设计 + 工程取舍题,刁钻点在于:多数人只会背“向量+BM25+RRF”的套路,但说不出为什么需要多路、各路召回数怎么定、融合权重如何调优、以及如何避免“召回越多噪声越大”的陷阱。答好了能展示你对检索系统整条链路的掌控力,包括召回率与精度的平衡、延迟与效果的trade-off,以及实际落地中的debug经验。
2️⃣ 标准答
多路召回是指在一个检索系统中,同时运行多种异构的检索策略(如向量检索、关键词检索、知识图谱检索),各自独立召回 top-k 候选,再通过融合策略合并去重,最终输出一个统一的候选集。核心目标是互补不同检索方法的盲区,提升召回率和鲁棒性。
具体做法分三步:设计检索路数、确定每路召回数、融合策略。
第一步:设计检索路数常见组合包括:
- 向量检索(Dense Retrieval):用 embedding 模型(如 BGE-M3、E5-mistral)将 query 和文档编码为向量,通过 HNSW 或 IVFPQ 索引做近似最近邻搜索。优势是语义匹配强,但依赖训练数据分布,对长尾实体名、缩写(如“GPT” vs “Generative Pre-trained Transformer”)容易失效。
- 关键词检索(Sparse Retrieval):用 BM25(默认 k1=1.5, b=0.75)或 SPLADE 做词频匹配。优势是精确匹配实体和术语,对低频词敏感,但无法处理同义词(如“汽车” vs “车辆”)。
- 知识图谱检索(Graph Retrieval):通过 SPARQL 或 Cypher 查询知识库中的结构化关系(如“张艺谋导演的电影”)。优势是能回答多跳推理问题,但构建和维护成本高。
- 混合检索(Hybrid):如 ColBERT 的 late interaction 或 ColBERT-v2 的 token-level 匹配,兼顾稀疏和稠密特性,但计算开销大。
第二步:确定每路召回数这是工程取舍的关键。假设总候选集上限为 N=100,各路召回数不能平均分配。经验法则:
- 向量检索:分配 50-60 个,因为语义匹配是主流。
- BM25:分配 30-40 个,作为精确匹配的兜底。
- 知识图谱:分配 10-20 个,仅当 query 含明确实体关系时启用。
- 坑:如果每路都召回 top-100,合并后可能超过 200 条,导致下游 reranker 延迟飙升。解法是动态调整:根据 query 类型(如实体查询 vs 开放域问题)动态分配各路召回数,例如实体查询时加大 BM25 权重。
第三步:融合策略常见三种:
- RRF(Reciprocal Rank Fusion):对每路结果按排名倒数加权,公式
score = Σ 1/(k + rank),k 通常取 60。优势是无参数、鲁棒,但无法处理各路召回数不一致的情况。 - 加权求和:对每路结果赋予固定权重(如向量 0.6、BM25 0.3、图谱 0.1),然后按加权分数排序。优势是可调优,但权重需要大量标注数据或线上 A/B 测试。
- 学习排序(Learning to Rank):用 LambdaMART 或 ListNet 训练一个排序模型,输入各路特征(如向量相似度、BM25 分数、实体匹配度)。优势是效果上限高,但需要标注数据,且线上推理成本高。
实际落地的坑 + 解法:
- 坑:各路结果重复度高(如向量和 BM25 都召回同一篇文档),导致融合后有效候选数不足。解法:在融合前做去重,按文档 ID 去重后保留最高分;或者用最大边际相关性(MMR) 做多样性重排。
- 坑:BM25 分数和向量相似度尺度不一致,直接加权求和会偏向分数高的路。解法:对每路分数做归一化(如 min-max 归一化或 z-score),或者用 RRF 这种基于排名的融合。
- 坑:知识图谱检索延迟高(可能 200ms+),拖累整体系统。解法:将知识图谱检索改为异步并行,或者只在 query 包含明确实体时触发(用 NER 模型预判)。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从三个层面回答:第一,多路召回的定义和设计思路,核心是互补不同检索方法的盲区,比如向量检索做语义匹配、BM25 做精确匹配、知识图谱做结构化查询。第二,具体做法包括确定每路召回数和融合策略,常用 RRF 或加权求和,注意分数归一化和去重。第三,实际落地中的坑,比如各路召回数动态调整、延迟优化、以及重复候选的处理。总结一句:多路召回不是堆砌检索器,而是工程取舍的艺术,核心是平衡召回率、精度和延迟。”
4️⃣ 高频追问 & 应对
追问 1:如果多路召回后候选集太大,下游 reranker 延迟高怎么办?
应对策略:首先,限制总候选集上限,比如 N=100,然后动态调整每路召回数。其次,用级联架构:先跑低延迟的 BM25 快速过滤到 top-200,再用向量检索精排到 top-50,最后用 reranker(如 Cohere Rerank 或 BGE-Reranker)重排。第三,对 reranker 做模型量化(如 INT8)或知识蒸馏,减少推理时间。如果延迟要求极严(<50ms),可以放弃 reranker,直接用 RRF 融合结果。
追问 2:怎么评估多路召回的效果?用哪些指标?
应对策略:核心指标是 Recall@K 和 MRR。Recall@K 看前 K 个候选是否覆盖正确答案,MRR 看第一个正确答案的排名。具体做法:在自建数据集上,对比单路(如仅向量)和多路的 Recall@20,通常多路能提升 5-15%。另外,要关注多样性指标(如 intralist diversity),避免多路召回后候选集同质化。线上可以用 A/B 测试,看最终用户点击率或任务完成率。
追问 3:如果 BM25 和向量检索结果冲突(比如 BM25 召回高分但向量低分),怎么处理?
应对策略:这取决于 query 类型。如果是实体查询(如“iPhone 15 价格”),BM25 的精确匹配更可靠,应该提高 BM25 权重。如果是开放域问题(如“如何提高睡眠质量”),向量检索的语义匹配更重要。工程上,可以用一个轻量级分类器(如 fastText)判断 query 类型,然后动态调整融合权重。或者用 RRF,它基于排名而非分数,天然鲁棒。如果冲突严重,可以引入置信度阈值:当某路结果分数低于阈值时,直接丢弃。
5️⃣ 避坑 · 常见错误答法
- ❌ 说“多路召回就是向量检索+BM25,然后取并集” → ✅ 正确切入:强调每路召回数需要动态调整,融合策略要处理分数尺度不一致和重复候选,否则召回越多噪声越大。
- ❌ 说“RRF 是万能的,不需要调参” → ✅ 正确切入:RRF 的 k 值需要根据数据分布调优(通常 60 是经验值),而且 RRF 无法处理各路召回数不一致的情况,需要先做归一化。
- ❌ 说“知识图谱检索太慢,不用也罢” → ✅ 正确切入:知识图谱检索对实体关系查询效果显著,可以通过异步并行或条件触发来优化延迟,不能一刀切放弃。
6️⃣ 简历呼应
- 如果你有 RAG 项目:从实际系统切入,比如“在构建企业知识库问答系统时,我实现了向量检索(BGE-M3)+ BM25 + 知识图谱三路召回,用 RRF 融合,Recall@20 从单路的 72% 提升到 86%”,并强调动态调整每路召回数的工程细节。
- 如果你只做过传统 NLP:用搜索系统类比,比如“传统搜索引擎的倒排索引和语义检索结合,本质就是多路召回”,然后迁移到 RAG 场景,强调 BM25 和向量检索的互补性。
- 如果你是校招无项目:聚焦论文复现,比如“我复现了 ColBERT-v2 的 late interaction 机制,它本质是 token-level 的多路召回,然后通过 RRF 融合”,并提到在 MS MARCO 数据集上 Recall@1000 提升 3%。
- 论文:Karpukhin et al., “Dense Passage Retrieval for Open-Domain Question Answering” (DPR, 2020)
- 论文:Robertson & Zaragoza, “The Probabilistic Relevance Framework: BM25 and Beyond” (2009)
- 论文:Cormack et al., “Reciprocal Rank Fusion Outperforms Condorcet and Individual Rank Learning Methods” (RRF, 2009)
- 工具:LangChain 的 MultiRetrievalQAChain 实现多路召回
- 博客:Pinecone 的 “Hybrid Search: Combining Sparse and Dense Retrieval”