Source Bundle

langmem 证据页

来自 docs/langmem 的原始分析文档与行号。

证据页
怎么用这页
  • 左上角是文档名,下面是带行号的原始内容。
  • 学习页里的源码锚点会跳到这里的具体行号。
Docs

原始文档与行号

这些内容直接来自当前仓库的 docs/。

langmem.md
`langmem`
1
# `langmem`
2
3
## 仓库定位
4
5
`langmem` 更像一套 `LangGraph / BaseStore` 上的 memory/context 工具库,而不是单个完整 agent。它把短期摘要、长期 memory 抽取与搜索、后台反射、namespace 隔离拆成独立模块。
6
7
## 源码架构树
8
9
```text
10
langmem
11
├─ short_term/summarization.py
12
│ ├─ RunningSummary
13
│ ├─ summarize_messages()
14
│ └─ SummarizationNode
15
├─ knowledge/extraction.py
16
│ ├─ MemoryManager
17
│ ├─ create_memory_searcher()
18
│ └─ MemoryStoreManager
19
├─ knowledge/tools.py
20
├─ reflection.py
21
├─ utils.py
22
├─ graphs/auth.py
23
└─ langgraph.json
24
```
25
26
## 关键结论摘要
27
28
- `langmem` 的 `context` 主线是短期摘要节点,把旧消息压成 `running_summary`,而不是维护一个完整 agent transcript runtime。
29
- 长期 memory 的核心是 `MemoryManager` 与 `MemoryStoreManager`,它们围绕 `BaseStore` 做抽取、搜索、增删改和写回。
30
- `namespace` 不是硬编码目录,而是从 `RunnableConfig["configurable"]` 动态解析出来。
31
- 后台反射由 `ReflectionExecutor` 管理,可以本地延迟执行,也可以远端触发 LangGraph run。
32
33
## 专题文档
34
35
- [01-架构与范围](./langmem/01-%E6%9E%B6%E6%9E%84%E4%B8%8E%E8%8C%83%E5%9B%B4.md)
36
- [02-context管理](./langmem/02-context%E7%AE%A1%E7%90%86.md)
37
- [03-memory实现](./langmem/03-memory%E5%AE%9E%E7%8E%B0.md)
38
- [04-存储与状态](./langmem/04-%E5%AD%98%E5%82%A8%E4%B8%8E%E7%8A%B6%E6%80%81.md)
39
- [05-调用链、压缩与边界](./langmem/05-%E8%B0%83%E7%94%A8%E9%93%BE%E3%80%81%E5%8E%8B%E7%BC%A9%E4%B8%8E%E8%BE%B9%E7%95%8C.md)
40
41
## 关键源码索引
42
43
- `src/langmem/short_term/summarization.py:53-860`
44
- `src/langmem/knowledge/extraction.py:217-2109`
45
- `src/langmem/knowledge/tools.py:25-515`
46
- `src/langmem/utils.py:15-213`
47
- `src/langmem/reflection.py:90-401`
48
- `src/langmem/graphs/auth.py:13-79`
49
- `langgraph.json:3-11`
50
51
## 阅读提示
52
53
先看 `02-context管理`,再看 `03-memory实现`。`langmem` 最容易被误解成“完整 agent 框架”,但它实际上更像给别的 agent/workflow 提供 memory/context 组件。
54
langmem/01-架构与范围.md
`langmem`:架构与范围
1
# `langmem`:架构与范围
2
3
## 1. 模块分层
4
5
`langmem` 的主干可以按四层理解:
6
7
- `short_term`:短期上下文摘要。
8
- `knowledge`:长期 memory 抽取、搜索、写回与工具封装。
9
- `reflection`:后台或远端执行 memory 处理。
10
- `utils / graphs`:namespace、消息格式化、auth 隔离、LangGraph 挂载。
11
12
### 源码锚点
13
14
- `src/langmem/short_term/summarization.py:53-860`
15
- `src/langmem/knowledge/extraction.py:217-2109`
16
- `src/langmem/reflection.py:90-401`
17
- `src/langmem/utils.py:15-213`
18
19
## 2. 范围边界
20
21
本项目不是单个 agent runtime,没有仓库自定义的本地 SQLite / transcript 层。`langgraph.json` 只负责 graph、auth 和 store 挂载,真正的存储依赖注入式 `BaseStore`。
22
23
### 源码锚点
24
25
- `langgraph.json:3-11`
26
- `src/langmem/graphs/semantic.py:13-41`
27
28
## 3. 关键边界
29
30
- `running_summary` 是 graph state,不是长期 memory。
31
- `BaseStore namespace` 是运行时解析,不是固定目录路径。
32
- `graph_rag.py` 当前只是注释示意,不属于主运行链。
33
34
### 源码锚点
35
36
- `src/langmem/short_term/summarization.py:53-76`
37
- `src/langmem/utils.py:15-87`
38
- `src/langmem/graph_rag.py:1-175`
39
langmem/02-context管理.md
`langmem`:context 管理
1
# `langmem`:context 管理
2
3
## 1. 短期上下文摘要
4
5
`summarize_messages()` 会按 token 预算扫描消息,保留 `SystemMessage`,在达到阈值时把前面的消息压成 summary,并把 summary 作为新的 system message 插入返回结果。如果触发点是带 `tool_calls` 的 AI 消息,还会把对应 `ToolMessage` 一并纳入。
6
7
### 源码锚点
8
9
- `src/langmem/short_term/summarization.py:102-334`
10
- `tests/short_term/test_summarization.py:208-592`
11
12
## 2. `RunningSummary` 与跨轮次状态
13
14
`RunningSummary` 保存 `summary`、`summarized_message_ids`、`last_summarized_message_id`。下一轮会跳过已摘要过的消息,避免重复压缩;消息缺少 `id` 时源码直接报错。
15
16
### 源码锚点
17
18
- `src/langmem/short_term/summarization.py:53-76`
19
- `src/langmem/short_term/summarization.py:137-199`
20
- `tests/short_term/test_summarization.py:592-794`
21
22
## 3. `SummarizationNode`
23
24
`SummarizationNode` 把摘要逻辑包装成 LangGraph 节点,默认从输入 `messages` 读取上下文,把结果写到 `summarized_messages`,并把 `running_summary` 存到 `context`。当输入输出 key 相同时,它会先插入 `RemoveMessage(REMOVE_ALL_MESSAGES)` 来整体替换消息历史。
25
26
### 源码锚点
27
28
- `src/langmem/short_term/summarization.py:660-860`
29
- `tests/short_term/test_summarization.py:794-850`
30
31
## 4. 运行时上下文的另一个入口:namespace 与 conversation 格式化
32
33
`NamespaceTemplate` 从 `RunnableConfig["configurable"]` 动态解析 namespace;`get_conversation()` 把消息转成统一文本;`get_dialated_windows()` 在没有 query model 时提供多尺度最近窗口。
34
35
### 源码锚点
36
37
- `src/langmem/utils.py:15-123`
38
langmem/03-memory实现.md
`langmem`:memory 实现
1
# `langmem`:memory 实现
2
3
## 1. `MemoryManager`
4
5
长期 memory 的最小抽取单元是 `MemoryManager`。它先把消息包装成 conversation 文本,再交给 extractor 按 schema 做抽取、更新、删除;`existing` 提供已有 memories 上下文,`Done` 允许多步收敛,`RemoveDoc` 表达删除语义。
6
7
### 源码锚点
8
9
- `src/langmem/knowledge/extraction.py:217-534`
10
11
## 2. `create_memory_searcher()`
12
13
搜索链路是“先生成 query,再搜 memory”。它通过 prompt + tools 生成 `search_memory` 请求,取回 artifact 后按分数排序;没有单独 query model 时,`MemoryStoreManager` 还会退化为对最近 dilated windows 直接搜索。
14
15
### 源码锚点
16
17
- `src/langmem/knowledge/extraction.py:695-815`
18
- `src/langmem/knowledge/extraction.py:1012-1048`
19
20
## 3. `MemoryStoreManager`
21
22
`MemoryStoreManager` 才是带存储的主链路:先解析 namespace,再从 store 中找候选 memories,然后调用 `MemoryManager` 做增删改整理,最后把 `final_puts / final_deletes` 写回 store。
23
24
关键实现点包括:
25
26
- `_stable_id`:用 `uuid5(namespace,key)` 稳定映射 memory
27
- `default_factory`:无结果时初始化默认 memory
28
- `MemoryPhase`:允许额外整理阶段
29
- `enable_inserts / enable_deletes`:控制模型能否新增或删除
30
31
### 源码锚点
32
33
- `src/langmem/knowledge/extraction.py:832-1280`
34
35
## 4. agent 工具层
36
37
`create_manage_memory_tool` 与 `create_search_memory_tool` 是给上层 agent 调用的工具包装。两者都依赖 `NamespaceTemplate` 注入 namespace,而不是写死到某个固定目录。
38
39
### 源码锚点
40
41
- `src/langmem/knowledge/tools.py:25-355`
42
- `src/langmem/knowledge/tools.py:362-515`
43
langmem/04-存储与状态.md
`langmem`:存储与状态
1
# `langmem`:存储与状态
2
3
## 1. `BaseStore` 是核心后端
4
5
`langmem` 自身没有仓库级 SQLite 或文件型 memory root。长期 memory 的真实落点取决于注入的 `BaseStore`;仓库内的关键状态更多是 graph state 与 runtime config。
6
7
### 源码锚点
8
9
- `src/langmem/knowledge/extraction.py:832-1280`
10
- `langgraph.json:3-11`
11
12
## 2. namespace 由运行时决定
13
14
`NamespaceTemplate` 把模板片段从 `RunnableConfig["configurable"]` 里解析出来,因此同一套代码可以在不同用户、线程、项目下映射到不同的 store namespace。
15
16
### 源码锚点
17
18
- `src/langmem/utils.py:15-87`
19
20
## 3. 后台与远端执行
21
22
`ReflectionExecutor` 负责把 memory 处理延迟到后台。本地实现会把任务放进优先队列并注入 `Runtime(store=...)`;远端实现则通过 LangGraph client 创建远端 run,并携带 `thread_id` 与 namespace。
23
24
### 源码锚点
25
26
- `src/langmem/reflection.py:143-401`
27
28
## 4. auth 隔离
29
30
`graphs/auth.py` 会按用户身份重写 namespace:空 namespace 会自动加上 `ctx.user.identity`,前缀不匹配时也会补用户身份。这意味着存储隔离是权限 / namespace 级别,而不是本地目录级别。
31
32
### 源码锚点
33
34
- `src/langmem/graphs/auth.py:59-79`
35
langmem/05-调用链、压缩与边界.md
`langmem`:调用链、压缩与边界
1
# `langmem`:调用链、压缩与边界
2
3
## 1. 三条主调用链
4
5
- `messages -> summarize_messages / SummarizationNode -> context.running_summary`
6
- `messages + existing memories -> MemoryManager -> MemoryStoreManager -> BaseStore`
7
- `messages -> ReflectionExecutor -> background runnable / remote run`
8
9
### 源码锚点
10
11
- `src/langmem/short_term/summarization.py:337-860`
12
- `src/langmem/knowledge/extraction.py:217-1666`
13
- `src/langmem/reflection.py:143-401`
14
15
## 2. 压缩边界
16
17
`langmem` 的“压缩”主要就是摘要节点本身,而不是完整 agent runtime 里的 transcript compaction。它处理的是“如何把旧消息压成继续可用的 summary”,不是“如何重写 thread 历史文件”。
18
19
### 源码锚点
20
21
- `src/langmem/short_term/summarization.py:102-334`
22
23
## 3. 关键边界
24
25
- `graph_rag.py` 当前不是主链。
26
- 许多行为依赖测试确认,例如 tool calls、重复 ID、same-key overwrite。
27
- 这是一套 memory/context 组件,不负责完整 agent 生命周期。
28
29
### 源码锚点
30
31
- `src/langmem/graph_rag.py:1-175`
32
- `tests/short_term/test_summarization.py:70-850`
33
- `tests/short_term/test_summarization_async.py:72-796`
34