Agent Memory — 三层架构与工具栈
Agent Memory — 三层架构与工具栈
Agent 跑 5 步还行,50 步 context 爆——大多数人第一反应「换 1M context 模型」。但 1M 跑 50 步成本是 200K 跑 5 步的 100 倍以上,且 Lost in the Middle 在 1M 下更严重。正确方向是给 agent 加分层 memory,不是加 context 预算。
三层 memory — 按生命周期分
借 OS 术语。Letta 项目(GitHub)按这个隐喻设计:
| 层 | 生命周期 | OS 类比 | 装什么 | 大小 |
|---|---|---|---|---|
| Scratchpad | 单 task | CPU 寄存器 | tool call 中间结果、临时变量 | 1-10K |
| Working | 单 session | RAM | 对话历史、task plan、用户 input | 5-50K |
| Persistent | 跨 session | 磁盘 | 用户偏好、学到的事实、过去 task 摘要 | 无上限 |
每层工具栈不同——混在一起就是「context 爆」的根因。
Layer 1: Scratchpad — Task 内临时
放什么:search tool 返回结果、markdown 表格中间产物、top 3 判断推理。
Scratchpad 不用 memory 服务——活在当前 task 的 messages array。tool 调用完,结果作为 tool_result 塞回 messages,下轮 LLM 看得到。
- 单 task 完成后丢弃
- Token 上限 10K,超了拆 sub-task(第 9 章)
- task 30 步后 scratchpad 还膨胀——task 该拆,不是 memory 该升级
JR omni-report「Phase 0/1/2/3/4」就是 scratchpad pattern——每 phase commit,下一 phase 重读 git 不读上一 phase scratchpad,避免污染。
Layer 2: Working memory — Session 内滚动
放什么:本会话所有轮次、多步 task 的 plan、session 级配置(语言偏好、详细度)。
简单:滚动窗口
保留最近 N 轮,更早截断。LangChain 的 ConversationBufferWindowMemory:
# tested: 2026-04-26 · langchain@0.3.x
from langchain.memory import ConversationBufferWindowMemory
memory = ConversationBufferWindowMemory(k=10) # 只留最近 10 轮
适合:短对话、Q&A 助手。不适合:回顾 30 轮前细节。
进阶:滚动 + 历史摘要
最近 N 轮原文 + 更早轮次用便宜模型(Haiku)压成摘要塞 system prompt。LangChain ConversationSummaryBufferMemory、LlamaIndex ChatSummaryMemoryBuffer 都做这个。
约束:摘要有信息损失,精确数字、引用、代码片段的轮次不能压。
Anthropic 原生:Message Batches API
100K+ 轮次(极少数)走 Anthropic Message Batches API 异步处理整段 history 做 RAG-on-history。
Layer 3: Persistent memory — 跨 session
放什么:用户偏好(语言、风格、专业领域)、学到的事实(在 X 公司、做 Y 业务、关注 Z 议题)、之前 task 的成果摘要(不是原文)。
production agent vs toy demo 的最大区别。只有 persistent memory 能让 agent 跨会话「记得」。
Mem0 — arXiv:2504.19413
提取-更新两阶段:对话结束 extraction 抽 salient facts,update phase 用 LLM 决定 add / update / delete / no-op。Mem0 实测:vs OpenAI 默认 thread memory,准确率高 26%,p95 延迟低 91%,token 省 90%+。
# tested: 2026-04-26 · mem0ai@0.1.x
from mem0 import Memory
m = Memory()
m.add("用户在悉尼工作,做 AI engineer", user_id="alice")
results = m.search("alice 在哪个城市", user_id="alice")
# → "用户在悉尼工作"
Letta — GitHub
OS 三层(core + archival + recall)。Letta benchmark:plain filesystem(每个 user 一个 markdown 文件)74% 准确率,打败不少 specialized vector store memory 库——简单做法常常够用。
OpenAI Threads / Anthropic Conversation API
OpenAI Assistants thread 自带 persistent context。Anthropic 无等价 thread,但 prompt caching 5 分钟 TTL + 自存 history 等价。
自建 — Filesystem / DB
每个 user 一个 markdown 文件,conversation 结束 LLM 写 summary 到末尾,检索时 read 整个文件塞 context。Letta benchmark 证明 user-level state ≤ 10K 字时比 vector store 准。
JR 真实案例:skills-data-manager 的 prod-state.json
JR Academy skills-data-manager(tools/skills-data-manager/)做 bootcamp 课程同步——本地编辑、diff prod、一键同步。persistent memory:
curriculum/{bootcamp-slug}/public/prod-state.json
└─ 每次从 prod 拉数据回来时缓存的「最后已知 prod 状态」
└─ next diff 用本地内容 - prod-state 算变化
└─ 跨 session 持久化,避免每次都拉 prod
「filesystem as persistent memory」的活案例——一个 JSON 文件就是 persistent memory,简单、可调试、可 git 跟踪。memory entry 爆到 1000+ 条且需按语义召回时才升级到 Mem0/Letta。别为「未来可能需要」提前上 memory 服务。
Mem0/Letta vs DIY filesystem — Trade-off
| 维度 | Managed(Mem0 / Letta) | DIY filesystem |
|---|---|---|
| 接入 | < 1 天 | 1-3 天 |
| 召回质量 | 26% > baseline | < 100 entry 同等;> 1000 落后 |
| 延迟 | 100-500ms | 5-50ms |
| 成本 | $0.01-0.10/MAU + token | 0 |
| 可调试 | 黑盒 | 100% 可读 |
| 数据合规 | 离开公司 | 可控 |
| Multi-user | 内置 user_id 隔离 | 自己写 |
| 适合 | 100+ user × 频繁会话 | < 100 user / 内部工具 |
JR 规则:先 filesystem,跑 3 个月看 entry 数 + 召回质量,超阈值再迁 Mem0。Letta 74% filesystem score 是这个规则的根据。
一句话带走
Memory 不是一种东西,是三种:scratchpad(task 内)/ working(session 内)/ persistent(跨 session)。混在一起处理就是 context 爆。Production agent 必须分层——scratchpad 走 messages array,working 走滚动窗口 + 摘要,persistent 先 filesystem 后 Mem0。
引用来源
- Mem0 team. (2025-04-28). Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory. arXiv:2504.19413.
- Mem0 research benchmark. Benchmarking Mem0's token-efficient memory algorithm — 26% acc / 91% latency / 90% token 节省 vs OpenAI baseline.
- Letta. Letta documentation — OS-inspired 三层 memory(core / archival / recall)+ filesystem 74% benchmark surprise.
- LangChain. Migrating from ConversationSummaryBufferMemory — 滚动 + 摘要 working memory pattern.
- Anthropic. Message Batches API — 异步处理超长 conversation.
- mem0ai. GitHub — Mem0 开源实现.
Production case: JR Academy skills-data-manager(tools/skills-data-manager/)— prod-state.json 作为 filesystem persistent memory.
📚 相关资源
❓ 常见问题
关于本章主题最常被搜索的问题,点击展开答案
为什么 agent 不能用 1M context 模型一劳永逸?
1M context 不解决问题:200K → 1M 成本涨 5×,Lost in the Middle 在 1M 下更严重(中段失明范围更广)。正确方向是给 agent 加分层 memory(scratchpad / working / persistent),不是给 context 加预算。
Mem0 和 Letta 哪个适合我的项目?
按用户量分:< 100 user 用 filesystem,> 1000 user 用 Mem0。Mem0 用 extraction-update 两阶段,vs OpenAI baseline 准确率高 26%、p95 延迟低 91%、token 成本省 90%。Letta 走 OS 三层(core/archival/recall)但 benchmark 显示 plain filesystem 拿 74% 反超 vector store。
Working memory 和 persistent memory 边界在哪?
按生命周期切:Working = 当前 session 内的滚动 context(用 LangChain ConversationSummaryBufferMemory 摘要更早轮次),Persistent = 跨 session 的事实库(用户偏好、学到的事实、之前 task 的成果摘要)。Session 结束 working 清空,persistent 保留到下次。
做单人助手类产品 memory 三层都要做吗?
不需要:单人助手最少 working + persistent 两层够。Working 用 LangChain ConversationSummaryBufferMemory 自动摘要、Persistent 用 SQLite + 手动 schema 存用户偏好/事实。Scratchpad 只在 agent 跑多步推理时才用,简单 chat 不需要。
Mem0 / Letta 一个月跑下来贵不贵?
Mem0 自托管免费(开源 Apache 2.0),托管版 Mem0 Cloud free tier 1K memory + 1K search/月够 demo。Letta 100% 开源自托管,PostgreSQL + 一个 Python service 即可,云成本就是 PG 实例(~$15/月 RDS t4g.micro)。两个都不会成本爆炸。
Memory 系统最常见的失败模式是什么?
把所有 LLM 输出无脑写 persistent,3 个月后 memory 库膨胀到 50K+ 条目,每次 search 召回的全是过期/矛盾内容。正确做法:写入前过 LLM-as-judge 一层判断「该不该记」、加 expiration(30/90 天)、定期跑去重 + 矛盾合并。Mem0 默认就做这些,自己手写就要补上。