RAG过程有两个阶段,一是召回,二是重排
召回:快速进行检索,数据库中1000万chunk, 快速召回1000个相关的chunk,不用很精确;
重排:精确的工作由重排实现,比如重排取 Top5的内容;
RAG的难点主要有两个,一个是前期的文档处理;二是数据的召回;由于大模型本身无法分辨输入到模型中的文档质量,因此关于数据的召回只能进行人为的控制,而人为控制的方法只能通过技术手段来进行约束,下面是常用的策略
1. 改进检索算法
知识图谱:利用知识图谱中的语义信息和实体关系,增强对查询和文档的理解,提升召回的相关性
2. 引入重排序(Reranking)
重排序模型:对召回结果进行重排,提升问题和文档的相关性。常见的重排序模型有BGE-Rerank和Cohere Rerank。
场景: 用户查询“如何提高深度学习模型的训练效率?”
召回结果:初步召回10篇文档,其中包含与“深度学习”、“训练效率”相关的文章。
重排序:BGE-Rerank对召回的10篇文档进行重新排序,将与“训练效率”最相关的文档(如“优化深度学习训练的技巧”)排在最前面,而将相关性较低的文档(如“深度学习基础理论”)排在后面。
重排序Rerank主要用于优化初步检索结果的排序,提高最终输出的相关性或准确性。BGE-Rerank和Cohere Rerank是两种广泛使用的重排序模型,它们在检索增强生成(RAG)系统、搜索引擎优化和问答系统中表现优异。
2.1 BGE-Rerank
由北京智源人工智能研究院(BAAI)开源发布,属于FlagEmbedding项目的一部分。基于Transformer的Cross-Encoder结构,直接计算查询(Query)与文档(Document)的交互相关性得分。
训练数据:支持多语言(中、英等),训练数据包括T2Ranking、MSMARCO、NLI等数据集。
提供bge-reranker-base和bge-reranker-large两个版本,后者在精度上更优。
优点:开源免费,适合本地化部署,保护数据隐私。在中文任务中表现优秀,适用于垂直领域优化。
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('BAAI/bge-reranker-large')
model = AutoModelForSequenceClassification.from_pretrained('BAAI/bge-reranker-large')
model.eval()
pairs = [['what is panda?', 'The giant panda is a bear species endemic to China.']]
inputs = tokenizer(pairs, padding=True, truncation=True, return_tensors='pt')
scores = model(**inputs).logits.view(-1).float()
print(scores) # 输出相关性分数 4.9538
2.2 Cohere Rerank
由Cohere公司提供的商业API服务。基于专有的深度学习模型,支持多语言(如rerank-multilingual-v3.0)。
训练数据:优化了语义匹配,特别适用于混合检索(如结合BM25和向量检索)后的结果优化。
使用方式:通过API调用,集成到LangChain、LlamaIndex等框架中。
优点:简单易用,适合快速集成到现有系统。在英文和多语言任务中表现优异,如提升Hit Rate(命中率)和MRR(平均倒数排名)。
import cohere
co = cohere.Client(api_key="YOUR_API_KEY")
query = "What is the capital of France?"
docs = ["Paris is the capital of France.", "Berlin is the capital of Germany."]
results = co.rerank(query=query, documents=docs, top_n=2, model='rerank-multilingual-v3.0')
print(results) #Cohere Rerank的API返回的是归一化后的相关性分数(如0-1),更易解释。
cohere-reranker.py
特性 BGE-Rerank Cohere Rerank
3. 优化查询扩展
3.1 相似语义改写
使用大模型将用户查询改写成多个语义相近的查询,提升召回多样性。例如,LangChain的MultiQueryRetriever支持多查询召回,再进行回答问题。
# 加载向量数据库,添加allow_dangerous_deserialization=True参数以允许反序列化
vectorstore = FAISS.load_local("./faiss-1", embeddings, allow_dangerous_deserialization=True)
# 创建MultiQueryRetriever
retriever = MultiQueryRetriever.from_llm(
retriever=vectorstore.as_retriever(),
llm=llm
)
query = "客户经理的考核标准是什么?"
# 执行查询
results = retriever.get_relevant_documents(query)
3.2 双向改写
将查询改写成文档(Query2Doc)或为文档生成查询(Doc2Query),缓解短文本向量化效果差的问题。
4. 索引扩展
4.1 离散索引扩展
使用关键词抽取、实体识别等技术生成离散索引,与向量检索互补,提升召回准确性。
关键词抽取:从文档中提取出重要的关键词,作为离散索引的一部分,用于补充向量检索的不足。
实体识别:从文档中识别出命名实体(如人名、地点、组织等),作为离散索引的一部分,增强检索的精确性。
4.2 连续索引扩展
结合多种向量模型(如OpenAI的Ada、智源的BGE)进行多路召回,取长补短。
4.3 混合索引召回
将离散索引(如关键词、实体)与向量索引结合,通过混合召回策略提升检索效果。
4.4 Small-to-Big 索引策略
一种高效的检索方法,特别适用于处理长文档或多文档场景。核心思想是通过小规模内容(如摘要、关键句或段落)建立索引,并链接到大规模内容主体中。这种策略的优势在于能够快速定位相关的小规模内容,并通过链接获取更详细的上下文信息,从而提高检索效率和答案的逻辑连贯性。
Small-to-Big机制:
- 小规模内容检索:用户输入查询后,系统首先在小规模内容(如摘要、关键句或段落)中检索匹配的内容。小规模内容通常是通过摘要生成、关键句提取等技术从大规模内容中提取的,并建立索引。
- 链接到大规模内容:当小规模内容匹配到用户的查询后,系统会通过预定义的链接(如文档 ID、URL 或指针)找到
对应的大规模内容(如完整的文档、文章)。大规模内容包含更详细的上下文信息,为 RAG 提供丰富的背景知识。 - 上下文补充:将大规模内容作为 RAG 系统的上下文输入,结合用户查询和小规模内容,生成更准确和连贯的答案。