
01
—
LangGraph workflow详解
1、State状态:全知全能的“共享白板”
在 LangGraph 中,State是所有节点(Nodes)沟通的唯一桥梁。类似于一个中央的共享白板,不同的节点都可以更新或查看白板。
比如某个mcp查询到日志信息,可以写到白板上定义的某个key中,其他节点也可以随时查看白板上的这些信息。
LangGraph 使用 Python 的TypedDict来定义State状态。
如下图所示,通常有两种类型,一个是覆盖型字段,每次更新都会覆盖旧值;另一种是增量型字段,保存的信息是一直追加的。

2、Workflow(工作流):不仅是流程,更是“交通规则”
LangGraph 的工作流由三个核心要素组成:
a、Node(节点):干活的人
节点(Node)就是干活的人。它可以是一个 LLM、一个 Python 函数、或者一个调用 MCP 工具的动作。
定义了langgraph的workflow后,通过workflow.add_node的方法,把Node添加到workflow中。

输入: 当前的 State(白板上的所有信息)。
输出: 对 State 的更新(我想在白板上写点什么)。
b、Edge(边):固定的传送带
通过workflow.add_edge的方法是把不同Node给串联起来。

c、Conditional Edge(条件边):智能的大脑
这是 LangGraph 超越低代码编排的地方。低代码通常是线性的,而 LangGraph 可以在节点之间插入逻辑判断。
方法是:workflow.add_conditional_edges

d、workflow入口点:
可以用set_entry_point作为workflow的初始点,也可以用“START”来作为初始点。


3、实战演示:一个“会自我修正”的 Agent
让我们把 State 和 Workflow 结合起来,看一个完整的微型代码。
这是一个“笑话生成器”,如果笑话不好笑,它会自己重写。
代码如下:
from typing import TypedDict, Literal
import os
from langgraph.graph import StateGraph, START, END
from langchain_community.chat_models.tongyi import ChatTongyi
# --- 1. State 定义 (白板) ---
class JokeState(TypedDict):
topic: str
joke: str
feedback: str
# 记录重试次数,防止死循环
retry_count: int
# 设置环境变量 - 使用阿里云千问API Key
os.environ["DASHSCOPE_API_KEY"] = "your-dashscope-api-key-here"
# --- 2. Nodes 定义 (干活的人) ---
llm = ChatTongyi(model="qwen-plus") # 使用千问plus模型
def generate_joke(state: JokeState):
msg = f"讲一个关于 {state['topic']} 的笑话。"
response = llm.invoke(msg)
# 更新 state:覆盖旧笑话,并增加重试计数
return {
"joke": response.content,
"retry_count": state.get("retry_count", 0) + 1
}
def critique_joke(state: JokeState):
msg = f"评价这个笑话是否好笑,只回答'yes'或'no':{state['joke']}"
response = llm.invoke(msg)
return {"feedback": response.content.lower()}
# --- 3. Edges 定义 (SOP 流程) ---
def router(state: JokeState) -> Literal["generate", END]:
# 强制熔断机制:如果试了3次还不行,强制结束
if state["retry_count"] > 3:
return END
if "no" in state["feedback"]:
return "generate" # 循环!回到生成节点
return END
# --- 4. 组装图 ---
builder = StateGraph(JokeState)
builder.add_node("generator", generate_joke)
builder.add_node("critic", critique_joke)
builder.add_edge(START, "generator")
builder.add_edge("generator", "critic")
# 关键的循环逻辑
builder.add_conditional_edges("critic", router, {
"generate": "generator",
END: END
})
app = builder.compile()
# --- 5. 运行 ---
inputs = {"topic": "程序员", "retry_count": 0}
# 像流一样运行
for output in app.stream(inputs):
print(output)
执行效果如下:

02
—
MCP标准传输协议介绍
在 MCP (Model Context Protocol) 架构中,协议层 (Transport Layer) 负责 Client (如 Claude Desktop, LangGraph Agent) 和 Server (工具提供方) 之间的通信。
目前 MCP 定义了两种官方标准传输协议:Stdio 和 HTTP (SSE)。
1、stdio 协议(标准输入输出)
这是 MCP 最基础、也是开发阶段最常用的模式。它基于操作系统的进程间通信(Pipe)。
在这种模式下,Client(LangGraph Agent)作为父进程,会直接启动 Server 作为子进程。
a、发送消息: Client 将 JSON-RPC 消息写入 Server 的 stdin (标准输入)。
b、接收消息: Server 将响应结果写入 stdout (标准输出),Client 读取并解析。
c、日志处理: 由于 stdout 被占用了,Server 的调试日志通常输出到 stderr。

