首页 / AI应用开发 / LangGraph 0.2 实战:构建带记忆与工具调用的状态化 AI Agent 工作流 1 次阅读
LangGraph 0.2 实战:构建带记忆与工具调用的状态化 AI Agent 工作流
AI 应用开发

LangGraph 0.2 实战:构建带记忆与工具调用的状态化 AI Agent 工作流

从状态图设计到持久化执行,手把手打造生产级 AI Agent 架构

2026 年 3 月 3 日 · 约 12 分钟阅读

为什么需要状态化 Agent?

在构建复杂的 AI 应用时,你是否遇到过这些痛点:

  • 多轮对话中上下文丢失,用户需要重复描述需求
  • 长任务执行到一半崩溃,无法从断点恢复
  • 工具调用结果无法在后续步骤中复用
  • 缺乏对 Agent 执行过程的观察和干预能力

这些问题背后,是一个共同的技术挑战:如何管理 Agent 的状态。传统的请求 - 响应模式无法胜任需要持久化、可恢复、可干预的生产级应用。

LangGraph 0.2 正是为解决这些问题而生。作为 LangChain 团队 2026 年重点推出的状态图框架,它提供了:

  • 状态持久化:使用 Checkpoint 机制保存每一步的状态
  • 可中断执行:在任意节点暂停,允许人类审查或修改
  • 记忆管理:区分短期工作记忆和长期跨会话记忆
  • 图式编排:用节点和边精确描述复杂工作流
LangGraph 状态持久化架构对比图

核心概念:LangGraph 的设计哲学

LangGraph 不是一个高层抽象框架,而是一个低层编排运行时。它不替你写 Prompt,也不封装模型细节,而是提供构建可靠 Agent 的基础设施。

🔄

State(状态)

TypedDict 定义的类型化状态,贯穿整个执行流程

Node(节点)

执行计算的基本单元,可以是 LLM 调用、工具执行或状态更新

🔗

Edge(边)

定义节点间的转移逻辑,支持条件分支和并行执行

💾

Checkpoint(检查点)

持久化存储,实现故障恢复和人类介入

环境准备与依赖

本教程使用以下工具和版本:

🐍

Python 3.10+

LangGraph 0.2 需要 Python 3.10 或更高版本

📦

LangGraph 0.2.x

核心状态图框架

🔗

LangChain 1.x

模型和工具集成

🗄️

SQLite / Postgres

检查点存储后端

# 创建虚拟环境
python -m venv langgraph-demo
cd langgraph-demo
source bin/activate

# 安装核心依赖
pip install -U langgraph langchain-core
pip install langchain-anthropic langchain-community
pip installaiosqlite  # SQLite 检查点存储
LangGraph 依赖关系与安装流程图

实战步骤:从零构建状态化 Agent

1

定义状态结构

状态是 LangGraph 的核心。我们需要用 TypedDict 明确定义Agent 在整个生命周期中需要维护的数据:

from typing import TypedDict, Annotated, List, Literal
from langgraph.graph.message import add_messages

# 定义消息类型
from langchain_core.messages import HumanMessage, AIMessage

class State(TypedDict):
    """Agent 的完整状态定义"""
    messages: Annotated[List, add_messages]  # 对话历史(自动去重)
    user_info: dict  # 用户画像和偏好
    current_task: str  # 当前任务描述
    intermediate_results: List[dict]  # 中间计算结果
    retry_count: int  # 重试次数
    status: Literal["pending", "running", "waiting", "completed", "failed"]

add_messages 是一个归约函数(reducer),它会自动合并新旧消息,避免重复。

LangGraph 状态结构示意图
2

创建节点函数

节点是执行实际计算的地方。每个节点接收当前状态,返回更新:

from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage, AIMessage

# 初始化 LLM
llm = ChatAnthropic(model="claude-sonnet-4-5-20250929", temperature=0.7)

def call_llm(state: State) -> dict:
    """LLM 调用节点:生成响应"""
    messages = state["messages"]
    response = llm.invoke(messages)

    return {
        "messages": [response],
        "status": "running"
    }

