Interview: 多路召回+融合排序的架构中,不同召回源的分数如何归一化和融合?
题目解析
实际RAG系统通常结合多种召回方式:BM25关键词匹配、向量语义检索、知识图谱结构化查询等。不同来源返回的分数尺度和分布完全不同(BM25可能是0-30,向量相似度是-1到1),如何将它们融合为统一的排序是一个关键的工程问题。
解答思路
主要融合策略:1)分数归一化后加权求和——将每路分数归一化到[0,1](如min-max归一化),然后按权重加权。问题是不同query下各路的分数分布不同,固定权重不够灵活;2)Reciprocal Rank Fusion(RRF)——不用原始分数,只用排名。RRF_score = Σ 1/(k+rank_i),k通常取60。优点是对分数尺度不敏感,鲁棒性强;3)学习排序(Learning to Rank)——训练一个模型学习最优的融合权重,可以是特征级(pointwise)或对级(pairwise)。
关键要点
- RRF是实践中最常用的方法:简单、无需训练、效果稳定
- 加权融合需要根据查询类型动态调整权重——关键词明确的查询给BM25更高权重
- 去重策略:同一文档可能被多路同时召回,需要去重并合并分数
- 召回数量的分配也很重要:如果语义检索召回100个BM25只召回20个,RRF会偏向语义结果
加分回答
可以讨论Milvus 2.4引入的Hybrid Search功能——原生支持多路召回和融合排序。还可以分析Vespa的排序框架如何支持多阶段、多信号的融合。更高级的话题:用Cross-Encoder做最终的联合重排序可以隐式地学习最优融合——因为Cross-Encoder直接对query-document对评分,无需显式融合分数。还可以提到Cohere的reranker API如何简化了这个流程。
常见踩坑
- 简单地将不同来源的分数直接相加——尺度差异导致某一路完全支配结果
- 归一化时使用全局统计量而非per-query统计量——每个query的分数分布可能完全不同
- 每路召回数量严重不均衡——应该让每路召回相近数量的候选再做融合