这是"AI 上下文压缩与记忆"系列的第三篇。 第一篇搭了框架,第二篇聊了"session 不崩", 这篇来种一棵树——跨会话记忆。
前言:金鱼的困境
你有一个 Agent 助手。它很聪明,代码写得不错,调试也有两下子。
周一,你花了二十分钟告诉它:项目用 Rust,ORM 是 SQLx, 数据库连接走 DATABASE_URL 环境变量,测试要跑 cargo nextest, 代码风格遵循 rustfmt 默认配置。
周二,你打开新 session。
"帮我加一个用户查询接口。"
"好的!我来用 Python 和 SQLAlchemy 帮你写一个……"
你盯着屏幕,深呼一口气——它全忘了。
不是它不够聪明——它昨天做得很好。问题是每次新 session 开始, 它的世界就重新归零。昨天的对话?不存在。昨天学到的偏好? 从未发生过。
这就是金鱼的困境——Agent 可以很聪明,但如果记忆只有七秒, 聪明又有什么用?
第二篇解决的是"session 不崩"。这篇要解决的是一个更深层的问题:Agent 能不能记住东西?能不能学习?能不能成长?
三种哲学:什么是"记忆"?
跨会话记忆的产品现在已经遍地开花——Mem0、Zep、Letta、Mastra、 Hermes、Honcho……光名字就能列一页。
但如果你把它们全拆开来看,底下只有三种哲学。 每个产品都是在回答同一个问题:什么才是"记忆"?
不同的回答,导致完全不同的架构决策。
哲学 1:记忆是一个仓库(Memory as Retrieval)
最朴素的答案:记忆就是把过去的东西存起来,需要时查出来。
技术上怎么做?把对话切成块,embed 成向量, 丢进 Pinecone 或 Weaviate。用户下次来的时候, 去向量数据库里找"最相似"的历史片段,塞进 prompt。
这是 RAG 思路的自然延伸。你已经会用 RAG 查文档了, 那把"用户的历史对话"也当成文档来查,不就有记忆了?
听起来合理。而且确实能用。
但它有一个要命的缺陷:没有时间感。
你一年前说"我喜欢 Python"。昨天你说"我转 Rust 了"。 在向量空间里,这两句话的相似度差不多——都是关于编程语言偏好的。 系统可能两条都召回,让 Agent 无所适从: "这个用户到底用 Python 还是 Rust?"
更糟的是,它不理解"为什么"存了某条信息。它只能按相似度排序, 不能按重要性排序。你提了一嘴的咖啡偏好, 可能跟你反复强调的技术栈约束排在同一个位置。
哲学 2:记忆是一本不断改写的笔记(Memory as Compression)
第二种答案更激进:记忆不是仓库,是笔记。
不存原文。不搞向量数据库。 让 LLM 把历史浓缩成一份持续更新的"观察笔记"。 笔记太长了?再浓缩一次。递归压缩,永远只保留最精华的部分。
Mastra 的 Observational Memory(2026 年 2 月才发布)把这个思路 做到了极致。它用两个后台 Agent 配合:
- Observer
:当未观察的消息积累到 30K tokens, 它把这些消息压缩成一组带日期的"observations" - Reflector
:当 observations 本身积累到 40K tokens, 它重新组织、去重、合并,把笔记本身再精简一次
压缩后的笔记直接留在 context 里。不存数据库,不做检索。 就这么留着。
这意味着——完全消除了检索环节。没有向量数据库,没有查询延迟, 没有"查不到"的风险。笔记就在眼前,每次推理都能看到。
压缩率也相当惊人:纯文本 3-6 倍,工具密集型的工作负载 5-40 倍。
但代价很明确:有损且不可逆。一旦被压掉,原文就没了。 如果 Observer 在压缩时判断某条信息不重要并扔掉了, 而三周后你突然需要它——抱歉,找不回来了。
哲学 3:记忆是一张不断生长的图(Memory as Knowledge)
第三种答案最有野心:记忆是一个知识图谱。
不是"一条一条的对话记录", 而是实体(人、项目、工具、概念)和关系(使用、偏好、属于、发生于) 构成的网络。
Zep 的 Temporal Knowledge Graph 走的就是这条路。它的强项是时序—— 不只知道"用户喜欢 Rust",还知道什么时候开始喜欢的, 之前用的是什么,转换的原因是什么。你可以问出这种查询:"上个月这个用户提到过哪些客户? 他们之间是什么关系?时间线是怎样的?"这在检索派那里是做不到的——向量数据库能告诉你"最相似的 5 个片段", 但告诉不了你"这些实体之间有什么联系"。
Mem0 也支持 graph 模式。它在 LOCOMO 基准上的数据很亮眼: 相比 OpenAI Assistants 提升 26% 的 LLM-as-Judge 得分, p95 延迟降低 91%,token 成本省 90%+。
但图的代价也很真实:构建复杂、维护头疼。 实体抽取要做,关系消歧要做,图随时间腐烂要定期清理。 这不是一个"搭好就不用管"的系统。
三种哲学不是对立的
重要的话再说一遍:它们不是互斥的。
大多数成熟的生产系统最终会混用——
- 热数据
(当前 session 必须知道的东西)→ 压缩后直接留在 prompt 里 - 温数据
(跨 session 的结构化事实和实体关系)→ 知识图或专门的记忆 DB - 冷数据
(几个月前的历史对话)→ 向量数据库按需召回
这其实就是那个反复出现的温度分层架构。 上一篇聊会话内压缩时遇到过,这里又遇到了—— 不是因为大家互相抄,而是认真想过这个问题的人都会走到这里。
一个反直觉的发现:最土的方案可能最好
在介绍具体产品之前,有一个发现必须先说。 因为它会影响你对后面所有系统的判断。
Letta(原 MemGPT,OS 启发式的记忆架构)团队做了一个实测。 他们把自己的系统跟各种专用记忆系统对比。 结果发现——一个极简的"按时间戳索引的原始文本文件"系统, 在某些场景下超越了几个专用记忆系统。文本文件。时间戳。就这样。
这个结论很打脸,但它不是孤例。 Hermes Agent 用 SQLite + FTS5 而不是向量数据库。 Mastra 干脆消除了检索环节。 这些决策都在重复同一条规律:
在正确的架构下,简单方案的竞争力被严重低估。
所以当你看到后面那些复杂的系统时,记住这条规律:先试最简单的,证明不够再升级。不要因为"这个方案太土"就跳过它。
Hermes Agent的五层架构
Hermes Agent:不靠压缩,靠分层
好,现在来看具体产品。第一个要聊的是 Hermes Agent, 因为它的设计哲学跟其他所有系统都不一样。
Hermes Agent 是 Nous Research 在 2026 年 2 月发布的 (OpenClaw 的官方继任者)。它的核心哲学一句话概括:
别压缩。把东西分好层,压缩就用不上了。
其他 Agent 工具把"压缩"当核心问题——上下文会满,怎么压回去? Hermes 反过来问:如果我把记忆分好层,每层都控制好大小, 上下文还会满吗?
答案是:几乎不会。压缩成了第五层——最后兜底的手段。
Layer 1:MEMORY.md / USER.md —— 一个精心管理的小口袋
这是 Hermes 最聪明的设计。两个文件,硬性字符上限:
MEMORY.md:2200 字符(约 800 tokens),存环境、工作流、经验教训 USER.md:1375 字符(约 500 tokens),存用户偏好
注意:硬性上限。不是"建议不超过",是"超了就报错":
Memory at 2,100/2,200 chars.Adding this entry (250 chars) would exceed the limit.Replace or remove existing entries first.
这意味着什么?意味着 Agent 必须持续做取舍。新经验来了,口袋满了, 必须决定:扔掉一条旧的,还是把两条旧的合并成一条腾出空间。
这跟传统记忆系统的"无限增长 + 后台清理"完全相反。 传统系统像一个只进不出的抽屉,塞到塞不下了再请人来收拾。 Hermes 像一个精心管理的钱包——有限的卡位, 每加一张新卡就得考虑该不该把旧卡拿出去。
有限空间强制优先级。这是一个深刻的设计原则。还有一个细节:没有 read action。 记忆不是"需要时查出来"的东西,它在每次 session 开始时 作为冻结快照直接注入系统提示。一直在视野里。不用查,不用等。
Layer 2:Skill Documents —— Agent 给自己写的经验笔记
这是 Hermes 跟其他所有 Agent 工具最不一样的地方。
当 Hermes 完成一个复杂任务——比如调通了一个诡异的 Docker 网络配置—— 它会自己把经验合成成一个 Skill Document。 遵循 agentskills.io 开放标准的 markdown 文件。下次遇到类似的 Docker 网络问题?它不用从头摸索, 直接翻自己的经验笔记。
更妙的是,Skill Documents 会在使用过程中自我改进。 如果笔记里的某个步骤过时了,Agent 在执行时会更新它。
这跟 Claude Code 的 CLAUDE.md 有本质区别:
CLAUDE.md是人写给 Agent 看的项目说明书 Skill Documents 是Agent 写给自己看的经验笔记
前者是"你告诉它怎么做",后者是"它自己学会了怎么做"。 这才是真正的"学习"。
Layer 3:FTS5 Session Search —— 最朴素的冷存储
所有 CLI 和消息会话存在 SQLite 里,支持 FTS5 全文搜索, 配 Gemini Flash 做摘要。Agent 想找"三周前我们讨论过的那个数据库迁移方案"? 全文搜索,找到,用 LLM 总结一下,搞定。
不是向量数据库。是 SQLite + FTS5。
记住前面说的那条规律——"最土的方案可能最好"。 对大多数场景来说,全文搜索已经够用了。 除非你的用户问题真的需要语义相似度 (比如"我之前那个发不了电的问题"——这种模糊表述 FTS5 确实抓不住), 否则 SQLite + FTS5 的运维成本几乎为零。
Layer 4:External Memory Providers —— 插件式扩展
Hermes 提供 8 个外部记忆提供商的插件—— Honcho、Mem0、ByteRover、Supermemory 等。 一次只能激活一个,但内置记忆(Layer 1-3)始终并行工作。
这里有一个很容易被忽视但极其重要的工程细节:自动 context fencing。
什么意思?想象一下如果不做 fencing 会发生什么:
Agent 从 Honcho 召回了一段记忆:"用户偏好 Rust" 这段记忆被写入当前对话 对话结束后,对话内容同步到 Honcho Honcho 看到对话里有"用户偏好 Rust"——把它当成新信息再记一次 下次召回时,这条信息被加强了权重 循环往复,雪球效应
这是递归记忆污染——Agent 自己的回忆反复强化自己, 最终变成一个自我封闭的回音室。
Hermes 的解决方案:在捕获对话回合时,自动剥离已召回的记忆。 被召回的内容打上标记,不会被再次写入。
如果你在设计任何"读历史 → 写记忆 → 又读历史"的链路,今天就要做 fencing。否则你迟早会在生产环境里遇到这个 bug, 而且它非常难调试——因为数据看起来都是"正确"的, 只是不应该重复出现这么多次。
Layer 5:Auto-compression —— 最后的安全网
压缩在 Hermes 里是第五层——其他四层都失效了才轮到它。 当估计 token 数超过模型上下文的 85% 时触发。
日常运行中?几乎用不上。因为前四层已经把上下文控制得很好了。Hermes 的零上下文成本子 Agent。
Hermes让子 Agent 通过 Python RPC 调用工具——不是在主 Agent 的上下文里调工具,而是在一个完全独立的 Python 脚本里调。
主 Agent 看到的是什么?是"脚本运行成功,输出:XXX"。一行。
这比 Claude Code 的子 Agent 更激进—— Claude Code 的子 Agent 虽然有独立上下文,但结果会以结构化方式返回。 Hermes 的子 Agent 连返回格式都是自由的—— 主 Agent 只看一行纯文本输出。
他们管这叫"zero-context-cost turns"。名副其实。
从 Hermes 身上能学到什么?
即使你不用 Hermes,它的五个设计思想值得偷:
- 有限空间强制优先级
—— 记忆不要无限增长,给它一个硬上限 - 让 Agent 自己管记忆
—— 给它工具,让它决定记什么 - 热数据不需要数据库
—— 直接放系统提示就行 - 冷数据不需要向量检索
—— SQLite + FTS5 对大多数场景够用 - 子 Agent 是终极压缩
—— 零上下文成本是可以达到的
完全不同的维度:Honcho 和心智建模
前面所有的系统——Mem0、Zep、Letta、Mastra、Hermes—— 不管它们的架构多不同,都在做同一件事:存事实,查事实。
"用户用 Rust。" → 存起来。 "用户的项目叫 Apollo。" → 存起来。 "用户上次遇到了连接超时问题。" → 存起来。然后需要的时候查出来,塞进 prompt。
Honcho 觉得这整条路都走偏了。
"事实列表"的局限
Honcho 的核心论断(原话):
"记忆系统存储事实。用户和 Agent 不只是事实。 而事实浪费 tokens。传递重要的上下文需要推理。"
什么意思?
你用 Rust——这是事实。 你偏好函数式风格——这也是事实。 你在项目里用 SQLx——还是事实。
但是: "这个用户在压力下倾向于过度简化问题。" "这个用户更喜欢看代码而不是听解释。" "这个用户在不确定时会反复问同一个问题,但措辞每次不同。"
这些不是事实。它们是推论—— 只有通过多次对话、持续观察、归纳推理才能得出的结论。你没法用 key-value 存"这个用户在压力下倾向于过度简化问题"。 因为用户从来没说过这句话。这是你(或者一个聪明的系统) 在跟他交互了二十次之后推断出来的。
Honcho 的定位不是记忆系统,是 social cognition engine—— 社会认知引擎。它最像的不是 Mem0 或 Zep,而是一个心理学家。所有参与者都是 Peer
Honcho 的数据模型有一个反常识的设计:没有"用户"和"Agent"的区分。
在大多数系统里,有明确的角色划分——人类是用户,AI 是助手。 Honcho 把所有参与者统一叫做 Peer(对等体)。
为什么?因为在复杂的多 Agent 场景里,你可能有:
一个人类用户 一个客服 Agent 一个销售 Agent 一个技术支持 Agent
这四个参与者之间的交互都可能产生有价值的观察。 Honcho 需要建模的是人,不是"用户-助手对话"。
关键设计点:每个 Peer 有一个 observe_me 开关。 通常人类 Peer 的 observe_me=True(Honcho 会对他们建模), AI Peer 的 observe_me=False(不建模 AI)。
为什么不建模 AI?因为 AI 的输出会污染对人的理解。 如果 Honcho 同时观察 AI 和人类,它可能会把 AI 的表达风格 归因到人类身上——"这个用户喜欢用 bullet points"。 不,那是你的 Agent 喜欢用 bullet points,用户只是在忍受它。
三个 LLM Agent:Deriver、Dialectic、Dreamer
Honcho 内部本身就是一个多 Agent 系统。 三个专门的 LLM Agent 各司其职,配合得像一台精密机器。
Deriver(推导者)—— 写入端
每当有新的对话消息进来,Deriver 在后台异步处理它, 提取两种不同的观察:
- 显式观察
(Explicit):"用户说他在用 Rust" —— 用户直接说的,直接记。 - 演绎观察
(Deductive):"基于多次对话推断, 用户偏好类型安全、编译时检查的语言" —— 用户没说,但可以推断。
演绎观察才是 Honcho 的真正价值。
Mem0 也能存"用户用 Rust"。但"用户偏好类型安全的语言"这种推论, 需要观察他在多次对话中的行为模式才能得出。 这不是检索问题,是推理问题。
Dialectic(辩证者)—— 读取端
当你的 Agent 需要了解用户时,它不是去查向量数据库, 而是跟 Honcho 聊天。
传统做法:
Agent → 查 vector DB → 拿到 5 个相似片段 → 拼接到 promptHoncho 做法:Agent → "这个用户偏好什么沟通方式?"→ Honcho 内部 LLM 推理(调用多个工具、迭代组装上下文)→ "这个用户偏好简洁直接的沟通,不喜欢冗长的解释,更喜欢看代码示例而不是文字描述"→ 注入 prompt注意区别:传统检索返回的是
片段——你得自己理解它们。 Dialectic 返回的是回答——它已经替你理解过了。
这就是 Honcho 的旗舰 API:Dialectic API。
你可以问它:
"向这个用户解释技术概念的最佳方式是什么?" "这个用户的主要目标是什么?" "这个用户今天的情绪跟上周比有什么变化?"
这些问题你没法对向量数据库提。
Honcho 的论证很优雅:自然语言本身就是进化优化来描述人类身份的。 硬塞到 schema 和 key-value 里必然损失信息。 用自然语言问关于用户的问题、用自然语言回答—— 这比任何结构化存储都更丰富。
Dreamer(做梦者)—— 巩固端
这是最有意思的一个,也是其他任何记忆系统都没有的。
Dreamer 做什么?它在后台异步地、持续地、没有触发条件地整理 Honcho 的记忆。策略是随机游走:从一个近期的高价值观察开始, 搜索相关的观察,发现冗余就合并,发现矛盾就消解, 发现碎片就拼接成完整的画像。
这就像你睡觉时大脑在做的事—— 白天吸收了一堆零散的信息,晚上大脑默默地整理、归类、巩固。 醒来之后你觉得某个问题突然想通了——不是因为你获得了新信息, 而是因为旧信息被重新组织了。
为什么这很重要?因为其他记忆系统都有一个隐疾:记忆条目会随时间碎片化、冗余、矛盾。
碎片化:"用户用 Rust" + "用户的 Rust 版本是 1.75" "用户最近升级到了 Rust 1.78"——三条记忆,讲的是一件事 冗余:"用户偏好简洁回复" + "用户不喜欢冗长解释"——同义重复 矛盾:"用户用 React" + "用户已转向 Vue"——哪个是最新的?
Mem0、Zep 这些系统在写入时做去重和冲突消解——但那是被动的、即时的。 Dreamer 是主动的、异步的、长期的。 它不等你写入新信息才整理,它自己找时间去整理。
三个 Agent 的分工,有个优雅的类比:
- Deriver
像你的潜意识——随时在吸收新经验 - Dialectic
像你被问起时的有意识回忆——组织语言来回答 - Dreamer
像你睡眠时的记忆巩固——后台默默整理
Honcho 的延迟折中:Working Representations。Dialectic API 强大,但有一个代价:慢。 每次查询都要跑一轮 LLM 推理,很难做到 200ms 级。Honcho 的解决方案是 Working Representations—— 一个用户画像的缓存快照。
两种检索模式:
- Dialectic(实时推理)
质量高、延迟高、贵 —— 用于关键时刻,比如首次对话 - Working Representations(缓存快照)
质量中、延迟低、便宜 —— 用于日常交互,可能稍微过时但够用
一个有意思的工程选择:当 Hermes Agent 集成 Honcho 时,Honcho 的输出不注入系统提示。为什么? 因为系统提示如果每次都变,prompt caching 就失效,成本会暴涨。
Honcho 的输出被附加到当前回合的 user message 里。 系统提示保持不变,cache 继续命中。 一个微小的决策,省了大笔钱。
Honcho 不能什么
说了这么多 Honcho 能做什么,也必须说清楚它不能做什么:
1. 不解决会话内压缩
Honcho 是跨会话层的东西。你的单个 session 上下文快满了, Honcho 帮不了你——那是第二篇讲的 Claude Code / OpenHands 的领域。
2. 不是事实数据库
"这个用户的订单号是 ORD-2025-1234" ——这种精确事实不该存 Honcho。 它擅长的是"理解这个人是谁",不是"准确记住他的订单号"。 精确事实存 PostgreSQL,心智模型存 Honcho。各司其职。
3. 成本不低
三个后台 LLM Agent 持续推理。虽然 Honcho 默认用 Gemini Flash 做便宜的部分、用 Claude 做贵的部分, 但如果你的用户量大,这笔账必须算清楚。
4. 最关键的:Honcho 跟 Mem0、Zep 不是竞品
它们解决的是不同问题。一个成熟的系统可能同时用两者—— Mem0 存事实,Honcho 建模心智。就像你需要一个 CRM 存客户数据, 同时需要一个有经验的客户经理去"理解"客户一样。
Agent的记忆设计选择:一条渐进路径
如果你现在开始构建 Agent 系统,这是我的建议——从简单开始,逐步升级,每一步都验证是否真的需要再复杂一点。
阶段 1:先不要记忆层
我是认真的。
直接用 Anthropic 的 compact_20260112 beta 做会话压缩。 先让 Agent 的单 session 能跑起来。先把核心体验做好。
记忆系统是锦上添花,不是雪中送炭。 一个没有记忆但单 session 做得好的 Agent, 比一个有记忆但单 session 做不好的 Agent 有用一万倍。
阶段 2:最简单的记忆
如果用户反馈"Agent 什么都记不住",加一个最简单的方案:
文件系统记忆(Letta 验证过:文本文件 + 时间戳就能跑赢很多系统) 或者 Hermes 的 MEMORY.md 模式(有界、Agent 自管理、零依赖)
这一步的关键是控制复杂度。不要一上来就搭向量数据库。 那条路的运维成本比你想象的高得多,而收益可能没你想象的大。
阶段 3:引入专门的记忆系统
如果简单方案撑不住了——记忆量太大、查询太复杂、 用户在不同 session 里的行为关联性很强——这时候再引入专用系统。
选哪个?看你的核心需求:
- 通用 Q&A / 偏好记忆
→ Mem0(最成熟、SDK 最完善) - 时序语义重要
→ Zep("谁在何时说了什么"是核心能力) - 压缩优先、不要数据库
→ Mastra Observational Memory(最简架构) - AWS 生态
→ AgentCore Memory(集成成本低)
阶段 4:考虑心智建模
如果你的产品**真的需要"理解用户"**而不只是"记住用户说过的话"—— 客服场景、个人助手场景、教育辅导场景—— 这时候考虑加入 Honcho 作为独立的心智建模层。
但请注意:这是一个高级能力,不是所有产品都需要。 如果你的 Agent 只是帮人写代码、查资料、跑自动化, 事实层面的记忆就够了。心智建模是留给那些真正以人为中心的产品的。
你最好不要做的事
一上来就引入向量数据库(先试文本文件和 SQLite) 把精确业务事实存到 Honcho 里(订单号归 PostgreSQL) 指望一套系统解决所有问题(事实 + 心智 = 两个系统) 忽略记忆巩固(记忆会随时间腐烂,需要 Dreamer 这样的整理机制) 忘记 context fencing(递归污染是真实的生产 bug)
系列回顾
三篇写完了。回头看看我们走过的路:
第一篇建了一张地图:两个层次(会话内 vs 跨会话)、 四种压缩积木、三种记忆哲学、温度分层、五个反直觉的发现。
第二篇深入了第一个战场:会话内压缩。 四种产品(Claude Code、OpenHands、Codex CLI、Amp) 四种性格(管家、老师、工程师、军刀),五条血泪教训。
第三篇来到了第二个战场:跨会话记忆。 三大哲学(仓库、笔记、图谱),Hermes 的五层分层, 以及 Honcho 开辟的全新维度——心智建模。
如果只记三件事:
1. 压缩和记忆是两个层次,分开设计。时间尺度不同、失败模式不同、解决方案不同。 别试图用一套系统打天下。
2. 简单方案先行。文本文件 + 时间戳可能就够了。SQLite + FTS5 可能就够了。 先证明不够,再升级。不要因为"这个方案太土"就跳过它。
3. "理解用户"和"记住用户"是两件事。Honcho 押注的心智建模是一个正在崛起的新维度。 不是所有产品都需要,但如果你的产品是关于人的—— 客服、教育、个人助手——这条路值得认真看看。
希望这个系列对你有用。如果你正在构建 Agent——祝你在撞墙之前就看见墙。
夜雨聆风