LangGraph解析
随着大语言模型(LLM)技术的快速发展,AI应用的需求已经从简单的问答扩展到了复杂的多步骤任务处理、多智能体协作等场景。传统的线性链式开发方式在面对这些复杂需求时显得力不从心。LangGraph应运而生,它是一个用于构建有状态、多智能体AI应用的开源框架,采用图(Graph)结构来编排复杂工作流,为开发者提供了更强大和灵活的工具。
本文将基于LangGraph的官方文档和实践经验,从基础概念到核心机制,再到实际应用案例,全面深入地解析LangGraph的技术原理和应用方法,帮助开发者掌握这一强大的AI应用开发框架。
一、LangGraph基础概览
1.1 核心理念:图驱动的工作流
LangGraph将AI应用的逻辑抽象为一张由"节点"(Nodes)和"边"(Edges)构成的状态图。下图清晰展示了这种结构与执行方式:
在LangGraph的图结构中,每个组件都有明确的职责:
| 组件 | 定义 | 功能 | 示例 |
|---|---|---|---|
| 节点(Nodes) | 独立的执行单元 | 处理数据,执行操作 | 调用LLM、执行工具函数、查询数据库 |
| 边(Edges) | 流程控制逻辑 | 决定下一步执行哪个节点 | 固定连接、条件分支、动态路由 |
| 状态(State) | 共享的数据结构 | 保存上下文信息 | 消息历史、查询结果、中间状态 |
1.2 主要特点与优势
LangGraph相比传统的AI应用开发框架,具有以下显著特点:
| 特性 | 说明 | 应用场景 |
|---|---|---|
| 循环与条件分支 | 支持智能体的"思考-行动"循环,动态改变执行路径 | 需要多轮决策的任务 |
| 内置状态管理 | 通过检查点自动持久化状态,支持断点续执行 | 长时间运行的应用 |
| 人机协同 | 可在流程中暂停并等待人工输入或审批 | 高风险或需要把关的场景 |
| 多智能体协作 | 原生支持定义多个智能体,编排协同工作 | 复杂的团队协作任务 |
| 可观测性 | 与LangSmith集成,提供可视化调试 | 开发和调试阶段 |
1.3 生态系统与使用方式
LangGraph提供了灵活的集成路径,开发者可以根据需求选择不同的使用方式:
| 使用方式 | 特点 | 适用场景 |
|---|---|---|
| 独立使用 | 作为底层框架,自定义智能体系统 | 有特殊需求的开发者 |
| 与LangChain集成 | 无缝兼容LangChain生态中的模型、工具 | 已熟悉LangChain的开发者 |
| 高级组件 | 使用预构建的智能体模式 | 快速开发常见应用 |
| 商业平台 | 提供部署、托管、监控等生产级功能 | 企业用户 |
1.4 LangGraph与LangChain的区别
| 特性 | LangChain | LangGraph |
|---|---|---|
| 核心抽象 | 链(Chain),线性编排 | 状态图(Stateful Graph),带循环和分支 |
| 适用场景 | RAG、文档处理、一次性问答 | 智能体、多轮对话、自动化流程、多智能体系统 |
| 状态管理 | 通过Memory组件传递上下文 | 内置的、中心化的状态管理 |
二、LangGraph图的关键概念
2.1 智能体(Agent)
智能体是LangGraph中最基础也是最重要的概念之一。
工作原理
| 特性 | 说明 |
|---|---|
| 核心机制 | LLM基于环境反馈循环使用工具 |
| 实现复杂度 | 相对简单,但需要清晰的工具集设计 |
| 适用场景 | 开放性问题,无法预测所需步骤数量 |
| 关键要求 | 需要良好的工具集和文档设计 |
2.2 工作流(Workflow)
2.2.1 并行化(Parallelization)
并行化是指让多个LLMs同时处理一个任务,并通过编程方式对它们的输出结果进行聚合。
两种主要变体:
| 类型 | 说明 | 示例 |
|---|---|---|
| 分段(Sectioning) | 将任务分解成多个相互独立的子任务 | 生成报告的不同部分(摘要、方法、结果) |
| 投票(Voting) | 对同一个任务运行多次,综合多个结果 | 多个LLMs进行情感分析,投票确定结果 |
并行化的适用场景:
| 场景 | 优势 |
|---|---|
| 提高速度 | 显著缩短处理时间 |
| 提高置信度 | 综合多个结果,提高可靠性 |
| 复杂任务处理 | 每个LLM专注于特定方面 |
2.2.2 路由(Router)
路由的工作是将输入进行分类,并将其导向到相应的后续任务。
| 路由的作用 | 说明 |
|---|---|
| 输入分类与任务导向 | 根据输入内容导向合适的处理流程 |
| 分离关注点 | 每个任务专注于特定领域 |
| 避免性能受损 | 不同输入类型分配给最适合的处理任务 |
2.2.3 协调者(Orchestrator)
在协调者-工作者模式中,一个协调者将任务分解并将每个子任务分配给工作者。
| 组件 | 职责 |
|---|---|
| 协调者 | 动态分解任务,分配子任务,综合结果 |
| 工作者 | 处理分配的特定子任务 |
与并行化模式的区别:
| 特性 | 并行化模式 | 协调者-工作者模式 |
|---|---|---|
| 子任务定义 | 预先定义好的 | 动态生成的 |
| 灵活性 | 相对固定 | 高度灵活 |
| 适用场景 | 已知结构的任务 | 无法预测子任务的复杂任务 |
2.2.4 评估者-优化器(Evaluator-optimizer)
| 适用场景 | 说明 |
|---|---|
| 明确的评估标准 | 存在清晰的质量衡量标准 |
| 迭代改进的价值 | 每次调整都能显著提升结果 |
| 人类反馈有效 | LLM能够理解并应用人类反馈 |
| LLM反馈能力 | LLM能够提供有效的评估和改进建议 |
三、深度理解LangGraph核心:Graph
3.1 Graph的基本组成
Graph是LangGraph的基本构建模块,它是一个有向无环图(DAG),用于描述任务之间的依赖关系。
| 元素 | 定义 | 说明 |
|---|---|---|
| State(状态) | 共享的数据结构 | 在整个应用当中共享,包含所有节点的状态 |
| Node(节点) | 处理数据的单元 | Python函数,以State为输入,返回更新后的State |
| Edge(边) | 依赖关系 | Python函数,根据当前State决定下一步执行哪个Node |
3.2 State状态
3.2.1 State的定义方式
使用TypedDict定义:
from typing import TypedDict
class OverallState(TypedDict):
foo: str
user_input: str
graph_output: str
使用Pydantic BaseModel定义:
from pydantic import BaseModel
class OverallState(BaseModel):
a: str
| 定义方式 | 特点 | 适用场景 |
|---|---|---|
| TypedDict | 轻量级,类型提示 | 简单状态结构 |
| Pydantic BaseModel | 支持验证、序列化 | 需要数据验证的场景 |
3.2.2 State的更新机制
| 更新策略 | 说明 | 示例 |
|---|---|---|
| 默认替换 | 直接替换字段值 | return {"a": "goodbye"} |
| 合并操作 | 使用add_messages、add等操作 | messages: Annotated[list[AnyMessage], add_messages] |
MessagesState便捷使用:
from langgraph.graph import MessagesState
# 直接使用,无需手动定义
state = MessagesState()
3.3 Node节点
3.3.1 Node的基本定义
def node_1(state: InputState) -> OverallState:
return {"foo": state["user_input"] + "> 长沙市"}
| 特性 | 说明 |
|---|---|
| 输入 | State对象(必选)+ config(可选) |
| 输出 | 更新后的State对象 |
| 命名 | 唯一字符串,未指定时使用函数名 |
3.3.2 Node的高级特性
| 特性 | 说明 | 示例 |
|---|---|---|
| 缓存机制 | 相同输入优先从缓存获取结果 | cache_policy=CachePolicy(ttl=5) |
| 重试机制 | 失败时自动重试 | retry=RetryPolicy(max_attempts=4) |
缓存示例:
from langgraph.types import CachePolicy
from langgraph.cache.memory import InMemoryCache
builder.add_node("node1", node_1, cache_policy=CachePolicy(ttl=5))
graph = builder.compile(cache=InMemoryCache())
# 第一次调用:执行节点逻辑
graph.invoke({"number": 5}, config={"configurable": {"user_id": "123"}})
# 第二次调用:从缓存获取
graph.invoke({"number": 5}, config={"configurable": {"user_id": "456"}})
3.4 Edge边
3.4.1 边的类型
| 边类型 | 说明 | 示例 |
|---|---|---|
| 普通边 | 固定连接两个节点 | builder.add_edge("node_1", "node_2") |
| 条件边 | 根据状态动态选择下一个节点 | builder.add_conditional_edges(START, routing_func) |
| Send动态路由 | 一个节点同时路由到多个节点 | Send("node1", {"msg": message}) |
3.4.2 普通边和EntryPoint
from langgraph.constants import START, END
builder.add_edge(START, "node_1")
builder.add_edge("node_1", "node_2")
builder.add_edge("node_2", END)
3.4.3 条件边
def routing_func(state: State) -> str:
if state["number"] > 5:
return "node1"
else:
return END
builder.add_conditional_edges(START, routing_func)
使用映射的方式:
def routing_func(state: State) -> bool:
return state["number"] > 5
builder.add_conditional_edges(
START,
routing_func,
{True: "node_a", False: "node_b"}
)
3.4.4 Send动态路由
from langgraph.types import Send
def routing_func(state: State):
result = []
for message in state["messages"]:
result.append(Send("node1", {"msg": message}))
return result
builder.add_conditional_edges(START, routing_func)
3.5 子图的使用
创建子图:
# 子图构建
subgraph_builder = StateGraph(State)
subgraph_builder.add_node("sub_node", sub_node_function)
subgraph_builder.add_edge(START, "sub_node")
subgraph_builder.add_edge("sub_node", END)
subgraph = subgraph_builder.compile()
# 父图构建
builder = StateGraph(State)
builder.add_node("subgraph_node", subgraph)
builder.add_edge(START, "subgraph_node")
builder.add_edge("subgraph_node", END)
graph = builder.compile()
3.6 图的Stream支持
| Stream模式 | 说明 | 适用场景 |
|---|---|---|
| values | 流式传输状态的完整值 | 需要查看每步的完整状态 |
| updates | 流式传输更新内容 | 只关心状态变化 |
| custom | 流式传输自定义数据 | 调试和监控 |
| messages | 流式传输LLM的Token | 实时显示LLM响应 |
| debug | 传输尽可能多的信息 | 深度调试 |
Custom Stream示例:
from langgraph.config import get_stream_writer
def node(state: State):
writer = get_stream_writer()
writer({"自定义key": "在节点内返回自定义信息"})
return {"answer": "some data"}
for chunk in graph.stream(inputs, stream_mode="custom"):
print(chunk)
四、LangGraph实战:SQLAgent实现
4.1 SQL应用场景
| 场景 | 说明 |
|---|---|
| 自然语言查询 | 用户用自然语言查询数据库 |
| 数据分析 | 自动生成SQL并执行分析 |
| 报表生成 | 根据需求自动生成报表 |
4.2 langchain_community的使用
4.2.1 安装
pip install langchain-community pip install langchain-community[sql]
4.2.2 基本使用
from langchain_community.utilities import SQLDatabase
from langchain_community.agent_toolkits import SQLDatabaseToolkit
db = SQLDatabase.from_uri("sqlite:///Chinook.db")
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
tools = toolkit.get_tools()
4.2.3 主要功能模块
| 模块 | 功能 |
|---|---|
| utilities | 实用工具类,如SQLDatabase |
| agent_toolkits | 智能体工具包,如SQLDatabaseToolkit |
| llms | 各种LLM集成 |
| chat_models | 聊天模型集成 |
4.3 SQL智能体的创建
完整示例:
import asyncio
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_community.utilities import SQLDatabase
from langchain_community.agent_toolkits import SQLDatabaseToolkit
llm = init_chat_model("deepseek:deepseek-chat")
db = SQLDatabase.from_uri("sqlite:///Chinook.db")
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
tools = toolkit.get_tools()
system_prompt = """
你是SQL数据库智能体,根据问题生成正确的{dialect}查询语句。
限制查询结果最多{top_k}条,只查询相关列。
严禁执行INSERT、UPDATE、DELETE等操作。
开始时必须查看表结构。
""".format(dialect=db.dialect, top_k=10)
agent = create_agent(llm, tools, system_prompt=system_prompt)
async def main():
async for step in agent.astream(
{"messages": [{"role": "user", "content": "哪种音乐类型的曲目平均时长最长?"}]},
stream_mode="values"
):
step["messages"][-1].pretty_print()
asyncio.run(main())
4.4 SQL工具介绍
| 工具 | 功能 |
|---|---|
| sql_db_query | 执行SQL查询语句 |
| sql_db_schema | 获取数据库表结构信息 |
| sql_db_list_tables | 获取所有可用表名 |
| sql_db_query_checker | 安全验证SQL查询 |
4.5 MCP Server Chart集成
集成示例:
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
mcp_client = MultiServerMCPClient({
"mcp-server-chart": {
"command": "npx",
"args": ["-y", "@antv/mcp-server-chart"],
"transport": "stdio"
}
})
mcp_tools = asyncio.run(mcp_client.get_tools())
agent = create_agent(llm, tools + mcp_tools, system_prompt=system_prompt)
MCP特点:
| 特性 | 说明 |
|---|---|
| MCP协议支持 | 提供MCP适配器功能 |
| 多服务器连接 | 支持连接多个MCP服务器 |
| 工具集成 | 将外部工具集成到智能体 |
| 图表生成 | 支持数据可视化 |
五、LangGraph本地服务器与UI界面
5.1 配置langgraph.json
{
"$schema": "https://langgra.ph/schema.json",
"dependencies": ["."],
"graphs": {
"agent": "./main.py:agent",
"sql_agent": "./example/pro2/sql_agent.py:agent"
},
"env": ".env",
"image_distro": "wolfi"
}
| 配置项 | 说明 |
|---|---|
| $schema | Schema定义 |
| dependencies | 依赖关系 |
| graphs | 图的入口点 |
| env | 环境变量文件 |
| image_distro | 镜像发行版 |
5.2 启动服务器
langgraph dev
5.3 UI界面功能
| 功能 | 说明 |
|---|---|
| 实时聊天交互 | 与智能体实时对话 |
| 工具调用可视化 | 显示工具调用过程 |
| 状态追踪 | 追踪状态变化 |
| 调试功能 | 详细的调试信息 |
更多推荐




所有评论(0)