def analyze_task(state: State) -> dict:
    """任务分析节点:理解用户需求"""
    last_message = state["messages"][-1].content

    # 分析任务复杂度
    prompt = f"""分析以下任务的复杂度:
    {last_message}

    返回 JSON: {{"complexity": "low|medium|high", "estimated_steps": int, "required_tools": []}}"""

    analysis = llm.invoke([HumanMessage(content=prompt)])

    return {
        "current_task": last_message,
        "intermediate_results": [{"step": "analysis", "result": analysis.content}]
    }
LangGraph 节点执行流程图
3

添加工具调用能力

LangGraph 与 LangChain 的工具系统无缝集成。我们定义工具并让 LLM 决定是否调用:

from langchain_core.tools import tool
from langgraph.prebuilt import ToolNode

@tool
def search_web(query: str) -> str:
    """搜索网络获取最新信息"""
    # 实际项目中集成 Tavily/Serper 等搜索 API
    return f"搜索结果:关于{query}的最新信息..."

@tool
def calculate(expression: str) -> str:
    """执行数学计算"""
    try:
        result = eval(expression, {"__builtins__": {}}, {})
        return f"计算结果:{result}"
    except Exception as e:
        return f"计算错误:{e}"

@tool
def save_to_memory(key: str, value: str) -> str:
    """保存信息到长期记忆"""
    # 实际项目中写入数据库
    return f"已保存:{key} = {value}"

# 绑定工具到 LLM
llm_with_tools = llm.bind_tools([search_web, calculate, save_to_memory])

# 创建工具调用节点
tool_node = ToolNode([search_web, calculate, save_to_memory])

# 条件路由:判断是否需要调用工具
def should_call_tool(state: State) -> Literal["tool_node", "call_llm"]:
    last_message = state["messages"][-1]
    if isinstance(last_message, AIMessage) and last_message.tool_calls:
        return "tool_node"
    return "call_llm"
4

构建状态图

有了节点和边,就可以组装完整的状态图:

from langgraph.graph import StateGraph, START, END

# 创建图
builder = StateGraph(State)

# 添加节点
builder.add_node("analyze_task", analyze_task)
builder.add_node("call_llm", call_llm)
builder.add_node("tool_node", tool_node)

# 添加边(定义流程)
builder.add_edge(START, "analyze_task")  # 从分析任务开始
builder.add_edge("analyze_task", "call_llm")

# 条件边:根据是否需要工具调用来路由
builder.add_conditional_edges(
    "call_llm",
    should_call_tool,
    {
        "tool_node": "call_llm",  # 工具执行后返回 LLM
        "call_llm": END  # 无需工具,直接结束
    }
)

# 编译为可执行图
app = builder.compile()
LangGraph 状态图结构可视化
5

配置持久化检查点

检查点是 LangGraph 的核心特性,它让状态可以跨请求持久化:

from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.types import Thread

# 配置 SQLite 检查点存储
checkpointer = SqliteSaver.from_conn_string(":memory:")  # 生产环境用文件路径

# 重新编译,传入检查点
app = builder.compile(checkpointer=checkpointer)

# 使用线程 ID 区分不同会话
thread_config = {"configurable": {"thread_id": "user-123-session-456"}}

# 运行 - 第一次请求
result1 = app.invoke(
    {"messages": [{"role": "user", "content": "帮我分析 Python 异步编程的核心概念"}]},
    config=thread_config
)

# 运行 - 后续请求(自动恢复之前的状态)
result2 = app.invoke(
    {"messages": [{"role": "user", "content": "继续讲 async/await 的实际应用"}]},
    config=thread_config
)

检查点不仅保存状态,还支持时间旅行:你可以查看任意历史版本,甚至回滚到过去的状态。

LangGraph 检查点持久化机制示意图
6

实现人类介入(Human-in-the-Loop)

生产环境中,某些操作需要人类确认。LangGraph 允许在任意节点中断执行:

