- 说出 Letta 使用的三个记忆层级(核心、回忆、归档)以及各自的职责。
- 解释记忆块模式:Human 块、Persona 块和用户自定义块都是一等对象。
- 描述什么是睡眠时间计算,它为什么不在关键路径上,以及它为什么能运行比主 Agent 更强的模型。
- 实现一个脚本化的双 Agent 循环:主 Agent 负责应答,睡眠时间 Agent 在回合之间整固记忆块。
问题
MemGPT(第 07 课)解决了虚拟内存的控制流。随后出现了三个生产环境问题:
- 延迟。 每个记忆操作都在关键路径上。如果 Agent 需要在用户等待时剪枝、摘要或对账,尾延迟就会爆炸。
- 记忆腐化。 写入不断累积。被推翻的事实留在原处。检索淹没在陈旧内容里。
- 结构丢失。 扁平的归档存储无法表达「Human 块始终在 prompt 里;Persona 块始终在 prompt 里;Task 块按会话替换」。
Letta(letta.com)是原 MemGPT 项目在 2024 年采用的平台名称——论文中的模式仍保留 MemGPT 这个名字——2026 年的 Letta V1 重写是更晚的独立步骤。记忆块让结构显式化;睡眠时间计算把整固移出关键路径。
概念
三个层级
| 层级 | 作用域 | 位置 | 由谁写入 |
|---|---|---|---|
| 核心 | 始终可见 | 主 prompt 内部 | Agent tool call + 睡眠时间重写 |
| 回忆 | 对话历史 | 可检索 | 自动回合日志 |
| 归档 | 任意事实 | 向量 + KV + 图 | Agent tool call + 睡眠时间摄入 |
核心对应 MemGPT 的 core。回忆是带被驱逐尾部的对话缓冲区。归档是外部存储。这一划分清理了 MemGPT 两级结构的过载问题。
记忆块
块是核心层级中带类型、持久、可编辑的段落。原 MemGPT 论文定义了两个:
- Human 块 —— 关于用户的事实(姓名、角色、偏好、目标)。
- Persona 块 —— Agent 的自我概念(身份、语气、约束)。
Letta 将其推广为任意用户自定义块:用 Task 块表示当前目标,用 Project 块表示代码库事实,用 Safety 块表示硬约束。每个块都有 id、label、value、limit(字符上限)、description(让模型知道何时该编辑它)。
块通过工具面编辑:
block_append(label, text)block_replace(label, old, new)block_read(label)block_summarize(label)—— 压缩接近上限的块。
睡眠时间计算
2025 年 Letta 的补充:在后台、关键路径之外运行第二个 Agent。睡眠时间 Agent 处理对话记录和代码库上下文,把 learned_context 写入共享块,并整固或失效归档记录。
随之而来的特性:
- 没有延迟成本。 主应答不等待记忆操作。
- 允许使用更强的模型。 睡眠时间 Agent 可以是更贵、更慢的模型,因为它不受延迟约束。
- 天然的整固窗口。 在用户不等待时去重、摘要、失效被推翻的事实。
这个形态和人类的工作方式一致:你先做事,睡一觉,长期记忆在一夜之间沉淀。
原生推理
Letta V1(letta_v1_agent,2026)弃用 send_message/心跳和内联的 Thought: token,改用原生推理。Responses API(OpenAI)和带扩展思考的 Messages API(Anthropic)在独立通道上输出推理,跨回合传递(生产环境中在提供商之间加密)。控制循环仍是 ReAct。思考轨迹是结构性的,而不是 prompt 形态的。
这个模式会在哪里出错
- 块膨胀。 无限制的
block_append很快触到上限。在导致超限的写入之前接上块摘要器。 - 静默漂移。 睡眠时间 Agent 重写了一个块,主 Agent 却从未察觉。给块做版本管理,并在轨迹中展示 diff。
- 被投毒的整固。 睡眠时间 Agent 把攻击者可触达的内容处理进核心。第 27 课同样适用于睡眠时间这一面。
构建它
code/main.py 实现了:
Block—— id、label、value、limit、description。BlockStore—— CRUD +near_limit(label)辅助方法。- 两个脚本化 Agent ——
PrimaryAgent处理一个回合,SleepTimeAgent在回合之间整固。 - 一段轨迹,展示带块写入的三回合对话,以及一次摘要某个块并失效某条陈旧事实的睡眠时间处理。
运行它:
python3 code/main.py运行记录展示了这种分工:主回合很快并产生原始写入;睡眠处理负责压实和清理。
使用它
- Letta(letta.com)作为参考实现。可自托管或使用托管云。
- Claude Agent SDK 技能作为块形态的知识——技能就是一个命名、带版本、可检索的指令块,Agent 按需加载。
- 自建方案适用于希望控制存储后端的团队。遵循 Letta API 契约,以便日后迁移。
交付它
outputs/skill-memory-blocks.md 为任意运行时生成 Letta 形态的块系统,带睡眠时间钩子,并包含安全规则和引用接线。
练习
- 增加一个
block_summarize工具:当near_limit返回 true 时,把块值替换为模型生成的摘要。哪个触发阈值能同时最小化摘要调用和块溢出? - 在归档上实现睡眠时间去重:文本 token 重叠超过 90% 的两条记录合并为一条。只在睡眠处理中做,绝不在关键路径上做。
- 给块做版本管理。每次写入都记录旧值和一个 diff。暴露
block_history(label),让运维能调试「Agent 为什么忘了 X」。 - 把睡眠时间 Agent 当作不可信写入者。当它们触碰 Persona 或 Safety 块时,提交前要求第二个 Agent 复审。
- 把示例移植到 Letta API(
letta_v1_agent)。块 schema 有什么变化?原生推理又如何改变轨迹形态?
关键术语
| 术语 | 人们怎么说 | 实际含义 |
|---|---|---|
| 记忆块(Memory block) | 「可编辑的 prompt 段落」 | 核心记忆中带类型、持久、LLM 可编辑的片段 |
| Human 块 | 「用户记忆」 | 关于用户的事实,固定在核心中 |
| Persona 块 | 「Agent 身份」 | 自我概念、语气、约束,固定在核心中 |
| 睡眠时间计算 | 「异步记忆工作」 | 第二个 Agent 在关键路径之外做整固 |
| 核心 / 回忆 / 归档 | 「层级」 | 三层记忆划分:始终可见 / 对话 / 外部 |
| 块上限 | 「cap」 | 每个块的字符限制;强制摘要 |
| 原生推理 | 「思考通道」 | 提供商层面的推理输出,而非 prompt 层面的 Thought: |
| 学习上下文(Learned context) | 「睡眠输出」 | 睡眠时间 Agent 写入共享块的事实 |
延伸阅读
- Letta, Memory Blocks 博客 —— 块模式
- Letta, Sleep-time Compute 博客 —— 异步整固
- Letta, Rearchitecting the Agent Loop —— 原生推理重写
- Packer 等,MemGPT(arXiv:2310.08560) —— 源头