
如果你正在学习大语言模型应用开发或者想用 LangChain 构建自己的 AI 应用那么这篇文章就是为你准备的。市面上很多教程要么停留在概念要么代码跑不通要么一上来就堆砌复杂的抽象让初学者望而却步。这篇文章的核心目的就是帮你绕开这些“弯路”用最直接、最实战的方式从零构建一个真正可用的 LangChain 应用。LangChain 的价值不在于它封装了多少个模块而在于它提供了一套清晰的“设计模式”让你能系统性地组织 Prompt、模型、工具和数据。很多人学了很久依然只会调用LLMChain面对复杂的 Agent、RAG 系统时无从下手。问题的关键往往在于没有理解其核心的“组件化”思想和数据流转逻辑。本文将从一个具体的实战场景出发构建一个能联网搜索、读取本地文档并给出智能回答的 AI 助手。我们将一步步拆解 LangChain 的核心组件包括 Models、Prompts、Chains、Agents 和 Memory并提供每一环节可运行的代码。读完本文你将能清晰地回答LangChain 解决了什么工程问题它的核心抽象是什么如何从零搭建一个可用的应用以及在实际项目中需要注意哪些“坑”1. LangChain 究竟解决了什么问题在深入代码之前我们必须先理解 LangChain 诞生的背景。如果没有 LangChain开发者要构建一个基于大模型的复杂应用通常会面临以下困境流程碎片化你需要手动拼接调用 API、处理 Prompt 模板、解析模型输出、调用外部工具如搜索、数据库、管理对话历史。这些代码散落在各处难以维护和复用。复杂性陡增当应用逻辑变得复杂例如需要根据模型输出决定下一步调用哪个工具代码会迅速变成难以理解的“面条代码”。切换成本高如果你想从 OpenAI 的 GPT 切换到 Anthropic 的 Claude或者使用本地部署的模型你需要重写大量的接口调用和输出解析逻辑。LangChain 的出现正是为了应对这些挑战。它本质上是一个用于开发由语言模型驱动的应用程序的框架。它通过提供一套标准化的、可组合的“组件”Components和“链”Chains将上述碎片化的流程模块化。一个核心判断LangChain 不是一个“开箱即用”的最终产品而是一个“乐高积木”式的工具箱。它的价值在于提供了构建复杂 AI 应用的设计范式和基础构件。学习 LangChain就是学习如何用这些构件高效、清晰地搭建出你想要的 AI 应用。2. 核心概念与架构理解 LangChain 的“乐高”哲学LangChain 将应用构建过程抽象为几个核心概念理解它们是上手的关键。2.1 核心组件 (Components)这是最基础的“积木块”。Models (模型)各种大语言模型LLMs、聊天模型Chat Models和嵌入模型Embedding Models。LangChain 提供了统一的接口让你可以轻松切换不同供应商的模型。Prompts (提示词)管理 Prompt 的模板化、动态组装和优化。这是提升模型表现的关键。Indexes (索引)用于与外部数据文档、数据库进行交互。核心是Retrieval检索模块常与RAG技术结合。Memory (记忆)用于在多次交互中持久化状态如对话历史。让模型拥有“上下文”能力。Chains (链)将多个组件或其他链按预定顺序组合起来形成一个完整的执行流程。这是 LangChain 的核心抽象。Agents (智能体)高级的链它引入了一个“大脑”通常是 LLM可以自主决定调用哪些工具Tools并根据结果决定下一步行动从而实现复杂的多步任务。Tools (工具)Agent 可以调用的函数例如搜索引擎、计算器、数据库查询等。2.2 数据流转LCEL (LangChain Expression Language)这是 LangChain 推荐的、用于组合链的新方式。它让链的构建像写管道pipe一样直观和声明式。# 一个简单的 LCEL 示例 from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain_core.output_parsers import StrOutputParser prompt ChatPromptTemplate.from_template(请用一句话介绍 {topic}) model ChatOpenAI(modelgpt-3.5-turbo) output_parser StrOutputParser() # 使用管道操作符 | 连接组件形成一个链 chain prompt | model | output_parser # 调用链 result chain.invoke({topic: 人工智能}) print(result)LCEL 的好处是代码清晰、易于调试并且自动支持流式输出、异步调用等高级功能。对于新项目强烈建议从 LCEL 开始。3. 环境准备与安装搭建你的开发环境在开始实战前我们需要一个干净的 Python 环境。3.1 创建并激活虚拟环境使用 conda 或 venv 管理依赖是 Python 开发的最佳实践可以避免包冲突。# 使用 conda (推荐) conda create -n langchain-demo python3.10 conda activate langchain-demo # 或者使用 venv python -m venv venv # Windows venv\Scripts\activate # macOS/Linux source venv/bin/activate3.2 安装核心依赖我们将安装 LangChain 的核心包、与 OpenAI 交互的社区包以及一些实用的工具包。pip install langchain langchain-core langchain-community langchain-openai # 用于文档加载和文本分割 pip install pypdf python-dotenv tiktoken # 可选用于向量数据库本文示例使用内存版 pip install chromadb3.3 配置 API 密钥LangChain 本身不提供模型你需要一个模型供应商的 API 密钥。本文以 OpenAI 为例。将你的密钥保存在项目根目录的.env文件中不要提交到代码仓库。在项目根目录创建.env文件。写入你的 OpenAI API Key# .env 文件内容 OPENAI_API_KEYsk-your-actual-api-key-here在代码中通过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)4. 实战项目构建多功能 AI 助手我们的目标是构建一个助手它具备三种能力基础对话回答通用知识问题。联网搜索回答实时性问题如最新新闻、股价。文档问答读取你提供的 PDF 文档并基于文档内容回答问题。我们将分模块实现最终整合。4.1 模块一基础对话链这是最简单的链展示了 Prompt、Model、Output Parser 的组合。# basic_chat.py from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser import os from dotenv import load_dotenv load_dotenv() # 1. 定义模型 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0.5, api_keyos.getenv(OPENAI_API_KEY)) # 2. 定义提示词模板 prompt_template ChatPromptTemplate.from_messages([ (system, 你是一个乐于助人的AI助手。请用中文回答用户的问题。), (human, {user_input}) ]) # 3. 定义输出解析器将模型输出解析为字符串 output_parser StrOutputParser() # 4. 使用 LCEL 组合成链 basic_chain prompt_template | llm | output_parser # 5. 调用链 if __name__ __main__: question 解释一下什么是机器学习 response basic_chain.invoke({user_input: question}) print(f用户: {question}) print(f助手: {response})关键点解析temperature控制模型输出的随机性0-1。值越低输出越确定、保守值越高越有创造性。对于问答0.5-0.7 是常用范围。ChatPromptTemplate.from_messages允许你定义多轮对话的角色system, human, ai。system消息用于设定 AI 的角色和行为。invoke同步调用链的方法。输入是一个字典键需与提示词模板中的变量名如{user_input}匹配。运行这个脚本你将得到模型对“机器学习”的解释。4.2 模块二为助手添加“记忆”普通的链是无状态的。为了让助手能记住对话历史我们需要引入Memory。# chat_with_memory.py from langchain_openai import ChatOpenAI from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationChain import os from dotenv import load_dotenv load_dotenv() # 1. 初始化模型和记忆 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0.7, api_keyos.getenv(OPENAI_API_KEY)) # ConversationBufferMemory 会保存完整的对话历史 memory ConversationBufferMemory(return_messagesTrue) # 2. 创建对话链 conversation ConversationChain( llmllm, memorymemory, verboseTrue # 设置为 True 可以看到链的思考过程调试时非常有用 ) # 3. 进行多轮对话 print( 开始对话 (输入 quit 退出) ) while True: user_input input(\n你: ) if user_input.lower() quit: break response conversation.predict(inputuser_input) print(fAI: {response}) # 查看当前记忆内容 # print(f当前记忆: {memory.buffer})关键点解析ConversationBufferMemory最简单的记忆类型将整个对话历史存储在内存中。对于长对话可能会消耗大量 Token。ConversationChainLangChain 提供的一个预置链专门用于处理带记忆的对话。verboseTrue这是学习 LangChain 的神器。当设置为True时控制台会打印出链执行的每一步包括传入的 Prompt、模型的原始响应等极大方便调试。predictConversationChain的调用方法。运行后你可以问“我叫小明”再问“我的名字是什么”AI 会正确回答“小明”。4.3 模块三添加联网搜索能力Agent这是 LangChain 最强大的功能之一。我们创建一个Agent让它自主决定何时使用搜索引擎。首先安装必要的工具包pip install langchain-community然后我们需要一个搜索工具的 API。这里以Tavily Search API为例它专为 AI 优化无需复杂配置。你也可以使用 Serper API 或其他。前往 Tavily 官网 注册获取免费 API Key。将其添加到.env文件TAVILY_API_KEYyour_tavily_key。# agent_search.py from langchain_openai import ChatOpenAI from langchain_community.tools import TavilySearchResults from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # 用于拉取预定义的 Prompt import os from dotenv import load_dotenv load_dotenv() # 1. 定义模型 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0, api_keyos.getenv(OPENAI_API_KEY)) # 2. 定义工具 # TavilySearchResults 是一个封装好的搜索工具 search_tool TavilySearchResults(api_keyos.getenv(TAVILY_API_KEY), max_results2) tools [search_tool] # 3. 获取一个为 ReAct 框架设计好的 Prompt # ReAct (Reason Act) 是让 Agent 进行思考再行动的一种流行范式 prompt hub.pull(hwchase17/react-chat) # 4. 创建 ReAct Agent agent create_react_agent(llm, tools, prompt) # 5. 创建 Agent 执行器 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 强烈建议打开观察 Agent 的思考过程 handle_parsing_errorsTrue # 处理解析错误避免崩溃 ) # 6. 运行 Agent if __name__ __main__: questions [ 今天北京天气怎么样, OpenAI 最近有什么新产品发布吗, LangChain 和 LangGraph 有什么区别 ] for question in questions: print(f\n\n用户问题: {question}) print(- * 50) try: result agent_executor.invoke({input: question, chat_history: []}) print(f助手回答: {result[output]}) except Exception as e: print(f执行出错: {e})关键点解析Agent 工作流程当收到问题后Agent由 LLM 驱动会“思考”Reason决定是否需要使用工具Act。如果需要它会生成工具调用的指令执行工具得到结果然后根据结果再进行下一步思考或给出最终答案。verboseTrue务必打开。你会看到类似Thought:、Action:、Observation:的日志这是理解 Agent 如何工作的关键。handle_parsing_errorsTrue模型有时可能输出不符合工具调用格式的内容这个参数可以防止程序因此崩溃。运行此脚本Agent 会针对实时性问题如天气、新闻自动调用搜索工具并整合信息给出回答。4.4 模块四添加文档问答能力RAGRAG 是目前让大模型获取私有、最新知识的主流技术。流程是加载文档 - 分割文本 - 向量化 - 存储 - 检索 - 生成答案。# rag_document_qa.py from langchain_openai import ChatOpenAI, OpenAIEmbeddings from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.vectorstores import Chroma from langchain.chains import RetrievalQA from langchain.prompts import PromptTemplate import os from dotenv import load_dotenv load_dotenv() # 1. 加载文档 (以 PDF 为例) loader PyPDFLoader(./docs/sample.pdf) # 请准备一个 sample.pdf 文件到 docs/ 目录下 documents loader.load() print(f加载了 {len(documents)} 页文档。) # 2. 分割文本 # 大模型有上下文长度限制需要将长文档切分成小块 text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个块的最大字符数 chunk_overlap50, # 块之间的重叠字符保持上下文连贯 separators[\n\n, \n, 。, , , , , , ] ) texts text_splitter.split_documents(documents) print(f分割成 {len(texts)} 个文本块。) # 3. 向量化并存储 # 使用 OpenAI 的嵌入模型将文本转换为向量 embeddings OpenAIEmbeddings(api_keyos.getenv(OPENAI_API_KEY)) # 使用 Chroma 作为向量数据库这里使用内存模式生产环境需持久化 vectorstore Chroma.from_documents(documentstexts, embeddingembeddings, persist_directory./chroma_db) # vectorstore.persist() # 如果需要持久化到磁盘调用此方法 # 4. 创建检索器 retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 检索最相关的 3 个块 # 5. 定义自定义提示词模板 prompt_template 请根据以下上下文信息回答问题。如果你不知道答案就说你不知道不要编造答案。 上下文 {context} 问题{question} 请用中文给出答案 PROMPT PromptTemplate( templateprompt_template, input_variables[context, question] ) # 6. 创建检索问答链 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0, api_keyos.getenv(OPENAI_API_KEY)) qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 将检索到的所有文档块“塞”进 Prompt retrieverretriever, chain_type_kwargs{prompt: PROMPT}, # 使用自定义提示词 return_source_documentsTrue # 返回源文档用于验证 ) # 7. 进行问答 if __name__ __main__: questions [ 这份文档主要讲了什么, # 根据你的文档内容提具体问题 ] for question in questions: print(f\n问题: {question}) result qa_chain.invoke({query: question}) print(f答案: {result[result]}) print(来源文档片段:) for i, doc in enumerate(result[source_documents][:2]): # 显示前两个来源 print(f [{i1}] {doc.page_content[:200]}...) # 截取前200字符关键点解析文本分割chunk_size和chunk_overlap是 RAG 系统的关键超参数需要根据文档特点和模型上下文窗口调整。向量数据库Chroma是一个轻量级、易用的向量数据库。生产环境可以考虑Weaviate、Pinecone、Qdrant等。检索器retriever负责根据问题向量从向量库中找到最相似的文本块。chain_typestuff这是最简单的检索链类型将所有检索到的文档内容拼接后送入 Prompt。其他类型如map_reduce、refine适用于更长的文档。5. 整合与进阶构建统一的多功能助手现在我们将记忆、搜索和 RAG 能力整合到一个系统中。一个简单的思路是使用一个Router Chain或Agent来根据用户问题类型选择不同的处理链。这里展示一个基于LLMRouterChain的简单路由示例# integrated_assistant.py from langchain_openai import ChatOpenAI from langchain.chains.router import MultiPromptChain from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationChain import os from dotenv import load_dotenv load_dotenv() llm ChatOpenAI(modelgpt-3.5-turbo, temperature0, api_keyos.getenv(OPENAI_API_KEY)) # 1. 定义不同目的地的提示词信息 destinations [ { name: general_chat, description: 适用于一般性对话、闲聊、知识问答, prompt_template: 你是一个友好的助手。请用中文回答用户的通用问题。\n\n用户问题{input} }, { name: document_qa, description: 适用于回答关于特定文档内容的问题。用户会提供文档上下文。, prompt_template: 请严格根据以下文档上下文回答问题。如果上下文不包含答案请说不知道。\n\n上下文{context}\n\n问题{input}\n答案 }, # 注意搜索功能需要工具调用更适合用 Agent这里仅作路由演示 ] destination_names [d[name] for d in destinations] destination_descriptions [f{d[name]}: {d[description]} for d in destinations] destination_prompts {d[name]: d[prompt_template] for d in destinations} # 2. 创建路由提示词模板 router_template MULTI_PROMPT_ROUTER_TEMPLATE.format( destinations\n.join(destination_descriptions) ) # 3. 创建路由链 router_chain LLMRouterChain.from_llm( llm, router_template, output_parserRouterOutputParser() ) # 4. 创建目标链这里简化实际每个链应独立实现 from langchain.chains import LLMChain from langchain.prompts import PromptTemplate destination_chains {} for dest in destinations: prompt PromptTemplate( templatedest[prompt_template], input_variables[input] if dest[name] general_chat else [input, context] ) chain LLMChain(llmllm, promptprompt) destination_chains[dest[name]] chain # 默认链 default_chain ConversationChain(llmllm, output_keytext) # 5. 组合成多提示链 chain MultiPromptChain( router_chainrouter_chain, destination_chainsdestination_chains, default_chaindefault_chain, verboseTrue ) # 6. 测试路由 if __name__ __main__: test_inputs [ 你好今天过得怎么样, # 应路由到 general_chat 根据这份合同甲方的义务是什么, # 应路由到 document_qa (需要提供context) ] for inp in test_inputs: print(f\n输入: {inp}) # 注意document_qa 链需要 context 参数这里仅为演示路由逻辑 result chain.run(inp) print(f路由结果: {result})关键点这是一个简化的架构演示。在生产中document_qa链需要接入真实的向量检索器而搜索功能则需要通过Agent来实现。更成熟的方案是构建一个Agent其工具集Tools包含文档检索工具和搜索工具由 LLM 自行决定调用哪个。6. 运行、调试与效果验证6.1 如何运行确保已安装所有依赖 (pip install ...)。正确配置.env文件中的OPENAI_API_KEY和TAVILY_API_KEY。准备一个 PDF 文档放在./docs/sample.pdf供 RAG 测试。从最简单的basic_chat.py开始运行确保基础环境连通。逐步运行chat_with_memory.py、agent_search.py、rag_document_qa.py观察输出和verbose日志。6.2 验证成功基础对话能收到连贯、合理的回复。记忆功能在多轮对话中AI 能记住之前提到的信息。联网搜索查看verbose日志应出现Thought:、Action: Search、Observation:等步骤最终答案应包含实时信息。文档问答AI 的回答应严格基于你提供的文档内容。可以故意问一个文档外的问题验证它是否会回答“不知道”。6.3 调试技巧开启verboseTrue这是最重要的调试手段能让你看清 LangChain 内部的执行步骤和传递给模型的 Prompt。检查 API 响应如果调用失败首先检查 API 密钥、网络连接和额度。打印中间变量在链的关键步骤打印输入输出例如打印分割后的文本块、检索到的文档内容等。7. 常见问题与排查思路问题现象可能原因排查方式解决方案ModuleNotFoundError: No module named langchain_xxx依赖包未安装或版本不兼容。检查pip list确认包名是否正确。LangChain 将很多功能拆到了子包。使用pip install langchain-community等命令安装对应社区包。检查官方文档确认所需包名。AuthenticationError/Invalid API KeyAPI 密钥错误、未设置或环境变量未加载。1. 检查.env文件格式和内容。2. 在代码中print(os.getenv(“KEY”))验证是否加载成功。3. 检查 API 供应商控制台确认密钥有效且有余额。1. 确保.env文件在项目根目录且内容为KEYvalue格式。2. 在代码开头调用load_dotenv()。3. 重新生成或充值 API 密钥。Agent 不调用工具直接回答问题1. Prompt 未引导 Agent 使用工具。2. 工具描述不清晰。3. 模型温度 (temperature) 过高。开启verboseTrue查看模型的Thought过程。看它是否考虑了工具。1. 使用经过验证的 Agent Prompt如hwchase17/react-chat。2. 为工具编写清晰、具体的description。3. 将temperature设为 0 以获得更确定性的输出。RAG 回答与文档内容不符1. 文本分割不合理破坏了语义。2. 检索到的文本块不相关。3. Prompt 未强制要求基于上下文。1. 打印texts查看分割效果。2. 打印result[‘source_documents’]查看检索到的源文本。3. 检查 Prompt 模板。1. 调整chunk_size和chunk_overlap或尝试其他TextSplitter。2. 调整检索的k值或尝试不同的search_type如mmr。3. 在 Prompt 中加入“如果不知道就说不知道”的强指令。程序运行缓慢1. 网络请求延迟调用 OpenAI API。2. 本地嵌入模型计算慢。3. 向量检索未使用索引。使用代码计时定位耗时环节。1. 考虑使用异步调用 (ainvoke)。2. 对于生产环境使用高效的嵌入模型如text-embedding-3-small和向量数据库如Weaviate,Qdrant。3. 对向量数据库创建索引。Max retries exceeded或网络超时网络不稳定或 API 服务器问题。查看完整错误堆栈。1. 增加超时设置ChatOpenAI(..., request_timeout30)。2. 添加重试逻辑from tenacity import retry, stop_after_attempt。3. 检查本地网络和代理设置。8. 最佳实践与工程化建议将原型转化为可维护、可部署的项目需要注意以下几点配置管理永远不要将 API 密钥硬编码在代码中。使用.env文件和环境变量。考虑使用pydantic-settings进行类型安全的配置管理。错误处理与重试网络请求和模型调用可能失败。使用tenacity库为关键操作添加重试机制并做好异常捕获和日志记录。成本与速率限制监控 API 调用成本和频率。为ChatOpenAI等客户端设置max_retries和max_tokens限制。对于开源模型注意本地资源消耗。Prompt 工程将 Prompt 模板保存在外部文件如 JSON、YAML或数据库中便于管理和 A/B 测试。为关键应用设计系统提示词System Prompt明确角色、格式和边界。RAG 优化分块策略根据文档类型代码、论文、手册选择合适的分割器。可以尝试按标题分割、语义分割等高级方法。检索优化除了相似性检索可结合关键词检索BM25进行混合搜索Hybrid Search。对检索结果进行重排序Re-ranking以提升精度。元数据过滤在存储向量时附带文档来源、章节、日期等元数据检索时可以进行过滤。Agent 设计工具设计工具函数应单一职责描述清晰。工具返回的结果应简洁、结构化便于模型理解。限制与兜底为 Agent 设置最大迭代次数 (max_iterations)防止陷入死循环。设计清晰的退出或求助机制。可观测性使用LangSmithLangChain 官方平台来跟踪、调试和评估链和 Agent 的每一次调用这是生产级应用不可或缺的。版本化与测试像对待其他代码一样对 Prompt、链的配置进行版本控制。为你的 AI 工作流编写单元测试和集成测试。9. 总结与学习路径通过本文的实战你应该已经掌握了 LangChain 的核心概念和构建一个多功能 AI 助手的基本流程。我们从最简单的链开始逐步加入了记忆、工具调用Agent和检索RAG这些核心能力。LangChain 的学习曲线在于理解其“组件化”的抽象思想。一旦你接受了 Models, Prompts, Indexes, Chains, Agents, Tools, Memory 这套范式构建复杂应用就会变得有章可循。接下来的学习方向深入 LangGraph如果你需要构建有复杂状态流转、循环或分支的工作流如一个支持多轮工具调用的超级 AgentLangGraph是比基础Agent更强大的选择。它允许你以图Graph的形式可视化定义工作流。探索更多工具和集成LangChain 社区有海量的工具和集成数据库、各类 API。根据你的业务需求去langchain-community中寻找现成的解决方案。优化 RAG 管道RAG 的效果很大程度上取决于检索质量。深入研究嵌入模型、检索算法、重排序和 Prompt 优化这是当前提升 AI 应用效果的关键战场。部署与生产化学习如何使用FastAPI或LangServe将你的链封装成 API 服务如何容器化部署以及如何集成监控和日志系统。学习的最佳方式永远是动手。建议你以本文的代码为起点尝试修改参数、更换工具、接入自己的数据源在解决实际问题的过程中你会对 LangChain 有更深刻的理解。