记忆块与睡眠时间计算

Build~75 minutesPython (stdlib)先修要求: Phase 14 · 07 (MemGPT)
模型可以直接编辑的离散功能记忆块,以及在主 Agent 空闲时异步整固记忆的睡眠时间 Agent。正是这两个想法,让你把记忆扩展到单次对话之外。
学习目标
  • 说出 Letta 使用的三个记忆层级(核心、回忆、归档)以及各自的职责。
  • 解释记忆块模式:Human 块、Persona 块和用户自定义块都是一等对象。
  • 描述什么是睡眠时间计算,它为什么不在关键路径上,以及它为什么能运行比主 Agent 更强的模型。
  • 实现一个脚本化的双 Agent 循环:主 Agent 负责应答,睡眠时间 Agent 在回合之间整固记忆块。

问题

MemGPT(第 07 课)解决了虚拟内存的控制流。随后出现了三个生产环境问题:

  1. 延迟。 每个记忆操作都在关键路径上。如果 Agent 需要在用户等待时剪枝、摘要或对账,尾延迟就会爆炸。
  2. 记忆腐化。 写入不断累积。被推翻的事实留在原处。检索淹没在陈旧内容里。
  3. 结构丢失。 扁平的归档存储无法表达「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 课同样适用于睡眠时间这一面。
memory-blocks静态版本未包含此交互图

构建它

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 形态的块系统,带睡眠时间钩子,并包含安全规则和引用接线。

练习

  1. 增加一个 block_summarize 工具:当 near_limit 返回 true 时,把块值替换为模型生成的摘要。哪个触发阈值能同时最小化摘要调用和块溢出?
  2. 在归档上实现睡眠时间去重:文本 token 重叠超过 90% 的两条记录合并为一条。只在睡眠处理中做,绝不在关键路径上做。
  3. 给块做版本管理。每次写入都记录旧值和一个 diff。暴露 block_history(label),让运维能调试「Agent 为什么忘了 X」。
  4. 把睡眠时间 Agent 当作不可信写入者。当它们触碰 Persona 或 Safety 块时,提交前要求第二个 Agent 复审。
  5. 把示例移植到 Letta API(letta_v1_agent)。块 schema 有什么变化?原生推理又如何改变轨迹形态?

关键术语

术语人们怎么说实际含义
记忆块(Memory block)「可编辑的 prompt 段落」核心记忆中带类型、持久、LLM 可编辑的片段
Human 块「用户记忆」关于用户的事实,固定在核心中
Persona 块「Agent 身份」自我概念、语气、约束,固定在核心中
睡眠时间计算「异步记忆工作」第二个 Agent 在关键路径之外做整固
核心 / 回忆 / 归档「层级」三层记忆划分:始终可见 / 对话 / 外部
块上限「cap」每个块的字符限制;强制摘要
原生推理「思考通道」提供商层面的推理输出,而非 prompt 层面的 Thought:
学习上下文(Learned context)「睡眠输出」睡眠时间 Agent 写入共享块的事实

延伸阅读

示意图共 1 张

sleep-time-compute diagram
sleep-time-compute

“Stay hungry, stay foolish.”

— Steve Jobs

esc
↑↓切换↵打开esc关闭