首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >LangGraph workflow详解以及MCP调用

LangGraph workflow详解以及MCP调用

作者头像
Wangzy
发布2026-06-22 18:54:06
发布2026-06-22 18:54:06
1480
举报

前记: LangGraph 是一个底层编排框架和运行时,用于构建、管理和部署长时间运行的有状态代理,了解到国外公司如Replit、Elastic、LinkedIn & Uber 等公司已经在生产环境在使用langgraph搭建智能体。上一篇文章简单介绍了LangGraph框架,本文再来详细了解学习下该智能体框架。

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 结合起来,看一个完整的微型代码。

这是一个“笑话生成器”,如果笑话不好笑,它会自己重写。

代码如下:

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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_tools

c、用langchain_core.tools的tool当装饰器,直接封装langchain_tools

代码语言:javascript
复制
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

代码语言:javascript
复制
# 绑定工具到 LLM
llm = ChatOpenAI(model="gpt-4o")
llm_with_tools = llm.bind_tools(tools)

3、LangGraph 原生支持执行 LangChain Tools,把LangChain Tools添加成langgraph的Node

代码语言:javascript
复制
builder.add_node("tools", ToolNode(tools)) 

4、langgraph的流程中使用规划+执行节点,将workflow输入message传给LLM,去做规划,返回tool_calls并更新对应的state,继而让执行节点去执行这些tools_calls并更新对应的state。

对应的大模型规划提示词如下:

代码语言:javascript
复制
你是一个自主规划助手。你的任务是:
1. 理解用户的请求
2. 分析需要执行哪些操作
3. 规划执行步骤
4. 调用相应的工具完成任务
你可以使用的工具包括:
- get_weather: 查询天气预报
- search_web: 搜索互联网信息
- calculate: 执行数学计算
请根据用户的需求,智能地规划并执行任务。

执行节点代码如下:

代码语言:javascript
复制
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,敬请期待。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-12-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 周银杂谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前记: LangGraph 是一个底层编排框架和运行时,用于构建、管理和部署长时间运行的有状态代理,了解到国外公司如Replit、Elastic、LinkedIn & Uber 等公司已经在生产环境在使用langgraph搭建智能体。上一篇文章简单介绍了LangGraph框架,本文再来详细了解学习下该智能体框架。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档