微信扫码
添加专属顾问
我要投稿
前言
在《RAG实战篇:构建一个最小可行性的Rag系统》中,风叔详细介绍了Rag系统的实现框架,以及如何搭建一个最基本的Naive Rag。
在前面四篇文章中,风叔分别介绍了索引(Indexing)、查询转换(Query Translation)、路由(Routing)和查询构建(Query Construction)环节的优化方案。
在这篇文章中,围绕检索召回(Retrieval),风叔详细介绍如何优化RAG系统的召回结果,提升LLM大模型的回答准确度。
在检索召回的时候,用户的问题会被输入到嵌入模型中进行向量化处理,然后系统会在向量数据库中,搜索与该问题向量语义上相似的知识文本或历史对话记录并返回。
在Naive Rag中,系统会将所有检索到的块直接输入到 LLM生成回答,导致出现中间内容丢失、噪声占比过高、上下文长度限制等问题。
下面,我们结合源代码,详细介绍下Reranking(重排序)、Refinement(压缩)和Corrective Rag(纠正性Rag)这三种优化召回准确率的方案。
具体的源代码地址可以在文末获取。
1. Rerank(重排序)
重排序,顾名思义,就是将检索召回的结果,按照一定的规则或逻辑重新排序,从而将相关性或准确度更高的结果排在前面,提升检索质量。
重排序主要有两种类型,基于统计打分的重排序和基于深度学习的重排序。
在《RAG实战篇:优化查询转换的五种高级方法,让大模型真正理解用户意图》一文中,提到RAG Fusion 中的 reciprocal_rank_fusion 就是一种基于统计打分的重排序,我们再来回顾一下,如以下代码所示:
def reciprocal_rank_fusion(results: list[list], k=60):""" Reciprocal_rank_fusion that takes multiple lists of ranked documentsand an optional parameter k used in the RRF formula """# Initialize a dictionary to hold fused scores for each unique documentfused_scores = {}# Iterate through each list of ranked documentsfor docs in results:# Iterate through each document in the list, with its rank (position in the list)for rank, doc in enumerate(docs):# Convert the document to a string format to use as a key (assumes documents can be serialized to JSON)doc_str = dumps(doc)# If the document is not yet in the fused_scores dictionary, add it with an initial score of 0if doc_str not in fused_scores:fused_scores[doc_str] = 0# Retrieve the current score of the document, if anyprevious_score = fused_scores[doc_str]# Update the score of the document using the RRF formula: 1 / (rank + k)fused_scores[doc_str] += 1 / (rank + k)# Sort the documents based on their fused scores in descending order to get the final reranked resultsreranked_results = [(loads(doc), score)for doc, score in sorted(fused_scores.items(), key=lambda x: x[1], reverse=True)]# Return the reranked results as a list of tuples, each containing the document and its fused scorereturn reranked_results
from langchain_community.llms import Coherefrom langchain.retrievers importContextualCompressionRetrieverfrom langchain.retrievers.document_compressors import CohereRerankfrom langchain.retrievers.document_compressors import CohereRerankretriever = vectorstore.as_retriever(search_kwargs={"k": 10})# Re-rankcompressor = CohereRerank()compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever=retriever)compressed_docs = compression_retriever.get_relevant_documents(question)
2. Refinement(压缩)
压缩,即对于检索到的内容块,不要直接输入大模型,而是先删除无关内容并突出重要上下文,从而减少整体提示长度,降低冗余信息对大模型的干扰。
langchain中有一个基础的上下文压缩检索器可以使用,叫做ContextualCompressionRetriever。
from langchain.retrievers import ContextualCompressionRetrieverfrom langchain.retrievers.document_compressors import LLMChainExtractorfrom langchain_openai import OpenAIllm = OpenAI(temperature=0)compressor = LLMChainExtractor.from_llm(llm)compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever=retriever)compressed_docs = compression_retriever.invoke("What did the president say about Ketanji Jackson Brown")
LLMChainFilter是一个稍微简单但更强大的压缩器,它使用 LLM 链来决定过滤掉哪些最初检索到的文档以及返回哪些文档,而无需操作文档内容
from langchain.retrievers.document_compressors import LLMChainFilter_filter = LLMChainFilter.from_llm(llm)compression_retriever = ContextualCompressionRetriever(base_compressor=_filter, base_retriever=retriever)compressed_docs = compression_retriever.invoke("What did the president say about Ketanji Jackson Brown")pretty_print_docs(compressed_docs)
3. Corrective Rag(纠错性Rag)
Corrective-RAG (CRAG) 是一种 RAG 策略,它结合了对检索到的文档进行自我反思/自我评分。
CRAG 增强生成的方式是使用轻量级的“检索评估器”,该评估器为每个检索到的文档返回一个置信度分数,然后该分数决定触发哪种检索操作。例如评估器可以根据置信度分数将检索到的文档标记为三个桶中的一个:正确、模糊、不正确。
如果所有检索到的文档的置信度分数均低于阈值,则假定检索“不正确”。这会触发采取新的知识来源(例如网络搜索)的行动,以实现生成的质量。
如果至少有一个检索到的文档的置信度分数高于阈值,则假定检索“正确”,这会触发对检索到的文档进行知识细化的方法。知识细化包括将文档分割成“知识条”,然后根据相关性对每个条目进行评分,最相关的条目被重新组合为生成的内部知识。
所以,Corrective Rag的关键在于”检索评估器“的设计,以下是一个实现检索评估器的示例:
from langchain_core.prompts import ChatPromptTemplatefrom langchain_core.pydantic_v1 import BaseModel, Fieldfrom langchain_openai import ChatOpenAI# Data modelclass GradeDocuments(BaseModel):"""Binary score for relevance check on retrieved documents."""binary_score: str = Field(description="Documents are relevant to the question, 'yes' or 'no'")# LLM with function callllm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)structured_llm_grader = llm.with_structured_output(GradeDocuments)# Promptsystem = """You are a grader assessing relevance of a retrieved document to a user question. \nIf the document contains keyword(s) or semantic meaning related to the question, grade it as relevant. \nGive a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question."""grade_prompt = ChatPromptTemplate.from_messages([("system", system),("human", "Retrieved document: \n\n {document} \n\n User question: {question}"),])retrieval_grader = grade_prompt | structured_llm_graderquestion = "agent memory"docs = retriever.get_relevant_documents(question)doc_txt = docs[1].page_contentprint(retrieval_grader.invoke({"question": question, "document": doc_txt}))
但是,Corrective Rag的局限性是严重依赖于检索评估器的质量,并容易受到网络搜索引入的偏见的影响,因此微调检索评估器可能是不可避免的。
到这里,三种有效优化检索召回的方法就介绍完了。
总结
在这篇文章中,风叔详细介绍了优化Retrival(检索召回)的三种方法,包括Rerank(重排序)、RefineMent(压缩)、Corrective Rag(纠错性Rag)。
检索召回的下一步是最终内容生成,即使使用了上述检索召回的优化方案,最终生成环节也可能遇到格式错误、内容不完整、政治不正确等问题。因此,在生成环节,我们也需要相应的优化方案,给整个RAG流程画上完美的句号。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2025-10-26
关于RAG系统在多轮对话中的问题改写(优化)方法—使用历史记录改写问题
2025-10-26
你的RAG知识库,真的“喂”对数据了吗?拆解dify分段策略,告别无效召回
2025-10-16
基于大模型的智能问答场景解决方案——RAG提升召回率的关键
2025-10-16
用合成数据评测 RAG 系统:一份可直接上手的 DeepEval 实操指南
2025-10-16
2025 年 RAG 最佳 Reranker 模型
2025-10-16
HiRAG问答流程深入分析
2025-10-13
LightRAG × Yuxi-Know——「知识检索 + 知识图谱」实践案例
2025-10-13
PG用户福音|一次性搞定RAG完整数据库套装
2025-09-15
2025-09-02
2025-08-05
2025-08-18
2025-08-25
2025-08-25
2025-08-25
2025-09-03
2025-08-20
2025-09-08
2025-10-04
2025-09-30
2025-09-10
2025-09-10
2025-09-03
2025-08-28
2025-08-25
2025-08-20