LangGraph的运行时:编译、执行与持久化(三)

一、编译

StateGraph 只是一张"蓝图",compile() 会把它变成一个可执行的 Runnable。

复制代码
builder = StateGraph(MyState)
# ... 添加节点和边 ...
graph = builder.compile()   # 编译

编译时 LangGraph 会做几件事:

编译时做的事 说明
校验图结构 检查是否有孤立节点、是否有入口
绑定持久化 如果传了 checkpointer,会绑定到图上
生成执行计划 把节点和边转换成可调度的执行流程
返回 Runnable 编译后的图支持 invoke、stream、batch 等方法

2. 编译参数

复制代码
graph = builder.compile(
    checkpointer=memory,      # 持久化
    store=store,              # 长期记忆
    interrupt_before=["node_a"],  # 在某节点前中断
    interrupt_after=["node_b"],   # 在某节点后中断
)

二、执行:四种调用方式

编译后的图是一个 Runnable,支持标准调用方法。

方法 用途 是否阻塞
invoke 执行一次,返回最终 State 阻塞
stream 流式执行,逐个输出 非阻塞迭代
batch 批量执行多个输入 阻塞
ainvoke / astream 异步版本 异步

1. invoke:最简单的执行

复制代码
result = graph.invoke({"messages": [], "count": 0})
print(result)

2. stream:流式执行(推荐)

stream 可以实时看到每个节点的输出,而不是等全部跑完。

复制代码
for chunk in graph.stream({"messages": []}):
    print(chunk)

stream_mode 决定了输出的粒度:

stream_mode 输出内容
"values" 每个节点执行后的完整 State
"updates" 每个节点返回的更新字典
"messages" LLM 生成的 token 流
"custom" 节点内通过 writer 自定义的输出
复制代码
# 只看每个节点的更新
for chunk in graph.stream(input, stream_mode="updates"):
    print(chunk)
    # 输出:{'node_a': {'count': 1}}

3. batch:批量执行

复制代码
results = graph.batch([
    {"messages": [], "count": 0},
    {"messages": [], "count": 100}
])

4. 执行时的 config

复制代码
config = {
    "configurable": {
        "thread_id": "user_123"   # 会话 ID
    },
    "recursion_limit": 25          # 最大迭代次数
}
result = graph.invoke(input, config)

三、持久化:Checkpointer

没有持久化时,每次调用都是独立 的,图不记得上次说了什么。Checkpointer 让图能记住历史,实现多轮对话。

使用方式

复制代码
from langgraph.checkpoint.memory import MemorySaver

memory = MemorySaver()
graph = builder.compile(checkpointer=memory)

# 第一次调用
config = {"configurable": {"thread_id": "user_1"}}
graph.invoke({"messages": ["你好"]}, config)

# 第二次调用(自动恢复上下文)
graph.invoke({"messages": ["继续"]}, config)

常用 Checkpointer

Checkpointer 存储位置 适用场景
MemorySaver 内存 开发测试
SqliteSaver SQLite 文件 本地生产
PostgresSaver PostgreSQL 生产环境
RedisSaver Redis 高并发

查看历史状态

复制代码
# 获取当前状态
state = graph.get_state(config)

# 获取历史状态列表
history = list(graph.get_state_history(config))

四、长期记忆:Store

1. Checkpointer vs Store

特性 Checkpointer Store
作用范围 单个会话(thread_id) 跨会话
存储内容 图的完整状态 键值对数据
典型用途 多轮对话 用户偏好、长期知识

2. 使用方式

复制代码
from langgraph.store.memory import InMemoryStore

store = InMemoryStore()
graph = builder.compile(store=store)

# 在节点中访问 store
def my_node(state, runtime: Runtime):
    # 写入
    runtime.store.put(("users", "user_1"), "preference", {"theme": "dark"})
    # 读取
    pref = runtime.store.get(("users", "user_1"), "preference")
    return {"result": pref}

五、中断与恢复(人机协同)

1. 中断的两种方式

复制代码
# 方式一:编译时指定
graph = builder.compile(
    interrupt_before=["approve_node"],  # 在节点前中断
    interrupt_after=["review_node"]     # 在节点后中断
)

# 方式二:节点内调用 interrupt
from langgraph.types import interrupt

def approve_node(state):
    user_input = interrupt("是否批准?")
    return {"approved": user_input == "yes"}

2. 恢复执行

复制代码
from langgraph.types import Command

# 用 Command 恢复
graph.invoke(Command(resume="yes"), config)

3. 中断流程图

六、示例

复制代码
from typing import TypedDict, Annotated
from operator import add
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver

class ChatState(TypedDict):
    messages: Annotated[list, add]

def chatbot(state: ChatState) -> dict:
    # 模拟 LLM 回复
    user_msg = state["messages"][-1]
    return {"messages": [f"回复:{user_msg}"]}

builder = StateGraph(ChatState)
builder.add_node("chatbot", chatbot)
builder.add_edge(START, "chatbot")
builder.add_edge("chatbot", END)

# 编译时绑定 checkpointer
memory = MemorySaver()
graph = builder.compile(checkpointer=memory)

# 多轮对话
config = {"configurable": {"thread_id": "user_1"}}

graph.invoke({"messages": ["你好"]}, config)
graph.invoke({"messages": ["再见"]}, config)

# 查看完整历史
state = graph.get_state(config)
print(state.values["messages"])
# ['你好', '回复:你好', '再见', '回复:再见']
相关推荐
leoZ2311 小时前
第 40 篇 AI 团队搭建与角色分工
人工智能·大模型·agent
Alice-YUE1 小时前
A2A 协议详解:Agent 间通信标准、四大核心机制与 MCP 互补
大模型·多智能体·ai agent·mcp·a2a协议
小范的技术工坊1 小时前
大模型同步、异步、流式输出
大模型·结构化
Dontla6 小时前
(LangGraph教程)3. UX and Human-in-the-Loop——Lesson 5:Time travel时间旅行(未索引)
langgraph
Dontla6 小时前
(LangGraph教程)3. UX and Human-in-the-Loop——Lesson 1: Streaming流式传输(未索引)
langgraph
Dontla7 小时前
(LangGraph教程)3. UX and Human-in-the-Loop-——Lesson 2:Breakpoints断点(未索引)
langgraph
浅安的邂逅17 小时前
20929-OpenAI 一天踩三脚急刹:暂停前沿训练、叫停 Astra、披露越权访问澳政府网站
人工智能·大模型·ai编程·行业动态·ai日报
问天_观心21 小时前
大模型训练与推理优化(二)
人工智能·深度学习·学习·大模型·transformer
小范的技术工坊1 天前
大模型蒸馏
人工智能·算法·数据挖掘·大模型