from langgraph.types import interrupt

def confirm_action(state: State) -> dict:
    """需要人类确认的节点"""
    pending_action = state["intermediate_results"][-1]

    # 中断执行,等待人类响应
    confirmation = interrupt({
        "type": "confirmation",
        "action": pending_action,
        "message": "请确认是否执行此操作"
    })

    if confirmation:
        return {"status": "approved"}
    else:
        return {"status": "rejected"}

# 添加中断节点
builder.add_node("confirm_action", confirm_action)

# 编译时设置中断点
app = builder.compile(
    checkpointer=checkpointer,
    interrupt_before=["confirm_action"]  # 在执行前中断
)

# 获取待处理的中断
pending_interrupts = app.get_state(thread_config).tasks

中断机制在金融审批、医疗诊断等场景中至关重要。

7

流式输出与事件驱动

LangGraph 支持流式输出和事件订阅,适合实时 UI 和监控:

import asyncio

# 流式获取状态更新
async def stream_execution():
    async for event in app.astream(
        {"messages": [{"role": "user", "content": "写一个 FastAPI 应用"}]},
        config=thread_config,
        stream_mode="values"  # 流式传输状态值
    ):
        print(f"状态更新:{event['status']}")
        print(f"消息数:{len(event['messages'])}")

# 事件驱动:订阅特定事件
async def subscribe_to_events():
    async for event in app.astream_events(
        {"messages": [{"role": "user", "content": "分析这段代码"}]},
        config=thread_config,
        version="v2"
    ):
        if event["event"] == "on_chat_model_stream":
            print(f"LLM 输出:{event['data']['chunk'].content}")
        elif event["event"] == "on_tool_end":
            print(f"工具完成:{event['name']}")

asyncio.run(stream_execution())
LangGraph 流式输出事件时序图

常见问题与解决方案

Q: 如何处理状态过大导致的性能问题?

LangGraph 的状态是累积的。对于大型状态,建议:

  • 使用引用而非内联存储大对象(如文件内容)
  • 定期清理 messages 列表,保留最近的 N 条
  • 将中间结果写入外部存储,状态中只保留引用 ID

Q: 多租户场景下如何隔离状态?

使用复合 thread_id:{user_id}:{session_id}:{workflow_type}。配合数据库索引,可以高效查询特定用户的所有状态。

Q: 如何调试状态图的执行流程?

LangGraph 提供可视化调试工具:

# 获取执行图
graph_png = app.get_graph().draw_mermaid_png()

# 查看完整状态历史
state_history = app.get_state_history(thread_config)

Q: 检查点存储支持哪些后端?

官方支持:SQLite(开发)、Postgres(生产)、Redis(高速缓存)、Memory(测试)。也支持自定义实现 LangGraphCheckpointSaver 接口。

总结:掌握 LangGraph 的关键要点

  • 状态定义:用 TypedDict 明确定义 Agent 需要维护的所有数据
  • 节点设计:每个节点应该是纯函数,接收状态返回更新
  • 工具集成:使用 ToolNode 和条件边实现灵活的工具调用路由
  • 持久化:检查点机制让状态可以跨请求恢复
  • 人类介入:interrupt 机制实现审批和审查流程
  • 流式输出:astream 和 astream_events 支持实时交互
进阶学习:LangGraph 还支持子图(SubGraph)、并行执行(Pregel 模式)、动态节点等高级特性。掌握基础后,可以探索官方文档中的分布式部署和性能优化章节。
LangGraph AI Agent 状态管理 LangChain
选择栏目
今日简报 播客电台 实战教程 AI挣钱计划 关于我
栏目
全球AI日报国内AI日报全球金融日报国内金融日报全球大新闻日报国内大新闻日报Claude Code 玩法日报OpenClaw 动态日报GitHub 热门项目日报AI工具实战AI应用开发编程实战工作流自动化AI原理图解AI Agent开发AI变现案例库AI工具创收AI内容变现AI接单提效变现前沿研究
我的收藏