LangChain RAG 技术深度实战:从原理到生产级优化全链路

张开发
2026/4/20 7:34:14 15 分钟阅读

分享文章

LangChain RAG 技术深度实战:从原理到生产级优化全链路
前言LangChain 在 RAG 领域的地位就像 React 在前端开发中的地位——争议很多但绕不开。本文不讨论要不要用 LangChain而是聚焦在用 LangChain 实现生产级 RAG 的关键技术点包括很多官方文档里没说清楚的坑。—## 一、RAG 系统的质量三角在动手写代码之前先理解 RAG 的质量评估框架——RAGAS 三角答案相关性Answer Relevance ▲ / \ / \ / \上下文相关性 ──── 答案忠实度(Context (Faithfulness) Relevance)三个维度缺一不可-上下文相关性检索到的片段和问题有多相关检索质量-答案忠实度生成的答案是否基于检索内容没有幻觉生成质量-答案相关性最终回答是否真的回答了用户的问题整体质量优化顺序建议先优化上下文相关性再优化答案忠实度最后调整答案相关性。—## 二、文档解析被忽视的关键环节大多数 RAG 教程直接从加载文档开始但文档解析质量直接决定 RAG 天花板。### PDF 解析的坑python# 低质量方案很多教程在用from langchain.document_loaders import PyPDFLoaderloader PyPDFLoader(document.pdf)docs loader.load()# 问题表格变乱码多栏排版错位图表丢失python# 高质量方案使用 marker 或 docling# 安装pip install marker-pdffrom marker.convert import convert_single_pdffrom marker.models import load_all_modelsmodels load_all_models()full_text, images, metadata convert_single_pdf( document.pdf, models, batch_multiplier2)# 效果正确识别表格、多栏排版、公式### 语义切片 vs 固定长度切片固定长度切片如每 512 tokens 切一刀会把语义相关的内容切断。语义切片实现pythonfrom langchain_experimental.text_splitter import SemanticChunkerfrom langchain_openai.embeddings import OpenAIEmbeddings# 使用嵌入模型计算语义边界text_splitter SemanticChunker( OpenAIEmbeddings(), breakpoint_threshold_typepercentile, # 按相似度百分位切 breakpoint_threshold_amount95 # 相似度低于95%分位时切割)docs text_splitter.create_documents([text])效果语义切片的 RAG 准确率比固定切片高约 15-20%。—## 三、混合检索BM25 向量的最优组合纯向量检索的问题对精确匹配不友好。“公司的注册资本是多少”——用户想要精确数字向量检索可能返回相关但不精确的内容。纯 BM25 关键词检索的问题无法理解语义相近但措辞不同的查询。解法混合检索Hybrid Searchpythonfrom langchain.retrievers import EnsembleRetrieverfrom langchain_community.retrievers import BM25Retrieverfrom langchain_community.vectorstores import Qdrant# 向量检索器vector_store Qdrant.from_documents(docs, embeddings)vector_retriever vector_store.as_retriever(search_kwargs{k: 10})# BM25 检索器bm25_retriever BM25Retriever.from_documents(docs)bm25_retriever.k 10# 混合检索权重 4:6向量:BM25ensemble_retriever EnsembleRetriever( retrievers[bm25_retriever, vector_retriever], weights[0.4, 0.6])# 使用docs ensemble_retriever.invoke(公司注册资本是多少)权重调优经验- 以精确信息为主法律、财务BM25 权重 0.6- 以语义理解为主技术问答向量权重 0.7- 均衡场景各 0.5—## 四、查询优化让 AI 理解用户真实意图用户的问题往往不是最优的检索查询。### 查询重写Query Rewritingpythonfrom langchain.prompts import ChatPromptTemplatefrom langchain_openai import ChatOpenAIrewrite_prompt ChatPromptTemplate.from_template(你是一个查询优化专家。将用户的问题重写为更适合检索的查询。原始问题{question}要求1. 扩展关键词包含同义词、相关术语2. 消歧义明确指代对象3. 拆分多意图问题为单一问题输出格式重写后的查询只输出查询不要解释)llm ChatOpenAI(modelgpt-5-mini)rewriter rewrite_prompt | llmrewritten rewriter.invoke({question: 这个产品怎么用})# 输出{产品名称} 的使用方法、操作步骤和注意事项### HyDE假设文档生成不用原始问题检索而是先让 LLM 生成一个假设答案文档再用这个文档检索pythonfrom langchain.chains import HypotheticalDocumentEmbedderhyde_chain HypotheticalDocumentEmbedder.from_llm( llmChatOpenAI(modelgpt-5-mini), embeddingsOpenAIEmbeddings(), chain_typestuff)# 生成假设文档并检索similar_docs hyde_chain.retrieve(解释 transformer 的注意力机制)—## 五、Reranker提升精准度的最后一道关初始检索Top-20→ Reranker 重排序 → 取 Top-5 给 LLMpythonfrom langchain.retrievers import ContextualCompressionRetrieverfrom langchain_community.cross_encoders import HuggingFaceCrossEncoderfrom langchain.retrievers.document_compressors import CrossEncoderReranker# 加载本地 Reranker 模型BGE-Reranker-v2-m3 是 2026 年中文最佳model HuggingFaceCrossEncoder( model_nameBAAI/bge-reranker-v2-m3)# 重排 Top-20 取 Top-5compressor CrossEncoderReranker(modelmodel, top_n5)compression_retriever ContextualCompressionRetriever( base_compressorcompressor, base_retrieverensemble_retriever)docs compression_retriever.invoke(你的问题)性能数据加 Reranker 后NDCG5 平均提升 18%延迟增加约 150ms。—## 六、生成优化让 LLM 只说检索到的内容pythonfrom langchain.prompts import ChatPromptTemplateqa_prompt ChatPromptTemplate.from_messages([ (system, 你是一个严谨的问答助手。 回答规则1. 只使用以下检索到的内容回答问题2. 如果检索内容中没有相关信息明确说根据现有资料无法回答此问题3. 在答案末尾标注信息来源参考文档标题4. 不要添加检索内容之外的任何信息检索内容{context}), (human, {question})])—## 七、完整生产级 RAG 流水线pythonfrom langchain_core.runnables import RunnablePassthroughfrom langchain_core.output_parsers import StrOutputParserdef format_docs(docs): return \n\n.join([ f[来源: {doc.metadata.get(source, 未知)}]\n{doc.page_content} for doc in docs ])# 完整 RAG 链rag_chain ( { context: rewrite_prompt | llm | (lambda x: x.content) | compression_retriever | format_docs, question: RunnablePassthrough() } | qa_prompt | llm | StrOutputParser())# 调用answer rag_chain.invoke(你的问题)—## 八、评估与监控pythonfrom ragas import evaluatefrom ragas.metrics import ( faithfulness, answer_relevancy, context_recall, context_precision)# 准备评估数据集eval_dataset Dataset.from_dict({ question: questions, answer: answers, contexts: retrieved_contexts, ground_truth: ground_truths})# 运行评估results evaluate( eval_dataset, metrics[faithfulness, answer_relevancy, context_recall, context_precision])print(results)# 输出# faithfulness: 0.87# answer_relevancy: 0.91# context_recall: 0.83# context_precision: 0.79—## 总结生产级 RAG 的质量提升路径1.优先修文档解析换 marker/docling 代替 PyPDF→ 召回率 20%2.换语义切片SemanticChunker→ 相关性 15%3.加混合检索BM25 向量→ 综合精准度 15%4.加 RerankerBGE-Reranker→ Top-5 精准度 18%5.加查询重写HyDE / Query Rewriting→ 复杂问题 10%按优先级依次实施每一步都有明确的效果提升别一口气全上。

更多文章