尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

【langgraph 从入门到精通graphApi 篇】Memory 与长期记忆

【langgraph 从入门到精通graphApi 篇】Memory 与长期记忆
📅 发布时间:2026/7/22 1:56:46

文章目录

    • 第 8 章:Memory 与长期记忆
      • 8.1 本章目标
      • 8.2 核心概念
        • Checkpoint vs Store
        • 短期记忆 vs 长期记忆架构
        • Store 命名空间设计
      • 8.3 实战
        • 实战 1:用户偏好记忆
        • 实战 2:语义记忆搜索
      • 8.4 API 速查
      • 8.5 错误与避坑指南
        • 坑 1:混淆 Store 和 Checkpoint
        • 坑 2:命名空间设计不当
        • 坑 3:语义搜索未配置 embedding
        • 坑 4:忘记在 compile 时传入 store
      • 8.6 最佳实践总结

第 8 章:Memory 与长期记忆

8.1 本章目标

学完本章你将能够:

  1. 理解短期记忆(Checkpoint)与长期记忆(Store)的区别
  2. 掌握 InMemoryStore / PostgresStore 的配置和使用
  3. 学会在节点中通过 Runtime 访问 Store
  4. 实现语义记忆搜索功能

8.2 核心概念

Checkpoint vs Store
特性Checkpoint(短期记忆)Store(长期记忆)
存储内容图状态快照(State 的完整副本)应用定义的键值数据
作用范围单个 Thread(对话线程)跨 Thread(跨会话)
生命周期对话结束后可清理持久保留
典型用途对话连续性、HITL、容错用户偏好、知识库、共享信息
访问方式自动(每个 super-step 保存)手动(节点中显式读写)

比喻:Checkpoint 就像"草稿自动保存"——每次编辑后自动保存当前状态。Store 就像"客户档案"——记录客户的长期偏好,所有对话都能访问。

短期记忆 vs 长期记忆架构

Store (长期记忆)

Checkpointer (短期记忆)

会话 2 (thread-2)

会话 1 (thread-1)

自动保存

自动保存

读写

读写

对话1

对话2

对话3

对话1

对话2

thread-1
checkpoints

thread-2
checkpoints

用户偏好
历史摘要
共享知识

Store 命名空间设计
# 命名空间使用 tuple 结构,支持层级隔离("user_123","memories")# 用户 123 的记忆("user_123","preferences")# 用户 123 的偏好("user_456","memories")# 用户 456 的记忆("global","knowledge")# 全局知识库

8.3 实战

实战 1:用户偏好记忆
fromtypingimportTypedDict,Annotatedfromdataclassesimportdataclassfromlanggraph.graphimportStateGraph,START,END,add_messagesfromlanggraph.checkpoint.memoryimportMemorySaverfromlanggraph.store.memoryimportInMemoryStorefromlanggraph.runtimeimportRuntimefromlangchain_core.messagesimportBaseMessage,HumanMessage,AIMessage# ============================================# 定义 Context(运行时上下文)# ============================================@dataclassclassContext:user_id:str# ============================================# 定义 State# ============================================classState(TypedDict):messages:Annotated[list[BaseMessage],add_messages]# ============================================# 定义节点(使用 Runtime 访问 Store)# ============================================asyncdefmemory_node(state:State,runtime:Runtime[Context])->dict:""" 使用 Runtime 访问 Store 实现长期记忆。 关键点: 1. 在函数签名中声明 runtime: Runtime[Context] 参数 2. LangGraph 自动注入 Runtime 实例 3. 通过 runtime.context 访问上下文 4. 通过 runtime.store 访问 Store """user_id=runtime.context.user_id namespace=(user_id,"memories")# 从 Store 读取用户记忆memories=awaitruntime.store.asearch(namespace,limit=10)# 构建包含记忆的回复ifmemories:memory_text="我记得以下信息:\n"+"\n".join(f" -{m.value.get('content','')}"forminmemories)else:memory_text="我还没有关于你的记忆。"# 如果有新信息,存入 Storelast_msg=state["messages"][-1]if"记住"inlast_msg.contentor"我叫"inlast_msg.content:awaitruntime.store.aput(namespace,f"memory_{len(memories)+1}",{"content":last_msg.content},)return{"messages":[AIMessage(content=f"收到!{memory_text}")]}# ============================================# 构建图# ============================================store=InMemoryStore()checkpointer=MemorySaver()builder=StateGraph(State)builder.add_node("memory",memory_node)builder.add_edge(START,"memory")builder.add_edge("memory",END)# 编译时传入 store 和 context_schemagraph=builder.compile(checkpointer=checkpointer,store=store,context_schema=Context,)# ============================================# 异步运行# ============================================importasyncioasyncdefmain():config={"configurable":{"thread_id":"mem-001"}}context=Context(user_id="user_123")# 第一次对话result=awaitgraph.ainvoke({"messages":[HumanMessage(content="我叫小明,记住这个")]},config=config,context=context,)print(f"AI:{result['messages'][-1].content}")# 第二次对话(新 thread,但同一 user_id)config2={"configurable":{"thread_id":"mem-002"}}result=awaitgraph.ainvoke({"messages":[HumanMessage(content="你还记得我叫什么吗?")]},config=config2,context=context,)print(f"AI:{result['messages'][-1].content}")asyncio.run(main())
实战 2:语义记忆搜索
fromlanggraph.store.memoryimportInMemoryStore# 创建带语义搜索的 Storestore=InMemoryStore(index={"embed":"openai:text-embedding-3-small",# 嵌入模型"dims":1536,# 嵌入维度"fields":["content","$"],# 要索引的字段})# 存储带语义信息的记忆asyncdefstore_with_semantics():awaitstore.aput(("user_123","memories"),"mem_1",{"content":"用户喜欢喝咖啡,尤其是拿铁"},)awaitstore.aput(("user_123","memories"),"mem_2",{"content":"用户是 Python 程序员"},)awaitstore.aput(("user_123","memories"),"mem_3",{"content":"用户住在北京朝阳区"},)# 语义搜索:自然语言查询results=awaitstore.asearch(("user_123","memories"),query="用户喜欢喝什么饮料?",# 自然语言查询limit=3,)foriteminresults:print(f" [{item.key}]{item.value['content']}")# 输出: [mem_1] 用户喜欢喝咖啡,尤其是拿铁asyncio.run(store_with_semantics())

