LangChain实战指南:从核心概念到RAG与Agent工程落地 最近不少读者问我LangChain 版本更新这么快社区资料又杂到底该怎么学才不踩坑这个问题问得很实在。我见过不少团队把 LangChain 当成“调用大模型的 HTTP 封装”来用结果项目一复杂就发现到处都是坑Prompt 拼装混乱、工具调用不稳定、RAG 检索结果差、Agent 经常陷入死循环。问题出在哪大部分时候不是大模型不行而是没理解 LangChain 的编排逻辑。这篇教程我会从示例代码出发讲清楚 LangChain 里最核心的几个概念再落到可运行的企业项目实战思路。内容包括Core 核心组件、LCEL 表达式语言、RAG 知识库问答、ReAct 模式与 Agent 中间件、MapReduce 长文本处理以及 2025 年绕不开的 MCP 协议。阅读之前先给你一个明确判断LangChain 不是一个“模型调用工具”而是一个“大模型应用编排框架”。你的学习重点应该放在 Chain链、Agent代理、Memory记忆、RAG检索增强这几个工程抽象上而不是某个模型的 API 怎么调。这篇文章适合哪些人已经会调用大模型 API但不知道怎么把 Prompt、知识库、外部工具组装成完整应用的开发者。正在做或准备做 RAG 知识库问答但效果不理想想系统梳理流程的人。想理解 Agent 和 ReAct 模式但不清楚 LangChain 里 Agent 中间件如何工作的读者。想从示例跑到企业项目需要知道常见问题和最佳实践的工程师。1. LangChain 到底解决什么问题先看一个真实场景。假设你要做一个客服助手让用户直接问“我的订单到哪了”。没有框架的时候你要写多少代码定义一个 Prompt 模板把用户问题塞进去。调用大模型接口拿到回答。如果用户问“帮我查天气”还要根据意图调用天气接口。如果用户问“这个月报表分析一下”你需要把数据库数据取出来塞进 Prompt。多轮对话还要手动维护历史消息列表。这些问题本身不难但组合在一起就变得繁琐。更关键的是大模型应用通常不是“单次问答”而是一个多步骤流程理解意图、检索资料、调用工具、生成答案、格式化输出。每一步都会引入不确定性而 LangChain 提供的就是一套把这些步骤串起来的标准方式。画一条对比线直接调 API你关注的是 HTTP 请求、Token 消耗、输出解析。使用 LangChain你关注的是数据怎么流转、工具怎么接入、异常怎么处理。换句话说LangChain 把“大模型对话”变成了“可编排的数据流”。它提供的不是某个特别强的模型能力而是一套工程化框架帮你统一管理 Prompt、模型、输出解析、记忆和工具。还有个容易混淆的问题LangChain 和 LangGraph 是什么关系简单说LangGraph 是 LangChain 团队推出的下一代编排框架更擅长构建有状态、有环、需要人工干预的复杂 Agent 应用。LangChain 经典 API 适合线性或简单分支流程LangGraph 适合复杂的图结构流程。初学者建议先扎实掌握 LangChain 核心再学 LangGraph不要一上来就追新。2. LangChain 核心概念与架构梳理LangChain 发展到现在模块划分已经发生了不小变化尤其 0.1 之后到 0.3 这个阶段接口和包名都在调整。但从学习角度你可以把它分成几个核心抽象Model / Chat Model也就是大模型封装。LangChain 支持 OpenAI、Anthropic、Google Gemini以及国内常见的 OpenAI 兼容接口。只要模型提供 OpenAI 兼容的 HTTP 接口就能接入。Prompt Template提示词模板。把固定的系统指令和动态的用户输入分开避免每次都在代码里拼字符串。Output Parser输出解析器。把模型返回的文本解析成结构化数据比如 JSON、Pydantic 对象、逗号分隔列表。LangChain 0.2 之后提供了with_structured_output这类更简洁的方式底层依赖模型本身的 JSON 输出能力。Memory对话记忆。管理多轮对话中的历史消息常见方案有ConversationBufferMemory、ConversationSummaryMemory等。不过在 LangChain 新版本中官方越来越推荐直接把历史消息作为参数传入messages而不是依赖 Memory 模块的隐式状态。Chain / LCEL链和表达式语言。LCELLangChain Expression Language是 LangChain 推荐的链式编程语法用|连接不同组件。RAG检索增强生成。先通过检索从外部知识库中找到相关资料再把资料和问题一起交给模型生成答案。Agent / Tool智能体和工具。Agent 决定“调用哪个工具”“什么时候调用”工具是 Agent 可以执行的外部函数。ReAct 是经典 Agent 实现之一核心是“思考-行动-观察”循环。Callback回调机制。你可以在链执行过程中挂上回调用来记录日志、追踪 Token 消耗、实现流式输出。为了理解它们之间的关系可以打个比方。LangChain 像一条自动化生产线传送带是 LCEL 的|符号负责把物料运到各工位。Prompt Template 是产品设计图规定产品长什么样。Model 是核心加工机器负责生成内容。Output Parser 是质检员检查产品是否符合规格。Memory 是仓库保存半成品和历史记录。RAG 是外协供应商从外部库调取原料。Agent 是调度员根据情况决定下一步让哪台机器工作。3. 环境准备与 LangChain 安装开始实操前先准备环境。建议用 Python 3.10 以上版本如果机器上没有先装好 Python 并配置国内镜像源。安装 LangChain 时要注意官方现在把核心包拆开了。以前pip install langchain就够现在很多功能需要单独安装对应包比如langchain-openai、langchain-community、langchain-chroma。下面给出一套相对完整的安装命令版本请以实际环境为准本文着重演示通用思路# 创建虚拟环境 python -m venv langchain-demo source langchain-demo/bin/activate # Windows 下执行 langchain-demo\Scripts\activate # 安装核心包 pip install langchain langchain-openai langchain-community # 如果做 RAG常用文档加载、切分、向量库相关包 pip install langchain-text-splitters chromadb pypdf # 如果做 Agent 结构化和工具调用建议安装 pip install pydantic接下来设置大模型 API Key。为了示例通用我以 OpenAI 兼容接口为例。很多国内大模型服务也提供兼容接口只需要替换base_url、api_key、model三处配置。创建.env文件OPENAI_API_KEY你的API_KEY OPENAI_API_BASEhttps://你的兼容接口地址 OPENAI_MODEL_NAMEgpt-4o-mini如果暂时没有 API Key可以用一个假的 Key 先把代码流程跑通会报鉴权错误但能看到调用逻辑也可以考虑本地模型方案比如基于 llama.cpp 部署 Qwen 系列模型用 OpenAI 兼容接口接入。4. 第一个 LangChain 示例从 Runnable 到 LCEL4.1 基础模型调用先写一个最简单的示例。新建demo_basic.pyimport os from langchain_openai import ChatOpenAI # 从环境变量读取配置 llm ChatOpenAI( modelos.getenv(OPENAI_MODEL_NAME, gpt-4o-mini), temperature0.7, ) response llm.invoke(用一句话解释什么是 RAG) print(response.content)这个示例做的事情很简单调用模型并输出回答。注意llm.invoke()返回的不是字符串而是一个AIMessage对象所以要用.content拿到文本。4.2 引入 Prompt Template实际项目很少直接丢一个问题给模型而是需要一套结构化提示词。改进一下from langchain_core.prompts import ChatPromptTemplate prompt ChatPromptTemplate.from_messages([ (system, 你是一个资深 AI 技术专家回答问题要简洁、准确、有逻辑。), (human, 请解释以下技术概念{concept}), ]) chain prompt | llm result chain.invoke({concept: LCEL}) print(result.content)这里的竖线|就是 LCEL 的核心语法表示把 prompt 的输出传给 llm。LCEL 让链式调用看起来非常直观也容易被优化执行。4.3 加入输出解析如果希望模型返回结构化 JSON可以加一个输出解析器或者直接用with_structured_outputfrom langchain_core.pydantic_v1 import BaseModel, Field class TechConcept(BaseModel): name: str Field(description概念名称) definition: str Field(description定义) use_case: str Field(description使用场景) llm_with_structure llm.with_structured_output(TechConcept) result llm_with_structure.invoke( 介绍一下 ReAct 模式包含名称、定义和使用场景 ) print(result.name) print(result.definition) print(result.use_case)这个能力依赖大模型的 JSON 输出能力不是所有模型都稳定。如果模型返回的 JSON 格式不规范建议在 Prompt 中加强说明或者增加重试机制。到这里你就掌握了 LangChain 最基础的三个组装动作Prompt 模板、模型调用、输出解析。这也是所有复杂应用的最小单元。5. RAG 知识库问答完整示例RAG 是 LangChain 里最常被提到的应用场景。它的目的是解决大模型“编造知识”的问题在生成回答之前先从外部知识库检索相关内容把检索结果作为参考材料发给模型。5.1 RAG 完整流程一个标准 RAG 流程包含以下步骤文档加载读取 PDF、TXT、网页、Word 等文件。文本分割把长文档切分成 chunk避免超出模型上下文窗口。向量化用 Embedding 模型把 chunk 转成向量。存储把向量保存到向量数据库Chroma、FAISS、Milvus、PGVector 等。检索用户提问时把问题向量化在数据库中做相似度检索。增强生成把检索到的 top-k 文档与用户问题组装成 Prompt交给模型生成。5.2 文档加载与分割先看文档加载和分割的示例from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter # 假设你有一份 txt 文档 loader TextLoader(help_docs.txt, encodingutf-8) documents loader.load() # 切分参数需要根据实际文档调整 text_splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap50, separators[\n\n, \n, 。, , , , ] ) docs text_splitter.split_documents(documents) print(f切分后文档块数: {len(docs)})chunk_size和chunk_overlap是两个关键参数。chunk_size决定每块多大chunk_overlap决定块与块之间重复多少内容。这里的坑是如果分割太细语义会被切断如果分割太粗检索精度下降。建议从 300-800 起步根据模型上下文和业务场景调优。5.3 向量化与存储接着用向量数据库存储from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma # Embedding 模型 embeddings OpenAIEmbeddings() # 创建并持久化向量库 vectorstore Chroma.from_documents( documentsdocs, embeddingembeddings, persist_directory./chroma_db ) print(向量库构建完成) # 检索测试 retriever vectorstore.as_retriever(search_kwargs{k: 3}) results retriever.invoke(退换货的流程是什么) for doc in results: print(doc.page_content) print(----)如果不需要持久化可以不用persist_directory。但企业场景中一般都要做持久化因为文档更新后不需要全量重建向量库。5.4 组装 RAG 问答链检索器准备好后写一个完整的 RAG 问答链from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI prompt ChatPromptTemplate.from_messages([ (system, 你是一个企业知识库助手。请基于【参考资料】回答问题。如果资料中没有相关内容明确回答不知道不要编造。\n\n 【参考资料】\n{context}), (human, {question}), ]) llm ChatOpenAI() def format_docs(docs): return \n\n.join([doc.page_content for doc in docs]) rag_chain ( { context: retriever | format_docs, question: lambda x: x[question] } | prompt | llm ) answer rag_chain.invoke({question: 退换货需要哪些条件}) print(answer.content)这里有个值得注意的小技巧retriever | format_docs表示先检索再把结果拼成字符串。LCEL 的好处是你可以轻松在中间插入日志、重试、甚至替换检索器。5.5 RAG 效果不理想怎么排查RAG 项目做出来容易做好很难。如果你的 RAG 问答效果差按这个顺序排查召回不准看检索返回的 top-k 文档里到底有没有正确答案。没有问题出在切分策略或 Embedding 模型。切分不合理检查 chunk 是否截断了关键语义尝试调整chunk_size和chunk_overlap。提示词表达不清把资料给模型时要说清楚“以资料为准”而不是让模型自由发挥。Embedding 模型与领域不匹配中文场景建议评估中文 Embedding 模型而不是直接使用默认英文模型。上下文被无关信息污染top-k 不要取太大通常 3-5 即可。6. Agent 与 ReAct 模式让模型学会调用工具LangChain 里 Agent 是另一个高频话题也是最容易让人困惑的部分。6.1 什么是 ReActReAct 是 Reasoning Acting 的缩写核心思想是让模型在“推理”和“行动”之间循环Thought思考模型判断当前需要做什么。Action行动选择一个工具并调用。Observation观察查看工具返回结果。重复以上过程直到得出最终答案。这种方式让大模型不只是在“生成文字”而是变成了一个“能使用工具的决策器”。6.2 定义一个简单工具并创建 Agent下面用一个计算器工具演示 Agent 的完整流程。这里不依赖外部 API你可以直接运行。from langchain_openai import ChatOpenAI from langchain.agents import create_tool_calling_agent, AgentExecutor from langchain_core.tools import tool from langchain_core.prompts import ChatPromptTemplate # 1. 定义一个工具 tool def calculate_expression(expression: str) - str: 计算一个数学表达式的值例如 1 2 * 3。 try: # 注意生产环境不要直接用 eval这里仅用于演示简单工具调用 result eval(expression) return str(result) except Exception as e: return f计算失败: {str(e)} # 2. 创建模型 llm ChatOpenAI(modelgpt-4o-mini, temperature0) # 3. 创建 Agent prompt ChatPromptTemplate.from_messages([ (system, 你是一个智能助手可以调用工具来回答问题。), (human, {input}), (placeholder, {agent_scratchpad}), ]) agent create_tool_calling_agent(llm, [calculate_expression], prompt) agent_executor AgentExecutor(agentagent, tools[calculate_expression], verboseTrue) # 4. 运行 result agent_executor.invoke({input: 计算 (12 34) * 5 的结果}) print(result[output])运行后你会看到 Agent 的思考过程和工具调用记录。这里有个重要提醒eval在真实生产环境会引入任意代码执行风险切勿直接用于线上。真实项目中应当使用ast解析、受限表达式引擎或专用计算库。6.3 Agent 中间件的含义“Agent 中间件”在实际项目中有两层含义第一层是Agent 与工具之间的适配层。Agent 需要理解哪些工具可用、工具参数怎么填、工具返回怎么处理这层适配逻辑就是中间件。第二层是Agent 与大模型之间的调度层。LangChain 里的 AgentExecutor、LangGraph 的状态图都承担了调度职责。你可以在这一层做权限校验、流量控制、日志埋点、工具调用审计。在企业项目里我建议不要把 Agent 逻辑和大模型调用代码混在一起。应该单独封装一层 ToolService让 Agent 只能通过这一层访问内部系统避免模型直接调用任意内部接口。6.4 什么场景适合 AgentAgent 适合这些场景用户指令不固定需要动态决定调哪个工具。需要跨多个系统协作比如查库存、下单、发通知。需要复杂多步推理的任务。不适合的场景高频低延迟的场景。Agent 推理会多次调用模型延迟和成本明显更高。流程固定的场景。如果流程固定直接写代码或用 Chain 更稳定、可维护。对安全要求极高且不允许模型自主决策的工具调用场景。7. MapReduce 在 LangChain 中的用法MapReduce 在 LangChain 里主要用于长文本处理。大模型有上下文窗口限制几万字的文档没办法一次性放进 Prompt这时可以用 MapReduce 思路Map 阶段把文档切成多段对每段分别做摘要或处理。Reduce 阶段把所有段落摘要合并再生成一个总摘要。LangChain 早期版本提供load_summarize_chain和map_reduce_chain。新版本中更灵活的方式是用 LCEL 自己组装一段 MapReduce 逻辑from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain_text_splitters import RecursiveCharacterTextSplitter llm ChatOpenAI(modelgpt-4o-mini, temperature0) # 假设有一篇长文 long_text open(long_article.txt, encodingutf-8).read() # 切分成块 splitter RecursiveCharacterTextSplitter(chunk_size2000, chunk_overlap200) chunks splitter.split_text(long_text) # Map 阶段对每一块生成摘要 map_prompt ChatPromptTemplate.from_messages([ (system, 请用不超过100字概括以下内容), (human, {text}), ]) def map_summarize(text: str) - str: chain map_prompt | llm return chain.invoke({text: text}).content summaries [map_summarize(chunk) for chunk in chunks] # Reduce 阶段合并摘要 reduce_prompt ChatPromptTemplate.from_messages([ (system, 你是一个总结专家请基于以下分块摘要生成一份连贯的总摘要), (human, {summaries}), ]) final_chain reduce_prompt | llm final_summary final_chain.invoke({summaries: \n\n.join(summaries)}).content print(final_summary)MapReduce 的要点是“分而治之”。如果段落之间逻辑依赖很强直接切分可能丢失上下文。解决办法是可以加大chunk_overlap或者在 Reduce 阶段把上一步摘要也补充进 Prompt。8. MCP模型上下文协议MCP 是 2025 年前后 AI 应用领域最热门的关键词之一它的全称是 Model Context Protocol模型上下文协议。这个协议由 Anthropic 提出目标是统一“AI 应用如何接入外部工具和数据源”的接口标准。8.1 为什么需要 MCP没有统一协议时每个 AI 项目接入一个外部工具都要写一套自定义适配代码。比如接数据库要写数据库插件接设计工具要写设计工具插件接代码仓库要写代码仓库插件。这些插件互相不通用每个应用要重复实现一遍。MCP 提供了一套标准客户端Client调用方的 AI 应用。服务端Server暴露工具、数据源能力的独立服务。协议定义了工具发现、调用、资源访问的消息格式。引入 MCP 后工具提供方只需要实现一次 MCP Server所有支持 MCP 的客户端都能直接使用这个工具。8.2 MCP 与 LangChain 的关系MCP 和 LangChain 不是竞争关系。LangChain 是应用编排框架MCP 是工具接入的开放协议。LangChain 可以支持 MCP 客户端把它作为 Tool 的一种来源。在企业项目里更稳妥的做法是用 MCP 标准化工具供给用 LangChain/LangGraph 编排 Agent 逻辑。两者结合可以让“工具复用”和“Agent 调度”各司其职。8.3 MCP 落地时的注意事项如果你所在团队计划落地 MCP有几个建议先从标准化内部工具开始比如数据库查询服务、运维脚本、内部 API而不是一上来就接外部所有服务。对 MCP Server 做权限隔离。Agent 能调用哪些工具必须由中间层控制不能用模型自由调用全部工具。工具描述要写清楚。模型理解工具的主要依据是描述文本描述越清晰调用准确率越高。MCP 的生态还在快速变化建议保持版本关注不要把所有逻辑都绑定在某个偏门实现上。9. 企业项目中的常见问题与排查思路把上面所有知识放到实际项目里你会发现真正的问题往往不在代码语法而在系统设计。下面列举我在 LangChain 工程落地中见过的高频问题做成排查表供你参考。问题现象可能原因排查方式解决方案模型返回格式不稳定解析失败模型 JSON 能力弱或 Prompt 指令不明确打印原始输出检查是否标准 JSON使用with_structured_output或增加格式示例和重试逻辑RAG 检索结果与问题无关chunk 切分不合理、Embedding 模型不匹配、检索 top-k 设置过大单独测试检索器返回的文档相关内容调整 chunk 大小、更换 Embedding 模型、缩小 top-k 范围Agent 陷入多次工具调用循环模型未拿到足够信息、工具返回不明确、Prompt 没有限制调用轮次开启 verbose 日志观察 Thought 和 Observation在提示词中加入最大轮次限制在 AgentExecutor 层设置max_iterations多轮对话丢失上下文没有正确维护历史消息检查传给模型的 messages 是否包含完整历史手动把历史消息加入 prompt或使用合适的 Memory 实现工具调用报错工具输入参数格式不对、工具内部异常未捕获查看工具返回的原始错误在工具函数内捕获异常返回可读错误信息避免 Agent 无法理解流式输出失效回调函数未注册或使用了不支持流式的组件检查是否是 LCEL 链是否注册了streaming回调统一使用 LCEL 链注册on_llm_new_token回调向量库数据过时回答仍是旧内容文档更新后没有重新构建或增量更新向量库检查向量库中是否存在过期 chunk建立文档版本管理每次更新后重新生成对应向量这里的核心思路是任何和模型相关的异常都要先拿到原始输入和原始输出再判断问题出在 Prompt、检索还是工具层。不要一上来就改代码先把链路中的每一步打印出来。10. 企业项目最佳实践与工程建议最后这部分是把 LangChain 从示例项目推到生产环境时必须考虑的内容。很多教程没讲这些恰恰是它们最值钱的部分。10.1 不要把 Prompt 散落在代码中Prompt 应该集中管理按业务模块拆分配置而不是散落在各个 python 文件里。推荐的做法是用 YAML 或 JSON 文件维护 Prompt 模板通过配置中心或版本管理工具管理。这样可以做到 Prompt 修改不重新发版。一个简化的 prompt 配置文件示例# config/prompts/rag.yaml rag_system_prompt: | 你是一个严谨的知识库助手。 只基于【参考资料】回答不要编造内容。 如果资料中没有答案请直接回答“资料中未找到相关信息”。 rag_human_prompt: | 用户问题{question} 参考资料 {context}代码里通过yaml.safe_load读取即可。注意配置文件的读取要放在启动阶段并做好异常处理。10.2 给 Agent 工具调用设置边界企业项目的 Agent 工具调用必须有边界所有工具调用记录完整日志包括工具名、入参、出参、耗时。高风险操作删除、更新、发送消息必须二次确认不要直接让模型执行。为每个工具设置超时时间避免 Agent 被外部接口拖死。根据用户身份控制工具可见范围不同角色能看到不同工具列表。这些内容看似和 LangChain 无关但实际上决定了 Agent 能不能上线。10.3 做好成本控制与性能优化大模型应用的成本主要在 Token 消耗和调用延迟。以下几个实践经验很值得参考对 RAG 检索到的文档做“相关性过滤”只保留高分文档减少 Token 浪费。对 Agent 设置最大迭代次数防止模型反复调用工具导致成本飙升。对重复性问答场景增加缓存层相同问题直接命中缓存。监控每个链路的 Token 消耗建立基线出现异常时能及时发现。10.4 安全与合规注意不要在 Prompt 中写入系统内部账号密码、密钥、内部 IP。不要让人工智能应用直接访问生产数据库接入时使用只读账号并且限制数据范围。用户上传文档时要校验文件类型、大小、内容防止恶意文件或注入提示词。对模型输出做内容合规检测尤其是面向公众用户的应用。10.5 版本管理与升级策略LangChain 迭代速度很快0.1、0.2、0.3 之间 API 都有变化。建议使用明确的依赖版本锁定不要使用langchain全家桶最新版而不锁定。升级前先看官方迁移文档用测试环境跑通核心用例再升级。核心链路要做好单元测试和集成测试尤其要测试 Prompt 变更对输出的影响。11. 总结与下一步学习路线这篇文章从一个实际开发痛点出发把 LangChain 的核心概念、RAG、Agent、ReAct、MapReduce、MCP 和工程化实践串成了一整条学习线。你可以按照下面这个路线继续深入先把基础调用跑通用本文第 4 节的代码替换成你自己的模型配置理解 Prompt、LLM、OutputParser 三件套。做一个最小 RAG 项目准备一份业务文档按第 5 节的代码实现加载、切分、向量化、检索、问答重点体会切分参数和检索质量的关系。再用 Agent 做工具调用按第 6 节的代码加入一个计算工具或查询工具观察 ReAct 循环中的 Thought、Action、Observation。然后研究 LangGraph当你的流程出现分支、循环、人工确认这些复杂状态时LangGraph 会比传统 AgentExecutor 更合适。最后关注 MCP 生态理解协议本身把工具标准化避免每个项目重复造轮子。关于 LangChain 的学习还有一个很重要的提醒不要被版本更新带乱节奏。框架会变API 会变但 Chain、RAG、Agent 这套应用范式不会轻易过时。你真正要学会的是“把大模型接入业务流程”的工程思维。代码示例可以复制工程经验需要你在自己的项目里一点点踩出来。建议把本文收藏下来做项目时回来对照检查。