09 RAG 优化技巧
09 RAG 优化技巧一、RAG 常见问题问题表现优化方向召回不全相关文档没被检索到多路召回、查询改写噪声过多检索到不相关的内容重排序、压缩过滤语义鸿沟用户问题和文档表述不一致HyDE、查询扩展上下文过长检索结果太多超出 token 限制压缩、摘要二、MultiQueryRetriever多查询检索自动生成多个查询变体扩大召回范围 MultiQueryRetriever 演示 运行方式python 09_多查询检索.py fromlangchain.retrieversimportMultiQueryRetrieverfromlangchain_openaiimportChatOpenAI,OpenAIEmbeddingsfromlangchain_community.vectorstoresimportFAISSfromlangchain_core.documentsimportDocument# 1. 创建向量数据库docs[Document(page_contentLangChain是一个用于构建大模型应用的框架),Document(page_contentLangGraph用于构建有状态的Agent工作流),Document(page_contentRAG是检索增强生成技术结合检索和生成),Document(page_content向量数据库用于存储和检索文本的向量表示),]embeddingsOpenAIEmbeddings()vectorstoreFAISS.from_documents(docs,embeddings)# 2. 创建 MultiQueryRetrieverllmChatOpenAI(modelqwen-plus,temperature0.3)retrieverMultiQueryRetriever.from_llm(retrievervectorstore.as_retriever(search_kwargs{k:3}),llmllm,include_originalTrue# 包含原始查询)# 3. 检索 - 自动生成多个查询变体query什么是LangChainresultsretriever.invoke(query)print(f原始查询:{query})print(f\n检索到{len(results)}个文档)fori,docinenumerate(results):print(f{i1}.{doc.page_content})工作原理LLM 自动生成 3-5 个查询变体每个变体独立检索合并去重结果三、SelfQueryRetriever自查询检索自动从自然语言中提取结构化过滤条件 SelfQueryRetriever 演示 运行方式python 09_自查询检索.py fromlangchain.retrieversimportSelfQueryRetrieverfromlangchain.chains.query_constructor.baseimportAttributeInfofromlangchain_openaiimportChatOpenAI,OpenAIEmbeddingsfromlangchain_community.vectorstoresimportFAISSfromlangchain_core.documentsimportDocument# 1. 创建带元数据的文档docs[Document(page_contentLangChain是大模型应用框架,metadata{source:官方文档,year:2023,category:框架}),Document(page_contentMilvus是开源向量数据库,metadata{source:技术博客,year:2024,category:数据库}),Document(page_contentRAG技术用于增强大模型回答,metadata{source:论文,year:2023,category:技术}),]embeddingsOpenAIEmbeddings()vectorstoreFAISS.from_documents(docs,embeddings)# 2. 定义元数据字段信息metadata_field_info[AttributeInfo(namesource,description文档来源如官方文档、技术博客、论文,typestring),AttributeInfo(nameyear,description文档发布年份,typeinteger),AttributeInfo(namecategory,description文档类别如框架、数据库、技术,typestring),]# 3. 创建 SelfQueryRetrieverllmChatOpenAI(modelqwen-plus,temperature0)retrieverSelfQueryRetriever.from_llm(llmllm,vectorstorevectorstore,document_contents技术文档,metadata_field_infometadata_field_info,enable_limitTrue,# 允许限制返回数量search_kwargs{k:5})# 4. 使用自然语言查询自动提取过滤条件# 示例1带过滤条件query1查找2023年的技术文档results1retriever.invoke(query1)print(f查询:{query1})fordocinresults1:print(f -{doc.page_content}(来源:{doc.metadata[source]}, 年份:{doc.metadata[year]}))# 示例2带类别过滤query2查找关于框架的文档只返回1个results2retriever.invoke(query2)print(f\n查询:{query2})fordocinresults2:print(f -{doc.page_content}(类别:{doc.metadata[category]}))工作原理LLM 解析自然语言查询自动提取过滤条件如年份、类别生成结构化查询向量检索 元数据过滤四、ContextualCompressionRetriever上下文压缩压缩检索结果只保留相关内容 ContextualCompressionRetriever 演示 运行方式python 09_上下文压缩.py fromlangchain.retrieversimportContextualCompressionRetrieverfromlangchain.retrievers.document_compressorsimportLLMChainExtractorfromlangchain_openaiimportChatOpenAI,OpenAIEmbeddingsfromlangchain_community.vectorstoresimportFAISSfromlangchain_core.documentsimportDocument# 1. 创建向量数据库长文档docs[Document(page_contentLangChain是一个强大的大模型应用开发框架。 它提供了统一的接口来连接LLM、工具和数据源。 LangChain支持多种模型提供商包括OpenAI、Anthropic等。 它还提供了丰富的组件如Prompt Template、Chains、Agents等。 LangChain的LCEL语言使得组件组合变得非常简单。),Document(page_contentPython是一种流行的编程语言。 它广泛用于数据科学、机器学习和Web开发。 Python的语法简洁易学适合初学者。 近年来Python在AI领域的应用越来越广泛。),]embeddingsOpenAIEmbeddings()vectorstoreFAISS.from_documents(docs,embeddings)# 2. 创建压缩器llmChatOpenAI(modelqwen-plus,temperature0)compressorLLMChainExtractor.from_llm(llm)# 用LLM提取相关内容# 3. 创建压缩检索器compression_retrieverContextualCompressionRetriever(base_compressorcompressor,base_retrievervectorstore.as_retriever(search_kwargs{k:2}))# 4. 检索并压缩queryLangChain有哪些组件resultscompression_retriever.invoke(query)print(f查询:{query})print(f\n压缩后的结果)fori,docinenumerate(results):print(f{i1}.{doc.page_content})工作原理检索相关文档可能很长用 LLM 提取与查询相关的部分返回压缩后的内容五、EnsembleRetriever集成检索结合多种检索方式的优势 EnsembleRetriever 演示 运行方式python 09_集成检索.py fromlangchain.retrieversimportEnsembleRetrieverfromlangchain_community.retrieversimportBM25Retrieverfromlangchain_community.vectorstoresimportFAISSfromlangchain_openaiimportOpenAIEmbeddingsfromlangchain_core.documentsimportDocument# 1. 准备文档docs[Document(page_contentLangChain是大模型应用框架),Document(page_contentLangGraph用于构建Agent),Document(page_contentRAG是检索增强生成技术),Document(page_content向量数据库存储文本向量),Document(page_contentMilvus是开源向量数据库),]# 2. 创建 BM25 检索器关键词检索bm25_retrieverBM25Retriever.from_documents(docs)bm25_retriever.k3# 3. 创建向量检索器语义检索embeddingsOpenAIEmbeddings()vectorstoreFAISS.from_documents(docs,embeddings)vector_retrievervectorstore.as_retriever(search_kwargs{k:3})# 4. 创建集成检索器ensemble_retrieverEnsembleRetriever(retrievers[bm25_retriever,vector_retriever],weights[0.4,0.6]# BM25权重0.4向量权重0.6)# 5. 检索query什么是LangChainresultsensemble_retriever.invoke(query)print(f查询:{query})print(f\n集成检索结果)fori,docinenumerate(results):print(f{i1}.{doc.page_content})工作原理BM25 擅长精确关键词匹配向量检索擅长语义相似度集成两者互补优势六、检索策略对比策略优势劣势适用场景MultiQueryRetriever扩大召回范围增加 LLM 调用成本用户问题模糊SelfQueryRetriever支持结构化过滤依赖元数据质量有明确过滤需求ContextualCompression减少噪声增加延迟文档内容冗长EnsembleRetriever综合多种检索需要调优权重通用场景HyDE增强语义匹配生成假设可能不准问题表述简短七、在掌柜智库中的应用掌柜智库项目采用了三路召回 RRF 融合 Rerank 精排的策略向量检索 (保基础) ──┐ ├── RRF 本地融合 ──┐ HyDE 检索 (补弱意图) ──┘ ├── Rerank 全局精排 → 答案生成 联网搜索 (扩边界) ─────────────────────┘设计思路向量检索基础兜底语义相似度召回HyDE 检索增强弱意图查询用假设性答案召回联网搜索补充外部信息扩展知识边界RRF 融合整合本地两路召回结果Rerank 精排统一排序过滤噪声详见 [[…/掌柜智库/00-项目概览/02-模块流程设计|掌柜智库模块流程设计]]八、RAG 优化清单优化点具体操作预期效果分块策略调整 chunk_size 和 chunk_overlap提升召回精度Embedding 选择使用 BGE-M3 等中文优化模型提升中文语义理解查询改写使用 LLM 改写用户问题弥合语义鸿沟多路召回向量 BM25 HyDE提升召回率重排序使用 Reranker 精排减少噪声压缩过滤提取相关内容减少 token 消耗元数据过滤添加结构化字段精确筛选九、常见问题Q1: 如何选择合适的检索策略简单场景基础向量检索即可召回不足尝试 MultiQueryRetriever 或 EnsembleRetriever噪声过多使用 ContextualCompressionRetriever 或 Reranker有结构化需求使用 SelfQueryRetrieverQ2: HyDE 和 MultiQuery 的区别维度HyDEMultiQuery原理生成假设性答案作为查询生成多个查询变体目的增强语义匹配扩大召回范围适用问题简短、语义稀疏问题模糊、多角度召回Q3: 如何评估检索效果召回率相关文档是否被检索到精确率检索结果中相关文档的比例MRRMean Reciprocal Rank相关文档的排名位置端到端评估最终答案的质量相关笔记[[04-RAG检索增强]] · [[05-Agents智能体]] · [[…/掌柜智库/00-项目概览/02-模块流程设计|掌柜智库模块设计]]