LangGraph 工作流详解
PAI 使用 LangGraph 的StateGraph 构建有状态的对话工作流。本文档详细说明状态结构、检查点机制、上下文传递和图的构建方式。
GraphState 结构
GraphState 是一个 TypedDict(total=False),定义了在工作流节点之间传递的全部状态字段:
total=False 意味着所有字段都是可选的。节点只需要返回需要更新的字段,LangGraph 会自动合并到当前状态中。extra 上下文字段
extra 字典承载了工作流中各种动态上下文信息,以下是主要的 key:
上下文渲染
context.py 中的 render_conversation_context 函数负责将 extra 中的上下文信息渲染为结构化文本,供 Router 和各节点的 LLM 调用使用:
- 会话摘要 — 截断到 300 字符
- 最近对话 — 按
role: content格式列出 - 长期记忆 — 按
[类型|优先级] key: content格式列出
检查点策略
LangGraph 的检查点(Checkpointing)机制用于持久化工作流状态,支持跨轮次的状态恢复。- 开发环境
- 生产环境
InMemorySaver默认使用内存检查点,状态仅在进程生命周期内有效。适合本地开发和测试,无需外部依赖。
状态持久化与恢复
检查点机制确保每次 Graph invoke 的状态都会被保存,使得:- 跨轮次状态保持 — 同一会话的多轮对话共享
GraphState,节点可以访问之前轮次设置的intent、extra等信息 - 复杂任务续接 —
complex_task_pending在extra中标记未完成的多步任务,用户可以在后续消息中继续执行 - 故障恢复 — Redis 检查点支持服务重启后恢复工作流状态
图的构建与缓存
_build_graph
_build_graph 函数负责构建完整的工作流图:
get_graph 缓存
get_graph 是一个异步单例函数,使用模块级变量和 asyncio.Lock 实现线程安全的懒加载:
图实例在整个应用生命周期内只构建一次。
close_graph 函数在应用关闭时释放 Redis 检查点的连接资源。生命周期管理
图的生命周期包含三个阶段:1
初始化
首次调用
get_graph() 时,自动完成检查点初始化(尝试 Redis,失败时可降级到内存)和图构建2
运行
每次消息处理时通过
get_graph() 获取缓存的图实例,调用 ainvoke 执行工作流3
关闭
应用关闭时调用
close_graph(),释放 Redis 连接的上下文管理器资源(__aexit__ 或 __exit__)