LangChain 1.0 RAG实战:从零搭建一个AI知识库问答系统
2026/7/3 12:41:56 网站建设 项目流程

你有没有遇到过这种情况:让大模型回答公司内部文档的问题,它要么编答案,要么说"我不清楚"?RAG(Retrieval-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", encoding="utf-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_size=500, # 每块最多500个字符 chunk_overlap=50, # 相邻块之间重叠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(model="text-embedding-3-small")# 创建向量数据库并存入文档块vectorstore = Chroma.from_documents( documents=chunks, embedding=embeddings, persist_directory="./chroma_db", # 持久化存储目录)# 测试检索results = vectorstore.similarity_search("产品退货流程是什么?", k=3)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_type="similarity", # 相似度搜索 search_kwargs={"k": 3}, # 返回最相似的3个文档块)# 提示词模板prompt = ChatPromptTemplate.from_template("""基于以下参考资料回答用户问题。如果参考资料中没有相关信息,请说"根据现有资料无法回答"。参考资料:{context}用户问题:{question}回答:""")# 模型model = ChatOpenAI(model="gpt-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链的意思是:

  1. 用户问题同时传给retriever(检索相关文档)和question(原样传递)
  2. 检索结果格式化后和问题一起塞进提示词
  3. 发给模型生成回答
  4. 解析输出

进阶版:带来源引用的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( model="gpt-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_type="mmr", # 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_size=200)# 父块切分器(用于返回)parent_splitter = RecursiveCharacterTextSplitter(chunk_size=1000)retriever = ParentDocumentRetriever( vectorstore=vectorstore, docstore=InMemoryStore(), child_splitter=child_splitter, parent_splitter=parent_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%免费

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询