在第5章中,我们详细探讨了RAG离线索引阶段的四大核心环节——数据采集、数据清洗、文本分块和向量化,以及向量数据库这一关键基础设施。当高质量的知识库构建完成之后,RAG系统便进入了在线推理阶段。在线推理的第一步,也是最为关键的一步,便是检索(Retrieval):如何从数百万乃至数亿条文本块中,精准地找到与用户查询最相关的信息。检索质量的高低直接决定了RAG系统最终生成答案的准确性和可靠性。
本章将系统性地介绍RAG在线检索的完整技术体系。我们从最基础的查询向量化与相似度计算出发(6.1节),逐步深入到Top-K检索策略(6.2节)、检索结果重排序(6.3节)、混合检索(6.4节),再到新一代基于视觉语言模型的ColPali检索范式(6.5节),最后讨论多轮检索与迭代检索技术(6.6节)。这些技术层层递进,共同构成了一个从基础到前沿的完整检索技术图谱。无论是刚入门RAG的开发者,还是希望优化现有系统性能的资深工程师,都能在本章中找到实用的技术指导和最佳实践。
6.1 查询向量化与相似度计算
查询向量化是在线检索流程的第一步,也是整个检索过程的起点。其核心任务是将用户输入的自然语言查询文本转换为稠密向量表示,使其能够与知识库中已存储的文档向量在同一个向量空间中进行相似度比较。查询向量化看似简单,实则暗藏诸多技术细节——查询文本通常较短、信息密度高、且缺乏足够的上下文,这给向量化过程带来了独特的挑战。
6.1.1 查询文本的向量化过程
查询文本的向量化过程在原理上与文档向量化相同——都是通过嵌入模型将文本映射为高维向量空间中的点。然而,查询和文档在文本特征上存在显著差异:查询通常较短(平均5到20个词),信息密度高,且往往缺乏明确的上下文;而文档通常较长(数百到数千个词),包含丰富的上下文信息。这种不对称性导致查询向量和文档向量在向量空间中的分布特征不同,需要特殊的处理策略。
在实际工程中,查询向量化的第一步通常是查询预处理。查询预处理包括:去除查询中的冗余词汇和停用词、纠正拼写错误、扩展缩写词、以及查询改写(Query Rewriting)。查询改写是一种重要的技术,它通过将简短的用户查询扩展为更完整、更具描述性的表述,来提升检索效果。例如,将用户查询“RAG”改写为“检索增强生成技术(Retrieval-Augmented Generation)”,可以帮助嵌入模型更准确地理解查询意图。
查询向量化的第二步是选择合适的嵌入模型。关键原则是:查询向量化使用的嵌入模型必须与文档向量化使用的模型完全一致。这是因为不同的嵌入模型将文本映射到不同的向量空间,跨模型的向量不具有可比性。如果知识库使用BGE-M3模型进行文档向量化,那么在线查询时也必须使用BGE-M3模型进行查询向量化。此外,部分嵌入模型(如BGE-M3、E5系列)会区分查询和文档的前缀——在输入查询时需要添加特定的前缀标记(如“representative query:”),以引导模型生成更适合检索的查询向量。
查询向量化的第三步是处理查询中的特殊场景。对于多语言查询,需要确保嵌入模型支持对应语言;对于包含专业术语的查询,领域微调的嵌入模型通常表现更好;对于模糊或歧义查询,可以考虑使用LLM先对查询进行澄清和改写。Gao等人在RAG综述中将查询优化列为RAG系统的核心预处理技术之一,指出良好的查询表示是高质量检索的前提条件。
查询向量化示例(使用BGE-M3)
from FlagEmbedding import FlagModel
model = FlagModel('BAAI/bge-m3', use_fp16=True)
用户原始查询
query = "什么是RAG技术?"
添加查询前缀并编码
query_embedding = model.encode([query],
instruction='为这个句子生成表示以用于检索相关文章:')
query_embedding.shape: (1, 1024)
[1] Gao et al. Retrieval-Augmented Generation for Large Language Models: A Survey. 2024. arXiv:2312.10997
[2] Lewis et al. Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. NeurIPS 2020. arXiv:2005.11401
6.1.2 余弦相似度、欧氏距离、点积等相似度度量方式对比
相似度度量(Similarity Metric)是衡量两个向量之间“接近程度”的数学工具,是检索算法的核心计算基础。不同的相似度度量方式有不同的数学性质和适用场景,选择合适的度量方式对检索效果有直接影响。以下表格对三种主流的相似度度量方式进行了系统对比:
| 相似度度量 | 数学公式 | 取值范围 | 是否需要归一化 | 计算复杂度 | 主要特点 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 余弦相似度 | cos(A,B) = (A·B) / ( | A | · | B | ) | [-1, 1] | 不需要 | O(d) | 衡量方向一致性,忽略大小 | ||||
| 欧氏距离 | d(A,B) = sqrt(sum((ai-bi)^2)) | [0, +inf) | 推荐归一化 | O(d) | 衡量绝对距离,考虑大小 | ||||||||
| 点积(内积) | A·B = sum(ai*bi) | (-inf, +inf) | 需要归一化 | O(d) | 同时考虑方向和大小,计算最快 | ||||||||
| 曼哈顿距离 | d(A,B) = sum( | ai-bi | ) | [0, +inf) | 推荐归一化 | O(d) | 对异常值更鲁棒 | ||||||
| 切比雪夫距离 | d(A,B) = max( | ai-bi | ) | [0, +inf) | 推荐归一化 | O(d) | 取各维度最大差值 |
余弦相似度(Cosine Similarity)是RAG系统中最常用的相似度度量方式。它通过计算两个向量夹角的余弦值来衡量其方向上的一致性,取值范围为[-1, 1],其中1表示完全相同方向(最相似),0表示正交(无关),-1表示完全相反方向。余弦相似度的最大优势在于它对向量的长度(模长)不敏感——即使两个向量的长度差异很大,只要它们的方向一致,余弦相似度就接近1。这一特性使得余弦相似度特别适合文本检索场景,因为不同长度的文本可能具有不同的向量模长,但其语义相似性主要体现在向量的方向上。
欧氏距离(Euclidean Distance)衡量的是两个向量在空间中的直线距离,取值范围为[0, +inf),值越小表示越相似。与余弦相似度不同,欧氏距离同时考虑了向量的方向和大小。在使用欧氏距离时,通常建议先对向量进行L2归一化(将向量长度缩放为1),这样可以消除向量大小的影响,使欧氏距离与余弦相似度在排序结果上等价。在FAISS等向量检索库中,L2距离是默认的距离度量方式。
点积(Dot Product / Inner Product)是计算效率最高的相似度度量方式,因为它不需要计算向量的模长。然而,点积的结果同时受向量方向和大小的影响——如果向量未归一化,点积值可能无法准确反映语义相似性。因此,在使用点积作为相似度度量时,必须确保向量已经过L2归一化处理。归一化后,点积的排序结果与余弦相似度完全一致。许多向量数据库(如Pinecone、Weaviate)默认使用点积作为相似度度量,前提是存储的向量已经归一化。
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
6.1.3 相似度度量的选择建议
在实际的RAG系统开发中,相似度度量的选择应综合考虑以下因素:
对于大多数文本检索场景,余弦相似度是最安全的选择。它不要求向量预先归一化,对向量长度不敏感,且在语义检索任务上表现稳定。大多数嵌入模型(如OpenAI text-embedding、BGE系列、E5系列)的官方推荐都是使用余弦相似度。如果嵌入模型在训练时使用了对比学习(Contrastive Learning)且训练目标基于余弦相似度,那么在推理时使用余弦相似度可以保持训练和推理的一致性。
对于已经对向量进行L2归一化的场景,点积和余弦相似度在排序结果上完全等价,但点积的计算效率更高(省去了模长计算)。因此,在追求极致检索性能的生产环境中,可以先对向量进行归一化,然后使用点积作为距离度量。FAISS的IndexFlatIP就是专门为归一化向量的内积搜索设计的索引。
对于需要考虑向量绝对距离的场景(如聚类分析、异常检测),欧氏距离更为合适。欧氏距离能够捕捉向量在空间中的绝对位置差异,而不仅仅是方向差异。然而,在纯粹的语义检索任务中,欧氏距离通常不如余弦相似度表现好,因为文本向量的模长往往与文本长度相关,而非语义内容。
综合建议:在RAG系统的开发初期,使用余弦相似度作为默认选择;在系统优化阶段,如果嵌入模型输出的向量已经归一化,可以切换为点积以获得微小的性能提升;如果需要进行聚类或异常检测等分析任务,使用欧氏距离。无论选择哪种度量方式,最重要的是确保查询和文档使用相同的度量方式。
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
6.2 基础检索策略:Top-K检索
Top-K检索是RAG系统中最基础也是最常用的检索策略。其核心思想非常直观:给定一个查询向量,从知识库中找出与之最相似的K个文档或文本块,作为后续生成阶段的上下文输入。尽管Top-K检索的原理简单,但其中的参数选择、阈值设定和多样性控制等细节,对最终的检索质量和生成效果有着深远的影响。
6.2.1 Top-K检索的原理与流程
Top-K检索的完整流程可以分为四个步骤。第一步,查询向量化:将用户输入的自然语言查询通过嵌入模型转换为查询向量q。第二步,相似度计算:计算查询向量q与知识库中所有文档向量{d1, d2, ..., dn}之间的相似度分数。在实际系统中,这一步通常由向量数据库通过近似最近邻(ANN)算法高效完成,而非暴力遍历所有向量。第三步,排序:根据相似度分数对所有文档进行降序排列。第四步,截断:取排序后的前K个文档作为检索结果返回。
在向量数据库层面,Top-K检索的实现依赖于近似最近邻搜索算法。以HNSW算法为例,搜索过程从图的最顶层开始,通过贪心导航逐层向下查找与查询向量最近的节点,最终在底层进行精细搜索,返回相似度最高的K个结果。HNSW算法的时间复杂度约为O(log n),能够在毫秒级延迟内从百万级向量中完成Top-K检索。
Top-K检索的输出通常包含两部分信息:一是检索到的K个文本块的内容,二是每个文本块的相似度分数。相似度分数在后续流程中有多种用途:可以用作重排序的输入特征,可以用作生成阶段的注意力权重参考,还可以用作检索结果质量监控的指标。
Top-K检索示例(使用FAISS)
import faiss
import numpy as np
假设已有文档向量矩阵 doc_embeddings: (n_docs, dim)
dim = doc_embeddings.shape[1]
构建HNSW索引
index = faiss.IndexHNSWFlat(dim, M=32)
index.hnsw.efConstruction = 200
index.add(doc_embeddings.astype('float32'))
Top-K检索
k = 10
scores, indices = index.search(query_vector.reshape(1, -1), k)
scores: 相似度分数, indices: 对应的文档索引
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
[2] Lewis et al. RAG. NeurIPS 2020. arXiv:2005.11401
6.2.2 相似度阈值过滤
在实际的RAG系统中,并非所有Top-K检索结果都与查询真正相关。当查询涉及知识库中不存在的主题,或者查询表述模糊时,返回的Top-K结果可能全部或部分与查询不相关。如果将这些低质量结果直接送入生成模型,可能导致“幻觉”(Hallucination)——模型基于不相关的上下文生成看似合理但实际错误的信息。
相似度阈值过滤(Similarity Threshold Filtering)是解决这一问题的有效手段。其核心思想是:设定一个相似度阈值T,只有相似度分数大于T的检索结果才被保留,低于T的结果被过滤掉。这样,当查询与知识库中的所有文档都不相关时,系统可以返回空结果或触发“我不知道”的回退机制,而不是强行基于不相关的上下文生成答案。
阈值T的选择是一个需要权衡的问题。阈值设置过高,会导致召回率下降——一些真正相关的文档因为相似度略低于阈值而被过滤掉;阈值设置过低,则无法有效过滤低质量结果。在实际工程中,建议通过以下方法确定阈值:在标注数据集上绘制相似度分数的分布图,观察相关文档和不相关文档的分数分布,选择一个能够最大化F1分数的阈值。对于没有标注数据的场景,可以采用经验值——余弦相似度阈值通常设置在0.5到0.7之间,具体取值取决于嵌入模型和数据特征。
动态阈值是更高级的阈值策略。它不是使用固定阈值,而是根据查询的特征动态调整阈值。例如,对于信息明确的查询使用较低阈值(更宽松),对于模糊查询使用较高阈值(更严格)。另一种动态策略是基于统计方法:计算所有Top-K结果的相似度分数的均值和标准差,将阈值设为均值减去一个标准差,从而过滤掉明显偏离的异常低分结果。
相似度阈值过滤示例
def filter_by_threshold(results, scores, threshold=0.6):
filtered = []
for doc, score in zip(results, scores):
if score >= threshold:
filtered.append((doc, score))
if not filtered:
# 触发回退机制:返回"我不知道"或使用LLM直接回答
return None
return filtered
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
6.2.3 MMR(Maximal Marginal Relevance)多样性检索
传统的Top-K检索按照相似度分数降序返回结果,这可能导致返回的K个文档之间高度相似或重复。例如,当用户查询“什么是机器学习”时,Top-5结果可能全部来自同一篇介绍文章的不同段落,虽然每个段落都与查询相关,但它们提供的信息高度冗余,覆盖面狭窄。MMR(Maximal Marginal Relevance,最大边际相关性)算法正是为了解决这一问题而提出的。
MMR由Carbonell和Goldstein在1998年提出,其核心思想是在相关性和多样性之间取得平衡。MMR的选取得分公式为:MMR = arg max_{D in R\S} [lambda * Sim(D, Q) - (1 - lambda) * max_{D' in S} Sim(D, D')],其中R是候选文档集合,S是已选文档集合,Q是查询,lambda是相关性与多样性的权衡参数(取值范围为[0, 1]),Sim是相似度函数。
直观理解MMR的工作方式:在每一步选择中,算法不仅考虑候选文档与查询的相关性(第一项),还考虑候选文档与已选文档的相似度(第二项)。如果候选文档与已选文档高度相似,即使它与查询的相关性很高,也会因为第二项的惩罚而被降低优先级。参数lambda控制相关性和多样性的权重:lambda=1时退化为纯相关性排序(等同于Top-K),lambda=0时退化为纯多样性排序(最大化结果之间的差异)。实际应用中,lambda通常设置在0.5到0.7之间。
LangChain框架提供了MMR的内置实现,可以直接在向量检索器上使用。通过设置search_kwargs中的k参数(初始候选集大小)和fetch_k参数(最终返回数量),可以灵活控制MMR检索的行为。建议将fetch_k设置为k的2到3倍,以给MMR算法提供足够的选择空间。实验表明,在RAG系统中使用MMR替代纯Top-K检索,可以在不显著降低相关性的前提下,显著提升检索结果的覆盖面和信息多样性,从而改善生成答案的全面性。
LangChain MMR检索示例
from langchain_community.vectorstores import FAISS
使用MMR进行多样性检索
results = vectorstore.max_marginal_relevance_search(
query="什么是机器学习?",
k=5, # 最终返回5个结果
fetch_k=20, # 先获取20个候选
lambda_mult=0.5 # 相关性-多样性权衡参数
)
[10] Carbonell, J. and Goldstein, J. The Use of MMR, Diversity-Based Reranking for Reordering Documents and Producing Summaries. SIGIR 1998.
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
6.2.4 Top-K参数的选择建议
Top-K参数的选择是RAG系统中最常调优的超参数之一,它直接影响送入生成模型的上下文质量和数量。K值过小,可能遗漏关键信息,导致生成答案不完整;K值过大,会引入噪声信息,增加“Lost in the Middle”风险(模型倾向于忽略上下文中间部分的信息),同时增加推理延迟和Token消耗。
以下表格总结了不同场景下的推荐K值范围:
| 应用场景 | 推荐K值 | 上下文窗口考虑 | 说明 |
|---|---|---|---|
| 简单事实问答 | 3-5 | 小(2K-4K tokens) | 问题明确,少量高质量片段即可 |
| 复杂分析问答 | 5-10 | 中(4K-8K tokens) | 需要综合多个信息源 |
| 多跳推理 | 10-20 | 大(8K-16K tokens) | 需要多条证据链进行推理 |
| 文档摘要 | 10-15 | 大(8K-16K tokens) | 需要全面覆盖文档内容 |
| 代码生成 | 3-8 | 中(4K-8K tokens) | 代码片段通常较短 |
| 对话式RAG | 3-5 | 小(2K-4K tokens) | 实时性要求高,延迟敏感 |
| 企业知识库 | 5-10 | 中(4K-8K tokens) | 通用推荐起点 |
在实际工程中,Top-K的选择还需要考虑以下因素:生成模型的上下文窗口大小——如果使用GPT-3.5-turbo(16K上下文),可以适当增大K值;如果使用较小的模型(如4K上下文),需要限制K值以确保检索结果加上生成的答案不超过上下文窗口。此外,每个文本块的平均长度也会影响K值的选择——如果块较大(如1000 token),K值应相应减小;如果块较小(如200 token),K值可以适当增大。
建议的调优策略是:从一个保守的K值(如K=5)开始,在验证集上评估不同K值下的端到端生成质量(如答案的准确率、完整性和相关性),选择综合指标最优的K值。同时,应结合相似度阈值过滤和MMR多样性检索来进一步提升检索质量,而不是单纯依赖增大K值来提高召回率。
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
[2] Lewis et al. RAG. NeurIPS 2020. arXiv:2005.11401
6.3 检索结果重排序:提升相关性的关键
在基础的Top-K检索中,检索结果的相关性排序完全依赖于嵌入向量的相似度分数。然而,双编码器(Bi-Encoder)架构的嵌入模型在计算查询-文档相似度时,分别独立编码查询和文档,无法充分捕捉查询与文档之间的细粒度交互特征。这导致检索结果中可能存在排序不准确的情况——一些与查询真正高度相关的文档可能排名靠后,而一些表面相似但实际相关性较低的文档可能排名靠前。重排序(Reranking)技术正是为了解决这一问题而诞生的。
6.3.1 重排序的原理与作用
重排序的核心原理是引入一个更强大的“交叉编码器”(Cross-Encoder)模型,对初步检索的候选结果进行精细化的相关性评分和重新排序。两阶段检索架构(Two-Stage Retrieval Architecture)是目前RAG系统的主流范式:第一阶段使用双编码器进行高效的初步检索(Recall阶段),从海量文档中快速召回数百或数千个候选文档;第二阶段使用交叉编码器对候选文档进行精细的重排序(Precision阶段),从中选出最相关的数十个文档。
双编码器与交叉编码器的核心区别在于查询和文档的交互方式。双编码器分别将查询和文档编码为独立的向量,然后通过向量相似度计算相关性。这种方式计算效率高(文档向量可以预计算和缓存),但无法建模查询词与文档词之间的细粒度交互关系。交叉编码器则将查询和文档拼接为一个输入序列,通过Transformer的自注意力机制让查询和文档的每个token之间进行充分的交互,从而更准确地判断相关性。
两阶段架构的优势在于兼顾了效率和精度。第一阶段的双编码器检索可以在毫秒级延迟内从百万级文档中完成初步筛选;第二阶段的交叉编码器重排序虽然计算成本较高(需要对每个候选文档进行一次完整的Transformer推理),但由于候选集已经缩小到数百个,总体计算成本仍然可控。Gao等人在RAG综述中指出,两阶段检索架构是当前RAG系统检索模块的标准范式,能够在保持系统响应速度的同时显著提升检索精度。
重排序的作用不仅限于提升排序准确性。在实际的RAG系统中,重排序阶段还可以承担以下功能:融合多路检索结果(如将BM25检索结果和向量检索结果统一重排序)、应用业务规则(如对特定来源的文档进行加权)、以及实现个性化的结果排序。重排序阶段是RAG系统中灵活性最高的环节,开发者可以根据业务需求定制重排序逻辑。
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
[12] Thakur et al. BEIR: A Heterogeneous Benchmark for Zero-Shot Evaluation of Information Retrieval Models. NeurIPS 2021. arXiv:2104.08663
6.3.2 主流重排序模型介绍
近年来,重排序模型的研究取得了显著进展,涌现出多个高性能的开源和商业模型。以下表格对当前主流的重排序模型进行了系统对比:
| 模型 | 开发者 | 模型规模 | 上下文长度 | BEIR平均分 | 多语言支持 | 许可协议 |
|---|---|---|---|---|---|---|
| Cohere Rerank 3 | Cohere | 商业API | 4096 | 63.8 | 支持100+语言 | 商业 |
| bge-reranker-v2-m3 | BAAI | 568M参数 | 8192 | 62.5 | 支持100+语言 | MIT开源 |
| bge-reranker-large | BAAI | 560M参数 | 512 | 61.2 | 支持中文 | MIT开源 |
| bge-reranker-base | BAAI | 278M参数 | 512 | 60.1 | 支持中文 | MIT开源 |
| cross-encoder/ms-marco-MiniLM-L-12-v2 | Sentence Transformers | 420M参数 | 512 | 58.5 | 仅英文 | Apache 2.0 |
| cross-encoder/ms-marco-electra-base | Sentence Transformers | 110M参数 | 512 | 56.8 | 仅英文 | Apache 2.0 |
| Jina Reranker v2 | Jina AI | 137M参数 | 8192 | 61.0 | 支持多语言 | Apache 2.0 |
| Voyage Rerank 2 | Voyage AI | 商业API | 16000 | 64.2 | 支持多语言 | 商业 |
Cohere Rerank是目前最成熟的商业重排序API之一。Cohere提供了Rerank 3模型,支持超过100种语言,上下文长度为4096个token,在BEIR基准上表现优异。Cohere Rerank的使用非常简单——只需将查询和候选文档列表发送到API,模型会返回每个文档的相关性分数和重排序后的结果。Cohere还提供了多语言版本(multilingual),在跨语言检索场景中表现尤为出色。
BGE-Reranker系列是BAAI(北京智源人工智能研究院)推出的开源重排序模型,是目前最受欢迎的开源选择。其中bge-reranker-v2-m3是该系列的最新版本,支持超过100种语言,上下文长度扩展到8192个token,在多项基准测试中表现接近甚至超过商业模型。BGE-Reranker基于XLM-RoBERTa架构,使用对比学习在大规模多语言数据上进行训练,特别适合中文场景。该模型提供了多种使用方式:可以直接使用HuggingFace Transformers加载,也可以通过FlagEmbedding库使用,还可以通过sentence-transformers库集成。
Jina Reranker v2是Jina AI推出的轻量级重排序模型,仅有137M参数,但支持8192的长上下文长度。其优势在于推理速度快、资源消耗低,适合对延迟敏感的场景。Voyage Rerank 2是Voyage AI推出的商业重排序模型,支持16000的超长上下文,在BEIR基准上取得了领先的成绩,特别适合需要处理长文档的场景。
BGE-Reranker使用示例
from FlagEmbedding import FlagReranker
reranker = FlagReranker('BAAI/bge-reranker-v2-m3', use_fp16=True)
对候选文档进行重排序
pairs = [[query, doc] for doc in candidate_docs]
scores = reranker.compute_score(pairs)
按重排序分数降序排列
ranked_results = sorted(zip(candidate_docs, scores),
key=lambda x: x[1], reverse=True)
[7] Cohere. Rerank API Documentation. docs.cohere.com/docs/rerank
[8] BAAI. BGE-Reranker. github.com/FlagOpen/Fl…
[12] Thakur et al. BEIR Benchmark. NeurIPS 2021. arXiv:2104.08663
6.3.3 重排序的最佳实践
在实际的RAG系统中,重排序模块的配置和优化需要考虑多个维度。以下是经过实践验证的最佳实践:
何时使用重排序:重排序并非在所有场景下都是必要的。对于小规模知识库(如文档数量少于1万),直接使用Top-K检索可能已经足够;对于大规模知识库(如文档数量超过10万),重排序能够显著提升检索精度,是值得投入的优化。此外,对于对准确性要求极高的场景(如医疗、法律、金融),重排序几乎是必备的组件。Gao等人在RAG综述中指出,重排序在BEIR基准上平均可以带来2到5个百分点的NDCG@10提升。
候选集大小的选择:重排序的候选集大小(即第一阶段检索返回的文档数量)是一个需要权衡的参数。候选集太小(如20个),可能遗漏真正相关的文档;候选集太大(如500个),会增加重排序的计算延迟。建议的候选集大小为50到200个文档。在大多数场景下,100个候选文档是一个合理的起点。如果使用HNSW索引,可以通过调整ef_search参数来控制候选集大小。
性能与精度的权衡:交叉编码器的推理成本是双编码器的数十倍(因为需要对每个候选文档进行完整的Transformer推理)。对于延迟敏感的在线服务,可以采用以下策略来平衡性能和精度:使用较小的重排序模型(如bge-reranker-base而非bge-reranker-v2-m3);使用GPU加速推理;对候选集进行预过滤(如先按相似度阈值过滤掉明显不相关的文档);以及使用异步流水线(在用户等待期间并行执行重排序)。
重排序结果的截断:重排序完成后,通常需要从重排序结果中选取Top-N(N通常为3到10)送入生成模型。N的选择应考虑生成模型的上下文窗口大小和每个文档的平均长度。建议将重排序后的Top-N结果的总Token数控制在生成模型上下文窗口的50%到70%之间,为生成阶段预留足够的空间。
多路检索结果融合:在实际系统中,重排序阶段经常被用来融合来自不同检索通道的结果。例如,可以将BM25检索的Top-50结果和向量检索的Top-50结果合并为100个候选文档,然后使用重排序模型统一评分和排序。这种多路召回+统一重排序的架构能够综合关键词匹配和语义匹配的优势,显著提升检索的召回率和精度。
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
[12] Thakur et al. BEIR Benchmark. NeurIPS 2021. arXiv:2104.08663
6.4 混合检索:结合关键词与语义检索
尽管稠密向量检索(Dense Retrieval)在语义理解方面具有天然优势,但它在某些场景下仍然存在明显的局限性。例如,当查询中包含精确的专有名词、产品编号、人名等“硬匹配”需求时,语义检索可能无法精准定位到包含这些精确词汇的文档。BM25等传统的稀疏检索方法在关键词精确匹配方面表现优异,但缺乏语义理解能力。混合检索(Hybrid Retrieval)通过将稀疏检索和稠密检索的结果进行融合,综合了两者的优势,是目前RAG系统中检索效果最稳健的方案。
6.4.1 稀疏-密集混合检索
稀疏检索(Sparse Retrieval)和稠密检索(Dense Retrieval)代表了信息检索的两种基本范式。稀疏检索基于词袋模型(Bag-of-Words),使用高维稀疏向量(如TF-IDF或BM25权重向量)来表示文档和查询,通过词汇层面的匹配来计算相关性。稠密检索基于嵌入模型,使用低维稠密向量来表示文档和查询,通过语义层面的相似度来计算相关性。
SPLADE(SParse Lexical AnD Expansion)是Formal等人于2021年提出的一种先进的稀疏检索方法,它结合了传统稀疏检索的可解释性和神经网络的语义理解能力。SPLADE的核心创新在于“词汇扩展”(Term Expansion)机制:对于查询中的每个词,模型不仅保留原始词的权重,还会自动扩展出语义相关的词汇并赋予适当的权重。例如,查询“climate change”不仅会匹配包含“climate”和“change”的文档,还会匹配包含“global warming”、“greenhouse effect”等相关词汇的文档。
SPLADE的工作原理基于一种称为“稀疏表示学习”的技术。模型使用一个预训练的语言模型(如BERT)作为编码器,通过一个特殊的输出层将BERT的稠密输出映射为整个词表上的稀疏权重分布。训练时使用FLOPS正则化来鼓励稀疏性——即只让少量词汇获得非零权重。推理时,SPLADE为每个文档生成一个稀疏向量(大部分维度为零,仅少量词汇维度非零),查询和文档之间的相似度通过稀疏向量的点积计算。
SPLADE在BEIR基准上的表现令人印象深刻:在零样本设置下,SPLADE的性能显著优于传统的BM25,并且与许多稠密检索方法相当甚至更优。更重要的是,SPLADE保留了稀疏检索的可解释性优势——可以清楚地看到哪些词汇对匹配贡献了权重,这在需要解释检索结果的场景中非常有价值。SPLADE的改进版本SPLADEv2进一步提升了性能,在BEIR基准上取得了当时最优的稀疏检索结果。
[3] Formal et al. SPLADE: Sparse Lexical and Expansion Model for First Stage Ranking. SIGIR 2021. arXiv:2109.10086
[12] Thakur et al. BEIR Benchmark. NeurIPS 2021. arXiv:2104.08663
6.4.2 BM25 + 向量检索的融合策略
BM25(Best Matching 25)是信息检索领域最经典的排序算法之一,由Robertson和Zaragoza在2009年的综述论文中系统总结。BM25基于概率检索框架,通过计算查询词在文档中的词频(TF)、逆文档频率(IDF)和文档长度归一化因子来评估文档与查询的相关性。尽管BM25已有数十年历史,但它在精确关键词匹配方面的优势使其至今仍是许多检索系统的核心组件。
BM25的核心公式为:score(D, Q) = sum_{qi in Q} IDF(qi) * (f(qi, D) * (k1 + 1)) / (f(qi, D) + k1 * (1 - b + b * |D| / avgdl)),其中f(qi, D)是词qi在文档D中的词频,|D|是文档长度,avgdl是平均文档长度,k1和b是调节参数(通常k1=1.2到2.0,b=0.75)。IDF部分用于降低常见词的权重、提升稀有词的权重。BM25的优势在于计算效率极高(仅需词频统计)、对精确匹配敏感、且不需要训练数据。
将BM25与向量检索结合的混合检索架构是目前RAG系统的主流方案。实现混合检索的关键在于如何融合两种检索方法的排序结果。以下表格对比了四种主流的融合方法:
| 融合方法 | 核心原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| Reciprocal Rank Fusion (RRF) | 基于排名倒数求和 | 简单有效,无需训练 | 忽略分数绝对值 | 通用推荐方案 |
| 加权分数融合 | 对两路分数加权求和 | 灵活,可调权重 | 分数尺度不同需归一化 | 有标注数据可调参 |
| 级联检索 | 先稀疏后稠密(或反之) | 流程简单 | 可能遗漏另一路的好结果 | 对延迟敏感的场景 |
| 学习型融合 | 使用ML模型学习融合权重 | 效果最优 | 需要标注数据,复杂度高 | 有充足训练数据 |
Reciprocal Rank Fusion(RRF)是Cormack等人在2009年提出的一种简单而有效的排序融合方法。RRF的核心思想是:对于每个候选文档,计算其在各路检索结果中的排名的倒数之和,作为最终的融合得分。具体公式为:RRF_score(d) = sum_{r in R} 1 / (k + rank_r(d)),其中R是检索方法的集合,rank_r(d)是文档d在第r路检索中的排名,k是一个平滑常数(通常设为60)。RRF的优势在于它只依赖排名信息,不需要对分数进行归一化,因此可以无缝融合来自不同检索方法的排序结果。
加权分数融合是另一种常用的融合方法。它将BM25的分数和向量检索的余弦相似度分数分别乘以权重系数后相加:final_score = alpha * bm25_score + (1 - alpha) * cosine_score。权重alpha控制两路检索的相对重要性,通常需要通过实验调优。需要注意的是,BM25分数和余弦相似度分数的尺度可能不同,融合前需要进行归一化处理(如Min-Max归一化或Z-Score标准化)。
RRF融合实现示例
def reciprocal_rank_fusion(results_list, k=60):
fused_scores = {}
for results in results_list:
for rank, doc_id in enumerate(results):
if doc_id not in fused_scores:
fused_scores[doc_id] = 0
fused_scores[doc_id] += 1.0 / (k + rank + 1)
ranked = sorted(fused_scores.items(),
key=lambda x: x[1], reverse=True)
return ranked
融合BM25和向量检索结果
bm25_results = bm25.search(query, top_k=50)
vector_results = vector_db.search(query, top_k=50)
fused = reciprocal_rank_fusion([bm25_results, vector_results])
[9] Cormack, G.V. et al. Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods. SIGIR 2009.
[11] Robertson, S. and Zaragoza, H. The Probabilistic Relevance Framework: BM25 and Beyond. Foundations and Trends in IR, 2009.
[12] Thakur et al. BEIR Benchmark. NeurIPS 2021. arXiv:2104.08663
6.4.3 权重调优与自适应混合
在混合检索中,如何确定稀疏检索和稠密检索的融合权重是一个关键问题。固定的权重设置可能无法适应所有类型的查询——对于包含精确术语的查询,BM25的权重应该更高;对于语义性强的查询,向量检索的权重应该更高。自适应混合(Adaptive Hybrid)技术旨在根据查询的特征动态调整融合权重。
基于查询特征的自适应方法通过分析查询的文本特征来预测最优权重。常用的查询特征包括:查询长度(短查询通常更适合BM25)、查询中的命名实体比例(实体多则BM25权重应更高)、查询的语义模糊度(模糊查询更适合向量检索)、以及查询与知识库中文档的平均相似度分布。这些特征可以输入到一个简单的回归模型或分类器中,输出最优的融合权重。
基于置信度的自适应方法是一种更直观的策略。其核心思想是:如果两路检索对某个查询的排序结果高度一致(即同一个文档在两路检索中都排名靠前),则说明该查询的类型对两种方法都适用,可以使用均衡的权重;如果两路检索的排序结果差异很大,则需要根据查询特征选择更信任的一路。具体实现上,可以计算两路检索Top-K结果的Kendall tau相关系数或重叠率(Overlap Rate),作为权重调整的依据。
在实际工程中,建议采用以下渐进式策略:首先使用RRF作为默认融合方法(因为它不需要调参且效果稳定),然后在积累了一定的查询日志和用户反馈数据后,尝试基于数据的加权融合或自适应方法。对于大多数应用场景,RRF已经能够提供优秀的融合效果,在BEIR基准上的表现通常优于单一的BM25或向量检索。
[9] Cormack, G.V. et al. Reciprocal Rank Fusion. SIGIR 2009.
[12] Thakur et al. BEIR Benchmark. NeurIPS 2021. arXiv:2104.08663
6.5 新一代检索范式:ColPali与VLM-based检索
传统的RAG检索流程遵循“OCR/文本提取 -> 文本分块 -> 文本嵌入 -> 向量检索”的固定范式。这一范式在面对结构良好的纯文本文档时效果出色,但在处理包含复杂排版、表格、图表、公式和图片的文档时面临巨大挑战。OCR错误、表格结构丢失、图表信息无法提取等问题严重制约了传统检索方法在复杂文档场景下的效果。基于视觉语言模型(Vision-Language Model, VLM)的ColPali检索范式提出了一种革命性的新路径:直接使用文档的视觉表示进行检索,完全绕过了OCR和文本分块环节。
6.5.1 ColPali / ColQwen2的原理:基于视觉语言模型的文档检索
ColPali由Faysse等人在2024年提出(arXiv:2407.01449),其核心思想是利用视觉语言模型(VLM)直接将文档页面图像编码为向量表示,实现端到端的视觉文档检索。ColPali的名称来源于“ColBERT + PaliGemma”——它借鉴了ColBERT的晚期交互(Late Interaction)机制,并使用PaliGemma作为基础视觉语言模型。
ColPali的工作流程如下:首先,将文档的每一页渲染为高分辨率图像(通常使用PDF渲染工具将PDF页面转换为PNG图像);然后,将页面图像输入视觉语言模型(如PaliGemma),模型为图像中的每个视觉token生成一个嵌入向量;查询文本则通过文本编码器生成每个token的嵌入向量;最后,使用ColBERT风格的晚期交互机制计算查询和文档之间的相关性分数——即将查询中每个token的向量与文档中每个token的向量计算最大相似度(MaxSim),然后对所有查询token的MaxSim分数求和。
晚期交互(Late Interaction)是ColPali的关键技术。与双编码器(将整个文档压缩为一个向量)不同,晚期交互保留了文档中每个token的独立向量表示,使得检索时可以进行细粒度的token级别匹配。例如,当查询为“2024年第三季度收入”时,晚期交互可以精确匹配文档图像中“2024”、“Q3”和“收入”等关键词所在的区域,即使这些关键词分散在文档的不同位置。这种细粒度的匹配能力使得ColPali在复杂文档检索任务上显著优于传统的文本嵌入方法。
ColQwen2是ColPali架构的后续改进版本,使用Qwen2-VL作为基础视觉语言模型。Qwen2-VL在视觉理解能力上比PaliGemma更强,特别是在处理高分辨率图像和复杂排版方面。ColQwen2在多个文档检索基准上取得了当时最优的成绩,证明了基于VLM的文档检索范式的巨大潜力。
[4] Faysse, M. et al. ColPali: Efficient Document Retrieval with Vision Language Models. arXiv:2407.01449, 2024.
6.5.2 绕过OCR+文本分块的新路径
ColPali/VLM-based检索范式最革命性的意义在于它完全绕过了传统RAG流程中的OCR和文本分块环节。在传统流程中,OCR和文本分块是两个最脆弱的环节:OCR可能产生识别错误(特别是对手写体、低质量扫描件和复杂排版),文本分块可能破坏文档的结构完整性(特别是表格和跨页内容)。这些错误会在后续流程中被放大,最终影响检索和生成的质量。
ColPali的新路径将文档页面直接作为图像处理,避免了OCR引入的错误。视觉语言模型能够直接“看到”文档中的所有视觉元素——文字、表格、图表、公式、图片、布局等——并将其统一编码为向量表示。这意味着表格中的数据、图表中的信息、公式中的符号等传统方法难以提取的内容,在ColPali框架下可以被自然地纳入检索范围。
此外,ColPali还简化了RAG系统的整体架构。传统RAG系统需要维护复杂的文档处理管道(PDF解析 -> OCR -> 文本提取 -> 结构化处理 -> 文本分块 -> 向量化),每个环节都需要专门的工具和调优。ColPali将这一管道大幅简化为:PDF页面渲染 -> 图像向量化 -> 检索。这种简化不仅降低了系统的开发和维护成本,还减少了错误传播的环节。
然而,ColPali目前也存在一些局限性:视觉token的存储成本远高于文本token(一个文档页面可能产生数千个视觉token的向量),导致索引存储需求大幅增加;视觉语言模型的推理成本高于文本嵌入模型,检索延迟较高;对于纯文本文档,ColPali的优势不明显,传统文本检索可能更高效。因此,ColPali最适合处理包含复杂视觉元素的文档(如扫描件、包含表格和图表的技术文档、学术论文等)。
[4] Faysse, M. et al. ColPali: Efficient Document Retrieval with Vision Language Models. arXiv:2407.01449, 2024.
6.5.3 多语言与复杂排版文档的优势
ColPali/VLM-based检索在多语言文档和复杂排版文档场景中展现出独特的优势。在多语言场景中,传统OCR方法需要针对不同语言配置不同的OCR引擎和语言模型,且对混合语言文档(如中英混排)的处理效果往往不理想。视觉语言模型则天然具备多语言理解能力——Qwen2-VL等模型在训练时已经接触了大量多语言图文数据,能够直接处理包含中文、英文、日文等多种语言的文档图像。
在复杂排版文档场景中,ColPali的优势更加明显。现代文档的排版日益复杂——多栏布局、嵌入表格、浮动图表、脚注尾注、页眉页脚等元素交织在一起。传统OCR和文本提取工具在处理这些复杂排版时经常出现错位、漏识别和结构混乱等问题。视觉语言模型则能够理解文档的整体布局和空间关系,将不同位置的文本和视觉元素正确地关联起来。
以下表格对比了传统文本检索和ColPali视觉检索在不同文档类型上的适用性:
| 文档类型 | 传统文本检索 | ColPali视觉检索 | 推荐方案 |
|---|---|---|---|
| 纯文本文档(如小说、新闻) | 优秀 | 良好 | 传统文本检索(效率更高) |
| 结构化文档(如Markdown、HTML) | 优秀 | 良好 | 传统文本检索 |
| 包含表格的文档(如财报、数据报告) | 中等(表格结构易丢失) | 优秀(直接理解表格图像) | ColPali视觉检索 |
| 学术论文(含公式、图表、引用) | 中等(公式和图表难提取) | 优秀(视觉理解公式和图表) | ColPali视觉检索 |
| 扫描件PDF(如历史文档、手写体) | 差(OCR错误率高) | 优秀(直接处理图像) | ColPali视觉检索 |
| 多语言混排文档 | 差(需要多语言OCR) | 优秀(VLM天然多语言) | ColPali视觉检索 |
| 多栏排版文档(如杂志、报纸) | 中等(栏序易错乱) | 优秀(理解空间布局) | ColPali视觉检索 |
| 技术手册(含截图、流程图) | 差(截图信息丢失) | 优秀(理解视觉元素) | ColPali视觉检索 |
随着视觉语言模型能力的持续提升和推理成本的不断降低,ColPali/VLM-based检索有望成为RAG系统处理复杂文档的主流方案。目前,对于同时包含纯文本文档和复杂文档的企业知识库,一种务实的策略是采用混合方案:对纯文本文档使用传统的文本检索,对复杂文档使用ColPali视觉检索,然后在重排序阶段统一融合两路检索结果。
[4] Faysse, M. et al. ColPali: Efficient Document Retrieval with Vision Language Models. arXiv:2407.01449, 2024.
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
6.6 多轮检索与迭代检索
在许多实际应用场景中,单次检索往往不足以获取回答用户问题所需的全部信息。特别是在多跳推理(Multi-hop Reasoning)场景中,回答一个问题可能需要综合多个文档或多个知识片段的信息。此外,用户的初始查询可能表述模糊或不完整,需要通过分析初步检索结果来优化查询并再次检索。多轮检索(Multi-round Retrieval)和迭代检索(Iterative Retrieval)技术正是为了解决这些复杂场景下的信息获取需求而发展起来的。
6.6.1 多轮检索的动机与场景
多轮检索的核心动机源于以下三个方面的需求。第一,信息分散性:用户的问题可能涉及多个不同的主题或实体,相关信息分散在知识库的不同文档中,单次检索难以全面覆盖。例如,用户询问“比较Transformer和RNN在机器翻译任务上的优劣”,相关信息可能分布在不同论文的不同章节中,需要多次检索才能收集完整。
第二,查询模糊性:用户的初始查询往往不够精确或完整。例如,用户可能只输入“RAG”三个字母,而实际想了解的是“RAG技术在企业知识库中的应用案例”。通过初步检索获取一些相关文档后,系统可以分析这些文档的内容,推断用户的真实意图,然后生成更精确的查询进行二次检索。这种“检索-分析-再检索”的迭代过程能够显著提升检索的准确性。
第三,多跳推理需求:许多复杂问题需要多步推理才能回答。例如,“图灵奖获得者中,有哪些人曾参与深度学习的研究?”这个问题需要先检索图灵奖获得者列表,再从中筛选参与深度学习研究的人。每一步推理都可能需要额外的检索来获取支撑信息。Self-RAG和FLARE等迭代检索框架正是为这类多跳推理场景设计的。
多轮检索的典型应用场景包括:复杂问答系统(需要综合多个信息源)、对话式RAG(需要根据对话历史动态调整检索策略)、研究报告生成(需要从多个角度收集信息)、以及决策支持系统(需要全面收集相关证据)。在这些场景中,多轮检索能够显著提升系统的信息覆盖面和答案质量。
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
[2] Lewis et al. RAG. NeurIPS 2020. arXiv:2005.11401
6.6.2 迭代检索的实现方式
迭代检索是指在RAG流程中,检索步骤不是一次性完成的,而是根据生成过程中的需求动态触发多轮检索。近年来,研究者提出了多种迭代检索框架,以下介绍两种最具代表性的方法:FLARE和Self-RAG。
FLARE(Forward-Looking Active REtrieval Augmented Generation)由Jiang等人在2023年提出(arXiv:2305.06983),其核心思想是让模型“主动”决定何时需要检索。FLARE的工作原理如下:在生成过程中,模型逐个token地生成回答。当模型对下一个token的生成信心较低时(通过计算下一个token的概率分布的熵或top-1概率来判断),系统触发一次检索——将已生成的内容作为查询(或基于已生成内容生成一个查询),从知识库中检索相关文档,然后将检索结果注入到模型的上下文中,辅助后续的生成。
FLARE的关键创新在于其“前瞻性”(Forward-Looking)的检索触发机制。与被动检索(在生成之前一次性检索所有上下文)不同,FLARE让模型在生成过程中根据需要动态触发检索,类似于人类在写作过程中查阅资料的行为。这种机制的优势在于:只有在真正需要外部信息时才触发检索,避免了不必要检索带来的噪声干扰;检索到的信息与当前生成上下文高度相关,提高了信息的利用率。实验表明,FLARE在多个问答基准上显著优于标准RAG方法。
Self-RAG由Asai等人在2023年提出(arXiv:2310.11511),其核心思想是在生成过程中引入多个“反思token”(Reflection Tokens),让模型自主判断是否需要检索、检索结果是否相关、以及生成的答案是否有充分支撑。Self-RAG训练模型生成三种特殊的反思token:Retrieve(是否需要检索)、IsRel(检索结果是否相关)和IsSup(生成的陈述是否有支撑)。
Self-RAG的完整工作流程如下:当模型生成一个陈述后,它会生成一个Retrieve token来判断是否需要检索来支撑该陈述。如果判断需要检索,系统执行检索并将结果加入上下文,模型再生成IsRel token来评估检索结果的相关性。如果检索结果相关,模型利用检索结果生成或修正陈述,然后生成IsSup token来确认最终陈述是否有充分的证据支撑。这种多轮的自我反思机制使得Self-RAG能够在需要时主动检索信息,在不需要时直接生成,实现了检索和生成的深度耦合。
以下表格对比了FLARE和Self-RAG两种迭代检索框架:
| 特性 | FLARE | Self-RAG |
|---|---|---|
| 提出时间 | 2023年(arXiv:2305.06983) | 2023年(arXiv:2310.11511) |
| 检索触发机制 | 基于生成置信度(低置信度时触发) | 基于反思token(模型自主判断) |
| 是否需要微调 | 不需要(可即插即用) | 需要(训练反思token生成能力) |
| 检索粒度 | 段落级别 | 段落级别 |
| 核心优势 | 实现简单,即插即用 | 效果最优,可控性强 |
| 计算开销 | 中等(按需检索) | 较高(反思推理开销) |
| 适用场景 | 快速集成到现有RAG系统 | 追求极致效果的定制系统 |
FLARE检索触发逻辑示例(简化版)
def generate_with_flare(model, query, retriever, threshold=0.3):
response = ""
for step in range(max_steps):
# 获取下一个token的概率分布
logits = model.get_next_token_logits(query + response)
probs = softmax(logits)
max_prob = max(probs)
if max_prob < threshold: # 低置信度,触发检索
retrieved_docs = retriever.search(response[-200:])
context = "\n".join(retrieved_docs)
# 将检索结果注入上下文
response = model.generate(query + context)
else:
token = sample_from_probs(probs)
response += token
return response
[5] Jiang, Z. et al. Active Retrieval Augmented Generation. EMNLP 2023. arXiv:2305.06983
[6] Asai, A. et al. Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection. ICLR 2024. arXiv:2310.11511
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
6.6.3 多轮检索的最佳实践
在实际的RAG系统开发中,多轮检索和迭代检索的引入需要谨慎考虑以下因素:
检索轮次的控制:多轮检索的轮数不宜过多。通常建议最多进行2到3轮检索。过多的检索轮次不仅会增加系统延迟和计算成本,还可能引入越来越多的噪声信息,反而降低生成质量。建议设置一个检索轮次上限,并在每轮检索后评估检索结果的质量——如果新增的检索结果与已有结果高度重复或相关性很低,应提前终止检索过程。
查询演化策略:在多轮检索中,每一轮的查询应该如何构造是一个关键问题。常见的查询演化策略包括:查询扩展(Query Expansion)——在原始查询基础上添加同义词或相关术语;查询精化(Query Refinement)——根据上一轮检索结果调整查询表述;子查询分解(Sub-query Decomposition)——将复杂查询分解为多个简单的子查询分别检索;以及查询压缩(Query Compression)——去除查询中的冗余信息。在实际应用中,可以使用LLM来自动执行查询演化。
结果去重与合并:多轮检索可能返回重复或高度相似的文档。在将多轮检索结果送入生成模型之前,需要进行去重处理。去重可以使用精确去重(基于文档ID)和模糊去重(基于文本相似度)两种方式。此外,多轮检索的结果应该统一进行重排序,以确保最终送入生成模型的结果是最相关且最多样化的。
延迟与成本的权衡:多轮检索会显著增加系统的端到端延迟。每次额外的检索都需要额外的向量搜索时间(毫秒级)和重排序时间(十到百毫秒级)。对于实时性要求高的应用(如在线客服),建议限制检索轮次为1到2轮,并使用缓存策略减少重复检索。对于对延迟不敏感的应用(如研究报告生成),可以适当增加检索轮次以提升信息覆盖面。
监控与评估:多轮检索引入了更多的可变因素,需要建立完善的监控体系。建议监控以下指标:每轮检索的召回率和精度、检索触发率(多少比例的查询触发了多轮检索)、端到端延迟分布、以及最终生成答案的质量。这些指标可以帮助开发者识别多轮检索中的问题,并进行针对性的优化。
[1] Gao et al. RAG Survey. 2024. arXiv:2312.10997
[5] Jiang, Z. et al. FLARE. EMNLP 2023. arXiv:2305.06983
[6] Asai, A. et al. Self-RAG. ICLR 2024. arXiv:2310.11511
本章系统性地介绍了RAG在线检索的完整技术体系。我们从查询向量化和相似度计算的基础知识出发(6.1节),介绍了余弦相似度、欧氏距离和点积三种主流度量方式的原理和选择建议。在基础检索策略方面(6.2节),我们详细讨论了Top-K检索的原理、相似度阈值过滤、MMR多样性检索以及Top-K参数的选择建议。
在检索结果重排序方面(6.3节),我们深入分析了两阶段检索架构的优势,介绍了Cohere Rerank、BGE-Reranker等主流重排序模型,并提供了重排序模块的最佳实践。在混合检索方面(6.4节),我们介绍了SPLADE等稀疏-密集混合检索方法,详细讨论了BM25与向量检索的融合策略(特别是RRF方法),以及权重调优与自适应混合技术。
在新一代检索范式方面(6.5节),我们介绍了ColPali/ColQwen2基于视觉语言模型的文档检索方法,分析了其绕过OCR和文本分块的新路径,以及在多语言和复杂排版文档场景中的独特优势。在多轮检索方面(6.6节),我们讨论了多轮检索的动机和场景,介绍了FLARE和Self-RAG两种迭代检索框架,并提供了多轮检索的最佳实践。
这些检索技术共同构成了一个从基础到前沿、从通用到专用的完整技术图谱。在实际的RAG系统开发中,建议采用渐进式的技术选型策略:从基础的Top-K检索开始,逐步引入重排序和混合检索来提升效果,对于复杂文档场景考虑ColPali等新范式,对于复杂推理场景考虑迭代检索技术。
在下一章中,我们将进入RAG系统的最后一个核心环节——生成与增强。我们将讨论如何将检索到的上下文与用户查询一起输入到大语言模型中,生成准确、完整且有据可依的回答。生成阶段的质量直接决定了RAG系统的最终用户体验,而检索阶段提供的上下文质量是生成质量的根本保障。通过本章介绍的检索技术,我们已经为高质量的生成奠定了坚实的基础。
参考文献
[1] Gao, Y. et al. Retrieval-Augmented Generation for Large Language Models: A Survey. 2024. arXiv:2312.10997
[2] Lewis, P. et al. Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. NeurIPS 2020. arXiv:2005.11401
[3] Formal, T. et al. SPLADE: Sparse Lexical and Expansion Model for First Stage Ranking. SIGIR 2021. arXiv:2109.10086
[4] Faysse, M. et al. ColPali: Efficient Document Retrieval with Vision Language Models. 2024. arXiv:2407.01449
[5] Jiang, Z. et al. Active Retrieval Augmented Generation. EMNLP 2023. arXiv:2305.06983
[6] Asai, A. et al. Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection. ICLR 2024. arXiv:2310.11511
[7] Cohere. Rerank API Documentation. docs.cohere.com/docs/rerank
[8] BAAI FlagEmbedding. BGE-Reranker. github.com/FlagOpen/Fl…
[9] Cormack, G.V. et al. Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods. SIGIR 2009.
[10] Carbonell, J. and Goldstein, J. The Use of MMR, Diversity-Based Reranking for Reordering Documents and Producing Summaries. SIGIR 1998.
[11] Robertson, S. and Zaragoza, H. The Probabilistic Relevance Framework: BM25 and Beyond. Foundations and Trends in IR, 2009.
[12] Thakur, N. et al. BEIR: A Heterogeneous Benchmark for Zero-Shot Evaluation of Information Retrieval Models. NeurIPS 2021. arXiv:2104.08663