从零搭建LangChain+RAG知识库:企业级实战指南

为什么需要RAG知识库?
大语言模型(LLM)虽然强大,但存在知识截止、幻觉以及无法访问私有数据的问题。检索增强生成(RAG)通过将外部知识库中的相关文档片段实时注入LLM上下文,显著提升回答的准确性和时效性。LangChain作为目前最流行的AI应用框架,提供了模块化的RAG组件,让开发者能在几小时内搭建出一个企业级知识库原型。
环境准备与核心依赖
首先安装必要的Python包(建议Python≥3.10):
pip install langchain langchain-community langchain-openai chromadb pypdf python-docx tiktoken
本指南使用OpenAI的Embedding模型和ChatGPT作为LLM,你也可以替换为本地模型(如Ollama+llama3)。设置环境变量:OPENAI_API_KEY=你的key。
第一步:文档加载与分割
企业知识库通常包含PDF、Word、Markdown、网页等格式。LangChain提供统一的DocumentLoader接口。以PDF和Word为例:
from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 加载
loaders = [PyPDFLoader("report.pdf"), Docx2txtLoader("guide.docx")]
docs = []
for loader in loaders:
docs.extend(loader.load())
# 分割(按chunk size=500, overlap=50)
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
splits = splitter.split_documents(docs)
print(f"共分割为 {len(splits)} 个片段")
注意:chunk_size和overlap需要根据文档类型和LLM上下文长度调整。对于中英文混合内容,建议使用RecursiveCharacterTextSplitter,它会智能保留段落结构。
第二步:向量嵌入与向量库
将分割后的文本片段转换为向量并存入向量数据库。Chroma可以本地运行且免费:
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
vectorstore = Chroma.from_documents(documents=splits, embedding=embeddings, persist_directory="./chroma_db")
vectorstore.persist() # 持久化存储
生产环境中可考虑Pinecone、Weaviate或Milvus,支持分布式与更复杂的过滤。
第三步:构建检索链
LangChain的RetrievalQA链将检索与生成无缝衔接:
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
retriever = vectorstore.as_retriever(search_type="similarity", search_kwargs={"k": 4})
qa_chain = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=retriever)
# 测试
query = "我们的产品退货政策是什么?"
response = qa_chain.invoke({"query": query})
print(response["result"])
chain_type参数:
- stuff:将检索到的文档全部塞入上下文,适合片段少(≤4个)。
- map_reduce/refine:处理大量文档时性能更好,但会增加推理成本。
第四步:进阶优化——混合检索与重排序
纯向量相似度搜索可能漏掉精确匹配(如人名、编号)。推荐引入BM25稀疏检索:
from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever
bm25_retriever = BM25Retriever.from_documents(splits)
bm25_retriever.k = 4
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, retriever],
weights=[0.3, 0.7]
)
qa_chain_with_ensemble = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=ensemble_retriever)
此外,可在检索后增加重排序器(如Cohere rerank),提升最相关片段的优先级。
第五步:企业级部署与监控
生产环境需关注以下几个要点:
- 缓存:对高频重复查询使用
CacheBackedEmbeddings或Redis减少API调用成本。 - 异步支持:使用
langchain_community.chat_models.ChatOpenAI(async_mode=True)配合FastAPI实现高并发。 - 安全审计:所有用户查询先通过内容过滤模型;对向量库实施访问控制。
- 日志与评估:记录用户Query、检索到的文档ID、LLM响应,定期用RAGAS等框架评测准确率。
完整示例:结合记忆的对话式RAG
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
conv_chain = ConversationalRetrievalChain.from_llm(
llm=ChatOpenAI(model="gpt-4o-mini"),
retriever=ensemble_retriever,
memory=memory
)
while True:
user = input("问题:")
if user.lower() in ("exit","quit"): break
print(conv_chain.invoke({"question": user})["answer"])
该链自动维护对话历史,让用户能追问(如“上一条提到的退款流程再详细解释”)。
常见陷阱与应对
- 分割不合理:过长/过短的chunk都会降低检准率。建议动态chunk(依据标题层级切分)。
- 向量维度灾难:OpenAI ada-002是1536维,Chroma本地使用无压力;若用更大模型,考虑降维。
- LLM幻觉依旧:在系统提示词中强制要求“根据提供的上下文回答,不知道就说不知道”。
通过以上步骤,你已成功搭建一个具备企业级能力的RAG知识库。LangChain的模块化设计让你可以随时替换组件(如换成本地模型、换向量库),实现真正的灵活落地。下一步可尝试引入多模态RAG(处理表格、图片)或构建Agent来自动更新知识文档。