LangChain 1.0 RAG实战:从零搭建一个AI知识库问答系统

📅 2026/6/28 2:51:27
LangChain 1.0 RAG实战:从零搭建一个AI知识库问答系统
你有没有遇到过这种情况让大模型回答公司内部文档的问题它要么编答案要么说我不清楚RAGRetrieval-Augmented Generation检索增强生成就是解决这个问题的——先从你的文档里检索出相关内容再让模型基于这些内容回答。RAG是目前AI落地最成熟的场景没有之一。客服系统、文档问答、企业知识库、法律助手……底层都是RAG。今天这篇文章我带你用LangChain 1.0从零搭一个完整的RAG系统。RAG的核心思路一句话说清楚先把文档切成小块存进向量数据库用户提问时检索出最相关的几块然后把这些块塞进提示词让模型回答。流程图用户问题 ↓[Embedding模型把问题转成向量] ↓[在向量数据库中检索最相似的文档块] ↓[把检索结果用户问题一起发给大模型] ↓[大模型基于检索到的内容生成回答]第一步加载和切分文档RAG的第一步是把你的文档读进来并切成小块。为什么不能整篇喂给模型两个原因一是模型的上下文窗口有限装不下整篇文档二是小块检索精度更高整篇检索噪音太多。文档加载from langchain_community.document_loaders import TextLoader, PyPDFLoader# 加载txt文件loader TextLoader(company_faq.txt, encodingutf-8)docs loader.load()# 加载PDF文件loader PyPDFLoader(product_manual.pdf)docs loader.load()LangChain支持几十种文档格式Word、Markdown、HTML、CSV、Notion、飞书文档……在langchain-community里基本都能找到对应的Loader。文本切分from langchain_text_splitters import RecursiveCharacterTextSplittersplitter RecursiveCharacterTextSplitter( chunk_size500, # 每块最多500个字符 chunk_overlap50, # 相邻块之间重叠50个字符避免关键信息被切断 separators[\n\n, \n, 。, , , , , ], # 按优先级切分)chunks splitter.split_documents(docs)print(f文档被切成了 {len(chunks)} 块)几个要点chunk_size不是越小越好——太小会丢失上下文太大检索噪音多。500-1000字符是比较通用的范围chunk_overlap建议设为chunk_size的10%左右防止关键信息正好被切断separators的顺序很重要优先在段落、句子级别切分不到万不得已别在词中间切第二步向量化并存入数据库把文本块转成向量一串数字然后存进向量数据库。向量数据库能根据语义相似度快速检索。from langchain_openai import OpenAIEmbeddingsfrom langchain_community.vectorstores import Chroma# 选择Embedding模型embeddings OpenAIEmbeddings(modeltext-embedding-3-small)# 创建向量数据库并存入文档块vectorstore Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./chroma_db, # 持久化存储目录)# 测试检索results vectorstore.similarity_search(产品退货流程是什么, k3)for doc in results: print(doc.page_content) print(---)向量数据库怎么选数据库特点适用场景Chroma轻量、本地运行、开箱即用开发测试、小规模数据FAISSMeta开源、纯内存、速度极快大规模数据、不需要持久化Milvus分布式、高性能、生产级企业级大规模部署Pinecone全托管云服务、免运维不想自己管基础设施QdrantRust实现、性能好、过滤能力强需要元数据过滤的场景我的建议开发阶段用Chroma或FAISS快且省事上生产换Milvus或Pinecone。Embedding模型用OpenAI的text-embedding-3-small就行性价比高国内可以用智谱或百度的Embedding。第三步构建RAG链有了向量数据库接下来把检索和生成串起来。基础版RAG链from langchain_openai import ChatOpenAIfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParserfrom langchain_core.runnables import RunnablePassthrough# 检索器retriever vectorstore.as_retriever( search_typesimilarity, # 相似度搜索 search_kwargs{k: 3}, # 返回最相似的3个文档块)# 提示词模板prompt ChatPromptTemplate.from_template(基于以下参考资料回答用户问题。如果参考资料中没有相关信息请说根据现有资料无法回答。参考资料{context}用户问题{question}回答)# 模型model ChatOpenAI(modelgpt-4o-mini)# 构建RAG链def format_docs(docs): return\n\n.join(doc.page_content for doc in docs)rag_chain ( {context: retriever | format_docs, question: RunnablePassthrough()} | prompt | model | StrOutputParser())# 使用answer rag_chain.invoke(产品退货流程是什么)print(answer)这段LCEL链的意思是用户问题同时传给retriever检索相关文档和question原样传递检索结果格式化后和问题一起塞进提示词发给模型生成回答解析输出进阶版带来源引用的RAG让模型回答时标注信息来源方便用户验证from langchain_core.runnables import RunnableParallel# 提示词加上来源引用要求prompt_with_source ChatPromptTemplate.from_template(基于以下参考资料回答用户问题。回答时请标注信息来源的编号如[1][2]。参考资料{context}用户问题{question}回答格式回答内容[来源编号])rag_chain_with_source RunnableParallel( {context: retriever | format_docs, question: RunnablePassthrough()}) | prompt_with_source | model | StrOutputParser()第四步把RAG封装成Agent工具上面的RAG链是固定流程但你可能想让Agent自己判断什么时候该查文档、什么时候直接回答。这时候可以把RAG封装成工具from langchain.agents import create_agentdef search_knowledge_base(query: str) - str: 搜索公司知识库获取产品、流程、政策等相关信息。 当用户询问公司内部信息时应使用此工具。 results rag_chain.invoke(query) return resultsagent create_agent( modelgpt-4o-mini, tools[search_knowledge_base, search_web], # 知识库 网络搜索 system_prompt你是一个智能客服助手。- 公司内部信息产品、流程、政策等用search_knowledge_base查询- 实时信息、新闻、外部知识用search_web查询- 不要编造答案查不到就说不知道,)这样Agent就能根据问题类型自己选检索方式了——内部文档走知识库实时信息走搜索。高级RAG策略基础RAG能覆盖60%的场景剩下40%需要一些高级策略1. 查询改写用户的提问往往不是最优的检索query。比如用户问怎么退货但文档里写的是退换货流程。让模型先改写query再检索query_rewrite_prompt ChatPromptTemplate.from_template( 请将以下问题改写为更适合检索的查询词\n原始问题{question}\n改写后)rewrite_chain query_rewrite_prompt | model | StrOutputParser()# 用户问怎么退货 → 改写为退换货流程 退货条件 退货步骤 → 检索更准2. 混合检索纯向量检索擅长语义匹配但对关键词精确匹配不太行。混合检索结合了向量搜索和关键词搜索# Chroma支持的混合搜索配置retriever vectorstore.as_retriever( search_typemmr, # Maximum Marginal Relevance兼顾相关性和多样性 search_kwargs{k: 5, fetch_k: 10},)3. 父文档检索有时候切太碎了检索到的小块缺乏上下文。父文档检索的思路是检索小块返回小块所属的大块from langchain.retrievers import ParentDocumentRetrieverfrom langchain_text_splitters import RecursiveCharacterTextSplitterfrom langchain_community.storage import InMemoryStore# 子块切分器用于检索child_splitter RecursiveCharacterTextSplitter(chunk_size200)# 父块切分器用于返回parent_splitter RecursiveCharacterTextSplitter(chunk_size1000)retriever ParentDocumentRetriever( vectorstorevectorstore, docstoreInMemoryStore(), child_splitterchild_splitter, parent_splitterparent_splitter,)我踩过的RAG坑1. 文档切分粒度不对检索效果差这个得调。建议先用500字符的chunk_size试如果检索不到相关内容试着调大到800如果检索到了但回答跑偏试着调小到300。2. Embedding模型和生成模型的语言不匹配如果你的文档是中文的但用了英文为主的Embedding模型如早期的text-embedding-ada-002检索效果会很差。推荐用text-embedding-3-small或中文Embedding模型如BGE系列。3. 检索到的内容与问题无关这往往是因为query太模糊。加一个查询改写步骤或者用混合检索效果会好很多。4. 模型不按检索内容回答自己编在提示词里加上仅基于参考资料回答不要编造信息的约束并且明确告诉模型如果参考资料中没有相关信息请回答’根据现有资料无法回答’。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】