langmem 学习页

langmem 不是完整 agent,而是一套围绕 LangGraph / BaseStore 的短期摘要、长期 memory、反射执行和 namespace 隔离组件。

它更像可嵌入的 memory 能力层:短期上下文通过 RunningSummary 压缩,长期记忆通过 MemoryManager / BaseStore 写回,隔离和路由则交给 namespace 与 auth。

源码事实Memory / Context 能力层
这页怎么读
  • 先看“这一轮模型看到了什么”,建立模型视角。
  • 再看 context 和 memory 两张图,抓主链。
  • 最后看源码锚点和证据页,确认细节。
01

这一轮模型到底看到了什么

这一段只讲模型真正可见的材料,不把所有底层状态都算进 context。

context 组成图

短期摘要、长期记忆检索和命名空间路由是三条同时作用的链。

messages
原始消息流。
SummarizationNode
先把旧消息压成 running_summary。
MemoryManager
抽取新增、更新、删除候选。
MemoryStoreManager
拉取并整理 store 里的候选记忆。
NamespaceTemplate
决定写到哪个空间。
BaseStore
长期记忆真实落点。
  • 模型主要看到的是消息流,而不是完整仓库状态;短期部分会被压成 running_summary 再继续参与推理。
  • 触发摘要时,旧消息会被压缩为新的 system message;SystemMessage 会被保留,相关 ToolMessage 也可能一起进入摘要。
  • 长期记忆不是直接暴露整个存储,而是通过 MemoryManager 结合 existing memories、schema 和抽取结果进入模型处理链。
  • 搜索记忆时,模型先生成 query,再由工具链去检索 memory,返回的是筛选后的候选结果。
  • 运行时可见的 namespace 来自 RunnableConfig["configurable"],同一套逻辑会映射到不同存储空间。
  • 后台反射不是前台主链的一部分,模型通常只感知处理结果。
02

context 是怎么拼起来的

先看组成块,再看顺序。这里最容易帮助普通读者分清“哪些东西会真的进模型”。

短期摘要层

把历史消息压成可继续使用的 running_summary,控制上下文长度。

context

长期 memory 层

从对话中抽取、更新、删除可持久化记忆。

memory

搜索层

先生成 query,再从 memory store 检索相关候选。

retrieval

运行时命名空间层

根据 RunnableConfig[configurable] 动态解析 namespace。

routing

后台反射层

把 memory 处理延后到后台或远端执行。

execution

存储与隔离层

长期状态落在注入式 BaseStore,并受 auth/namespace 约束。

storage
  1. 读取 messages 和运行时配置,先解析 namespace 和当前上下文边界。
  2. summarize_messages() 或 SummarizationNode 先把旧消息压缩成 running_summary。
  3. MemoryManager 将对话文本与 existing memories 交给抽取器,产出新增、更新、删除候选。
  4. MemoryStoreManager 从 BaseStore 拉取候选 memory,再做整理、筛选和稳定定位。
  5. 生成 final_puts / final_deletes,把结果写回 BaseStore。
  6. 若启用异步链路,ReflectionExecutor 会把后续处理交给后台或远端 run。
03

memory 是怎么形成、保存、再被取回的

不要把记忆想成一个抽象黑盒。这里直接按时间顺序讲“它什么时候生成、存哪、怎么再回来”。

memory 流程时间线

langmem 的 memory 更像图节点与 store 管理器的协作,而不是一个统一数据库动作。

捕获消息
先拿到 messages 和运行时配置。
抽取候选 memory
按 schema 生成候选。
稳定 ID 定位
判断新增、更新还是删除。
final_puts / final_deletes
整理最终变更集。
写回 BaseStore
把长期记忆持久化。
下轮搜索召回
通过 search tools 再拿回来。
  1. 从对话中识别出值得保留的事实、偏好或任务状态。
  2. 抽取器按 schema 生成 memory 候选,并结合已有记忆判断是新增、更新还是删除。
  3. 通过稳定 ID 逻辑把同一条 memory 固定映射到同一位置。
  4. 需要时经过 MemoryPhase 做额外整理,空结果则可由 default_factory 初始化。
  5. 将最终变更整理成 final_puts / final_deletes。
  6. 写入 BaseStore,下一轮通过搜索链路再次被召回或更新。
04

存储分层图

很多误解都来自把 transcript、summary、文件、数据库和向量库混成一层看。

存储分层图

短期状态、命名空间、隔离和长期存储分别属于不同层,不是同一块数据库。

Graph state
messages、running_summary、summarized_messages。
Runtime config
configurable 决定线程与 namespace 参数。
Namespace + auth
负责路由和隔离。
BaseStore backend
长期记忆真正的后端。
ReflectionExecutor
后台或远端执行层。
  • Graph state:保存短期运行态,例如 messages、running_summary、summarized_messages。
  • Runtime config:RunnableConfig[configurable] 决定 namespace、线程和上下文参数。
  • Namespace layer:NamespaceTemplate 把运行时变量拼成目标 namespace。
  • Auth layer:graphs/auth.py 按身份重写或补全 namespace,做访问隔离。
  • BaseStore layer:长期 memory 的真实落点由外部注入,仓库本身不自带本地 SQLite 或文件根。
  • Background layer:ReflectionExecutor 负责把处理放到后台队列或远端 run 中。
05

哪些东西最容易被误认为 memory

这部分是防误解,不是额外功能清单。

常见误解

把 langmem 当成完整 agent runtime,而不是 memory/context 组件。

  • 把 running_summary 误认为长期记忆。
  • 硬编码 namespace,忽略 RunnableConfig[configurable] 的动态解析。
  • 以为仓库自带本地持久化存储,实际上真正后端是注入式 BaseStore。
  • 忽略消息 id,导致摘要去重和增量压缩出错。

读完应记住的 3 件事

先理解短期上下文,再看长期 memory,最后看存储与后台执行。

  • langmem 的核心边界是“把记忆组件拆开组合”,不是“提供一个完整 agent”。
  • 真正值得记住的是:摘要归摘要,记忆归记忆,持久化归 BaseStore,隔离归 namespace/auth。
06

关键源码位置

每个结论都要能往下追。这里列的都是站内证据入口,不是营销材料。

07

回到原始 docs 深挖

如果你想继续看原文、行号和分专题分析,可以直接跳到证据页。

证据页

站内会把这个 repo 对应的 docs 文件按行展开,方便核对路径和行号。

原始文档清单

你也可以直接从总览、仓库入口页和 5 篇专题页继续追。

  • 仓库入口页
  • 01-架构与范围
  • 02-context管理
  • 03-memory实现
  • 04-存储与状态
  • 05-调用链、压缩与边界