RAG的搜索与判断:为何检索需要独立的重排阶段
RAG需要搜索与判断机制:嵌入模型可以找到候选内容,但无法判断其相关性。因此采用两阶段设计,结合RRF、交叉编码器、ColBERT以及LLM重排序模型来实现这一功能。
许多团队在运用检索增强生成技术时都会遇到同样的难题。在白板上,这个流程看起来很简洁:输入查询,匹配向量,将最佳结果传递给模型,即可得到答案。但实际应用中很快就会出现问题:相关文档被遗漏,无关内容混入,稍作改写的提问就会改变答案,即便检索似乎正常运作,幻觉现象依然存在。
常见的解决办法是更换更优秀的嵌入模型、提高向量维度,或调整 top-k 值和分块大小。这些方法虽有一定道理,但调整的对象并不正确。更深层次的问题在于架构设计——传统的处理流程让同一个机制,即嵌入相似度计算,承担着两件截然不同的任务:筛选候选内容以及判断哪些候选内容是重要的。
解决办法是将任务拆分开来。采用模式搜索与评估相结合的方式:设计为两阶段流程,其中生成候选项和评估相关性是两个独立的工程问题,各自使用不同的工具。
为何仅靠相似度不够
简单的RAG方法会将查询转换为嵌入向量,从知识库中提取距离最近的K个片段,将其放在问题旁边,再让模型进行回答。这种做法隐含的假设是距离越近则相关性越高,因此无需任何验证就直接信任这K个片段。但这种方法存在四个问题。
相似并不等同于相关。嵌入距离只是衡量主题相近程度的一种粗略指标。两段文本可能彼此靠近,但其中一段并不能回答另一段提出的问题。一篇关于高血压治疗指南的文本与一篇关于心血管药物试验方法的文本可能会并排出现,但只有前者能帮助人们决定如何治疗患者。
排序可靠性较低。向量距离只是一种启发式方法,并非专为按相关性排序而设计的函数。在余弦相似度排序中,第三名与第七名之间的差距往往只是噪声而已。
上下文会被分割。文本分块会破坏文本之间的关联、层次结构以及因果关系。关于剂量的内容块可能与描述禁忌症的内容块分开,而单独来看这两部分都不完整。
结果并不稳定。细微的措辞变化都可能改变前K个结果集。询问二甲双胍的副作用与不良反应可能会得到不同的候选结果,最终答案也会随之改变。这是可靠性缺陷,而非调整细节。
简而言之,搜索只能提供候选结果,无法保证正确性。
两阶段设计
不必让一个系统同时完成查找和评估的工作,而是构建两个阶段,每个阶段针对自身目标进行优化。
第一阶段:搜索,会刻意扩大搜索范围,筛选出50到200个候选结果,这个数量远超过实际会展示给模型的数量,因为此阶段的目标是提高召回率。只要正确文档存在于这些候选结果中即可,即便其中混杂了大量无关信息。
第二阶段,法官大人,会采用更严格的测试标准。通常会使用交叉编码器重排器,它同时读取查询语句和各个候选内容,从而计算出真实的相关性分数。这样就能将候选内容缩减到五到十篇置信度较高的段落。只有经过筛选的上下文才会被传递给语言模型。
嵌入向量究竟起到了什么作用
正是误解了嵌入向量的作用,才导致团队过度依赖它们。想象一下,一位图书管理员不会阅读每一本书,而是为每本书标注几个关键主题。当有问题出现时,这位管理员会将问题转化为类似的标签,然后挑选出标签匹配度最高的书籍。这种方法虽然快捷,通常能找到有用的信息,但它仅基于表面主题而非深入理解,因此有些书籍虽然相关,却并非真正需要的内容。
其后果是:你的嵌入模型决定了你的搜索行为。它决定哪些内容会被找到,哪些会被忽略。但它并不决定什么内容是正确的,那是判断阶段的职责。
因此,选择嵌入模型实际上是一个关于召回率的决策。你正在选择第一阶段用来查看语料库的视角。需要权衡诸如MTEB和BEIR这样的检索基准、语言覆盖范围、模型大小与硬件匹配度、向量维度、最大输入长度以及推理速度等因素,所有这些都属于召回率相关的考量。
判断器的选项及适用场景
判断器是该架构中的一个角色,有多种实现方式,它们在准确性、延迟、复杂度和成本方面存在不同的权衡。
互逆排名融合
RRF完全不考虑相关性。它将来自多个来源的排序列表——例如关键词搜索和语义搜索的结果——合并为一个统一的排序顺序。对于每份文档,它会从所有列表中累加 1 / (k + 排名) 的值,其中k是一个常数,通常为60,该值用于削弱最高排名文档的过度影响。在多个列表中排名靠前的文档会获得更高的排序位置。
这种算法速度快、结果确定,无需模型推理,几乎不会产生延迟。由于它使用的是排名位置而非原始分数,因此避免了BM25分数与余弦相似度之间的差异,也就无需进行标准化处理。
它的局限性在于只能识别一致性。如果多个检索器都认为某份文档很重要,RRF就会认为它确实如此。这是一种合理的启发式方法,但终究只是启发式方法。它无法找出所有检索器都遗漏的相关文档,也无法区分主题相近的文档与真正能回答问题的文档。
在需要简单方式合并列表的混合搜索中可以使用它。它属于搜索阶段的一部分,用于优化候选文档,但不能替代最终判断者。
交叉编码器
交叉编码器将查询和候选内容作为拼接后的序列输入模型,进而输出相关性得分。双编码器则分别对查询和文档进行嵌入处理,而在这种方式中,查询中的每个词元都可以与文本中的每个词元建立关联。因此该模型能够理解查询中的特定短语与文本中的特定短语之间的关联。典型的例子包括诸如cross-encoder/ms-marco-MiniLM-L-12-v2这样的句子转换模型、托管的重排序服务,以及针对医疗、法律或科学数据经过微调的交叉编码器。
这类方法的优点在于准确性高。在排序基准测试中,它们通常能超越其他方法,因为它们能够捕捉到嵌入相似度无法体现的细微交互关系。这几乎相当于在无需调用完整大语言模型的情况下,判断某份文档是否真正回答了问题。
其成本在于每次查询和候选对都需要进行一次独立的向前传递处理。如果文档池有100份文档,那么每次查询就需要运行100次模型,因此延迟会随着文档池规模的增大而呈线性增长,而更大的模型会使情况更加恶化。
在那些答案质量至关重要的领域,比如医疗、法律、合规性检查、金融分析,以及任何错误检索都会带来严重后果的场合,它们都是默认的评估工具。如果延迟预算允许大约50到200毫秒的重新排序时间——大多数非实时系统都能满足这一要求——那么可以从这些模型开始使用。
ColBERT与后期交互
ColBERT是“基于BERT的上下文化延迟交互”的缩写,介于双编码器与交叉编码器之间。它分别将查询和文档编码为每个标记的向量,再通过匹配查询标记与文档标记来计算得分。由于文档向量可以预先计算,因此在查询时的成本远低于交叉编码器,同时又能保留比单一聚合向量更多的细节。其代价是索引规模更大,因为每个标记都需要一个向量。这类方法适合那些需要比普通嵌入更好的排序效果,同时又希望获得比交叉编码器更高处理吞吐量的系统。
以大语言模型作为评判者
通用语言模型可以直接对候选内容进行评分。它能够处理复杂的多层相关性问题,例如即便词汇没有重叠,也能意识到关于药物相互作用的内容与治疗安全相关的问题之间存在关联。它还可以遵循提示词中明确规定的相关性标准,因此能够适应特定领域中对“相关”这一概念的不同定义。
不过,它也是目前成本最高的选项。一次重新排序操作可能需要1到5秒的时间,其成本是交叉编码方式的10到100倍。不同次运行得到的评分可能会有所差异,而且这些模型还存在位置偏差,更倾向于优先考虑提示词中较早出现的文档。此外,托管型模型还会带来额外的外部依赖问题。
这种做法在两种场景下是合理的:一是离线环境或批量处理任务,其中延迟无关紧要,比如构建精选的知识库、在开发过程中评估检索效果,或是为专门的重新排序工具生成训练数据;二是高价值但处理量较小的工具,正确答案的价值足以弥补每次查询的成本,比如专家级的医学或法律研究。
为各阶段选择模型
理解模式是一回事,选择模型则是另一回事。该架构要求你根据任务需求做出两项选择。
从任务出发
临床问答、文档检索与合规性检查需要不同的处理方式。质量评估要求在数据量较少的情况下仍保持高精度;文档检索则更注重覆盖范围与多样性;而合规性检查则需要确定性强、可审计的检索结果,并尽可能减少误检。任务特性决定了后续的所有选择。
嵌入模型决定了召回率的上限
它决定了在人工审核之前系统能够找到哪些内容。那些从未进入候选集的相关文档,任何重排算法都无法将其找出来。可从以下方面对比不同候选项:
- 基准测试。应参考与您的任务类型最接近的检索任务(如段落检索或问答任务)的MTEB和BEIR指标,而不仅仅是总体得分。
原则是:调整嵌入模型时应注重覆盖率和速度,而非精确度。精确度则由评估人员来决定。
重排器决定最终准确性
它是大语言模型之前的最后一道过滤环节,其质量直接影响答案的准确性。可从以下方面进行评估:
- 排序准确性。这是核心指标。需在与您的应用领域相近的基准测试中查看nDCG、MRR和MAP数值。即便提升幅度很小,也能显著减少后续的幻觉现象。
- 延迟。重排器会对每个候选项运行一次,因此若有100个候选项,则需要执行100次运算。单次运算时间和总时间都是生产环境中的关键限制因素。
- 领域对齐。普通的重排模型在广泛检索任务上表现良好,但高价值领域往往能从基于领域相关性数据微调的重排模型中获益。即便普通重排模型在通用基准测试中的得分更高,经过医学文献训练的重排模型也能更准确地处理临床查询。
- 处理能力。在流量极大的情况下,重排模型可能成为性能瓶颈。可以考虑批量处理、模型并行化,以及是否可以使用更轻量的方案,如精简版的交叉编码器或后期交互模型,在大幅提升处理能力的同时保持可接受的准确率。
两者皆需投入
最优秀的系统不会在优秀的嵌入器与优秀的重排器之间做选择,因为这两者承担的任务互不重叠。拥有强大嵌入器但重排器较弱的系统虽然召回率很高,但最终结果会存在较多噪声;而嵌入器较弱但重排器强大的系统则能在不完整的候选集中给出精确的排序。单独使用其中任何一种都无法达到最佳效果。
解决方案是采用快速且召回率高的搜索方式,再结合强大且精确的排序机制。根据召回率需求选择嵌入器,根据精确度需求选择重排器,随后在各个阶段调整候选集的大小,以在覆盖范围与重排延迟之间取得平衡。
实际案例
假设有一名临床助理被问及,正在服用某种糖尿病药物的病人是否可以安全地再服用另一种药物。在搜索阶段,系统会同时执行关键词查询和向量查询,再通过RRF算法将结果合并,最终保留100个候选项。这些候选项包括每种药物的专论、一篇试验设计论文、一份通用营养手册以及几张药物相互作用表。仅从相似度来看,试验设计论文和营养手册的排名可能会高于药物相互作用表,因为它们的词汇与问题更为相关。
在法官阶段,系统会阅读每一百篇文本旁边的问题,并判断该文本是否真正涉及联合使用情况。交互表及相关禁忌段落会浮至顶部,而其他内容则被忽略,这样模型处理的文本数量就从混乱的十篇减少到六篇。同样的语料库、同样的嵌入向量,结果却不同,因为新增的组件做出了第一个组件原本从未被设计来做出的决策。
调整各阶段之间的过渡
候选集大小是关键参数。如果过小,评分员就永远看不到正确的段落,从而限制了整个系统的召回率;如果过大,则重排的延迟和成本会上升,但收益甚微。一个实用的设置方法是在带有标签的样本上记录正确段落在第一阶段出现的排名,然后选择一个几乎涵盖所有这些排名的候选集。如果正确段落通常出现在150名之后,问题很可能出在搜索阶段,需要改进嵌入模型、采用混合检索方式或优化分块策略,而非增加重排器的规模。
其他一些习惯也有帮助:
- 分别评估两个阶段的表现。在评分前测量候选集的召回率,评分后再测量最终列表的精确度,这样就能确定问题出在哪个阶段。
- 当语料库变化缓慢时,为频繁查询的结果缓存重排器得分。
应将此视为需要在自身数据上验证的假设,而非绝对结论,因为不同领域的效果以及基线模型的强弱都会影响最终结果。
核心要点
可靠的RAG系统并非通过寻找更优的嵌入向量来实现,而是通过将搜索与判断分开——一个阶段侧重最大化覆盖范围,另一个阶段侧重最大化准确性。
这种转变首先体现在概念层面,而非技术层面。不要将前K个结果视为最终答案,而应将其视为候选集;不要将相似度视为事实,而应将其视为需要验证的假设。先广泛搜索,再精准判断。
相关阅读
- Milvus上的高级RAG技术:混合搜索、HyDE、查询重写与重排序 — 逐步构建Milvus RAG流程:密集向量与BM25向量、RRF混合搜索、元数据过滤、查询重写、HyDE技术、分解处理以及交叉编码器重排序。
- 实用笔记:AI智能体不再需要向量搜索——深入探秘Agentic框架 — 对“实用笔记:AI智能体不再需要向量搜索——深入探秘Agentic框架”的详细操作指南,以及2026年将取代RAG的搜索技术栈:相关合约、检查机制及可直接使用的代码。