AI Agent白手起家48: RAG 检索调优实战 — 上下文压缩、排序与相似性分数

📅 2026/8/9 21:08:22
AI Agent白手起家48: RAG 检索调优实战 — 上下文压缩、排序与相似性分数
纲要检索调优的重要性原始向量检索的局限调优目标提高召回率和答案精准度上下文压缩LLMChainExtractor提取相关片段LLMChainFilter保留或丢弃文档DocumentCompressorPipeline串联多个压缩器排序优化解决“Lost in the Middle”问题LongContextReorder重排文档顺序相似性分数过滤similarity_search_with_score自定义打分并写入元数据进阶方向知识图谱增强 RAGGraphRAG简介完整可运行代码使用模拟模型演示压缩与排序引言在 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_contentLangChain 支持 OpenAI、DeepSeek 等多种模型。),Document(page_contentRAG 系统包含加载、切片、嵌入、检索、生成等步骤。),Document(page_content模型部署需考虑延迟、成本以及云端或本地的选择。),Document(page_content今日天气晴朗适宜户外运动。),]embeddingsFakeEmbeddings(size128)vectorstoreChroma.from_documents(docs,embeddings,collection_nametune)base_retrievervectorstore.as_retriever(search_kwargs{k:3})# 2. 使用 LLMChainExtractor 压缩# 模拟大模型返回与查询相关的精简内容extract_llmFakeListChatModel(responses[模型部署需考虑延迟、成本以及云端或本地的选择。])extractorLLMChainExtractor.from_llm(extract_llm)compression_retrieverContextualCompressionRetriever(base_compressorextractor,base_retrieverbase_retriever,)resultscompression_retriever.invoke(如何部署模型)print(压缩后文档数:,len(results))fordocinresults:print(内容:,doc.page_content)LLMChainFilter快速筛选如果只想保留整篇文档而不修改其文本可以使用LLMChainFilter。模拟模型需返回 “YES” 或 “NO”。filter_llmFakeListChatModel(responses[YES,NO,YES])compressor_filterLLMChainFilter.from_llm(filter_llm)filter_retrieverContextualCompressionRetriever(base_compressorcompressor_filter,base_retrieverbase_retriever,)resultsfilter_retriever.invoke(如何部署模型)print(过滤后文档数:,len(results))管道组合先过滤再提取通过DocumentCompressorPipeline可以把多个压缩器串联起来实现更复杂的处理流程。pipelineDocumentCompressorPipeline(transformers[compressor_filter,extractor])pipeline_retrieverContextualCompressionRetriever(base_compressorpipeline,base_retrieverbase_retriever,)resultspipeline_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万人次。),]reorderLongContextReorder()reordered_docsreorder.transform_documents(retrieved_docs)print(重排序后的文档顺序)fori,docinenumerate(reordered_docs):print(f{i1}:{doc.page_content})运行后可以看到与“故宫”最相关的文档被移到了首尾无关信息被排到中间有效提升了模型对关键信息的注意力。相似性分数过滤与自定义打分许多向量数据库支持similarity_search_with_score可以同时获取相关性分数。你可以利用这个分数进行阈值过滤或者将分数写入文档的metadata中供后续处理使用。# 使用同一向量库进行带分数的搜索results_with_scorevectorstore.similarity_search_with_score(模型部署,k2)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])进阶方向知识图谱增强 RAGGraphRAG当知识库中存在大量实体及关系时单纯的向量相似度难以挖掘间接关联。GraphRAG 在传统 RAG 基础上引入知识图谱利用图结构遍历与查询实体相关的其他节点例如通过“栖息地”或“食性”找到关联动物将图遍历结果与向量检索结果合并提供更全面的上下文。LangChain 已提供GraphRetriever支持这一模式尤其适用于生物分类、法律案例关联、产品配件推荐等场景。总结检索调优让 RAG 系统从“能搜到”升级为“搜得准、答案精”。上下文压缩去掉噪音智能排序避免关键信息丢失相似性分数过滤则进一步提高了信噪比。这些组件可以灵活组合无需改动核心检索逻辑。从简单的向量搜索出发逐步叠加压缩、排序和分数过滤你将能够构建出高质量、高可靠性的 RAG 应用。