RAG 系列(二):用 LangChain 搭建你的第一个 RAG Pipeline
从 100 行代码到生产级 Pipeline上一篇我们用手写 Python 搭了一个最小 RAG,100 行代码跑通了核心逻辑。但如果你想把那套代码搬到生产环境,很快就会撞上一堵墙。要加载 PDF?你需要PyPDF2或pdfplumber,然后发现表格、页眉页脚的解析是一场噩梦。要切分文本?你那个朴素的text.split("\n\n")会把句子拦腰截断、破坏代码块,或者切出超长的块直接把 Token 上限撑爆。想换个向量数据库?祝你下午愉快——每个数据库的 API 都不一样,距离度量不一样,元数据处理也不一样。想换个 LLM 提供商?OpenAI 的客户端、Anthropic 的客户端、本地llama.cpp……每个都有自己的消息格式、Token 计算方式、错误处理逻辑。这正是LangChain存在的意义。它不搞什么魔法,也不替代底层的模型或数据库。它只做一件简单但有价值的事:给所有组件提供一个统一的接口,让你专注于 RAG 系统的业务逻辑,而不是 plumbing( plumbing 指的是那些连接管道的脏活累活)。这篇文章,我们用 LangChain 的现代 API 重建 RAG Pipeline。读到最后,你会拥有一个完整的、可运行的项目:它能读取 PDF、智能切分、存入 ChromaDB、用多 Provider LLM 回答问题——而真正的 Pipeline 代码只有大约 30 行。LangChain 版本说明:本文代码基于langchain 1.2.x(当前主流稳定版)。langchain 1.x 对 0.3.x 做了破坏性重组,部分高层 API(如create_retrieval_chain)被移除。代码改用LCEL 原生语法(|管道符)组合 Chain,功能完全等价,且不依赖版本。完整源码:https://github.com/chendongqi/llm-in-action/tree/main/02-langchain-basicRAG Pipeline 的六大组件LangChain 把 RAG 拆解成六个组件。理解每个组件是做什么的、质量风险藏在哪里——这是以后调试 RAG 系统的关键。组件职责质量风险Document Loader读取原始文件(PDF、Word、Markdown、HTML)并提取文本表格、图片、奇怪格式会被搞砸Text Splitter把长文档切成语义连贯的小块块太大 = 精度低;块太小 = 丢失上下文Embedding Model把文本块转换成高维向量模型选错 = 语义不相关的文本聚到一起Vector Store持久化向量,支持快速相似度检索距离度量选错、没有元数据过滤 = 检索质量差Retriever接收查询,检索向量库,返回相关块Top-K 太小 = 漏信息;太大 = 引入噪声Chain编排完整流程:查询 → 检索 → 组装 Prompt → LLM → 答案Prompt 设计和上下文组装决定回答质量把六个组件想象成工厂里的一条流水线:Document Loader 是原材料进料口,Text Splitter 是精密切割站,Embedding Model 和 Vector Store 是仓库和库存系统,Retriever 是拣货员,Chain 是车间主任——协调一切并交付最终产品。流水线上任何一个工位配置错了,最终产品都会受影响——而棘手的是,失败看起来经常是 LLM 的问题,实际上是检索的问题。实战:完整的 LangChain RAG 项目我们来动手搭建。这个项目会读取一个目录下的 PDF 文件,建立索引,然后让你用自然语言提问。项目结构rag-project/ ├── requirements.txt ├── data/ │ └── sample.pdf # 把你的 PDF 文档放这里 └── rag_pipeline.pyStep 0:安装依赖langchain=0.3.0 langchain-text-splitters=0.3.0 langchain-openai=0.2.0 langchain-chroma=0.1.0 langchain-community=0.3.0 pypdf=4.0.0 python-dotenv=1.0.0完整源码(可直接运行):https://github.com/chendongqi/llm-in-action/tree/main/02-langchain-basic支持智谱 AI / OpenAI / Ollama 多 LLM Provider,Embedding 支持 SiliconFlow 和本地 Ollama。安装:pipinstall-rrequirements.txt还需要配置 API Key(复制.env.example为.env后填入):cp.env.example .env# 编辑 .env,填入 LLM_API_KEY 和 EMBEDDING_API_KEY支持的 Provider:LLM:智谱 AI(默认)、OpenAI、SiliconFlow、Ollama、AzureEmbedding:SiliconFlow(默认)、OpenAI、OllamaStep 1:加载文档PyPDFLoader帮我们处理 PDF 解析。它按页提取文本,返回一个Document对象列表,每个对象包含页面内容和元数据(页码、来源文件等)。fromlangchain_community.document_loadersimportPyPDFLoaderfrompathlibimportPathdefload_pdfs(data_dir:str="./data"):"""从数据目录加载所有 PDF 文件"""documents=[]pdf_paths=list(Path(data_dir).glob("*.pdf"))forpdf_pathinpdf_paths:loader=PyPDFLoader(str(pdf_path))pages=loader.load()documents.extend(pages)print(f"已加载 '{pdf_path.name}':{len(pages)}页")print(f"共加载