8.4 API 速查

API完整签名入参说明返回值说明
InMemoryStore()InMemoryStore(index=...)index: 语义搜索配置(可选)Store 对象内存存储
PostgresStore(conn)PostgresStore(conn)conn: 数据库连接Store 对象Postgres 持久化
store.put(namespace, key, value)put(ns: tuple, key: str, value: dict)ns: 命名空间;key: 键;value: 值None存储数据
store.search(namespace, query, limit)search(ns: tuple, query: str, limit: int)ns: 命名空间;query: 查询;limit: 数量结果列表语义搜索(需 index)
store.aget/get/adelete异步版本同上同上节点中异步调用
Runtime[Context]Runtime[Context]Context: 上下文类型运行时对象节点中注入上下文
context_schemacompile(context_schema=Type)context_schema: Context 类型CompiledGraph编译时声明 Context

8.5 错误与避坑指南

坑 1:混淆 Store 和 Checkpoint
# ❌ 错误:把用户偏好存在 Checkpoint 中# Checkpoint 是 thread 级别的,换 thread 就丢失了!classState(TypedDict):user_preferences:dict# 不应该放在 State 中# ✅ 正确:用户偏好存在 Store 中# Store 跨 thread 共享,通过 user_id 隔离awaitstore.aput(("user_123","preferences"),"key",value)
坑 2:命名空间设计不当
# ❌ 错误:所有用户共享命名空间awaitstore.aput(("memories"),"key",value)# 所有用户混在一起# ✅ 正确:按用户 ID 隔离awaitstore.aput(("user_123","memories"),"key",value)awaitstore.aput(("user_456","memories"),"key",value)
坑 3:语义搜索未配置 embedding
# ❌ 错误:没有配置 indexstore=InMemoryStore()# 没有 indexawaitstore.asearch(ns,query="自然语言查询")# 无法语义搜索,只能精确匹配# ✅ 正确:配置 indexstore=InMemoryStore(index={"embed":"openai:text-embedding-3-small","dims":1536,"fields":["content"],})
坑 4:忘记在 compile 时传入 store
# ❌ 错误graph=builder.compile(checkpointer=...)# 节点中 runtime.store 不可用!# ✅ 正确graph=builder.compile(checkpointer=...,store=store,# 必须传入)

8.6 最佳实践总结

  1. 用户级数据用 Store,会话级数据用 Checkpoint:按数据生命周期选择存储
  2. 命名空间使用(user_id, "category")结构:层级隔离,清晰明了
  3. 生产环境使用 PostgresStore 持久化:数据不丢失,支持高并发
  4. 语义搜索时选择合适的 embedding 模型:平衡成本和效果
  5. Context Schema 用于注入运行时信息:如 user_id、tenant_id 等,不需要放在 State 中

相关新闻

  • 金价高位运行!2026东莞黄金回收市场热度飙升,市民闲置变现激增 - 日常比对手册
  • 帝舵2026年7月最新声明:南昌官方售后网点地址及全国统一客服热线查询 - 帝舵中国官方服务中心
  • 亲身到店探访北京宝珀官方售后服务中心|全新维修地址及服务热线(2026年7月最新) - 宝珀官方售后服务中心

最新新闻

  • 2026年潍坊室内装修厂家怎么联系 正规对接渠道实用指南 - 品牌优推
  • Crawl4AI:专为LLM优化的智能网络爬虫工具
  • Linux设备驱动开发实战指南:从入门到精通的完整学习路径
  • 2026最新5款AI编程助手功能深度对比
  • TMS320F2837xS看门狗与中断实战:从寄存器配置到稳定代码
  • 无锡打井怕被坑?两代人做了二三十年的老钻井队靠得住 - 瑞溪泉水利

日新闻

  • AI云原生实战05-金融AI上云最难的不是技术,是“不出事“——TCE银行风控架构拆解
  • 2026年GEOSEO优化公司选型深度测评:五大硬核标准严选,这六家重塑搜索增长新格局 - 品牌前沿专家
  • **核验!2026年7月卡地亚香港**售后网点地址及服务电话公告 - 卡地亚服务中心

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号