纲要
- 检索调优的重要性
- 原始向量检索的局限
- 调优目标:提高召回率和答案精准度
- 上下文压缩
LLMChainExtractor:提取相关片段LLMChainFilter:保留或丢弃文档DocumentCompressorPipeline:串联多个压缩器
- 排序优化:解决“Lost in the Middle”问题
LongContextReorder重排文档顺序
- 相似性分数过滤
similarity_search_with_score- 自定义打分并写入元数据
- 进阶方向:知识图谱增强 RAG(GraphRAG)简介
- 完整可运行代码:使用模拟模型演示压缩与排序
引言
在 RAG 系统中,向量数据库返回的初步结果往往包含冗余、无关或排序不佳的内容。直接将这些原始片段塞入大模型,不仅浪费上下文窗口,还可能降低回答质量。
因此,在检索阶段之后增加调优环节——上下文压缩、智能排序和相似性分数过滤——是提升 RAG 应用准确性的关键步骤。LangChain 提供了一组即插即用的调优组件,本文将结合实际代码,演示如何在不依赖外部 API 的情况下实现这些优化。
上下文压缩:从粗糙到精炼
上下文压缩器能够过滤掉检索结果中与查询无关的内容,或者直接提取出最相关的句子。LangChain 提供了LLMChainExtractor(提取相关片段)和LLMChainFilter(决定是否保留整篇文档),并支持通过DocumentCompressorPipeline将多个压缩器串联使用。
下面的示例使用FakeListChatModel模拟大模型,展示压缩效果。
安装依赖:
pipinstalllangchain langchain-core langchain-community chromadbfromlangchain_community.embeddings.fakeimportFakeEmbeddingsfromlangchain_community.vectorstoresimportChromafromlangchain_core.documentsimportDocumentfromlangchain.retrieversimportContextualCompressionRetrieverfromlangchain.retrievers.document_compressorsimport(LLMChainExtractor,LLMChainFilter,DocumentCompressorPipeline,)fromlangchain_community.chat_models.fakeimportFakeListChatModel# 1. 构建测试向量库docs=[Document(page_content="LangChain 支持 OpenAI、DeepSeek 等多种模型。"),Document(page_content="RAG 系统包含加载、切片、嵌入、检索、生成等步骤。"),Document(page_content="模型部署需考虑延迟、成本以及云端或本地的选择。"),Document(page_content="今日天气晴朗,适宜户外运动。"),]embeddings=FakeEmbeddings(size=128)vectorstore=Chroma.from_documents(docs,embeddings,collection_name="tune")base_retriever=vectorstore.as_retriever(search_kwargs={"k":3})# 2. 使用 LLMChainExtractor 压缩# 模拟大模型:返回与查询相关的精简内容extract_llm=FakeListChatModel(responses=["模型部署需考虑延迟、成本以及云端或本地的选择。"])extractor=LLMChainExtractor.from_llm(extract_llm)compression_retriever=ContextualCompressionRetriever(base_compressor=extractor,base_retriever=base_retriever,)results=compression_retriever.invoke("如何部署模型?")print("压缩后文档数:",len(results))fordocinresults:print("内容:",doc.page_content)LLMChainFilter:快速筛选
如果只想保留整篇文档,而不修改其文本,可以使用LLMChainFilter。模拟模型需返回 “YES” 或 “NO”。
filter_llm=FakeListChatModel(responses=["YES","NO","YES"])compressor_filter=LLMChainFilter.from_llm(filter_llm)filter_retriever=ContextualCompressionRetriever(base_compressor=compressor_filter,base_retriever=base_retriever,)results=filter_retriever.invoke("如何部署模型?")print("过滤后文档数:",len(results))管道组合:先过滤再提取
通过DocumentCompressorPipeline可以把多个压缩器串联起来,实现更复杂的处理流程。
pipeline=DocumentCompressorPipeline(transformers=[compressor_filter,extractor])pipeline_retriever=ContextualCompressionRetriever(base_compressor=pipeline,base_retriever=base_retriever,)results=pipeline_retriever.invoke("如何部署模型?")print("管道压缩后文档数:",len(results))排序优化:挽救“中间丢失”的信息
研究表明,大模型更容易记住文档开头和结尾的内容,而对中间部分的信息容易忽略——这被称为“Lost in the Middle”现象。LangChain 的LongContextReorder可以将最相关的文档排在开头和结尾,次相关的放在中间,从而提高关键信息被捕获的概率。
fromlangchain_community.document_transformersimportLongContextReorder# 模拟一批检索结果retrieved_docs=[Document(page_content="北京故宫是中国明清两代的皇家宫殿。"),Document(page_content="天气炎热,注意防暑。"),Document(page_content="故宫博物院收藏了大量珍贵文物。"),Document(page_content="今日油价调整。"),Document(page_content="故宫每日限流8万人次。"),]reorder=LongContextReorder()reordered_docs=reorder.transform_documents(retrieved_docs)print("重排序后的文档顺序:")fori,docinenumerate(reordered_docs):print(f"{i+1}:{doc.page_content}")运行后可以看到,与“故宫”最相关的文档被移到了首尾,无关信息被排到中间,有效提升了模型对关键信息的注意力。
相似性分数过滤与自定义打分
许多向量数据库支持similarity_search_with_score,可以同时获取相关性分数。你可以利用这个分数进行阈值过滤,或者将分数写入文档的metadata中,供后续处理使用。
# 使用同一向量库进行带分数的搜索results_with_score=vectorstore.similarity_search_with_score("模型部署",k=2)fordoc,scoreinresults_with_score:print(f"分数:{score:.4f},内容:{doc.page_content}")# 将分数写入元数据scored_docs=[]fordoc,scoreinresults_with_score:doc.metadata["score"]=score scored_docs.append(doc)print("第一个文档的分数:",scored_docs[0].metadata["score"])进阶方向:知识图谱增强 RAG(GraphRAG)
当知识库中存在大量实体及关系时,单纯的向量相似度难以挖掘间接关联。GraphRAG 在传统 RAG 基础上引入知识图谱,利用图结构遍历与查询实体相关的其他节点(例如通过“栖息地”或“食性”找到关联动物),将图遍历结果与向量检索结果合并,提供更全面的上下文。LangChain 已提供GraphRetriever支持这一模式,尤其适用于生物分类、法律案例关联、产品配件推荐等场景。
总结
检索调优让 RAG 系统从“能搜到”升级为“搜得准、答案精”。上下文压缩去掉噪音,智能排序避免关键信息丢失,相似性分数过滤则进一步提高了信噪比。
这些组件可以灵活组合,无需改动核心检索逻辑。从简单的向量搜索出发,逐步叠加压缩、排序和分数过滤,你将能够构建出高质量、高可靠性的 RAG 应用。