理清LangChain、LangGraph、MCP层级,Agent开发不再失控

📅 发布时间:2026/9/7 6:58:06
理清LangChain、LangGraph、MCP层级,Agent开发不再失控
LangChain、MCP、LangGraph、Agent 这四个词放在一起时很容易让人误以为它们是一条流水线上的四个零件。很多第一次接触 AI 大模型应用开发的人会花一整周去装环境、拉代码、跑 demo最后发现 demo 很流畅一旦换成真实任务就开始失控。我在很长时间里也有同样的困惑。LangChain 说要编排LangGraph 说要管理状态MCP 说要统一工具接入Agent 说要让模型自己决策。每一个概念听起来都对但放到同一个项目里就不知道该谁指挥谁。后来我换了一个角度来看问题它们根本不是同一个维度的竞争关系而是 Agent 应用里的三个不同层级。LangChain 负责编排MCP 负责工具接入的协议标准LangGraph 负责流程的状态管理。只有把这三层边界理清楚Agent 才不会只是一个看起来能跑、实际上碰运气的东西。这篇文章不打算做一次百科全书式的工具介绍而是想把我从 demo 走向真实项目时最关键的几个判断讲清楚。包括为什么单次跑通不等于能用LangGraph 和 LangChain 到底怎么分工MCP 解决的是哪一层问题以及从单一任务到生产环境还差哪些工程能力。1. 为什么你已经能跑通 Agent却总在真实任务里失控1.1 表面是模型不够强实际是三层职责混在一起我之前见过一个典型的项目。代码里写了一个 ReAct 风格的 Agent让它去调用搜索工具、数据库工具和文档工具。单条测试的时候效果很好模型能自己选工具、组织回答。但一旦放进真实业务流程连续处理几十个任务后开始出现几个很典型的问题工具调用顺序不稳定上一次是先查库再搜索这一次就变成了先搜索再查库。模型在某个工具返回空结果后没有走备用分支而是卡在同一个工具循环重试。一个任务需要多轮工具调用中间的中间状态没有保存一旦某一步失败整个链路就断了。这些问题表面看是模型决策能力不够但真正的原因往往是三层职责混在一起。LangChain 帮你把模型、工具、记忆接在一起但没有约束流程顺序你在写工具调用时也没有把“什么是步骤”“什么是状态”分开工具接入方式各自为政有的工具返回 JSON有的返回 Markdown模型还要额外花精力去理解格式差异。所以我说Agent 失控往往不是从模型开始的而是从编排层和状态层没有设计清楚开始的。1.2 LangChain、LangGraph、MCP 不是竞品是三个层级要理解这三个项目不能把它们摆在同一排对比而要先回答一个更基础的问题一个完整的 Agent 应用到底由几部分组成。我的理解是三部分。第一部分是流程编排。你要定义大模型先做什么、后做什么要不要调用工具调用完工具之后要不要再让大模型总结。这是 LangChain 的主场。它的价值在于把“模型调用 提示词 工具调用 输出解析”这种常见模式封装成可组合的链路。第二部分是状态管理。如果流程只有一个步骤不需要状态。但真实 Agent 往往有多个步骤比如先分析用户需求再决定查询哪些数据源然后执行查询最后汇总答案。每一步之间可能有分支、有循环、有条件回退。这时候你需要一个能描述图结构的东西让每个节点明确知道自己什么时候执行、执行完往哪里走。这是 LangGraph 的定位。第三部分是工具接入。Agent 要真正做事不只是聊天还得调用搜索、查数据库、操作 Excel、发消息、读文件。问题在于每个工具都有自己的接口格式、鉴权方式和数据返回格式如果每接一个工具就写一套定制代码Agent 会变得不可维护。MCPModel Context Protocol的作用是定义一套通用的工具接入协议让模型客户端、工具服务器、工具三方能按统一标准对话。把这三层分开之后你再看 LangChain、LangGraph、MCP就会清楚很多LangChain 是编排框架LangGraph 是流程状态引擎MCP 是工具接入协议。1.3 一套我常用的认知框架编排层、状态层、工具层如果你刚开始学习 AI 大模型应用开发我建议先不要只盯着某一个框架的 API而是先用下面这个框架给项目分层层级解决的核心问题主要角色常见误区编排层模型调用、工具调用、输出解析怎么组合LangChain什么都往 Chain 里塞状态层多步骤流程怎么避免失控LangGraph简单任务也用状态图工具层外部工具怎么统一接入、统一调用MCP Server / MCP Client工具越多越好在这个框架里Agent 只是最终呈现出来的效果不是某一个具体框架的名称。Agent 的底层必须有清晰的编排逻辑、可控的状态转换和稳定的工具接入协议。三者各归其位Agent 才可能从 demo 走向真实业务。这也是这篇文章后续所有内容的基础。后面讲到的安装、实操、参数、排查链路都会回到这个分层框架里。2. 最小可用的 Agent 到底怎么搭起来2.1 环境准备和依赖检查顺序无论你最终决定使用 LangChain、LangGraph 还是 MCP第一步都不是写业务代码而是确认运行环境。很多新手把时间浪费在模型报错上最后发现是 Python 版本不兼容或者依赖版本冲突。我一般会按下面这个顺序检查运行环境确认 Python 版本。LangChain 和 LangGraph 对 Python 3.9 到 3.12 的支持比较稳定但版本变化很快落地前要看你准备使用的版本对应的官方要求。依赖安装核心安装 LangChain、LangGraph以及模型接口对应的 SDK。不要一次性把几十个依赖都装进去先用最小依赖跑通再逐步添加。环境变量与密钥确认大模型 API 的 Key、域名、模型名称是否正确。这一步最容易出问题很多人明明代码没问题结果是因为环境变量没加载。模型连通性先单独调一次大模型接口确认基础对话能通。不要直接跳过这一步就冲到 Agent 链路里去。在这个阶段我更建议用最简单的示例代码去验证链路先不引入复杂的 Agent 逻辑。2.2 先跑通一条单次任务而不是一上来就编排复杂流程很多教程会直接给你展示一个复杂的 Agent 示例里面既有 ReAct 循环又有自定义工具还有多轮对话记忆。看起来很酷但对新手很不友好。我的建议是先做最小可用闭环模型接收一个问题 → 模型判断需要调用工具 → 调用工具 → 拿到结果 → 模型生成最终回答。这个闭环里最关键的不是模型本身而是工具的定义方式。模型并不知道你的工具是用 Python 写的、Java 写的还是 Node.js 写的它只能通过工具的名称、描述、输入参数来决定要不要调用。因此你的工具描述写得清不清楚直接决定模型会不会正确使用工具。如果你发现模型频繁调用错误工具先别怀疑模型能力回去检查工具描述。一个有效的工具描述应该包含工具能做什么。在什么情况下使用。输入参数的含义和格式。返回值是什么。这段描述本质上是写给模型看的“使用说明书”。说明书越清晰模型就越不容易选错。2.3 从“能回答”到“能用工具”的分界线工具描述与输入输出很多人在实际开发中会遇到这种场景模型已经接入了工具但回答还是和没接工具之前一模一样。原因通常不是模型没看到工具而是模型认为不需要调用工具或者工具返回的内容没有被正确传入模型上下文。这里需要区分两个概念一个是“模型知道有工具”另一个是“模型能把工具结果纳入回答”。两者中间还隔着一次工具调用和结果回填。我一般会用一个简单的方式做验证构造一个必须调用工具才能回答的问题比如“查询一下订单表的条数”。如果模型回答了某个数字说明工具调用链路通了如果模型说“我无法访问数据库”说明工具没有生效或者工具描述里没有说清楚“你可以通过 order_count 工具查询订单数”。这里的核心是工具调用成功后必须在返回给模型的内容里带上实际结果。如果链路断了模型等于什么工具信息都没拿到。3. LangGraph 和 LangChain 的分工什么时候需要状态机3.1 LangChain 的 Agent 在什么场景会失控LangChain 提供了非常方便的 Agent 封装你可以在几行代码内让模型自己决定调用哪些工具。这种方式的优点是灵活缺点是“过于灵活”。当一个任务只需要调一次工具时LangChain 的 Agent 封装通常够用。但当一个任务需要多次工具调用、并且后续决策依赖于前面调用结果时问题就会出现。举个例子。你想要让 Agent 完成一个调研流程先搜索某个行业的最新动态再根据搜索到的内容去数据库查询相关企业最后把这些内容整理成报告。这个流程看起来不复杂但如果用自由式的 LangChain Agent 去实现模型可能在第一步就跑了很远先查企业再搜行业然后突然去总结完全不符合你预设的流程顺序。更麻烦的是中间状态。如果搜索步骤成功、数据库查询失败Agent 应该重试数据库查询还是重新搜索如果缺少明确的流程控制模型可能会陷入一个无法收敛的循环。3.2 LangGraph 解决的是流程确定性不是让你多写代码LangGraph 的解决办法是把流程看成一张图。这张图有明确的节点Node和边Edge。每个节点做一件确定的事情比如“搜索”“查询数据库”“生成报告”。每条边定义节点之间的转换条件比如“如果搜索成功进入查询数据库节点如果搜索失败进入重试节点”。这样做带来的最大变化是流程从“模型自由发挥”变成“模型在预定义轨道里决策”。模型仍然可以决定具体怎么调用工具、怎么解读结果但它不能随意跳步骤、不能无限循环、不能漏掉关键节点。所以 LangGraph 不是让你多写代码而是让你的流程有确定性。对于需要稳定复现、必须按固定顺序执行的任务这种确定性非常重要。有人会问那为什么不直接用 Python 写 if else 流程控制呢我理解这个疑问。如果任务非常简单你当然可以用普通代码串起来。但 Agent 任务的特殊性在于很多分支不是预先能穷举的你需要让模型在关键节点做决策同时又要保证决策不会跳出流程边界。LangGraph 的价值正在于此它把“模型可以决策什么”和“流程必须怎么走”这两件事分开了。3.3 判断要不要上 LangGraph 的四个问题并不是所有场景都需要 LangGraph。我通常会问自己四个问题这个 Agent 是否需要多步骤协作如果只需要一次工具调用LangChain 就够。后续步骤是否依赖前面步骤的输出如果完全独立不需要严格顺序。是否需要人工审批、重试或回退如果希望遇到失败能回退到某个指定节点LangGraph 很有帮助。是否希望这个流程能被别人稳定复用如果代码要交付或者要给别人维护状态图比自由 Agent 清晰得多。如果四个问题里有三个以上答案是“是”那上 LangGraph 是值得的。如果大部分答案是“否”建议先保持简单不要为了架构而架构。4. MCP 真正改变的是工具接入方式不是模型能力4.1 以前怎么接工具MCP 之后怎么接在没有 MCP 的时候接一个工具通常是这样你把工具的调用函数直接写进 Agent 代码里声明一个 function schema然后让模型在需要时调用。每个工具都要单独写接入代码、单独处理认证、单独处理返回格式。这种方式在工具数量少的时候问题不大。当工具数量变多比如十个、二十个或者工具不在同一个服务里而是由不同团队维护就会变成一团乱麻。MCP 做的事是定义了一套标准协议。客户端通过 MCP 协议连接工具服务器工具服务器把工具的能力以标准格式暴露给客户端。模型不需要直接知道工具是什么语言写的、部署在哪里只需要知道协议提供的工具列表和调用方式。用生活中的例子来类比以前的工具接入方式有点像每个电器都要自带不同形状的插头电视是两脚的冰箱是三脚的充电器是 Type-C 的家里必须准备一堆转换头。MCP 相当于统一了插座规格设备之间通过标准协议连接接入成本大幅下降。4.2 一个最小 MCP 接入流程MCP 的完整实现细节会随版本变化我这里只提供一个最通用的流程框架你在实际落地前要结合自己的环境确认版本和接口变化。从开发者视角看MCP 涉及两个角色MCP Server把工具暴露出去的服务。比如你把一个查询数据库的能力封装成 MCP Server那么其他支持 MCP 的客户端就能直接通过标准协议调用这个能力。MCP Client连接 MCP Server 的客户端。LangChain、LangGraph 等框架通常会提供 MCP Client 相关的适配能力让上层 Agent 能调用下游 Server 暴露的工具。最小接入流程一般是三步启动一个 MCP Server把它想要暴露的工具注册到协议里。在 Agent 应用里配置 MCP Client通过协议获取工具列表。将工具列表绑定给大模型让模型在决策时可以调用这些工具。这里有一个需要留意的点MCP 解决的是“工具接入标准”的问题并不解决“模型知道何时调用工具”的问题。就算工具接入得再标准模型的工具描述不清晰或者提示词里没有给出使用场景Agent 依然可能选错工具。4.3 外部工具不代表越多越好要控制工具边界很多人接触 MCP 后会立刻陷入“接各种工具”的兴奋期。就在最近我也看到不少团队尝试把设计稿、开发、办公软件等工具都通过 MCP Server 接进来让大模型能直接操作各类桌面软件和业务系统。这种想象力是好的但在真实项目里我并不建议一次性接入太多工具。原因很简单工具列表越长模型在每一步决策时要理解的信息越多。工具之间功能重叠时模型容易混淆该用哪一个。每个工具都有返回数据格式和异常情况维护成本会成倍增加。我更建议的做法是每个业务场景只暴露当前需要的工具子集。比如做数据分析时只暴露数据库查询、表格处理、图表生成这三类工具而不是把几十个无关工具全塞进去。记住MCP 的价值在于简化接入而不是让你变成“工具收藏家”。5. 把 LangChain、MCP、LangGraph 串成一个完整 Agent5.1 串联后的调用链路应该是怎样现在把前面的分层框架落实到具体代码逻辑里一条完整的 Agent 调用链路通常是这样用户输入进入应用先做输入解析和意图判断。编排层把任务交给 LangGraph 定义的流程。流程里每个节点可能用到 LangChain 的组件比如提示词模板、模型调用、输出解析器。某个节点需要外部工具能力时通过 MCP Client 调用标准协议从 MCP Server 获取工具列表和调用结果。工具结果返回后LangGraph 的节点根据结果决定下一跳是继续调用工具、退出到人工审批还是直接生成最终回答。所有步骤的状态都保存在图的状态对象里后续节点可以直接读取。这条链路最好的地方在于每一层都能独立演化和单独测试。工具变了不影响流程逻辑流程调整了不需要大改工具接入模型换了只要保持工具描述兼容Agent 主体结构依然稳定。5.2 最容易出问题的六个环节在实际运行中我见过比较多的问题集中在以下六个环节每个环节都要单独加日志和检查点输入格式不统一用户输入有的是自然语言有的是 JSON有的带附件如果一开始没有标准化后面工具调用会很难处理。工具描述与真实行为不一致描述里说“查询用户信息”实际返回的字段却不是模型预期的结构模型会生成错误回答。状态被覆盖LangGraph 的状态如果设计得不清晰前面的步骤结果可能被后面的节点覆盖导致信息丢失。超时和限流模型接口、工具接口都有响应时间限制批量任务里很容易触发超时。要设置合理的超时重试策略。异常中断没有恢复点任务跑了一半进程重启前面的中间状态全丢了。如果任务重要必须考虑持久化状态。日志不够精细出问题的时候只知道“工具调用失败”但不知道是协议层失败、服务端失败还是模型解析失败。5.3 一个可复用的排查顺序输入、工具、状态、输出如果你发现 Agent 表现异常不要急着重新生成提示词先按顺序排查先看输入这条任务本身是否正常有没有超出预期格式。再看工具调用记录模型选了哪个工具传入参数是否正确工具返回了什么。再看状态流转在 LangGraph 的流程里节点是否按要求跳转状态有没有被正确更新。最后看输出解析最终回答是否完整回填了工具结果还是模型只凭记忆回答。我之所以总是强调这个顺序是因为大多数问题都出在“模型没拿到正确输入”或“工具结果没进入模型上下文”这两处而不是模型本身不够聪明。用这个排查链路基本能覆盖 80% 以上的实战问题。6. 从 Demo 到生产的距离比你想象的大6.1 单次跑通只说明流程没断不代表稳定可复用很多团队在 Agent 项目上都会经历一个阶段demo 很惊艳内部演示很顺利一旦进入生产环境就开始被各种异常打脸。单次跑通和稳定可复用完全是两回事。单次跑通只能证明流程主干没有断但它没有验证这样几件事批量任务下的并发稳定性和响应时间。工具接口异常时Agent 能否优雅降级。长时间运行时依赖版本、缓存、内存是否正常。不同用户输入类型下模型是否都能正确选择工具。权限边界是否清晰模型有没有可能通过工具调用做超出预期范围的操作。如果你准备把一个 Agent 从 demo 推向生产我建议先用一条真实业务数据做穿行测试然后扩大到十条如果连续通过再逐步增加并发。不要第一天就把所有任务都交给它去跑。6.2 还需要的工程化能力日志、重试、权限、缓存、可观测性从一个可以跑的 Agent变成一个可以长期用的 Agent至少要补齐下面这些能力日志每轮用户输入、工具调用、状态变更、模型输出都要记录。特别是工具调用的入参和出参是后续排查问题最重要的线索。重试与降级模型接口超时、工具服务异常时要有明确的失败重试策略不能无限重试也不能直接放弃。权限控制模型调用工具并非永远可靠。对于删除、修改、发送这类高影响操作建议加入人工审批节点。缓存高频查询和重复工具调用可以加缓存降低模型接口和工具服务的压力。可观测性把调用链路的关键节点串联起来可以通过追踪系统看到每一步耗时和状态。否则出问题的时候你不知道是哪一层拖慢了整体任务。对于一个普通的学习项目这些能力可能听起来有些重但一旦涉及真实业务每一项都会变成硬性要求。6.3 适合谁用不适合谁用最后说边界。LangChain、MCP、LangGraph 组成的这套 Agent 技术栈并不适合所有人和所有场景。适合使用的人已经掌握基础的大模型 API 调用想构建多步骤、多工具协作的 Agent。业务场景需要把外部工具和系统稳定接入到模型决策流程中。团队准备把 Agent 做成一个可复用、可维护的技术产品而不是一次性脚本。对流程确定性有要求比如任务编排、自动生成报告、数据处理流水线。不适合的场景只需要一个简单的问答机器人没有复杂工具调用直接用大模型 API 加提示词就够不需要引入这么多依赖。任务步骤非常固定且没有模型决策的需求用普通代码流程控制更简单。团队里没有人熟悉状态图设计和工具协议直接上这套技术栈容易变成维护负担。工具本身不稳定、接口文档缺失、没有基本日志和监控能力此时更应该先解决基础设施问题而不是急着上 Agent。Agent 开发真正的门槛不在于你学会了几个框架也不在于你能不能跑通一个 demo而在于你能不能把编排、状态、工具、模型这四个维度放到同一个项目里去平衡。LangChain、MCP、LangGraph 只是一套趁手的工具组合真正决定项目上限的还是你对流程边界、工具边界和状态设计的理解。如果你现在正在准备开始一个 Agent 项目我的建议很简单先用最小的链路跑通一次真实任务把每一步的输入输出都打上日志然后再决定要不要引入更复杂的编排和状态管理。先跑通再优化最后再谈工程化。这条路走通之后你会发现之前那些“为什么 Agent 总失控”的问题大多数都不是模型的问题而是结构的问题。