49-LangChain搭RAG问答机器人-从文档上传到智能回答全流程
文章目录
【49.Python+AI】用LangChain搭一个RAG问答机器人:从文档上传到智能回答全流程
📖 文章简介: 本文手把手教你用LangChain框架从零搭建一个完整的RAG问答机器人。内容覆盖Document Loader加载多格式文档、Text Splitter进行语义化分块、Vector Store向量化存储、Retrieval Chain检索链的组装与调优,全流程逐行代码讲解。文中配以Mermaid流程图展示RAG的数据管道,包含一个可直接运行的完整Demo——上传PDF,AI基于文档内容回答问题并附带引用来源,适合想快速落地第一个RAG应用的开发者。

🎬 个人主页: 源码骑士
❄ 专栏传送门: 《Android开发基础》《python基础课程》
⭐️热衷从源码视角拆解技术底层原理,将复杂架构讲得通俗易懂
🎬 源码骑士的简介:
5年Android Framework系统开发经验,曾主导多项系统级性能优化专项
技术栈覆盖Android系统全链路(Binder/Handler/AMS/WMS/启动流程)及Java后端全家桶(Spring + MyBatis + Redis + Oracle)
累计产出原创技术文章100+篇,文章以流程图为特色,被读者评价为"看一篇胜过啃一周源码"
导入语
前面你选好了向量数据库、搞懂了Embedding模型。但真正上手搭RAG时,你会面对一长串问题:PDF怎么加载?怎么切成合适的块?块存在哪?检索怎么和LLM串起来?用户问的问题怎么在检索之后喂给模型?
LangChain就是来解决这些"组装问题"的。它把RAG的每个环节抽象为标准组件,你可以像搭乐高一样把它们拼起来。这篇文章的目标:用一个完整的Python脚本,从PDF加载到智能问答,每一步都有代码、每一行都有注释。 看完你就能在自己的文档上跑起来。
1 ~> 用LangChain搭RAG:四步走
2 ~> 完整代码实现
2.1 环境准备
pip install langchain langchain-openai chromadb pypdf tiktoken
2.2 完整RAG流水线
# rag_bot.py —— 从PDF到智能问答,一个文件搞定
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
# ========== Step 1:加载PDF ==========
loader = PyPDFLoader("公司规章制度.pdf")
documents = loader.load()
print(f"加载了 {len(documents)} 页文档")
# 每一页是一个Document对象,包含page_content和metadata(页码等)
# ========== Step 2:文本分块 ==========
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块500字符
chunk_overlap=100, # 块之间重叠100字符(保持语义连续性)
separators=["\n\n", "\n", "。", ",", " ", ""] # 优先按段落→句子→词分割
)
chunks = text_splitter.split_documents(documents)
print(f"分割为 {len(chunks)} 个文本块")
# ========== Step 3:向量化并存储 ==========
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vector_store = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
collection_name="company_rules",
persist_directory="./chroma_db" # 持久化,下次不用重新向量化
)
# ========== Step 4:构建检索+生成链 ==========
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.2)
# 定义Prompt模板:告诉模型如何使用检索到的上下文
system_prompt = (
"你是一个企业知识库助手。根据以下检索到的文档片段回答问题。"
"如果文档中没有相关信息,就说'文档中未提及',不要编造。"
"回答时注明引用的来源。\n\n"
"检索到的文档片段:\n{context}"
)
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}"),
])
# 组装:文档填充链 + 检索链
document_chain = create_stuff_documents_chain(llm, prompt)
retriever = vector_store.as_retriever(
search_type="similarity", # 相似度检索
search_kwargs={"k": 4} # 每次检索4个最相关块
)
rag_chain = create_retrieval_chain(retriever, document_chain)
# ========== 开始问答 ==========
if __name__ == "__main__":
print("📚 RAG问答机器人已就绪,输入 'quit' 退出\n")
while True:
question = input("你的问题:")
if question.lower() == "quit":
break
response = rag_chain.invoke({"input": question})
print(f"\n回答:{response['answer']}\n")
# 显示引用来源
print("引用来源:")
for i, doc in enumerate(response["context"], 1):
print(f" [{i}] 第{doc.metadata.get('page', '?')}页: {doc.page_content[:100]}...")
print("-" * 50)
2.3 关键参数调优
| 参数 | 默认值 | 调优建议 |
|---|---|---|
chunk_size |
500 | 短文本:200300;长文档:8001000 |
chunk_overlap |
100 | 通常设为chunk_size的20%,保持语义连续性 |
search_kwargs["k"] |
4 | 简单问题23个,复杂推理问题68个 |
temperature |
0.2 | RAG场景保持低值,0~0.3足够 |
separators |
见上文 | 中文文档优先用。和,做分隔符 |
3 ~> Document Loader支持的文件格式
# PDF
from langchain_community.document_loaders import PyPDFLoader
# Word文档
from langchain_community.document_loaders import Docx2txtLoader
# 纯文本
from langchain_community.document_loaders import TextLoader
# CSV(每行作为一条记录)
from langchain_community.document_loaders import CSVLoader
# 网页
from langchain_community.document_loaders import WebBaseLoader
# 整个目录
from langchain_community.document_loaders import DirectoryLoader
思考 && 总结
- LangChain把RAG拆成四个标准步骤: Load → Split → Embed & Store → Retrieve & Generate。每步都有几行代码的模板,组合起来就是一个完整应用。
RecursiveCharacterTextSplitter是中文文档最好的分块器: 按段落→句子→词的顺序递进分割,比固定长度切分保持语义完整性更好。create_retrieval_chain一行封装了整个"检索+生成"链: 背后是Retriever查向量库 → 拼接Prompt → 喂给LLM的完整流水线。- chunk_overlap是防止"关键信息被切断"的保险: 100字符重叠意味着同一句话可能在相邻两个块中都完整出现。
- 温度设低是RAG的铁律: 你的答案应该来自检索到的文档,不是模型的"自由发挥"。
30行核心代码就能搭一个可用的RAG问答系统——这就是LangChain的抽象能力。但理解每个组件在做什么,比会用API更重要。
结尾
各位小伙伴,本文的内容到这里就全部结束了!源码骑士 — Android Framework & 全栈开发
👀 关注 | ❤️ 点赞 | ⭐ 收藏:把完整脚本存好下个项目直接改 | 💬 评论 | 🔄 一键四连!🗡️ 寄语:最好的学习方式就是用自己的文档跑一遍——找一份PDF,让AI基于它回答你的问题。
结语:找一份你熟悉的PDF文档,把上面的脚本拷过去,改一下文件路径。跑起来,问它一个问题——看到AI基于你的文档给出准确回答的那一刻,你就真正理解了RAG。不要忘记给博主"一键四连"哦!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)