用途
本技能面向使用 LangGraph 构建有状态智能体或工作流的开发者,解决四类问题:持久化图状态、记住多轮对话、在历史检查点之间回溯与编辑、配置子图 checkpointer 的作用域。
主要能力
1. 两类记忆
- 短期记忆(checkpointer):每个超级步保存/加载图状态,按 thread_id 区分不同检查点序列(即不同对话)。
- 长期记忆(store):跨线程保存用户偏好、事实等信息。
2. Checkpointer 选型
资料给出三种实现的适用性:
- InMemorySaver:测试与开发,非生产就绪。
- SqliteSaver:本地开发,部分生产就绪。
- PostgresSaver:生产环境,生产就绪。
3. 线程管理
使用 {"configurable": {"thread_id": "..."}} 传入配置。不同 thread_id 的状态相互隔离,例如 user-alice 与 user-bob 各自独立。资料强调:调用时必须始终提供 thread_id,否则状态不会持久化。
4. 状态历史与时间旅行
- 通过
graph.get_state_history(config)浏览检查点历史(TypeScript 为异步可迭代,可收集为数组)。 - 使用过去检查点的 config 并以
invoke(None, ...)(TypeScript 为invoke(null, ...))重放。 - 使用
update_state在过去的检查点上修改状态后恢复,实现分叉。 - 也可直接修改当前状态再恢复。
5. 子图 Checkpointer 作用域
编译子图时 checkpointer 参数控制持久化行为,三种模式对照如下:
checkpointer=False:无中断(HITL)、无多轮记忆,多次调用(不同或相同子图)均可,无状态检查;最简单、无检查点开销。- 省略 checkpointer(默认 None):支持中断,但不支持多轮记忆;每次调用全新开始,可暂停/恢复;并行执行时每次调用获得唯一命名空间;状态检查仅限当前调用。
checkpointer=True:支持中断与多轮记忆,跨调用保留状态;但同一节点内多次调用同一子图实例会产生命名空间冲突。
选择建议:不需要中断与持久化时用 False;需要 interrupt() 但不需要跨调用记忆时用默认;需要多轮对话记忆时用 True。
6. 并行子图命名空间
多个不同的有状态子图并行运行时,可将每个子图包在各自的 StateGraph 中并使用唯一节点名,以获得稳定的命名空间隔离。资料同时说明,通过 add_node 添加的子图本身已按名称自动获得命名空间,无需该包装。
7. 长期记忆(Store)
以 InMemoryStore 为例,提供 put/get/search/delete 操作;在节点中通过 Runtime 参数的 runtime.store 访问,编译时同时传入 checkpointer 和 store。不同线程可访问同一份长期记忆。
使用方式
资料同时给出 Python 与 TypeScript 示例:
- 编译时传入 checkpointer:
.compile(checkpointer=checkpointer)/.compile({ checkpointer })。 - PostgresSaver 的 setup() 应在部署时运行一次,而非应用启动时;示例注释说明它用于创建表。
- 子图按需选择
compile(checkpointer=False)、compile()或compile(checkpointer=True)。
适用场景
- 需要跨多轮记住对话的聊天式智能体。
- 需要人工介入中断(HITL)并可恢复的工作流。
- 需要回看、重放或分叉历史状态的调试与实验。
- 需要按用户隔离状态的多人/多会话应用。
- 需要跨会话共享用户偏好的长期记忆场景。
限制与注意事项
资料列出的常见错误与约束:
- 生产环境不要使用 InMemorySaver,进程重启会丢失数据;应使用 PostgresSaver。
- 不提供 thread_id 则状态不会持久化。
update_state会经过 reducer(例如列表追加),如需替换应使用 Overwrite。- 有状态子图(checkpointer=True)不支持在同一节点内并行调用同一实例如,命名空间会冲突。
- 不要在节点中直接访问 store,应通过 Runtime 参数获取。
暂未提供
资料未说明该技能的安装命令、版本要求、收费或授权信息,也未给出 SqliteSaver 的具体示例。