2、 HTTP 协议
这是企业级生产环境部署的主流模式。它允许 Client 和 Server 分离部署在不同的服务器上。
HTTP(HyperText Transfer Protocol)是通过网络进行远程调用的方式,通常以REST API形式提供。
让Gemini对比了下http协议的mcp和传统的restful api的区别,如下图:

03
—
LangGraph 和mcp的交互
如果说 LangGraph 是公司的 “项目经理”(负责流程控制、决策),那么 MCP (Model Context Protocol) 就是公司里的 “万能接口标准”。
要在 LangGraph 中使用 MCP,核心难点在于“如何把 MCP Server 里的工具,变成 LangGraph 能理解的 Tool 对象”。
LangGraph的workflow调用mcp有如下四个步骤:
1、将mcp-server中的tools转换成langchain_tools
介绍如下几种转换方式:
a、可以直接使用langchain_mcp_adapters.client的MultiServerMCPClient方法,通过http或stdio的方式获取到mcp-tools
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient(
{
"weather": {
"url": "http://localhost:8000/mcp",
"transport": "http",
}
}
)
tools = await client.get_tools()b、基于 Python mcp SDK 和 langchain-core把mcp-tools转换为langchain_tools
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from langchain_core.tools import tool
from langgraph.prebuilt import ToolNode
# 1. 建立 MCP 连接 (这是一个上下文管理器)
async def create_mcp_tools():
# 配置你的 MCP Server 路径
server_params = StdioServerParameters(
command="python",
args=["mcp_server_script.py"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# 2. 获取 MCP Server 里的所有工具列表
result = await session.list_tools()
mcp_tools = result.tools
langchain_tools = []
# 3. 【核心步骤】将 MCP 工具动态转换为 LangChain 工具
for mcp_tool in mcp_tools:
# 定义一个闭包函数来执行具体的 MCP 调用
async def _dynamic_tool_func(**kwargs):
return await session.call_tool(mcp_tool.name, arguments=kwargs)
# 设置函数的元数据(这很重要,LLM 靠这个理解工具怎么用)
_dynamic_tool_func.__name__ = mcp_tool.name
_dynamic_tool_func.__doc__ = mcp_tool.description
# 使用 LangChain 的装饰器或构造函数包装
# 这里简化演示,实际需要处理 input_schema 转换
lc_tool = tool(_dynamic_tool_func)
langchain_tools.append(lc_tool)
return langchain_toolsc、用langchain_core.tools的tool当装饰器,直接封装langchain_tools
from langchain_core.tools import tool
def _create_tools(self):
"""创建工具集,包括 MCP 工具"""
@tool
def calculate(expression: str) -> str:
"""执行数学计算
Args:
expression: 数学表达式,例如 '2+2' 或 '10*5'
Returns:
计算结果
"""
try:
result = eval(expression)
return f"计算结果:{expression} = {result}"
except Exception as e:
return f"计算错误:{str(e)}"
return [calculate]2、绑定tools到 LLM
# 绑定工具到 LLM
llm = ChatOpenAI(model="gpt-4o")
llm_with_tools = llm.bind_tools(tools)3、LangGraph 原生支持执行 LangChain Tools,把LangChain Tools添加成langgraph的Node
builder.add_node("tools", ToolNode(tools)) 4、langgraph的流程中使用规划+执行节点,将workflow输入message传给LLM,去做规划,返回tool_calls并更新对应的state,继而让执行节点去执行这些tools_calls并更新对应的state。
对应的大模型规划提示词如下:
你是一个自主规划助手。你的任务是:
1. 理解用户的请求
2. 分析需要执行哪些操作
3. 规划执行步骤
4. 调用相应的工具完成任务
你可以使用的工具包括:
- get_weather: 查询天气预报
- search_web: 搜索互联网信息
- calculate: 执行数学计算
请根据用户的需求,智能地规划并执行任务。执行节点代码如下:
def _execution_node(self, state: AgentState) -> AgentState:
"""执行节点:执行规划好的任务"""
messages = state["messages"]
last_message = messages[-1]
# 如果最后一条消息包含工具调用,则执行工具
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
return {
"messages": messages,
"next": "continue"
}
# 如果没有工具调用,说明任务完成
return {
"messages": messages,
"next": "end"
}04
—
结语
本文学习总结了LangGraph的workflow具体使用细节,以及和mcp的交互过程,在公司内部搭建基于LangGraph的workflow应该是够用了。
接下来的文章会介绍下LangGraph和RAG知识库的交互细节,以及langgraph+mcp+知识库的使用,还有state持久化和LangGraph可视化-LangSmith,敬请期待。