尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LangGraph04:记忆机制

LangGraph04:记忆机制 LangGraph 记忆机制checkpointer 与 thread_id 的会话隔离上一篇的机器人会查天气了但它依旧失忆每轮对话都是全新开始。本篇解决记忆问题——三行代码接入MemorySaver再搞懂thread_id是怎么让一百个用户各聊各的、互不串台的。失忆现场用户我叫小林。 机器人你好小林 用户我叫什么 机器人抱歉我没有关于您名字的信息。单次invoke/stream是无状态的传入的初始状态里只有当前这句话跑完就丢。想让机器人记住需要两样东西一份存储——每轮对话结束后把状态存下来下次接着用一个索引——存了很多人的对话之后得知道这份状态是谁的。LangGraph 分别用checkpointer和thread_id解决这两个问题。一个负责归档快照一个负责给每份档案编号。一、三行代码接入记忆不需要装新包langgraph.checkpoint.memory模块自带实现fromlanggraph.checkpoint.memoryimportMemorySaver# 1. 创建一个内存级检查点保存器memoryMemorySaver()# 2. 编译图时传入 checkpointer开启自动存档graphgraph_builder.compile(checkpointermemory)# 3. 每次调用时带上会话标识config{configurable:{thread_id:1}}改动只集中在编译和调用两处图本身节点、边、状态一行不用动。调用侧的变化也只有一个点——config成为stream的第二参数eventsgraph.stream({messages:[{role:user,content:user_input}]},config,# ← 第二参数位置固定stream_modevalues,)传了config之后图在执行前会先问 checkpointer这个thread_id之前存过状态吗存过 → 加载出来接着聊没存过 → 全新开始。执行完再把最新状态存回去。二、thread_id的隔离原理按房间号分区多用户场景下checkpointer 内部把状态按thread_id分区存放相同 ID 继续读写同一份不同 ID 互不可见graph checkpointerthread_id user_a─────────A 的对话状态thread_id user_b─────────B 的对话状态其实现可以简化为一个字典——键是thread_id值是该会话的状态快照classMemorySaver:def__init__(self):self.storage{}# key thread_iddefsave_checkpoint(self,thread_id,state):self.storage[thread_id]state# 写入自己那格defget_checkpoint(self,thread_id):returnself.storage.get(thread_id,None)# 只读自己那格隔离的完整逻辑就是三句话存的时候按thread_id归档取的时候只取自己归档的那份换个thread_id就什么都取不到自然从零开始。三、一个常见误解此线程非彼线程thread_id名字里有线程但它和 Python 的threading.Thread.ident操作系统线程 ID没有任何关系。把两个概念放一起对比维度LangGraph 的thread_idPython 的线程 ID所属层面LangGraph 框架内的业务概念操作系统/运行时概念管什么对话状态的归属记忆隔离代码执行单元的调度并发隔离谁来生成开发者自定义如user_123操作系统分配不可自定义何时失效随对话存在可长期有效线程结束即销毁典型取值1、session_xyz140703324567360这类整数一句话记法LangGraph 的thread_id管这份记忆是谁的Python 的线程 ID 管这段代码谁在跑八竿子打不着。两者还能叠加使用——用 Python 多线程同时服务 100 个用户每个用户再配一个独立thread_id各管各的互不冲突。四、四个实验验证隔离用同一个我叫 Will的场景做四组调用结果一目了然#调用时用的thread_id模型反应说明了什么11首次打招呼记住了 Will全新会话正常建档21再问我叫什么答出 Will同 ID 读回历史状态记忆生效32问我叫什么表示不认识新 ID 从零开始看不到1的档案41再问一次仍然答出 Will记忆一直在随时回得去实验 3 和实验 4 的对比最说明问题记忆不是模型变聪明了而是每次调用时加载对了状态文件。五、开发与生产的边界MemorySaver把状态存在进程内存里——快但服务一重启全部清空。它适合开发调试不适合上线。生产环境的升级路径是按需替换 checkpointer图代码完全不用动方案存储介质适用场景MemorySaver进程内存本地开发、单元测试SqliteSaverSQLite 文件单机轻量生产PostgresSaverPostgreSQL分布式、多实例、高并发生产隔离原理在三种方案里完全一致——都是拿thread_id当分区键换的只是存储介质。小结LangGraph 的记忆 checkpointer存档 thread_id索引。三个关键点MemorySavercompile(checkpointer...)三行接入节点代码零改动thread_id是状态的房间号同号续聊、异号隔离生产环境换SqliteSaver/PostgresSaver业务代码不用动。记忆能力补齐之后机器人能聊、能做、能记——入门篇到此闭环。下一篇开始下沉到源码层状态管理为什么是 LangGraph 的根基TypedDict和 Pydantic 两种状态定义怎么选。
返回列表