Source Bundle

letta 证据页

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

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

原始文档与行号

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

letta.md
`letta`
1
# `letta`
2
3
## 仓库定位
4
5
`letta` 是平台型 agent 系统。和本任务相关的主线至少有四层:`AgentState.memory/blocks` 的核心记忆、`MessageManager + ConversationManager` 的会话上下文、`ArchiveManager + PassageManager` 的长期检索记忆,以及可选的 git-backed memory。
6
7
## 源码架构树
8
9
```text
10
letta
11
├─ schemas/
12
│ ├─ agent.py
13
│ ├─ memory.py
14
│ ├─ message.py
15
│ ├─ conversation.py
16
│ └─ passage.py
17
├─ prompts/prompt_generator.py
18
├─ services/
19
│ ├─ context_window_calculator/
20
│ ├─ message_manager.py
21
│ ├─ conversation_manager.py
22
│ ├─ archive_manager.py
23
│ ├─ passage_manager.py
24
│ ├─ block_manager.py
25
│ └─ block_manager_git.py
26
├─ services/memory_repo/*
27
└─ server/server.py
28
```
29
30
## 关键结论摘要
31
32
- `letta` 的 system prompt 是 `Memory.compile()` 与 `PromptGenerator` 共同生成,再由 `ContextWindowCalculator` 做 token 级拆解和统计。
33
- 会话上下文的真实顺序由 `conversation_messages` 关系表维护,conversation 创建或分叉时会重建并持久化 system message。
34
- 长期记忆由 `Archive` + `Passage` 实现;这条路径与 core blocks memory 并行存在。
35
- 在配置允许时,`BlockManager` 会切换成 `GitEnabledBlockManager`,把 memory 写到 memfs/git repo,再同步 Postgres cache。
36
37
## 专题文档
38
39
- [01-架构与范围](./letta/01-%E6%9E%B6%E6%9E%84%E4%B8%8E%E8%8C%83%E5%9B%B4.md)
40
- [02-context管理](./letta/02-context%E7%AE%A1%E7%90%86.md)
41
- [03-memory实现](./letta/03-memory%E5%AE%9E%E7%8E%B0.md)
42
- [04-存储与状态](./letta/04-%E5%AD%98%E5%82%A8%E4%B8%8E%E7%8A%B6%E6%80%81.md)
43
- [05-调用链、压缩与边界](./letta/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)
44
45
## 关键源码索引
46
47
- `letta/schemas/agent.py:67-206`
48
- `letta/schemas/memory.py:68-688`
49
- `letta/prompts/prompt_generator.py:22-181`
50
- `letta/services/context_window_calculator/context_window_calculator.py:167-249`
51
- `letta/services/conversation_manager.py:222-320`
52
- `letta/services/message_manager.py:122-1262`
53
- `letta/services/block_manager_git.py:30-485`
54
- `letta/services/passage_manager.py:543-640`
55
- `letta/services/archive_manager.py:502-542`
56
- `letta/server/server.py:426-446`
57
58
## 阅读提示
59
60
先看 `02-context管理`,再看 `03-memory实现`。`letta` 里最容易混淆的是 core blocks memory、archive/passage 和记忆仓库 git 路径,它们是并行层,不是同一个对象的三种叫法。
61
letta/01-架构与范围.md
`letta`:架构与范围
1
# `letta`:架构与范围
2
3
## 1. 四层结构
4
5
`letta` 的相关实现可分成四层:
6
7
- `AgentState.memory / blocks`:核心记忆。
8
- `MessageManager + ConversationManager`:消息与会话上下文。
9
- `ArchiveManager + PassageManager`:长期检索记忆。
10
- `GitEnabledBlockManager + memory_repo/*`:可选 git-backed memory。
11
12
### 源码锚点
13
14
- `letta/schemas/agent.py:67-206`
15
- `letta/services/message_manager.py:122-1262`
16
- `letta/services/archive_manager.py:502-542`
17
- `letta/services/block_manager_git.py:30-485`
18
19
## 2. 范围边界
20
21
本组文档重点覆盖:
22
23
- `letta/schemas`
24
- `prompts/prompt_generator.py`
25
- `services/*manager.py`
26
- `context_window_calculator`
27
- `summarizer`
28
- `memory_repo`
29
- `server/server.py`
30
31
### 源码锚点
32
33
- `letta/prompts/prompt_generator.py:22-181`
34
- `letta/services/context_window_calculator/context_window_calculator.py:167-249`
35
- `letta/server/server.py:426-446`
36
37
## 3. 关键边界
38
39
- core blocks memory 不等于 archive/passage。
40
- git-backed memory 是 block memory 的可选后端,不是另一种 archive。
41
- 消息顺序由 `conversation_messages` 关系表维护,不应只看 message 表本身。
42
43
### 源码锚点
44
45
- `letta/schemas/memory.py:68-688`
46
- `letta/services/block_manager_git.py:30-485`
47
- `letta/services/conversation_manager.py:613-713`
48
letta/02-context管理.md
`letta`:context 管理
1
# `letta`:context 管理
2
3
## 1. `AgentState` 与结构化上下文
4
5
`AgentState` 同时携带 `message_ids`、`system`、`memory`、`blocks`、`sources`、`tools`、`compaction_settings` 等字段,说明 `letta` 的上下文不是单一字符串,而是结构化状态对象。
6
7
### 源码锚点
8
9
- `letta/schemas/agent.py:67-206`
10
11
## 2. `Memory.compile()`
12
13
`Memory.compile()` 是核心渲染点:
14
15
- 普通模式输出 `<memory_blocks>`
16
- line-numbered 模式给特定 agent/model 加行号
17
- git 模式把 `system/persona` 渲染为 `<self>`,其他系统文件渲染成 `<memory>` 树
18
- skills 会渲染成 `<available_skills>` 树
19
20
### 源码锚点
21
22
- `letta/schemas/memory.py:68-351`
23
- `letta/schemas/memory.py:351-688`
24
25
## 3. `PromptGenerator`
26
27
`PromptGenerator.compile_memory_metadata_block()` 会注入 `AGENT_ID`、`CONVERSATION_ID`、system prompt 重编译时间、previous message count、archival memory size;`compile_system_message_async()` 再把 `Memory.compile(...)` 的结果与 metadata 拼进 `{CORE_MEMORY}`。
28
29
### 源码锚点
30
31
- `letta/prompts/prompt_generator.py:26-181`
32
33
## 4. conversation 级 system prompt
34
35
`ConversationManager.compile_and_save_system_message_for_conversation()` 会在 conversation 创建或分叉时重建 system message,并作为 message 0 持久化,再把 message id 写进 `conversation_messages`。
36
37
### 源码锚点
38
39
- `letta/services/conversation_manager.py:222-320`
40
- `letta/services/conversation_manager.py:613-713`
41
42
## 5. `ContextWindowCalculator` 与摘要器
43
44
`ContextWindowCalculator` 会拆解 system prompt 的不同组成部分,并分别计算 token 数;`Summarizer` 则负责静态缓冲裁剪和部分驱逐时的递归摘要。
45
46
### 源码锚点
47
48
- `letta/services/context_window_calculator/context_window_calculator.py:167-249`
49
- `letta/services/summarizer/summarizer.py:36-488`
50
letta/03-memory实现.md
`letta`:memory 实现
1
# `letta`:memory 实现
2
3
## 1. core blocks memory
4
5
核心记忆载体是 `Block` / `Memory`。`Block` 具有 `label/value/limit/read_only/description/metadata` 等字段,`BasicBlockMemory` 默认持有 `human` 与 `persona` 两个块。
6
7
### 源码锚点
8
9
- `letta/schemas/block.py:1-134`
10
- `letta/schemas/memory.py:68-143`
11
12
## 2. git-backed memory
13
14
git-backed memory 使用 Markdown + YAML frontmatter 表示 block。`serialize_block()` 会写入 `description/read_only/metadata`,`parse_block_markdown()` 再反向解析;本地 memfs 默认目录在 `~/.letta/memfs`,repo 路径为 `{org_id}/{agent_id}/repo.git`。
15
16
### 源码锚点
17
18
- `letta/services/memory_repo/block_markdown.py:1-153`
19
- `letta/services/memory_repo/memfs_client_base.py:36-208`
20
- `letta/services/memory_repo/path_mapping.py:1-31`
21
22
## 3. `GitEnabledBlockManager`
23
24
`GitEnabledBlockManager` 的策略是 git 为 source of truth、Postgres 为 cache。create/update/delete 先写 memfs,再同步到 Postgres;启用或关闭 git memory 时,还会做 backfill 或回退。
25
26
### 源码锚点
27
28
- `letta/services/block_manager_git.py:30-485`
29
30
## 4. archive / passage 长期记忆
31
32
长期记忆由 `Archive` + `Passage` 实现。`PassageManager.insert_passage()` 会先取或创建默认 archive,再生成 embedding、写 SQL,并在特定 archive 配置下做额外 dual-write。`AgentManager.search_agent_archival_memory_async()` 是统一检索入口。
33
34
### 源码锚点
35
36
- `letta/services/passage_manager.py:543-640`
37
- `letta/services/archive_manager.py:502-542`
38
- `letta/services/agent_manager.py:2534-2620`
39
letta/04-存储与状态.md
`letta`:存储与状态
1
# `letta`:存储与状态
2
3
## 1. SQL / ORM 层
4
5
`letta` 的消息、conversation、archive、passage 等对象都走 ORM / SQL 持久化。与 context 相关的真实顺序由 `conversation_messages` 关系表维护,而不是单看 message 行本身。
6
7
### 源码锚点
8
9
- `letta/services/conversation_manager.py:613-713`
10
- `letta/services/message_manager.py:477-1262`
11
12
## 2. memfs / git repo / Postgres cache
13
14
启用 git-backed memory 后,内存块会写入 memfs 和 git repo,再同步 Postgres cache。`server.py` 会根据配置与 tag 决定是否启用这套路径,并切换对应的 block manager。
15
16
### 源码锚点
17
18
- `letta/server/server.py:155-161`
19
- `letta/server/server.py:426-446`
20
- `letta/services/block_manager_git.py:30-485`
21
22
## 3. context window 相关状态
23
24
`ContextWindowCalculator` 统计的对象包括 system、core memory、filesystem、tool rules、directories、summary、messages、tool definitions。这说明 `letta` 会把 prompt 结构本身当作状态的一部分来做分段计量。
25
26
### 源码锚点
27
28
- `letta/services/context_window_calculator/context_window_calculator.py:167-249`
29
30
## 4. 记忆仓库路径
31
32
本地 memfs 默认落在 `~/.letta/memfs`,并按 `{org_id}/{agent_id}/repo.git` 组织 git repo。skills 目录也会映射成 memory tree 的一部分。
33
34
### 源码锚点
35
36
- `letta/services/memory_repo/memfs_client_base.py:36-208`
37
- `letta/services/memory_repo/path_mapping.py:1-31`
38
letta/05-调用链、压缩与边界.md
`letta`:调用链、压缩与边界
1
# `letta`:调用链、压缩与边界
2
3
## 1. conversation 创建主链
4
5
conversation 创建或分叉时,`ConversationManager` 会重建 system message,把它作为 message 0 写入,再通过 `conversation_messages` 维护真实顺序。后续 `AgentManager.get_context_window()` 再基于该 conversation 做窗口计算。
6
7
### 源码锚点
8
9
- `letta/services/conversation_manager.py:222-320`
10
- `letta/services/conversation_manager.py:613-713`
11
- `letta/services/agent_manager.py:3561-3595`
12
13
## 2. 摘要压缩主链
14
15
`Summarizer` 提供两条路径:固定缓冲裁剪和部分驱逐摘要。它负责把 transcript 送给 LLM 生成 summary message,用于在长对话时减小上下文窗口。
16
17
### 源码锚点
18
19
- `letta/services/summarizer/summarizer.py:36-488`
20
21
## 3. archivial search 主链
22
23
archive / passage 的检索入口统一走 `search_agent_archival_memory_async()`,它会先处理时间和时区过滤,再选择 SQL 或 TPUF 的搜索路径。
24
25
### 源码锚点
26
27
- `letta/services/agent_manager.py:2534-2620`
28
29
## 4. 关键边界
30
31
- core blocks memory、archive/passage 和记忆仓库 git 路径是并行层。
32
- git-backed memory 不是 archive 的另一种名字。
33
- 消息顺序、system prompt 和摘要消息共同参与上下文窗口,而不是由单一 message 列表决定。
34
35
### 源码锚点
36
37
- `letta/schemas/memory.py:68-688`
38
- `letta/services/archive_manager.py:502-542`
39
- `letta/services/block_manager_git.py:30-485`
40
- `letta/services/context_window_calculator/context_window_calculator.py:167-249`
41