先讲一个比较扎心的现实很多同学学 AI Agent 开发学了一堆概念装了 LangChain又装了 LangGraph还听说 MCP 很火最后打开代码编辑器却不知道第一行该写什么。网上资料很多但大多数要么只讲概念要么直接甩一段跑不通的代码很少有人把LangChain、MCP、LangGraph、Agent这条完整链路串起来讲清楚。这篇文章的目标很直接从一个真实可运行的 Agent 项目入手带你走一遍完整流程。你会看到 LangChain 在什么环节发挥作用MCP 如何把外部工具接进来LangGraph 又是怎么让 Agent 流程更可控的。文章会包含完整代码、配置说明、运行演示和常见报错排查你可以边看边敲也可以直接拉到最后看最佳实践。无论你是刚开始接触大模型开发还是已经被各种概念绕晕这篇文章都值得你收藏备用。1. Agent 开发全景LangChain、MCP、LangGraph 到底是什么1.1 先从 Agent 的核心逻辑说起Agent智能体本质上是一个“让大模型自己做决策”的程序。它不再像普通的 ChatBot 那样一问一答而是具备一个循环接收用户任务。大模型判断需要调用什么工具。调用工具获取结果。根据结果继续推理。直到任务完成或达到终止条件。举个例子用户说“帮我查一下杭州明天的天气并提醒我带伞”。一个简单的 Prompt 工程只能让模型“编造”一个答案而 Agent 会主动调用天气查询工具、拿到真实数据、再组织语言回复用户。所以 Agent 开发的关键不是模型本身而是三个方面模型的推理能力、可用工具的数量与质量、流程编排的可靠性。1.2 LangChain 在 Agent 开发中承担什么角色LangChain 是国内开发者最早接触的 LLM 开发框架它的定位非常明确给大模型应用开发提供标准化的组件封装。在实际开发中你需要的很多能力 LangChain 都已经封装好了对 OpenAI、通义千问、文心一言、DeepSeek 等模型的统一调用接口。Prompt 模板管理。文档加载、切分、向量化、检索RAG 链路。工具Tool的定义与调用。Agent 的构建与执行器AgentExecutor。简单来说LangChain 的价值是“省事”。它把繁琐的模型调用和工具调用流程抽象成统一的 API让你更关注业务逻辑本身。但 LangChain 也有一个被很多人诟病的问题它把复杂的流程封装得太深了。尤其是AgentExecutor这一类高阶组件内部执行逻辑像一个黑盒出了问题很难排查。这也是 LangGraph 出现的一个重要原因。1.3 LangGraph 与 LangChain 的区别与联系LangGraph 和 LangChain 经常被放在一起比较但二者不是替代关系。可以这样理解LangChain 提供的是积木——模型封装、工具、Prompt、检索组件。LangGraph 提供的是拼图框架——把积木按照有状态、可循环、可分支的图结构组合起来。LangGraph 由 LangChain 团队推出但它的设计理念更底层把 Agent 的每一次执行过程建模成一张图Graph图上有节点Node和边Edge节点之间通过共享状态State传递数据。它解决的核心问题是LangChain AgentExecutor 难以处理复杂流程的问题支持循环结构Agent 可以在节点之间反复跳转。支持条件分支根据中间结果决定下一步走向。支持人工介入Human-in-the-loop关键节点可以暂停等待人工确认。状态管理更明确每一步执行过程都可观测、可追踪。一句话总结如果你只是想快速 demoLangChain 的 Agent 够用如果要做生产级、流程可控的 Agent 应用LangGraph 是更稳的选择。1.4 MCPAgent 接入工具的标准协议MCP 的全称是 Model Context Protocol模型上下文协议它在 2024 年底发布后迅速成为 AI 应用开发的热门话题。MCP 解决了一个非常现实的问题每接一个新的数据源或工具都要单独开发一套集成代码。比如接数据库写一套 SQL 工具接飞书写一套飞书 API接内部系统又要写一套鉴权逻辑——这些重复工作不仅耗时还难以复用。MCP 的思路是抽象出一套标准协议分为三个角色MCP Host运行 AI 应用的进程比如你的 Agent。MCP ClientHost 内部用于连接 Server 的客户端组件。MCP Server暴露一个或多个工具、资源、提示词的轻量服务通过标准协议提供能力。有了 MCP 之后理论上任何一个兼容 MCP 的 Agent 客户端都能直接连接任意一个 MCP Server不需要写定制的集成代码。这种“即插即用”的思路让 MCP 在开发者社区迅速流行起来。现在无论是设计协作工具、游戏引擎、数学软件还是数据库都开始支持 MCP 接入。另外补充一个常见疑问MCP 和 Computer Use 有什么区别简单说Computer Use 让模型直接操作图形界面走的是“视觉 鼠标键盘”的路径MCP 是让模型通过统一协议调用工具接口走的是“结构化调用”的路径。两者可以互补但适用场景不同不要混淆。2. 环境准备与版本说明在开始写代码之前先确认环境。本文的示例以 Python 3.10 及以上版本为例操作系统可以是 Windows、macOS 或 Linux代码本身是跨平台的。2.1 创建项目目录mkdir langchain-mcp-agent-demo cd langchain-mcp-agent-demo建议使用虚拟环境来隔离项目依赖避免不同项目之间包版本冲突python -m venv .venr source .venv/bin/activate # Windows 下执行 .venv\Scripts\activate2.2 安装核心依赖pip install langchain langchain-openai langgraph langchain-mcp-adapters mcp这里需要特别说明版本问题。LangChain、LangGraph、MCP 都处于快速迭代期API 变动比较频繁。在 2026 年初这个时间点LangChain 已经进入 1.x 时代LangGraph 的稳定版本也持续更新中。本文的代码以常用版本为参考你安装时大概率会拿到较新的版本如果遇到调用方式变化请以官方文档为准。为了减少不确定性可以在安装后查看版本pip show langchain langgraph mcp langchain-mcp-adapters2.3 模型 API Key 准备Agent 的核心是调用大模型你需要准备一个可用的模型 API Key。不同模型厂商 API 格式不同但 LangChain 提供了统一的封装。示例中会使用 OpenAI 兼容接口的模型比如 OpenAI、DeepSeek、通义千问的兼容模式都可以。如果没有 API Key也可以使用本地部署的开源模型只需要把ChatOpenAI换成ChatOllama等本地模型封装。为了简化示例下文统一以ChatOpenAI作为示例实际使用时替换为自己的模型即可。2.4 最终项目结构langchain-mcp-agent-demo/ ├── .env ├── basic_agent.py ├── mcp_server_weather.py ├── mcp_agent_client.py └── langgraph_agent.py3. 基础实战从零构建一个能调工具的 Agent先不看 MCP 和 LangGraph我们用一个最简单的 ReAct 模式 Agent 来理解整个工作流程。3.1 定义工具函数在 LangChain 中工具函数可以通过tool装饰器快速定义。每个工具必须有清晰的名称和描述因为大模型是靠描述来决定何时调用工具的。# 文件路径basic_agent.py from langchain_core.tools import tool tool def get_weather(city: str) - str: 查询指定城市的实时天气信息输入参数为城市名例如杭州 # 这里使用模拟数据实际项目中可以替换为真实天气 API weather_data { 杭州: 多云25℃东南风3级, 北京: 晴22℃微风, 上海: 小雨23℃东北风2级, } return weather_data.get(city, f暂未收录{city}的天气数据)注意工具函数的名称和 docstring 就是模型理解工具的入口一定要写清楚参数含义和返回格式。如果你写的描述含糊模型很容易在需要调用时犹豫或者在不需要调用时误调用。3.2 创建模型实例并构建 Agent# 文件路径basic_agent.py续 import os from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain_core.prompts import PromptTemplate api_key os.getenv(OPENAI_API_KEY, your-api-key-here) base_url os.getenv(OPENAI_BASE_URL, https://api.openai.com/v1) llm ChatOpenAI( modelgpt-4o-mini, api_keyapi_key, base_urlbase_url, temperature0, ) prompt PromptTemplate.from_template( 你是一个智能助手请尽可能使用工具来帮助用户解决问题。\n 工具如下\n {tools}\n 工具名称{tool_names}\n 用户问题{input}\n 请按 ReAct 模式逐步思考输出最终答案。 ) agent create_react_agent(llmllm, tools[get_weather], promptprompt) agent_executor AgentExecutor(agentagent, tools[get_weather], verboseTrue, handle_parsing_errorsTrue) result agent_executor.invoke({input: 杭州天气怎么样我需要带伞吗}) print(result[output])3.3 运行与结果分析export OPENAI_API_KEY你的Key python basic_agent.py如果一切正常你会看到类似下面的输出 Entering new AgentExecutor chain... 我需要先查询杭州的天气情况 调用工具 get_weather参数杭州 观察结果多云25℃东南风3级 根据查询结果杭州今天多云没有降雨不需要带伞。这个示例虽然简单但它完美展示了 Agent 的整个工作循环模型自己决定调用工具 - 工具执行并返回结果 - 模型综合结果生成回答。这里的verboseTrue会打印详细过程建议学习阶段开启。4. MCP 实战写一个标准的 MCP Server 并接入 Agent第 3 节使用的是 LangChain 内部定义的函数工具代码和业务强耦合。现在我们把工具改造成一个符合 MCP 标准的服务让它可以被任何兼容 MCP 的客户端复用。4.1 MCP Server 最小实现使用 MCP 官方 Python SDK 的 FastMCP 封装可以快速定义工具。下面实现一个天气查询服务# 文件路径mcp_server_weather.py from mcp.server.fastmcp import FastMCP mcp FastMCP(weather-server, host127.0.0.1, port8000) mcp.tool() def get_weather(city: str) - str: 查询指定城市的实时天气信息输入参数为城市名例如杭州 weather_data { 杭州: 多云25℃东南风3级, 北京: 晴22℃微风, 上海: 小雨23℃东北风2级, } return weather_data.get(city, f暂未收录{city}的天气数据) if __name__ __main__: mcp.run(transportstreamable_http)运行这个服务python mcp_server_weather.py启动后服务会在127.0.0.1:8000/mcp路径提供 MCP 协议接口。这里的核心概念是工具不再直接定义在 Agent 进程里而是独立成服务。以后不管谁想用天气查询能力只需要连接这个 Server 即可。关于传输方式常见的有stdio和streamable_http两种。如果 MCP Server 和 Agent 部署在同一台机器stdio更简单高效如果跨机器调用推荐http方式。具体以你安装的 mcp 库版本文档为准。4.2 在 Agent 中连接 MCP Server下面用langchain-mcp-adapters包中的客户端把 MCP Server 拉取为 LangChain 工具列表# 文件路径mcp_agent_client.py import asyncio from langchain_mcp_adapters.client import MultiServerMCPClient from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain_core.prompts import PromptTemplate async def main(): async with MultiServerMCPClient( { weather: { url: http://127.0.0.1:8000/mcp, transport: streamable_http, } } ) as client: tools await client.get_tools() print(从 MCP Server 获取到工具列表) for t in tools: print(f- {t.name}: {t.description}) llm ChatOpenAI( modelgpt-4o-mini, api_keyyour-api-key, base_urlhttps://api.openai.com/v1, temperature0, ) prompt PromptTemplate.from_template( 你是一个智能助手请尽可能使用工具来帮助用户解决问题。\n 工具如下\n {tools}\n 工具名称{tool_names}\n 用户问题{input}\n 请按 ReAct 模式逐步思考输出最终答案。 ) agent create_react_agent(llmllm, toolstools, promptprompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) result agent_executor.invoke({input: 上海天气怎么样}) print(result[output]) if __name__ __main__: asyncio.run(main())这段代码的关键点在于await client.get_tools()会从远程 MCP Server 拉取工具定义并转换成 LangChain 能直接使用的工具对象。对 Agent 来说这些工具和本地定义的工具没有区别但对工程架构来说工具的维护和发布方式已经完全解耦了。4.3 运行演示先启动 MCP Server再运行客户端python mcp_server_weather.py # 另开一个终端 python mcp_agent_client.py预期输出中客户端会打印类似以下内容从 MCP Server 获取到工具列表 - get_weather: 查询指定城市的实时天气信息输入参数为城市名例如杭州然后 Agent 完成一次完整的“查询上海天气”任务。到这里你已经理解了 MCP 的全链路MCP Server 暴露能力 - MCP Client 拉取能力 - Agent 编排使用能力。这套模式在真实项目中非常实用尤其是多团队协作开发时工具团队只需要维护 MCP ServerAgent 团队不需要关注工具内部实现。5. LangGraph 实战让 Agent 流程可控可观测前面的示例虽然能跑但流程还是太“黑盒”了。如果你希望精确控制 Agent 每一步做什么、什么时候结束、遇到什么情况走分支就需要 LangGraph 出场了。5.1 LangGraph 核心概念LangGraph 把 Agent 流程抽象成一张图。四个核心概念必须理解State状态在整个图执行过程中共享的数据结构所有节点都能读取和修改。Node节点图中的执行单元通常是一个函数。节点接收当前状态返回更新后的状态片段。Edge边节点之间的连接线决定图下一步走到哪个节点。Conditional Edge条件边根据当前状态动态决定下一步走向的边。5.2 用 LangGraph 构建一个 Agent 图下面示例构建一个简单的 Agent 工作流# 文件路径langgraph_agent.py from typing import TypedDict, Annotated from langgraph.graph import StateGraph, START, END from langgraph.graph.state import CompiledStateGraph class AgentState(TypedDict): user_input: str tool_result: str final_answer: str节点函数负责具体的逻辑处理。第一个节点负责调用 LLM 生成回复第二个节点负责调用工具。为了保持示例可运行节点内部使用模拟逻辑实际项目中可以替换为真实 LLM 调用和工具函数。def call_model(state: AgentState) - dict: # 模拟 LLM 调用实际代码中替换为 ChatOpenAI 等模型调用 original state[user_input] if 天气 in original: return {final_answer: f我已查询到相关天气信息请继续等待工具调用结果。} return {final_answer: f这个问题不需要工具我直接回答{original}} def call_tool(state: AgentState) - dict: # 模拟工具调用实际代码中可以调用 get_weather 或 MCP 工具 return {tool_result: f工具执行完成输入为{state[user_input]}模拟结果为晴26℃} # 条件路由函数根据用户输入决定走工具节点还是直接结束 def route_after_model(state: AgentState): if 天气 in state[user_input]: return tool return end接着是构图和编译。需要说明的是状态中通过Annotated和operator.add设置接收器reducers可以控制节点返回值如何合并到全局状态中。如果不想合并叠加直接返回整个字段覆盖即可下面的示例采用默认覆盖方式更方便理解。graph StateGraph(AgentState) graph.add_node(model, call_model) graph.add_node(tool, call_tool) graph.add_edge(START, model) # model 节点之后根据路由函数决定走向 graph.add_conditional_edges( model, route_after_model, {tool: tool, end: END} ) # 工具节点执行完后回到 model让模型基于工具结果生成最终回复 graph.add_edge(tool, model) app graph.compile() # 执行测试 result app.invoke({user_input: 杭州的天气怎么样, tool_result: , final_answer: }) print(最终回答, result[final_answer]) print(工具结果, result[tool_result])运行效果python langgraph_agent.py输出示例工具结果 工具执行完成输入为杭州的天气怎么样模拟结果为晴26℃ 最终回答 我已查询到相关天气信息请继续等待工具调用结果。虽然示例逻辑简单但你已经拥有了一个具备状态流转、条件分支、循环机制的 Agent 骨架。把第 5.2 的模拟逻辑换成真实代码核心区别就在call_model节点中调用大模型并在决定调用工具时通过state把问题传给call_tool工具的结果再传回模型节点进行第二次推理。这种图结构带来最直接的好处是每个节点的输入输出都可观测、可干预。你可以在任意节点之间插入日志、断言、人工确认这是传统 AgentExecutor 很难做到的。5.3 人工确认与中断生产环境的关键能力生产环境的 Agent 不能完全无人值守尤其是涉及删除、下单、发消息这类高风险操作时需要人来确认。LangGraph 支持在节点之间设置中断点并在恢复时注入人工审核结果。核心思路是编译图时设置interrupt_before或interrupt_after然后借助 LangGraph 的持久化检查点机制恢复执行。由于 API 版本差异较大这里不贴具体代码只强调实现思路你可以在工具节点执行前挂一个中断待人工审核通过后再恢复执行。这个能力对 Agent 落地到真实业务至关重要。5.4 关于“LangGraph 增加 Skill”的常见误解不少同学会问“LangGraph 怎么增加 Skill”。这里需要澄清一下LangGraph 本身没有名为 “Skill” 的内建概念。你的 Agent 要获得新能力通常通过三种途径在节点中调用一个已封装好的工具函数。接入一个 MCP Server把它提供的工具拉入当前流程。增加一个新的子图节点让整个工作流多一个处理阶段。也就是说“增加 Skill”的本质是扩充工具集或节点集。理解了这个底层逻辑就不会被不同框架的词汇差异搞晕。6. 常见问题与排查思路下面整理 Agent 开发中最高频的几类报错和现象按“问题 - 原因 - 解决”的思路展开问题现象常见原因解决思路agent execution terminated due to errorAgent 执行循环中断原因是模型输出格式错误或工具调用异常开启handle_parsing_errorsTrue检查工具参数与描述匹配加入重试节点Agent 不调用工具直接编造答案模型对工具描述理解不足或 Prompt 中未强调必须用工具优化工具名称和 docstring在 Prompt 中添加“请先确认是否需要调用工具再回答”MCP Server 启动后无法连接传输方式不匹配或端口地址配置错误检查 Server 端 transport 与客户端配置是否一致先用 curl 测试端点连通性LangGraph 节点状态为空State 的字段名与节点函数返回值不一致核查 TypedDict 字段命名节点函数返回 dict 中的 key 必须能对上 State 中的字段新增依赖后版本冲突LangChain 与 LangGraph 或 MCP 适配器版本跨度太大在虚拟环境中统一安装锁定主要依赖版本号遇到报错优先查看官方 changelog模型回答被截断设置了过低 max_tokens适当增大 max_tokens对长工具结果做摘要工具执行时间过长导致超时外部 API 响应慢设置超时参数将长耗时任务改造成异步任务或消息队列7. 最佳实践与工程建议代码能跑只是第一步下面这些经验是从真实项目中沉淀下来的建议直接收藏。7.1 用 MCP 管理工具不要把工具写死不管项目多小只要工具数量可能增加就建议用 MCP 来组织工具。约定好 MCP Server 的接口规范后工具的增删改都可以独立发布不需要频繁改动 Agent 主流程。你可以把工具按领域拆分例如user-mcp-server、order-mcp-server、inventory-mcp-serverAgent 按任务动态拉取所需工具。这样既减少了单次请求的上下文体积也降低了模型误选工具的概率。7.2 工具命名和描述要反复打磨工具描述的质量直接决定 Agent 准确率。一个常见误区是描述写得太抽象比如“处理用户输入”。更合理的写法是具体说明函数用途、参数格式、返回内容示例。此外工具数量要克制。一次性挂载几十个工具模型在长上下文中的选择准确率会明显下降。推荐策略是先按场景分组再按需加载。这与 MCP 多 Server 架构天然契合。7.3 在 LangGraph 中做好状态观测生产环境调试 Agent第一需求是“知道它每一步做了什么”。建议在每个节点开始和结束时输出结构化日志至少包含节点名称、输入摘要、输出摘要、耗时。如果你使用 LangGraph 的持久化检查点功能每次执行都会留下完整记录后续可以回放和重跑定位问题会高效很多。7.4 安全边界让 Agent 只掌握最小权限Agent 能调用工具意味着它拥有了一部分操作系统或业务系统的权限。务必遵守最小权限原则数据库账号只授权只读或指定库表。涉及删除、更新、转账、发消息等高风险操作必须有人工确认环节。所有工具调用都记录审计日志。对工具入参做严格校验防止通过 Agent 间接发起恶意请求。内部接口不要直接暴露给公网必要时加鉴权和限流。7.5 动态添加能力的方式有些开发者会问Agent 如何灵活地获得新技能常规做法是在 MCP Server 中新增一个工具函数然后客户端重新拉取工具列表。你的 Agent 启动时可以从配置中心读取已注册的 MCP Server 列表动态构建工具集。这样新增一个“查快递”的能力只需要发布一个新的 MCP Server然后更新配置即可不需要重新发布 Agent 主程序。8. 总结与下一步学习路线到这一步你已经掌握了一套完整的 Agent 开发链路用 LangChain 完成模型封装、工具定义、基础 Agent 构建。用 MCP 统一工具接入标准实现能力解耦和复用。用 LangGraph 对 Agent 流程做精细编排让状态、分支、循环、人工确认全部可控。接下来你可以从三个方向继续深入第一把基础 Agent 示例中的模拟逻辑替换成真实的 LLM 调用和真实业务工具亲手跑通一个端到端项目。第二研究 LangGraph 的持久化、流式输出、多 Agent 协作等进阶特性。第三拆解几个成熟的开源 MCP Server 实现理解复杂工具是如何设计成标准化服务的。如果文章对你有帮助可以收藏备用。你踩过哪些 Agent 开发的坑欢迎在评论区一起讨论。