
最近在尝试将大语言模型LLM应用到实际业务中时你是否遇到过这样的困境模型本身能力很强但让它理解你的私有数据、调用外部工具、或者记住多轮对话历史却异常困难每个环节都需要大量的定制化开发代码变得冗长且难以维护。这正是 LangChain 旨在解决的核心痛点。本文将带你系统性地认识 LangChain从核心概念到实战应用手把手教你构建一个能“思考”和“行动”的智能应用。无论你是刚接触 AI 应用开发的新手还是希望将现有 LLM 能力工程化的开发者通过本文你将掌握 LangChain 的核心架构、六大关键模块的用法并最终能独立搭建一个具备检索增强生成RAG能力的问答系统。我们会从零开始用代码贯穿始终。1. LangChain 核心概念为什么需要它在深入代码之前我们必须先理解 LangChain 究竟解决了什么问题。简单来说LangChain 是一个用于开发由语言模型驱动的应用程序的框架。它不是一个模型而是一个“粘合剂”和“脚手架”。想象一下强大的 LLM如 GPT-4、ChatGLM、文心一言是一个知识渊博但“与世隔绝”的大脑。它拥有强大的推理和生成能力但存在几个固有局限知识截止性它的训练数据有截止日期无法获取最新或私有信息。缺乏“行动”能力它无法直接查询数据库、调用 API 或执行计算。上下文长度限制无法一次性处理过长的文档或复杂的多轮对话历史。输出不可控其回答格式自由难以直接集成到需要结构化输出的系统中。LangChain 通过提供一套标准化的接口、组件和设计模式优雅地解决了这些问题。它将 LLM 与外部数据源、工具和记忆系统连接起来构建出能够“感知-思考-行动”的智能体Agent。它的核心价值在于标准化和模块化让开发者能像搭积木一样快速构建复杂的 LLM 应用。2. 环境准备与版本说明在开始实战前我们需要搭建开发环境。本文将使用 Python 作为开发语言并聚焦于 LangChain 的核心功能演示。环境要求操作系统Windows 10/11, macOS, 或 Linux (Ubuntu 20.04)Python 版本3.8 或更高版本 (推荐 3.9)包管理工具pip核心依赖安装我们将安装 LangChain 的核心库以及一些常用的社区集成包。建议在一个新的虚拟环境中进行。# 创建并激活虚拟环境 (以 conda 为例也可使用 venv) conda create -n langchain-demo python3.9 conda activate langchain-demo # 安装 LangChain 核心包 pip install langchain # 安装 OpenAI 集成包用于调用 GPT 模型需自备 API Key pip install openai # 安装用于文本加载和向量数据库的常用包 pip install langchain-community # 社区维护的集成组件 pip install chromadb # 轻量级向量数据库用于存储和检索文档嵌入 pip install tiktoken # OpenAI 的令牌计数器 pip install pypdf # 用于读取 PDF 文件 pip install python-dotenv # 用于管理环境变量版本说明与兼容性LangChain 生态迭代迅速本文示例基于langchain0.1.0及以上版本该版本号后采用了新的模块化架构。新版本将核心功能拆分为langchain-core并将许多集成移至langchain-community。如果你安装的是较旧版本如 0.0.x部分导入语句可能需要调整。建议始终关注官方文档的迁移指南。关键配置为了调用 OpenAI 的模型你需要准备一个 API Key。强烈建议使用环境变量管理避免将密钥硬编码在代码中。在项目根目录创建.env文件# .env OPENAI_API_KEY你的实际API密钥在代码中通过dotenv加载# config.py 或主程序开头 from dotenv import load_dotenv import os load_dotenv() # 加载 .env 文件中的环境变量 openai_api_key os.getenv(OPENAI_API_KEY) if not openai_api_key: raise ValueError(请在 .env 文件中设置 OPENAI_API_KEY)3. LangChain 六大核心模块拆解理解 LangChain 的架构是高效使用它的关键。其设计围绕以下六个核心模块展开它们相互协作构成了一个完整的 LLM 应用流水线。3.1 模型 I/O (Model I/O)这是与 LLM 交互的最基础层提供了与各种模型供应商对话的标准化接口。主要包括提示词 (Prompts)将用户输入和指令模板化。LangChain 提供了PromptTemplate、ChatPromptTemplate等工具支持动态插入变量。from langchain.prompts import ChatPromptTemplate template 你是一个专业的翻译助手。请将以下英文句子翻译成中文 英文{english_text} 中文 prompt ChatPromptTemplate.from_template(template) formatted_prompt prompt.format(english_textHello, LangChain!) # 输出: “你是一个专业的翻译助手...英文Hello, LangChain!\n中文”语言模型 (LLMs/Chat Models)LLM类用于文本补全模型如 text-davinci-003ChatModel类用于对话模型如 gpt-3.5-turbo。它们提供了统一的invoke或generate方法。from langchain_openai import ChatOpenAI model ChatOpenAI(modelgpt-3.5-turbo, api_keyopenai_api_key)输出解析器 (Output Parsers)将模型自由格式的文本输出解析成结构化的数据如 Pydantic 对象、列表、JSON便于后续程序处理。from langchain.output_parsers import PydanticOutputParser from pydantic import BaseModel, Field class Translation(BaseModel): original: str Field(description原始英文文本) translated: str Field(description翻译后的中文文本) parser PydanticOutputParser(pydantic_objectTranslation) # 可以指导模型按照指定格式输出然后由parser解析3.2 数据连接 (Retrieval)这是实现 RAG 的基石目标是将外部数据转换为模型可以理解和利用的格式。流程通常分为四步文档加载 (Document Loaders)从各种来源PDF、网页、数据库、Notion加载原始数据得到Document对象列表。from langchain_community.document_loaders import PyPDFLoader loader PyPDFLoader(path/to/your/document.pdf) documents loader.load()文本分割 (Text Splitters)将长文档切分成语义相关的小块Chunks以适应模型的上下文窗口。from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter RecursiveCharacterTextSplitter(chunk_size500, chunk_overlap50) chunks text_splitter.split_documents(documents)向量化与嵌入 (Embedding Models)使用嵌入模型如 OpenAItext-embedding-3-small将文本块转换为高维向量 embeddings。语义相似的文本向量距离也相近。from langchain_openai import OpenAIEmbeddings embeddings OpenAIEmbeddings(modeltext-embedding-3-small, api_keyopenai_api_key) vector embeddings.embed_query(什么是人工智能)向量存储与检索 (Vectorstores)将向量存储到专门的数据库如 Chroma, Pinecone, Weaviate中并实现基于相似度的快速检索。from langchain_community.vectorstores import Chroma vectorstore Chroma.from_documents(documentschunks, embeddingembeddings, persist_directory./chroma_db) retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 检索最相关的3个块3.3 链 (Chains)链是将多个模块组合在一起按预定顺序执行的工作流。这是 LangChain 得名的原因。最简单的链是LLMChain提示词 模型。更强大的有SequentialChain顺序链、RetrievalQA检索问答链等。from langchain.chains import RetrievalQA qa_chain RetrievalQA.from_chain_type( llmmodel, chain_typestuff, # 将检索到的文档“塞”进提示词 retrieverretriever, return_source_documentsTrue # 返回参考来源 ) result qa_chain.invoke({query: LangChain 有哪些核心模块})3.4 记忆 (Memory)为了让模型在对话中记住上下文需要记忆模块。它管理着对话历史的状态。ConversationBufferMemory简单存储所有历史消息。ConversationBufferWindowMemory只保留最近 K 轮对话。ConversationSummaryMemory对历史对话进行总结以节省令牌。from langchain.memory import ConversationBufferMemory memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 在链中集成 memory 参数即可实现带历史的对话。3.5 代理 (Agents)代理是 LangChain 最激动人心的部分。它让 LLM 具备“行动”能力。代理的核心是一个“推理循环”模型根据目标、可用工具和当前观察决定下一步是调用工具还是直接给出最终答案。工具 (Tools)代理可以调用的函数如搜索、计算、查询数据库等。LangChain 提供了大量内置工具也支持自定义。from langchain.agents import load_tools tools load_tools([serpapi, llm-math], llmmodel) # 加载搜索和计算工具代理执行器 (Agent Executor)负责运行代理的推理循环处理工具调用和结果返回。from langchain.agents import create_react_agent, AgentExecutor from langchain import hub prompt hub.pull(hwchase17/react) # 使用 ReAct 推理框架的提示词 agent create_react_agent(llmmodel, toolstools, promptprompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue) result agent_executor.invoke({input: 截至今天苹果公司AAPL的股价是多少如果我有100股总价值是多少人民币})3.6 回调 (Callbacks)回调系统允许你在链或代理执行的各个阶段开始、结束、出错等注入逻辑用于日志记录、监控、流式传输等。from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler model ChatOpenAI( modelgpt-3.5-turbo, streamingTrue, callbacks[StreamingStdOutCallbackHandler()], api_keyopenai_api_key ) # 调用时回答会逐词流式输出到控制台。4. 完整实战构建一个本地知识库问答系统 (RAG)现在我们将综合运用以上模块构建一个完整的 RAG 系统。该系统能够读取你的本地文档如产品手册、项目报告并回答基于这些文档内容的问题。4.1 项目结构与数据准备创建如下项目结构my_rag_project/ ├── data/ # 存放原始文档 │ └── product_manual.pdf ├── chroma_db/ # 向量数据库存储目录自动生成 ├── .env # 环境变量文件 ├── config.py # 配置文件 ├── build_vectorstore.py # 构建向量库的脚本 └── query_agent.py # 问答交互脚本将你的 PDF 或 TXT 文档放入data/目录。4.2 构建向量知识库这是离线预处理步骤只需在文档更新时运行。# build_vectorstore.py import os from dotenv import load_dotenv from langchain_community.document_loaders import PyPDFLoader, TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma # 加载配置 load_dotenv() openai_api_key os.getenv(OPENAI_API_KEY) def build_and_persist_vectorstore(data_dir./data, persist_dir./chroma_db): 加载指定目录下的所有文档处理并持久化向量存储。 documents [] # 1. 加载文档 for filename in os.listdir(data_dir): file_path os.path.join(data_dir, filename) if filename.endswith(.pdf): loader PyPDFLoader(file_path) documents.extend(loader.load()) print(f已加载 PDF: {filename}) elif filename.endswith(.txt): loader TextLoader(file_path, encodingutf-8) documents.extend(loader.load()) print(f已加载 TXT: {filename}) # 可扩展其他格式如 .docx, .md if not documents: print(未找到任何可处理的文档。) return None # 2. 分割文本 text_splitter RecursiveCharacterTextSplitter( chunk_size1000, # 每个块约1000字符 chunk_overlap200, # 块间重叠200字符保持上下文连贯 separators[\n\n, \n, 。, , , , , , ] ) chunks text_splitter.split_documents(documents) print(f文档共分割为 {len(chunks)} 个文本块。) # 3. 创建嵌入模型和向量库 embeddings OpenAIEmbeddings( modeltext-embedding-3-small, api_keyopenai_api_key ) # 4. 将向量存储到 Chroma 并持久化到磁盘 vectorstore Chroma.from_documents( documentschunks, embeddingembeddings, persist_directorypersist_dir ) print(f向量库已构建并保存至 {persist_dir}) return vectorstore if __name__ __main__: build_and_persist_vectorstore()运行此脚本python build_vectorstore.py。成功后会在chroma_db目录下生成持久化文件。4.3 实现问答链与交互接下来我们创建问答脚本它加载已构建的向量库并创建一个可以回答问题的链。# query_agent.py import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate # 加载配置 load_dotenv() openai_api_key os.getenv(OPENAI_API_KEY) def initialize_qa_system(persist_dir./chroma_db): 初始化问答系统加载向量库、模型并创建检索问答链。 # 1. 加载相同的嵌入模型 embeddings OpenAIEmbeddings( modeltext-embedding-3-small, api_keyopenai_api_key ) # 2. 从磁盘加载已持久化的向量库 vectorstore Chroma( persist_directorypersist_dir, embedding_functionembeddings ) # 创建检索器设置返回前4个最相关结果 retriever vectorstore.as_retriever(search_kwargs{k: 4}) # 3. 初始化 LLM llm ChatOpenAI( modelgpt-3.5-turbo, temperature0.1, # 低温度使输出更确定、更基于事实 api_keyopenai_api_key ) # 4. 自定义提示词模板指导模型基于上下文回答 prompt_template 请严格根据以下提供的上下文信息来回答问题。如果上下文没有提供足够的信息来回答问题请直接说“根据已知信息无法回答此问题”不要编造信息。 上下文 {context} 问题{question} 基于上下文的回答 PROMPT PromptTemplate( templateprompt_template, input_variables[context, question] ) # 5. 创建检索问答链 qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 简单地将所有检索到的文档合并到提示词中 retrieverretriever, chain_type_kwargs{prompt: PROMPT}, # 使用自定义提示词 return_source_documentsTrue # 非常重要返回参考来源 ) return qa_chain def main(): print(正在初始化本地知识库问答系统...) qa_chain initialize_qa_system() print(系统已就绪请输入您的问题输入 quit 或 退出 结束) while True: query input(\n您的问题: ).strip() if query.lower() in [quit, 退出, exit]: print(再见) break if not query: continue try: # 执行查询 result qa_chain.invoke({query: query}) answer result[result] source_docs result[source_documents] print(f\n回答: {answer}) print(\n--- 参考来源 ---) # 展示来源文档的片段和元数据如页码 for i, doc in enumerate(source_docs[:2]): # 显示前2个来源 source_info doc.metadata.get(source, 未知文件) page doc.metadata.get(page, N/A) # 显示来源文档的前200个字符作为预览 content_preview doc.page_content[:200] ... if len(doc.page_content) 200 else doc.page_content print(f[来源 {i1}] 文件: {source_info}, 页码: {page}) print(f 片段: {content_preview}\n) except Exception as e: print(f查询过程中出现错误: {e}) if __name__ __main__: main()4.4 运行与验证确保已运行build_vectorstore.py生成向量库。运行问答脚本python query_agent.py。在控制台输入基于你文档内容的问题。预期交互示例正在初始化本地知识库问答系统... 系统已就绪请输入您的问题输入 quit 或 退出 结束 您的问题: 我们产品的主要优势是什么 回答: 根据提供的上下文我们产品的主要优势包括三点第一采用了先进的X算法处理效率提升50%第二支持多种数据格式的无缝导入第三提供了7x24小时的实时技术支持。 --- 参考来源 --- [来源 1] 文件: data/product_manual.pdf, 页码: 5 片段: 第三章 产品优势。1. 性能卓越得益于自主研发的X算法本产品在标准测试集上的处理效率相比竞品提升约50%...4.5 结果说明通过这个实战项目我们成功构建了一个具备以下能力的系统知识本地化将私有 PDF/TXT 文档转化为可查询的知识库。精准问答通过向量相似度检索确保答案严格来源于提供的上下文极大减少了模型“幻觉”。答案可溯源展示答案所依据的原文片段和位置增强了可信度。架构清晰代码模块化预处理建库和推理问答分离便于维护和扩展。5. 常见问题与排查思路在开发和使用 LangChain 应用时你可能会遇到以下典型问题。问题现象常见原因解决思路ModuleNotFoundError: No module named ‘langchain_community‘LangChain 版本 0.1.0部分模块已迁移。安装langchain-community包pip install langchain-community。检查导入语句是否正确。调用 OpenAI API 超时或报错AuthenticationError1. API Key 未设置或错误。2. 网络连接问题。3. API 额度不足。1. 检查.env文件及加载代码。2. 检查网络代理设置如需。3. 登录 OpenAI 控制台检查额度和账单。向量检索结果不相关1. 文本分割策略不当块太大或太小。2. 嵌入模型不适合该类型文本。3. 检索参数k设置不合理。1. 调整chunk_size和chunk_overlap尝试不同的分割器。2. 尝试不同的嵌入模型如text-embedding-3-large。3. 调整search_kwargs{“k”: n}尝试不同的 n 值。模型回答忽略上下文自行编造提示词Prompt指令不够强。强化提示词例如“你必须且只能根据以下上下文回答...”并明确告知无法回答时应如何回应。处理长文档时程序内存溢出一次性加载或处理了过大的文件。使用流式加载器如果可用确保文本分割后单块大小合理考虑分批处理文档。Agent 陷入循环或调用错误工具工具描述不清晰或模型对任务理解有偏差。1. 为自定义工具编写清晰详细的描述。2. 尝试不同的 Agent 类型如ZERO_SHOT_REACT_DESCRIPTION,OPENAI_FUNCTIONS。3. 设置max_iterations参数限制循环次数。6. 最佳实践与工程建议将 LangChain 应用于生产环境时除了功能实现还需关注稳定性、性能和可维护性。提示词工程是核心模型的表现极大程度依赖于提示词。务必精心设计提示词明确角色、任务、格式要求和约束条件。将提示词模板化并独立管理便于迭代优化。管理好模型成本与延迟区分场景选择模型。简单的信息提取可用小模型如 GPT-3.5-Turbo复杂推理再用大模型如 GPT-4。利用缓存如LangChain的SemanticCache存储常见查询的嵌入和结果减少重复调用。构建稳健的检索流程多路召回与重排序不要只依赖一种检索方式。可以结合关键词搜索如 BM25和向量检索然后将结果合并并让更精细的模型进行重排序提升召回率和精度。元数据过滤在存储文档时为其添加元数据如文档类型、创建日期、章节。检索时可以利用这些元数据进行过滤使结果更精准。实施全面的异常处理与监控LLM API 调用可能失败务必添加重试机制和降级策略如切换备用模型。记录所有请求和响应的日志包括令牌使用量、耗时、检索到的文档 ID 等便于问题排查和成本分析。使用回调系统集成监控工具如 LangSmith LangChain 官方平台可视化跟踪链的执行过程。关注安全与合规数据泄露确保上传到第三方模型 API 的数据不包含敏感信息。对于高度敏感数据考虑使用本地部署的模型。提示词注入对用户输入进行适当的清洗和校验防止恶意输入篡改系统提示词导致模型执行非预期操作。输出审查对于面向公众的应用务必对模型的输出进行内容安全过滤防止生成有害或不适当的内容。模块化与可测试性将你的 LangChain 应用拆分为清晰的组件数据加载、处理、检索、生成。每个组件应职责单一便于单独测试和替换。例如可以轻松将向量数据库从 Chroma 切换到 Pinecone或将 LLM 从 OpenAI 切换到本地部署的 ChatGLM。掌握 LangChain 相当于获得了一套构建智能应用的“乐高”工具箱。从简单的提示词管理到复杂的自主智能体其模块化设计让想法能快速原型化。建议从本文的 RAG 示例出发然后尝试为你的问答系统添加对话记忆Memory让它能进行多轮追问再进一步尝试集成一个搜索工具让 Agent 能结合实时网络信息来回答问题。在实践中你会更深刻地体会到如何通过编排这些组件让大语言模型真正融入你的业务逻辑创造出有价值的 AI 应用。