RAG(检索增强生成)技术中,R 代表 Retrieval(检索),这一环节对最终生成质量至关重要。基于向量(Vector)的语义检索是最为熟知的基础模式,但在实际应用中,仅使用单一向量检索往往难以满足多样化的复杂需求。在模块化 RAG 的时代,许多新范式与算法都对检索环节进行了大量创新与优化。本文将深入探讨两种在 RAG 应用中可灵活应用的高级检索模式:融合检索(Fusion Retrieval)与递归检索(Recursive Retrieval)。
融合检索(Fusion Retrieval)
融合检索是一种结合多维度检索的方法。简单来说,就是通过多个不同的检索方法进行查询检索,并对召回的结果通过排序算法(如 RRF)重新排序融合后用于后续生成。融合检索可以组合多路不同维度的检索结果,以弥补单个向量索引在检索精确性上的不足。
1. 实现多路检索的方式
在实际应用中,可以根据自身需要选择不同的形式来实现多路检索:
- 基于问题重写与扩展:借助查询重写(Query Rewriter)或查询转换器对输入问题进行扩展,生成多个不同表达形式或不同角度细化的输入问题。对每个问题分别进行检索,然后对召回的知识块(Chunks)通过重排(Reranker)模块进行重新排序,并取最终的 Top-K 用于后续生成环节。
- 基于多种类型的索引:尽管基于高维向量的索引在很多场景下的自然语言语义检索表现不错,但并非全能。例如,你可能想借助知识图谱索引来更精确地获取实体之间的复杂关系;或者借助树状的摘要索引来更好地回答概要性问题。因此,可以同时通过多路不同类型的索引(如向量索引与关键词索引)对输入问题进行检索,并对召回的知识块进行重排序处理后获取 Top-K。
- 基于复合方案的多路检索:这是对上面两种方法的组合。即同时借助于问题扩展与索引扩展来实现更多路的知识召回,再通过重新排序获得 Top-K。这种组合方法由于召回了更多的 Chunks,有利于获取更相关的知识,但同时也增加了系统性能的消耗与模型使用的成本,在实际使用时需要根据测试结果进行取舍。
2. 融合检索的关键技术与代码示例
实现融合检索并不复杂,不管在 LangChain 还是 LlamaIndex 框架中,都有转换器(Rewriter)、检索器(Retriever)、排序器(Reranker)的概念与组件,可以自行组合来实现融合检索。
- 查询扩展:借助 LLM 自行实现;或者借助已有组件,比如 LlamaIndex 中的 QueryTransform 组件。
- Reranker:自行实现 RRF(Reciprocal Rank Fusion)算法函数,或者借助 Cohere Reranker 这样的专业排序模型实现。
- 检索融合:扩展已有的 Retriever 组件,实现自定义融合检索器;有的框架有现成的融合检索器,比如 LlamaIndex 的
QueryFusionRetriever。
以下是一个典型的融合检索器扩展的 Python 代码示例(基于 LangChain):
from langchain.retrievers import ContextualCompressionRetriever, MultiQueryRetriever
from langchain.vectorstores import FAISS
from langchain.llms import OpenAI
from langchain.embeddings import HuggingFaceEmbeddings
# 初始化向量存储和检索器
embeddings = HuggingFaceEmbeddings()
db = FAISS.load_local("./faiss_index", embeddings)
llm = OpenAI(temperature=0)
# 创建多路查询检索器
multi_query_retriever = MultiQueryRetriever.from_llm(
retriever=db.as_retriever(), llm=llm
)
# 执行查询
query =
relevant_docs = multi_query_retriever.get_relevant_documents(query)


