🎯 课程主题
理解 LangGraph 中**长期记忆(Long-term Memory)**的概念、适用场景以及存储架构,重点掌握 Store、namespace、key、value 四大核心结构和 InMemoryStore / PostgresStore 两种实现方案。
📝 核心知识点
1. 长期记忆 vs 短期记忆
| 维度 | 短期记忆(State) | 长期记忆(Store) |
|---|---|---|
| 作用域 | 会话(Thread)级别 | 用户/应用级别 |
| 线程共享 | 线程之间不共享 | 任意线程均可访问 |
| 生命周期 | 线程结束时释放 | 跨线程持久存在 |
| LangGraph 载体 | State | Store |
2. 长期记忆存储的数据类型(参考论文分类)
- 语义记忆(Semantic Memory):事实类信息,如用户偏好(简短回答、常用中文)、公司所属行业、用户 VIP 等级等。
- 情景记忆(Episodic Memory):经验类信息,记录 Agent 过去执行的动作和成功案例(few-shot examples),指导未来行为。
- 程序性记忆(Procedural Memory):规则与做事方法,如 Agent 系统提示词、工作流程、工具调用规则等。
3. Store 核心结构
长期记忆基于 LangGraph 提供的 Store 进行存储,包含以下四个核心概念:
| 概念 | 说明 | 类型 |
|---|---|---|
| Store | 对标短期记忆中的 State,由 LangGraph 提供 | InMemoryStore / PostgresStore |
| namespace | 命名空间,层级路径,用于组织和定位数据 | 字符串元组 tuple[str, ...] |
| key | namespace 下的唯一标识符,用于精确查找 | str |
| value | key 对应的存储值 | dict[str, Any] |
4. Store 的两种实现
| 实现类 | 适用场景 | 特点 |
|---|---|---|
InMemoryStore | 开发/测试 | 内存级存储,进程重启后数据丢失 |
PostgresStore | 生产环境 | 持久化到 PostgreSQL 数据库,数据不丢失 |
注意:"长期记忆"≠"持久化存储"。长期记忆强调的是跨线程共享的生命周期,而非存储介质。因此也有 InMemory 和数据库两种方案。
🏗️ 架构与工作流
┌─────────────────────────────────────────────────┐
│ Store │
│ ┌─────────────────────────────────────────────┐ │
│ │ namespace: ("users", "user123", "preferences") │
│ │ ├─ key: "profile" → value: {name, lang} │
│ │ └─ key: "settings" → value: {theme} │
│ ├─────────────────────────────────────────────┤ │
│ │ namespace: ("users", "user456", "preferences") │
│ │ └─ key: "profile" → value: {name, lang} │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
▲ ▲ ▲
│ │ │
Thread 1 Thread 2 Thread N
(State) (State) (State)
- 每个 Thread 持有各自的 State(短期记忆,存放 messages 列表)。
- 所有 Thread 共享同一个 Store 实例(长期记忆)。
- 通过
namespace区分不同用户、组织或业务线。 - 通过
key+namespace精确定位 value。
类比理解
namespace 好比文件系统的层级目录路径,是一个字符串元组:
("users", "bob", "memories")
类似 /users/bob/memories/ 这样的路径结构。key 和 value 则是该路径下实际存储的数据条目。
💻 代码实战
InMemoryStore 示例
from langgraph.store.memory import InMemoryStore
store = InMemoryStore()
# 写入
store.put(
namespace=("users", "user123", "preferences"),
key="profile",
value={"name": "小明", "language": "zh", "vip": True}
)
PostgresStore 示例
from langgraph.store.postgres import PostgresStore
with PostgresStore.from_conn_string("postgresql://...") as store:
store.setup()
store.put(
namespace=("users", "user123", "preferences"),
key="profile",
value={"name": "小明", "language": "zh", "vip": True}
)
三个核心 API 概览
| API | 功能 | 关键参数 |
|---|---|---|
put() | 写入/更新数据 | namespace, key, value, [index], [ttl] |
get() | 精确读取单条数据 | namespace, key |
search() | 多条件检索数据 | namespace_prefix, [query], [filter], [limit], [offset] |
⚠️ 常见问题与避坑指南
- namespace 是元组而非字符串:
namespace=("users",)而非namespace="users"。 - value 必须是字典类型:
value={"key": "val"},不能直接传字符串或列表。 - 开发/测试阶段:优先使用
InMemoryStore,快速迭代,不依赖数据库环境。 - 生产环境:切换到
PostgresStore,确保数据持久化;记得调用setup()初始化表结构。
💡 个人总结与延伸
- 长期记忆解决的核心问题是跨会话/跨线程的数据共享,使 Agent 能够"记住"用户偏好和历史经验。
- namespace 的分层设计提供了灵活的数据组织能力,可按用户、组织、业务线等多维度隔离数据。
- 后续课程将深入讲解
put()、get()、search()三个 API 的具体用法,以及在 Agent 中如何通过工具访问 Store。