RAG 应用的最终答案质量,很大程度上取决于检索阶段能不能把真正相关的片段排到前面。很多团队在调优时遇到的现象是:recall 看问题不大,相关片段确实被召回了,但排名靠后,生成的答案仍然不理想。另一种情况是召回的片段整体相关度偏低,连候选池里都没有真正有用的内容。这两种问题导向完全不同的优化动作,前者是重排序策略的问题,后者是召回管道的问题。
先分清失效发生在召回还是排序
从工程角度看,一个典型的检索管道是:query 经过 embedding 模型编码,在向量库中做 ANN 检索,取回 top-k 个片段,再进入重排序阶段,最后把排序后的结果交给 LLM 生成答案。这里描述的是一种常见的实现方式,具体细节可能因系统而异。
如果相关片段进了 top-k 但排在第 15 位,而最终只取前 5 个片段作为上下文,那么问题出在排序环节。如果相关片段根本不在 top-50 候选集里,那么问题出在召回环节。区分这两个环节,可以通过一个简单的实验:把 top-k 临时调大(比如从 5 调到 50),然后人工检查前 50 个结果中是否包含真正相关的片段。
- 调大后相关片段出现了,说明召回基本可用,接下来应该优化重排序。
- 调大后仍然没有相关片段,说明向量检索本身没有把目标内容找回来,需要调整召回策略。
这个判断步骤看起来很简单,但很多团队跳过它直接调 reranker,结果发现无论怎么换排序模型,答案质量都没有变化。
相关度低的几种典型失效场景
语义相似度与关键词匹配冲突
从工程角度看,向量检索通常被认为擅长捕捉语义相似,但有时语义相近不等于答案准确。例如用户搜索“如何关闭自动续费”,一条提到“取消订阅”的文档片段在向量空间中可能距离较近,但一篇直接出现“自动续费”关键词的文档反而因为措辞差异被排到后面。
对冲这一问题的常见思路是引入关键词检索(如 BM25)做多路召回,再通过融合策略合并结果。通常认为,BM25 对精确词项匹配敏感,向量检索对语义泛化敏感,两者互补。融合方式可以是简单的 RRF(Reciprocal Rank Fusion)——对各路召回的排名取倒数加权求和,也可以把多路结果一起送入 reranker 进行统一打分。
单一片段信息密度不足
chunk 切分过小时,每个片段只包含零散信息,即便排序正确,LLM 拿到手的内容也缺乏完整上下文。切分过大时,单个片段内混入无关内容,reranker 给出的相关度分数会被稀释。
chunk 大小没有统一最优值,它与文档类型、检索粒度、以及 LLM 上下文窗口都有关系。实操上可以从两个方向试验:一是保持固定 token 数切分并设置重叠(overlap),观察检索命中情况;二是按文档结构切分(章节、小节、段落),保持信息完整性。判断标准是:切分后召回的片段是否包含回答问题的完整上下文,而不是只看单条片段的相关度。
候选集太大导致排序压力过高
向量检索返回的 top-50 或 top-100 中,可能只有少数片段真的有用。如果不做精排,直接把全部候选塞进 LLM 上下文,模型既浪费 token,又容易被大量无关信息干扰。如果做了精排,但排序模型能力不足或排序逻辑过于简单,也无法把相关片段提上来。
重排序方法的适用条件
交叉编码器 reranker
从工程角度看,交叉编码器通常采用将 query 和候选片段拼接后一起输入模型的设计,输出一个相关度分数。与双编码器(向量检索使用的范式)相比,这种设计通常被认为能更充分地建模 query 与文档之间的交互,排序精度可能更高,但具体效果需要验证。
它的代价是计算成本远高于向量检索——每个 query-片段对都需要一次前向计算,因此一般在召回后的候选集上使用。从工程角度看,这里需要确认三个问题:
- 候选集规模:重排序的候选数量通常控制在 20~100 条,规模越大,延迟越高。
- 模型是否适合你的领域:如果文档是中文、代码或垂直领域内容,通用排序模型的效果不一定理想,需要在自己的数据集上验证。
- 延迟预算:reranker 的耗时可能成为整个 RAG 管道的瓶颈,需要与业务对端到端时延的要求做权衡。
基于多样性目标的重排(MMR)
MMR(Maximum Marginal Relevance)不是替代交叉编码器,而是在相关度排序之上再做一层多样性调整。从工程角度看,它通过一个折衷公式重新打分:既要候选与 query 相关,又要候选与已选片段之间足够不同,避免多条片段携带重复信息。
适用场景很明确:当检索结果中前几个片段高度同质化,都来自同一篇文章或围绕同一观点展开时,MMR 可以把覆盖不同角度的片段提升上来。但需要注意,MMR 本质上牺牲了一部分相关度来换取多样性,在需要精确引用的场景(比如直接回答事实性问题)中,过度追求多样性反而会降低答案准确性。
基于规则的过滤
规则过滤不产生新排序,但可以在重排序之前把明显无效的结果剔除。常见的过滤条件包括:
- 元数据过滤:按文档来源、日期、类型、权限范围等字段缩小候选范围。
- 阈值过滤:把相似度分数低于某个阈值的片段直接丢弃。
- 字符或长度过滤:过短的片段(如导航栏文本)、包含大量特殊符号的片段,通常不是有效内容。
如果 RAG 系统的文档库中混入了大量低质量内容,规则过滤往往比换一个更强的 reranker 模型带来更直接的改善,因为问题出在数据管道而不是排序算法。
修复排序问题的工程路径
路径一:混合检索 + 统一精排
这是目前应对单一向量检索局限最常用的做法。一种可行的做法是:
- 并行执行向量检索与关键词检索,各自取回一定数量的候选。
- 合并候选集时去重,保留文档 ID 或片段 ID。
- 将合并后的候选集送入交叉编码器 reranker 进行统一精排。
这个方法的关键在于验证“多路召回是否真的带来了新信息”。可以考虑的检查方式是:分别查看向量检索与关键词检索返回的结果集合,统计两路结果的重合度。如果重合度较高(例如超过 80%),说明其中一路可能没有贡献增量;如果重合度很低,则说明两路确实在互补。具体阈值需要根据实际数据验证。
路径二:调整 top-k 与重排序候选数
检索管道中的多个 k 值需要分明确区分:
- 向量检索的 top-k:决定了召回候选池的大小。相关片段能否进入候选池,取决于这个值。
- reranker 的输入规模:通常介于向量检索 top-k 与最终取用片段数之间。
- 最终送入 LLM 的片段数:决定了上下文窗口的利用方式。
如果发现相关片段总是排名偏低,先把向量检索的 top-k 调大,让更多潜在相关片段进入重排序阶段,再观察 reranker 是否能将其排到前面。如果调大后仍然排不上去,则说明 reranker 的分数分布与真实相关度不一致,需要评估是否换模型或增加微调数据。
路径三:用评估指标定位瓶颈
调整重排序策略不能只靠主观阅读。建议建立以下指标来衡量排序质量。在信息检索领域,通常将命中率(Hit Rate)定义为相关片段是否出现在最终取用的 top-n 中,这是一个相对宽松的指标,用来判断排序是否把相关片段“挤掉”了。MRR(Mean Reciprocal Rank)通常指相关片段在排序结果中的第一个出现位置,关注的是“最相关的片段能不能排第一”。NDCG(Normalized Discounted Cumulative Gain)通常指考虑多级相关度的排序质量指标,能反映整体排序的合理性,而不只关心第一名。这些是业界常用定义,具体定义可能因资料而异,建议参考权威信息检索教材或文档。
实践中比较有效的定位方法是:抽样一批 query,为每个 query 手动标注相关片段,然后对比召回结果与排序结果。如果相关片段在召回集合中但排序靠后,说明问题在 reranker;如果召回集合中根本没有相关片段,则问题在召回策略。
落地时不要忽略的边界条件
重排序调优在开发环境中表现很好,不代表生产环境中也可靠。以下几点需要在实际验证:
- reranker 的延迟与吞吐:在真实并发下,精排环节是否成为瓶颈。
- 文档更新频率:如果文档库持续更新,排序模型对新增内容的泛化能力需要持续监控。
- 你设计的“真相关片段”是如何标注的:不同人判断相关性的标准可能不一致,评估集的质量决定了调优方向是否正确。
从工程角度看,真正值得优先做的事
如果检索结果相关度差,优化的顺序建议是:先确认问题发生在召回还是排序;再检查候选集规模是否足够;然后用混合检索增加召回多样性;最后引入 reranker 并建立指标评估。
不要在一开始就追求复杂度更高的重排序模型。一个基础流程——向量检索召回 + 规则过滤 + 简单的评分融合——在大多数场景下已经能解决 70% 的相关度问题。剩余的 30% 才需要逐步引入交叉编码器、MMR 或领域微调。每增加一个模块,都应当有对应的指标改善作为依据,而不是因为它“行业里大家都在用”。