Source Bundle

mem0 证据页

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

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

原始文档与行号

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

mem0.md
`mem0`
1
# `mem0`
2
3
## 仓库定位
4
5
`mem0` 的核心是 Python OSS 实现里的 `Memory / AsyncMemory`。它不是完整 thread runtime,而是围绕“抽取式长期记忆”组织的能力层:用最近消息窗口和已有 memories 构造抽取上下文,再把结果落到向量库、SQLite history/messages 和 entity store。
6
7
## 源码架构树
8
9
```text
10
mem0
11
├─ mem0/memory/main.py
12
│ ├─ Memory / AsyncMemory
13
│ ├─ add/search/update/delete/history/reset
14
│ └─ procedural memory
15
├─ mem0/memory/storage.py
16
├─ mem0/memory/utils.py
17
├─ mem0/configs/prompts.py
18
├─ mem0/configs/base.py
19
└─ mem0/utils/factory.py
20
```
21
22
## 关键结论摘要
23
24
- `context` 管理的重点不是长对话缓存,而是“为抽取 memory 准备的上下文窗口”:最近 10 条消息 + 最近 10 条已有 memories。
25
- memory 持久化至少分三层:向量库存 memory 本体、SQLite 存 `history/messages`、entity store 存实体到 memory 的链接。
26
- 没有统一的对话 compaction 主线;只有 procedural memory 会显式走总结式生成。
27
- `Memory` 与 `AsyncMemory` 的算法基本一致,差别主要是异步包装,而不是两套不同设计。
28
29
## 专题文档
30
31
- [01-架构与范围](./mem0/01-%E6%9E%B6%E6%9E%84%E4%B8%8E%E8%8C%83%E5%9B%B4.md)
32
- [02-context管理](./mem0/02-context%E7%AE%A1%E7%90%86.md)
33
- [03-memory实现](./mem0/03-memory%E5%AE%9E%E7%8E%B0.md)
34
- [04-存储与状态](./mem0/04-%E5%AD%98%E5%82%A8%E4%B8%8E%E7%8A%B6%E6%80%81.md)
35
- [05-调用链、压缩与边界](./mem0/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)
36
37
## 关键源码索引
38
39
- `mem0/memory/main.py:268-1687`
40
- `mem0/memory/storage.py:11-257`
41
- `mem0/memory/utils.py:61-170`
42
- `mem0/configs/prompts.py:947-1016`
43
- `mem0/configs/base.py:13-13`
44
- `mem0/utils/factory.py:30-30`
45
46
## 阅读提示
47
48
阅读时要先把“抽取时上下文窗口”与“memory 本体存储”分开;否则很容易把 SQLite `messages/history` 误看成长久 memory 本身。
49
mem0/01-架构与范围.md
`mem0`:架构与范围
1
# `mem0`:架构与范围
2
3
## 1. 主体结构
4
5
Python OSS 核心里最重要的模块有:
6
7
- `Memory / AsyncMemory`
8
- `storage.py` 的 SQLite 历史与消息窗口
9
- `utils.py` 的消息预处理
10
- `configs/prompts.py` 的抽取 prompt
11
- `utils/factory.py` 的 embedder / llm / vector store / reranker 工厂
12
13
### 源码锚点
14
15
- `mem0/memory/main.py:268-1687`
16
- `mem0/memory/storage.py:11-257`
17
- `mem0/memory/utils.py:61-170`
18
- `mem0/configs/prompts.py:947-1016`
19
- `mem0/utils/factory.py:30-30`
20
21
## 2. 范围边界
22
23
本组文档主分析对象只覆盖 Python OSS 核心 `mem0/`。`mem0-ts`、`server`、`vercel-ai-sdk`、`openmemory` 只在附录或横向对照里顺带点到,不按同等深度展开。
24
25
### 源码锚点
26
27
- `mem0/__init__.py:1-1`
28
29
## 3. 关键边界
30
31
- `context` 主要服务 memory 抽取,而不是完整对话 runtime。
32
- SQLite `history/messages` 不是 long-term memory 本体。
33
- 向量库 + entity store 才是长期记忆主体。
34
35
### 源码锚点
36
37
- `mem0/memory/main.py:424-618`
38
- `mem0/memory/storage.py:150-257`
39
- `mem0/memory/main.py:327-327`
40
mem0/02-context管理.md
`mem0`:context 管理
1
# `mem0`:context 管理
2
3
## 1. `session_scope`
4
5
`add()` 要求至少提供 `user_id`、`agent_id`、`run_id` 之一,再把这些字段与 metadata 组合成稳定的 `session_scope` 字符串。SQLite 的消息窗口就是按这个 scope 隔离的。
6
7
### 源码锚点
8
9
- `mem0/memory/main.py:254-254`
10
- `mem0/memory/main.py:424-424`
11
12
## 2. 最近消息窗口
13
14
当前写入链路只保存每个 `session_scope` 最近 10 条消息。`save_messages()` 写入后会裁剪旧记录,`get_last_messages()` 则按时间顺序返回最近 N 条。
15
16
### 源码锚点
17
18
- `mem0/memory/storage.py:257-257`
19
20
## 3. 上下文预处理
21
22
`parse_messages()` 会把消息扁平化成统一文本;视觉消息则先经过 `parse_vision_messages()` 转成文本描述,再进入抽取流程。
23
24
### 源码锚点
25
26
- `mem0/memory/utils.py:61-170`
27
28
## 4. 抽取 prompt
29
30
`generate_additive_extraction_prompt()` 支持把 `Summary`、`Last k Messages`、`Recently Extracted Memories`、`Existing Memories`、`New Messages` 等信息拼进 prompt。但当前 `add()` 主路径实际只传了 `existing_memories`、`last_k_messages` 和 `custom_instructions`。
31
32
### 源码锚点
33
34
- `mem0/configs/prompts.py:947-1016`
35
- `mem0/memory/main.py:513-618`
36
37
## 5. agent-scoped context 后缀
38
39
`AGENT_CONTEXT_SUFFIX` 只在存在 `agent_id` 且不存在 `user_id` 时追加,说明 `mem0` 对“agent 级上下文”有单独 prompt 分支。
40
41
### 源码锚点
42
43
- `mem0/memory/main.py:575-575`
44
- `mem0/configs/prompts.py:947-947`
45
mem0/03-memory实现.md
`mem0`:memory 实现
1
# `mem0`:memory 实现
2
3
## 1. 写入主链
4
5
memory 写入的主链路是:
6
7
`检索旧 memories -> LLM 抽取 -> 批量 embed -> 去重 -> 向量库插入 -> SQLite history 落表 -> entity 链接`
8
9
### 源码锚点
10
11
- `mem0/memory/main.py:513-513`
12
13
## 2. 去重与 payload
14
15
去重依赖 `md5(text)`:先和已有 memories 的 hash 比,再和当前 batch 的 `seen_hashes` 比。写入 payload 时会保存 `data`、`hash`、`created_at`、`updated_at`、`text_lemmatized`,并把 `user_id / agent_id / run_id / actor_id / role` 等元数据提升到顶层。
16
17
### 源码锚点
18
19
- `mem0/memory/main.py:640-640`
20
- `mem0/memory/main.py:1400-1400`
21
22
## 3. 检索
23
24
`search()` 不是单一路径,而是混合检索:语义检索 + `keyword_search()` + BM25 + entity boost,再可选 rerank。过滤器支持 `eq/ne/gt/gte/lt/lte/in/nin/contains/icontains`、布尔组合和 wildcard。
25
26
### 源码锚点
27
28
- `mem0/memory/main.py:959-1152`
29
- `mem0/memory/main.py:1056-1056`
30
31
## 4. entity store 与 procedural memory
32
33
`entity_store` 是懒加载的独立 collection,名字为 `<collection_name>_entities`。`procedural_memory` 则是独立分支,用系统 prompt 生成一段总结式 memory,再作为普通 memory 写入。
34
35
### 源码锚点
36
37
- `mem0/memory/main.py:327-327`
38
- `mem0/memory/main.py:1432-1432`
39
40
## 5. 更新、删除与历史
41
42
`history()` 读的是 SQLite 历史表;`add / update / delete` 都会写 history。`update()` 会保留旧 memory 的 `created_at` 和会话标识,`delete()` 会先读旧记录再写历史。
43
44
### 源码锚点
45
46
- `mem0/memory/storage.py:150-150`
47
- `mem0/memory/main.py:1315-1552`
48
mem0/04-存储与状态.md
`mem0`:存储与状态
1
# `mem0`:存储与状态
2
3
## 1. 默认目录
4
5
`MEM0_DIR` 和默认 `history_db_path` 定义在配置层;`memory/setup.py` 会创建 `~/.mem0` 和 `config.json`。这套目录是 Python OSS 核心的本地状态根。
6
7
### 源码锚点
8
9
- `mem0/configs/base.py:13-13`
10
- `mem0/memory/setup.py:12-12`
11
12
## 2. SQLite 历史与消息窗口
13
14
`storage.py` 维护两类表:
15
16
- `history`:记录 add/update/delete 等历史动作
17
- `messages`:保存最近消息窗口
18
19
它们属于运行时辅助状态,不是长期 memory 本体。
20
21
### 源码锚点
22
23
- `mem0/memory/storage.py:11-257`
24
25
## 3. 向量库与路径
26
27
向量库后端由 `VectorStoreFactory` 和各 provider config 决定,本地文件型 provider 会补默认路径。长期 memory 本体主要驻留在向量库,而不是 SQLite。
28
29
### 源码锚点
30
31
- `mem0/utils/factory.py:30-30`
32
- `mem0/vector_stores/configs.py:6-6`
33
- `mem0/vector_stores/faiss.py:131-131`
34
35
## 4. entity collection
36
37
除了 memory 主 collection 之外,`entity_store` 还维护独立实体集合,用于把相关 memories 聚合到实体层。
38
39
### 源码锚点
40
41
- `mem0/memory/main.py:327-327`
42
mem0/05-调用链、压缩与边界.md
`mem0`:调用链、压缩与边界
1
# `mem0`:调用链、压缩与边界
2
3
## 1. `add()` 的调用链
4
5
`add()` 的核心流程是:
6
7
1. 解析 filters 与 `session_scope`
8
2. 读取最近消息窗口与已有 memories
9
3. 组装抽取 prompt
10
4. 调用 LLM 抽取
11
5. 去重、embed、写向量库
12
6. 写 SQLite history/messages
13
7. 更新 entity links
14
15
### 源码锚点
16
17
- `mem0/memory/main.py:424-618`
18
- `mem0/memory/main.py:640-1400`
19
20
## 2. `search()` 的调用链
21
22
搜索链路是:
23
24
`向量语义检索 -> keyword_search -> BM25 归一化 -> entity boost -> rerank`
25
26
因此它不是纯向量搜索。
27
28
### 源码锚点
29
30
- `mem0/memory/main.py:959-1152`
31
32
## 3. 异步实现的边界
33
34
`AsyncMemory` 不是另一套算法,主要通过异步包装和 `to_thread()` 复用同步逻辑。因此在行为分析上,同步版和异步版可以视为同一实现的两种运行方式。
35
36
### 源码锚点
37
38
- `mem0/memory/main.py:1687-1687`
39
40
## 4. 关键边界
41
42
- 没有完整 conversation compaction 主线。
43
- `history/messages` 是辅助上下文,不是长期 memory 本体。
44
- procedural memory 是单独的摘要式写入分支。
45
46
### 源码锚点
47
48
- `mem0/memory/main.py:1432-1432`
49
- `mem0/memory/storage.py:11-257`
50