1. 引言
随着大语言模型(LLM)应用从「单次问答」走向「复杂多步任务」,开发者面临两个核心挑战:如何让模型可靠地编排多个步骤,以及如何让模型安全地接入外部工具与数据。LangGraph 与 MCP(Model Context Protocol)分别从「流程编排」和「工具接入标准化」两个维度给出了答案。
LangGraph 是 LangChain 团队推出的低层级编排框架,它将 Agent 的推理过程建模为一张有向图:节点(Node)负责执行具体逻辑,边(Edge)负责控制流转,从而让开发者对 Agent 的行为拥有细粒度的控制力。MCP 则是由 Anthropic 于 2024 年底开源的一套开放协议,它统一了 LLM 应用与外部工具、数据源之间的交互方式,让「一次接入、处处复用」成为可能。
本文将从一个可运行的示例出发,完整讲解 LangGraph 与 MCP 的核心概念、集成方式与实战落地,帮助你快速上手这套现代 LLM 应用开发组合。
2. 核心概念速览
在动手写代码之前,我们先厘清两个框架各自解决什么问题。
2.1 LangGraph 是什么
LangGraph 的核心思想是「把 Agent 当图来写」。它提供以下关键抽象:
- State(状态):贯穿整个图执行的共享数据结构,所有节点读写同一份状态。
- Node(节点):图中的基本执行单元,接收当前状态,返回状态的部分更新。
- Edge(边):定义节点之间的流转关系,支持条件分支(Conditional Edge)。
- Checkpointer(检查点):保存每一步执行快照,支持断点续跑、人工介入与时间旅行。
相比 LangChain 早期的 AgentExecutor,LangGraph 让循环、分支、并行、人工审批等复杂控制流变得显式且可控。
2.2 MCP 是什么
MCP(Model Context Protocol)采用客户端-服务器架构,解决「工具接入碎片化」问题:
- MCP Host:LLM 应用本身(如 Claude Desktop、我们的 LangGraph Agent)。
- MCP Client:Host 内部与 Server 建立连接的组件。
- MCP Server:暴露工具、资源与提示词的独立服务,可以是本地进程,也可以是远程 HTTP 服务。
MCP 的价值在于:工具提供方只需实现一次 Server,就能被所有支持 MCP 的 Host 复用;应用方也无需为每个工具定制集成代码。
2.3 两者如何配合
LangGraph 负责「大脑的决策流程」,MCP 负责「手脚的标准化接入」。LangGraph Agent 在某个节点需要调用外部工具时,通过 MCP Client 向 Server 发起请求,拿到结果后写回 State,再决定下一步走向。
3. 环境准备
本文示例使用 Python 3.11+,需要安装以下依赖:
bash
pip install langgraph langchain-mcp-adapters mcp
其中 langchain-mcp-adapters 是 LangChain 官方提供的桥接库,它能把 MCP Server 暴露的工具转换为 LangChain 的 Tool 对象,从而无缝接入 LangGraph。
4. 构建一个最简单的 MCP Server
我们先写一个提供「天气查询」与「计算器」两个工具的 MCP Server。新建 weather_server.py:
python
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo-server")
@mcp.tool()
def get_weather(city: str) -> str:
"""查询指定城市的天气情况"""
# 这里替换为真实天气 API 调用
return f"{city} 今天晴,气温 22~28℃,微风。"
@mcp.tool()
def add(a: float, b: float) -> float:
"""计算两个数字之和"""
return a + b
if __name__ == "__main__":
mcp.run(transport="stdio")
启动该服务:
bash
python weather_server.py
此时服务会通过标准输入输出(stdio)等待 MCP Client 的连接。
5. 在 LangGraph 中接入 MCP 工具
接下来我们创建一个 LangGraph Agent,让它通过 MCP 调用上面两个工具。
5.1 创建 MCP Client 并加载工具
python
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from langchain_mcp_adapters.tools import load_mcp_tools
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
# 1. 配置 MCP Server 的启动参数
server_params = StdioServerParameters(
command="python",
args=["weather_server.py"],
)
# 2. 建立会话并加载工具
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await load_mcp_tools(session)
# 3. 创建 LLM
llm = ChatOpenAI(model="gpt-4o-mini")
# 4. 创建 LangGraph Agent
agent = create_react_agent(llm, tools)
# 5. 运行
result = await agent.ainvoke(
{"messages": [{"role": "user", "content": "北京天气怎么样?顺便算一下 12 加 35。"}]}
)
print(result["messages"][-1].content)
运行这段代码,Agent 会自主决定先调用 get_weather 再调用 add,最后汇总答案。
5.2 关键点说明
load_mcp_tools会把 MCP Server 暴露的所有工具一次性加载为 LangChain Tool。create_react_agent是 LangGraph 预置的 ReAct 风格 Agent,内部自动完成「思考-调用-观察」循环。- 整个 MCP 会话生命周期由
async with管理,确保资源正确释放。
6. 自定义 LangGraph 图:更精细的控制流
预置 Agent 适合快速上手,但真实项目往往需要自定义图结构。下面我们手动构建一个包含「规划-执行-总结」三个阶段的图。
python
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver
import operator
class AgentState(TypedDict):
messages: Annotated[list, operator.add]
plan: str
result: str
# 节点 1:规划
def plan_node(state: AgentState) -> dict:
return {"plan": "先查询天气,再计算数字"}
# 节点 2:执行(调用 MCP 工具)
async def execute_node(state: AgentState) -> dict:
# 实际项目中这里调用 MCP 工具
weather = await call_mcp_tool("get_weather", {"city": "北京"})
total = await call_mcp_tool("add", {"a": 12, "b": 35})
return {"result": f"{weather};求和结果:{total}"}
# 节点 3:总结
def summarize_node(state: AgentState) -> dict:
return {"messages": [{"role": "assistant", "content": state["result"]}]}
# 组装图
builder = StateGraph(AgentState)
builder.add_node("plan", plan_node)
builder.add_node("execute", execute_node)
builder.add_node("summarize", summarize_node)
builder.add_edge(START, "plan")
builder.add_edge("plan", "execute")
builder.add_edge("execute", "summarize")
builder.add_edge("summarize", END)
# 启用检查点,支持断点续跑
graph = builder.compile(checkpointer=InMemorySaver())
自定义图的价值在于:你可以精确控制每个节点的输入输出、在任意边加入条件分支、在节点之间插入人工审批,这些能力是预置 Agent 难以直接提供的。
7. 进阶:条件分支与人工介入
7.1 条件分支
当工具调用失败或结果异常时,我们可以让图走不同的路径:
python
def should_retry(state: AgentState) -> str:
if "错误" in state["result"]:
return "retry"
return "summarize"
builder.add_conditional_edges(
"execute",
should_retry,
{"retry": "execute", "summarize": "summarize"},
)
7.2 人工审批
在敏感操作(如发送邮件、执行删除)前插入人工确认节点:
python
from langgraph.types import interrupt
def human_approval(state: AgentState) -> dict:
decision = interrupt({"question": "是否允许执行该操作?"})
return {"approved": decision == "yes"}
当图执行到 interrupt 时,执行会暂停并等待外部输入,恢复后继续流转。这为生产环境提供了关键的安全保障。
8. 完整架构图
下面是 LangGraph + MCP 的整体协作流程:
#mermaid-svg-tuAykIDimHQzHmZM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tuAykIDimHQzHmZM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tuAykIDimHQzHmZM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tuAykIDimHQzHmZM .error-icon{fill:#552222;}#mermaid-svg-tuAykIDimHQzHmZM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tuAykIDimHQzHmZM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tuAykIDimHQzHmZM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tuAykIDimHQzHmZM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tuAykIDimHQzHmZM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tuAykIDimHQzHmZM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tuAykIDimHQzHmZM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tuAykIDimHQzHmZM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tuAykIDimHQzHmZM .marker.cross{stroke:#333333;}#mermaid-svg-tuAykIDimHQzHmZM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tuAykIDimHQzHmZM p{margin:0;}#mermaid-svg-tuAykIDimHQzHmZM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tuAykIDimHQzHmZM .cluster-label text{fill:#333;}#mermaid-svg-tuAykIDimHQzHmZM .cluster-label span{color:#333;}#mermaid-svg-tuAykIDimHQzHmZM .cluster-label span p{background-color:transparent;}#mermaid-svg-tuAykIDimHQzHmZM .label text,#mermaid-svg-tuAykIDimHQzHmZM span{fill:#333;color:#333;}#mermaid-svg-tuAykIDimHQzHmZM .node rect,#mermaid-svg-tuAykIDimHQzHmZM .node circle,#mermaid-svg-tuAykIDimHQzHmZM .node ellipse,#mermaid-svg-tuAykIDimHQzHmZM .node polygon,#mermaid-svg-tuAykIDimHQzHmZM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tuAykIDimHQzHmZM .rough-node .label text,#mermaid-svg-tuAykIDimHQzHmZM .node .label text,#mermaid-svg-tuAykIDimHQzHmZM .image-shape .label,#mermaid-svg-tuAykIDimHQzHmZM .icon-shape .label{text-anchor:middle;}#mermaid-svg-tuAykIDimHQzHmZM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tuAykIDimHQzHmZM .rough-node .label,#mermaid-svg-tuAykIDimHQzHmZM .node .label,#mermaid-svg-tuAykIDimHQzHmZM .image-shape .label,#mermaid-svg-tuAykIDimHQzHmZM .icon-shape .label{text-align:center;}#mermaid-svg-tuAykIDimHQzHmZM .node.clickable{cursor:pointer;}#mermaid-svg-tuAykIDimHQzHmZM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tuAykIDimHQzHmZM .arrowheadPath{fill:#333333;}#mermaid-svg-tuAykIDimHQzHmZM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tuAykIDimHQzHmZM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tuAykIDimHQzHmZM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tuAykIDimHQzHmZM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tuAykIDimHQzHmZM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tuAykIDimHQzHmZM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tuAykIDimHQzHmZM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tuAykIDimHQzHmZM .cluster text{fill:#333;}#mermaid-svg-tuAykIDimHQzHmZM .cluster span{color:#333;}#mermaid-svg-tuAykIDimHQzHmZM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tuAykIDimHQzHmZM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tuAykIDimHQzHmZM rect.text{fill:none;stroke-width:0;}#mermaid-svg-tuAykIDimHQzHmZM .icon-shape,#mermaid-svg-tuAykIDimHQzHmZM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tuAykIDimHQzHmZM .icon-shape p,#mermaid-svg-tuAykIDimHQzHmZM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tuAykIDimHQzHmZM .icon-shape .label rect,#mermaid-svg-tuAykIDimHQzHmZM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tuAykIDimHQzHmZM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tuAykIDimHQzHmZM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tuAykIDimHQzHmZM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
用户输入
LangGraph Agent
需要外部工具?
直接生成回复
MCP Client
MCP Server
天气 API / 计算器 / 数据库
最终输出
9. 常见问题与最佳实践
9.1 工具数量过多怎么办
当 MCP Server 暴露的工具超过几十个时,全部塞给 LLM 会显著增加 Token 消耗并降低选择准确率。建议:
- 按业务域拆分多个 MCP Server,按需加载。
- 在工具描述中写清楚使用场景与参数含义。
- 必要时在 LangGraph 中增加「工具路由」节点,先让模型选择工具组,再加载具体工具。
9.2 长任务如何保证可靠性
- 使用 Checkpointer 持久化状态,任务中断后可恢复。
- 为关键节点设置超时与重试机制。
- 对不可逆操作强制加入人工审批节点。
9.3 远程 MCP Server
除了本地 stdio 传输,MCP 还支持 Streamable HTTP 传输,适合部署在服务器上的远程工具服务。只需将 StdioServerParameters 替换为对应的 HTTP 客户端配置即可。
10. 总结
LangGraph 与 MCP 的组合,为 LLM 应用开发提供了一套「可控编排 + 标准接入」的现代范式:
- LangGraph 让你以图的方式精确控制 Agent 的每一步决策与流转,支持分支、循环、并行与人工介入。
- MCP 让工具接入标准化,一次实现、处处复用,大幅降低集成成本。
- 两者结合,既能应对复杂业务逻辑,又能保持工具生态的开放与可扩展。
建议你从本文的天气示例入手,先跑通「MCP Server → LangGraph Agent」的最小闭环,再逐步加入条件分支、人工审批与远程服务,最终构建出适合自己业务的生产级 Agent 应用。