尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

LangChain+MCP+LangGraph实战:构建工具调用型AI Agent

LangChain+MCP+LangGraph实战:构建工具调用型AI Agent 2026年的AI应用开发已经不再是“调一个模型接口”那么简单。你翻开源项目社区或者打开AI大模型相关岗位的要求几乎都会遇到几个固定关键词LangChain、MCP、LangGraph、Agent。问题在于这四个词经常被割裂地讲。有人只讲LangChain基础用法有人只介绍MCP协议概念有人直接扔一段LangGraph代码。真正把它们串成一条能跑通的应用链路并且讲清楚每一步为什么这么做的资料其实并不多。这篇文章打算做一件事从一个最小可运行的Agent项目出发把LangChain、MCP、LangGraph各自承担的角色拆清楚再手把手带你把它们组合成一个具备“工具调用能力”的AI助手。适合读者包括刚接触AI大模型开发、想搞懂Agent内部机制的同学已经在用LangChain但还不清楚它和LangGraph区别的开发者需要在项目中接入MCP工具服务的后端工程师。读完你至少能独立搭建一个“让大模型自主决定调用什么工具”的Agent并且知道常见报错该从哪里排查。1. 背景与核心概念四个关键词到底分别解决什么问题1.1 为什么2026年的Agent开发绕不开这四个词先说一个常见误区很多人把LangChain、MCP、LangGraph当成同类型框架去比较其实它们解决的完全是不同层面的问题。LangChain解决的是“大模型应用的基础零件问题”。它把模型调用、Prompt模板、文本切分、向量存储、工具定义这些高频操作封装成统一接口你不需要每次从零写调用代码。MCPModel Context Protocol模型上下文协议解决的是“大模型如何安全、标准化地连接外部工具和数据源”的问题。过去每个Agent接一个工具就要写一套私有协议MCP提供了一套统一标准。LangGraph解决的是“复杂Agent流程如何编排、如何控制状态”的问题。它允许你定义带循环、分支、人工确认的图结构工作流。Agent则是一种应用形态让大模型在循环中自主决定调用哪些工具、什么时候给出最终答案。把这四个词放在一起可以理解为LangChain提供零件MCP提供插槽LangGraph负责组装生产线Agent就是这条生产线上完成闭环任务的执行单元。1.2 常见应用场景智能客服用户提问后Agent自动查询订单库、物流接口再组织语言回答。代码助手Agent调用代码搜索工具、读取文件、执行测试命令。数据分析助手Agent连接数据库MCP服务自主写SQL、查数据、生成结论。自动化运维Agent根据告警信息调用监控接口、执行剧本、输出处理报告。这些场景的共同特征是模型不能只靠“记忆”回答必须实时获取外部信息并且整个决策链路可追踪、可控制。这正是LangChain MCP LangGraph组合擅长的地方。2. 环境准备与版本说明在开始写代码之前先把环境整理好。Agent开发中90%的“跑不起来”问题都出在Python版本、依赖包版本、密钥配置这三件事上。2.1 基础运行环境操作系统Windows / macOS / Linux 均可本文命令以通用命令行示例为准。Python建议使用 3.9 及以上版本。包管理工具pip 或 poetry。模型服务需要准备一个兼容OpenAI接口的大模型服务可以是云端API也可以是本地通过兼容网关暴露的服务。注意LangChain、LangGraph、MCP相关包的版本迭代非常快。本文不锁定具体小版本号建议安装时统一拉取最新稳定版同时保证Python环境干净最好使用虚拟环境。2.2 创建虚拟环境并安装依赖python -m venv agent-demo-env source agent-demo-env/bin/activate # Windows下使用 agent-demo-env\Scripts\activate pip install --upgrade pip pip install langchain langchain-openai langgraph langchain-mcp-adapters mcp python-dotenv如果安装过程中出现依赖冲突优先检查Python版本是否过老或尝试分步安装mcp和langchain-mcp-adapters。pip install mcp pip install langchain-mcp-adapters2.3 密钥配置新建.env文件用来存放模型服务的密钥与基础配置OPENAI_API_KEY你的密钥 OPENAI_API_BASEhttps://你的模型服务地址 OPENAI_MODEL_NAME你的模型名称如果你的模型服务商兼容OpenAI接口LangChain的ChatOpenAI可以直接通过base_url指定网关地址。不要把密钥硬编码在Python文件里更不要提交到Git仓库。3. 核心概念拆解先理解原理再动手写代码3.1 LangChain模型调用与工具定义的基础层LangChain的定位可以理解为一个“胶水层”。它不替代大模型而是让接入模型、拼接Prompt、定义工具这些操作变得更统一。看一个最基础的模型调用示例# 文件路径demo_langchain_basic.py import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage load_dotenv() llm ChatOpenAI( modelos.getenv(OPENAI_MODEL_NAME, gpt-4o-mini), temperature0, ) resp llm.invoke([HumanMessage(content用一句话介绍LangChain)]) print(resp.content)这里需要注意的点是ChatOpenAI并不强制要求使用OpenAI官方服务很多国内模型服务都提供OpenAI兼容接口你只需要设置base_url就可以让LangChain与不同厂商的模型对话。LangChain更重要的能力是工具定义。在Agent场景中大模型需要通过函数调用能力去触发外部操作。LangChain把工具的输入输出描述标准化让模型能够“看懂”工具参数。from langchain_core.tools import tool tool def add(a: int, b: int) - int: 计算两个整数相加的结果 return a b print(add.name) # add print(add.description) # 计算两个整数相加的结果这段代码背后的价值是大模型看到add函数的名称、描述、参数类型后才能自动生成正确的调用参数。如果你不给工具写好命名和描述模型就无法知道什么时候该调用它、参数应该填什么。3.2 MCP统一工具与数据源接入协议MCPModel Context Protocol由Anthropic提出目标是解决“每个Agent都要为不同工具编写私有接口”的重复劳动。MCP架构中有三个角色MCP Host运行大模型应用的宿主程序你的Agent应用就是Host。MCP ClientHost内部的通信客户端负责建立会话、发送工具调用请求。MCP Server独立进程或服务负责暴露工具Tools、资源Resources、提示模板Prompts。一个MCP Server可以同时给Claude Desktop、自定义LangChain应用、其他Host使用。也就是说工具只开发一次处处可复用。使用Python SDK可以快速创建一个MCP Server。当前主流写法是基于FastMCP高层封装# 文件路径mcp_server.py import datetime from mcp.server.fastmcp import FastMCP # 创建一个名为 weather-demo 的MCP服务 mcp FastMCP(weather-demo) mcp.tool() def get_weather(city: str) - str: 查询指定城市的天气情况城市名使用中文例如北京、上海 # 演示环境使用本地模拟数据实际项目中可以在这里调用天气服务API weather_map { 北京: 晴24℃微风, 上海: 多云28℃东南风3级, 广州: 阵雨30℃南风2级, } return weather_map.get(city, f抱歉暂时没有 {city} 的天气数据) mcp.tool() def get_current_time() - str: 获取服务器当前时间返回格式为 YYYY-MM-DD HH:MM:SS return datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S) if __name__ __main__: mcp.run()mcp.tool()装饰器会把函数自动注册成工具。工具描述写得好不好直接影响大模型调用它的准确率。注意FastMCP的具体导入路径在不同版本的mcp包中可能略有差异如果遇到导入错误可以查看当前SDK的官方文档确认最新推荐写法。这个示例的重点是让大家理解MCP Server的组织形式。默认情况下mcp.run()以stdio模式启动适合由父进程启动并通信。如果希望做成网络服务可以使用Streamable HTTP等传输模式原理类似但地址和端口配置需要按项目环境调整。3.3 LangGraph用图来编排Agent的执行流程LangChain比较擅长处理“线性链路”先调用模型再取结果再调用另一个模型。但真实Agent是“带循环的”模型决定调用工具工具返回结果结果再喂回模型模型可能再次调用工具直到最后才给出答案。这种循环用传统Chain表达很别扭LangGraph正是为此设计的。LangGraph把流程建模成“状态图”。你需要定义状态State在节点之间传递的数据结构。节点Node一个处理函数可以是调用模型也可以是执行工具。边Edge决定下一个执行哪个节点的连接关系。条件边Conditional Edge根据当前状态动态决定下一步走向。看一个最简单的手动状态图示例# 文件路径demo_langgraph_basic.py from typing import TypedDict from langgraph.graph import StateGraph, END from langgraph.graph.message import add_messages from typing import Annotated class AgentState(TypedDict): messages: Annotated[list, add_messages] def first_node(state: AgentState): return {messages: [(ai, 我是第一个节点)]} def second_node(state: AgentState): return {messages: [(ai, 流程执行结束)]} # 1. 构建状态图 graph StateGraph(AgentState) # 2. 添加节点 graph.add_node(first, first_node) graph.add_node(second, second_node) # 3. 设置入口 graph.set_entry_point(first) # 4. 连接边 graph.add_edge(first, second) graph.add_edge(second, END) # 5. 编译并运行 app graph.compile() result app.invoke({messages: []}) print(result[messages])运行后可以看到消息列表里依次出现了两个节点写入的内容。这说明LangGraph的执行顺序完全由你定义的边决定不是靠代码从上到下硬执行。3.4 Agent的核心循环思考、行动、观察理解了工具定义、MCP服务、图编排之后还需要理解Agent本身的运行逻辑。主流Agent采用ReAct思路Reason推理 Act行动。循环过程如下思考Thought模型理解用户问题判断当前需要什么信息。行动Action模型选择并调用一个工具传入结构化参数。观察Observation系统返回工具执行结果。重复上述步骤直到模型认为信息充分。最终回答Final Answer模型基于全部上下文组织最终回复。LangGraph的create_react_agent就是把这个循环封装好的高层接口。你只需要提供模型和工具列表框架会自动构建“模型节点 - 工具节点 - 模型节点”的循环。这个过程最容易被忽略的是模型是否具备“工具调用”能力。如果你的模型本身不支持function calling或者服务商没有开启相关参数那么Agent只会输出一串“我想调用某某工具”的话而不是真正触发调用。所以实战中模型选择是关键前提。4. 完整实战案例用LangChain MCP LangGraph构建一个工具型Agent接下来进入核心实战部分。我们要构建一个Agent它能够根据用户问题自主选择调用“查询天气”和“获取当前时间”两个MCP工具最终给出自然语言回答。4.1 项目结构agent-demo/ ├── .env ├── requirements.txt ├── mcp_server.py └── agent_app.py.env存放模型密钥、地址等配置。requirements.txt记录项目依赖。mcp_server.py基于FastMCP实现远端工具服务。agent_app.pyLangGraph Agent主程序加载MCP工具并完成对话。4.2 编写依赖清单langchain langchain-openai langchain-core langgraph langchain-mcp-adapters mcp python-dotenv保存后执行pip install -r requirements.txt如果你的环境同时存在多个Python项目强烈建议始终使用虚拟环境避免包版本冲突。4.3 编写MCP服务端天气和时间工具已经在上文写好了。这里再补充一个细节MCP Server也是普通的Python程序可以在本机以子进程方式启动也可以部署到远程服务器。本文演示的是以子进程方式启动所以LangChain客户端需要通过StdioServerParameters指定启动命令。为避免与其他模块冲突MCP服务端文件保持独立不要在里面导入LangChain相关包。4.4 编写Agent主程序# 文件路径agent_app.py import os import asyncio from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client from langchain_mcp_adapters.tools import load_mcp_tools load_dotenv() # 初始化大模型 llm ChatOpenAI( modelos.getenv(OPENAI_MODEL_NAME, gpt-4o-mini), temperature0, ) # 配置MCP Server启动参数使用python运行mcp_server.py server_params StdioServerParameters( commandpython, args[mcp_server.py], ) async def build_agent(): 创建Agent实例连接MCP服务并加载工具 # 建立stdio客户端连接 async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: # 初始化MCP会话 await session.initialize() # 将MCP Server暴露的工具转换为LangChain工具 tools await load_mcp_tools(session) # 使用LangGraph预置的ReAct Agent结构 agent create_react_agent(llm, tools) # 调用Agent传入用户消息 result await agent.ainvoke( {messages: [(user, 现在几点了顺便告诉我北京的天气。)]} ) return result if __name__ __main__: response asyncio.run(build_agent()) for message in response[messages]: # 打印每一轮消息便于观察Agent的思考与调用轨迹 print(f角色: {message.type}) print(f内容: {message.content}) print(---)这段代码的逻辑分为四步第一步初始化大模型。temperature设为0让模型尽量稳定、少做自由发挥。第二步配置MCP连接参数。commandpython表示用当前虚拟环境的Python启动服务端args[mcp_server.py]表示被启动的脚本。第三步在异步上下文中建立MCP会话。session.initialize()是握手过程必须等初始化完成之后才能加载工具。第四步调用load_mcp_tools把MCP Server暴露的工具转换成LangChain工具列表然后传给create_react_agent。4.5 运行与验证在项目目录下执行python agent_app.py如果一切正常你会看到类似以下结构的输出角色: human 内容: 现在几点了顺便告诉我北京的天气。 --- 角色: ai 内容: [{name: get_current_time, arguments: {}}, ...] --- 角色: tool 内容: 2026-01-18 14:30:22 --- 角色: ai 内容: [{name: get_weather, arguments: {city: 北京}}, ...] --- 角色: tool 内容: 北京晴24℃微风 --- 角色: ai 内容: 当前时间是2026-01-18 14:30:22。北京的天气是晴天24℃微风。这个输出展示了一次完整的Agent运行过程模型先调用了get_current_time拿到一个工具结果。模型发现还需要天气信息于是继续调用get_weather。拿到两个工具的返回结果后模型最终整合信息输出面向用户的完整回答。这就是ReAct循环在真实项目中的样子。你不需要手写循环判断逻辑LangGraph已经帮你处理了状态维护和流程控制。4.6 如果只想快速体验LangGraph自带工具有些人可能暂时不想接入MCP想先看Agent能不能跑通。可以临时把工具列表替换成普通LangChain工具from langchain_core.tools import tool tool def add(a: int, b: int) - int: 计算两个整数相加的结果 return a b agent create_react_agent(llm, [add]) result agent.invoke({messages: [(user, 计算123加456的结果)]})这种方式适合验证环境配置是否正确。等基础流程跑通再切换到MCP加载远程工具排错范围会更小。5. 常见问题与排查思路在Agent开发过程中报错是常态。下面这张表整理了我认为出现频率最高的几类问题每条都对应一套排查路径。问题现象常见原因解决思路pip安装依赖时出现冲突Python版本过低或包之间依赖不兼容使用Python 3.10虚拟环境重新安装分步安装mcp和langchain-mcp-adapters启动agent_app.py后MCP连接失败mcp_server.py路径不正确或当前虚拟环境未激活检查命令中args[mcp_server.py]的路径确认在虚拟环境中运行脚本Agent没有真正调用工具只输出文本模型服务不支持function calling或base_url配置错误确认模型服务商是否兼容OpenAI工具调用协议更换支持function calling的模型工具描述不生效模型反复调错参数函数签名和docstring写得不够具体在docstring中说明每个参数的含义、单位、取值范围给工具起无歧义的名字Agent进入死循环或调用次数过多图结构中没有设置最大迭代步数或工具频繁返回错误为create_react_agent配置recursion_limit检查工具内部是否有异常运行时报TypeError: coroutine object...异步代码没有使用await或asyncio.run检查load_mcp_tools或agent.ainvoke是否在异步上下文内正确等待加载MCP工具为空MCP Server启动失败或mcp.tool()没有被注册成功单独运行python mcp_server.py检查启动输出确认没有导入错误5.1 模型总是不调用工具怎么办这是Agent开发中最容易出现的问题。排查顺序建议如下先单独测试模型接口是否支持工具调用。可以直接用llm.bind_tools([add])方式看看返回结果里是否有tool_calls字段。检查Prompt是否给了模型足够的工具使用提示。create_react_agent会内置System Prompt但工具本身的描述仍然很重要。尝试把temperature调低模型在低温下更倾向遵循结构化调用指令。换成专门针对工具调用优化的模型不要用纯对话模型。5.2 MCP连接成功但工具执行超时MCP工具一般会在独立进程中执行如果工具函数内部有网络请求可能因为外部服务慢导致超时。实际项目中建议在工具内部做好超时控制。给工具函数添加异常捕获返回友好错误信息而不是让整个MCP进程崩溃。在Agent外层设置合理的递归限制和步数限制防止工具调用链无限拉长。6. 最佳实践与工程建议能跑通Demo只是第一步。把Agent部署到生产环境还需要考虑很多工程细节。6.1 工具即接口文档描述质量决定上限大模型无法“看到”工具内部实现它只能依靠函数名、参数类型、docstring做决策。因此函数名必须直观比如get_weather_by_city好于w_func_v2。说明每一个参数的格式和取值范围例如“城市名使用中文如北京、上海”。对于可能返回空结果的工具要主动说明边界情况。工具数量不宜过多。一个Agent节点挂几十个工具时模型出现选择困难的情况会明显上升。如果工具很多考虑先做工具分类路由。6.2 状态设计和超时控制LangGraph的状态是节点间传递的核心。状态字段定义得越清晰调试越容易。建议在TypedDict中把最终结果、中间步骤、错误信息分开存放不要把所有内容塞进一个大字典。同时设置recursion_limitresult agent.invoke( {messages: [(user, 查询北京天气)]}, config{recursion_limit: 15}, )这样即使模型反复调用工具也不会无限制地消耗你的模型API额度。6.3 安全边界与人工确认如果Agent涉及写数据库、发邮件、删除文件、执行Shell命令等敏感操作务必在关键节点前加入人工确认机制。LangGraph提供了Human-in-the-loop能力。你可以在工具节点之前增加一个中断节点由操作者确认后再继续执行。原则是默认禁止高风险操作白名单放行日志留痕。MCP Server本身也是一种攻击面。不要把带有危险权限的工具直接暴露给互联网MCP服务之间要做好鉴权与网络隔离遵循最小权限原则。6.4 配置、密钥与可观测性密钥一律从环境变量或密钥管理服务读取不要写死在代码里。不同环境开发、测试、生产使用不同的MCP Server地址和模型配置。对Agent的完整运行链路保存日志包括模型决策、工具入参、工具返回结果。有条件时接入LangSmith或自建Trace体系便于追踪每一步耗时和错误来源。7. 总结与后续学习建议现在你已经拥有了一个最小的“LangChain MCP LangGraph”技术骨架LangChain负责模型接入和工具抽象MCP让工具服务和主应用解耦LangGraph提供Agent循环控制能力Agent在循环中自主决定调用哪些工具来解决问题。这篇文章建立的是一个起点。真实项目中你还需要继续掌握几个方向。第一把MCP Server升级到网络传输模式让工具服务独立部署供多个Agent应用共用。这样工具团队和应用团队可以平行推进。第二研究LangGraph的高级节点特性比如条件分支、子图、持久化存储。当Agent流程变复杂后这些能力能帮你管理更细粒度的状态。第三完善工具服务的错误处理与监控。生产环境中工具不可用比模型不可用更常见。如果你对这块内容感兴趣建议直接打开官方文档从create_react_agent对应的接口定义开始阅读再动手改造本文示例给MCP Server增加一个新工具观察Agent会不会在复杂任务中自动组合多个工具。自己动手扩展一遍比反复看教程有效得多。希望这篇文章能在你入门AI Agent开发时帮你少走一些弯路。
返回列表