乐于分享
好东西不私藏

AI 跨会话记忆深度分析:从检索、压缩到心智建模

AI 跨会话记忆深度分析:从检索、压缩到心智建模

这是"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 会发生什么:

  1. Agent 从 Honcho 召回了一段记忆:"用户偏好 Rust"
  2. 这段记忆被写入当前对话
  3. 对话结束后,对话内容同步到 Honcho
  4. Honcho 看到对话里有"用户偏好 Rust"——把它当成新信息再记一次
  5. 下次召回时,这条信息被加强了权重
  6. 循环往复,雪球效应

这是递归记忆污染——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,它的五个设计思想值得偷:

  1. 有限空间强制优先级
     —— 记忆不要无限增长,给它一个硬上限
  2. 让 Agent 自己管记忆
     —— 给它工具,让它决定记什么
  3. 热数据不需要数据库
     —— 直接放系统提示就行
  4. 冷数据不需要向量检索
     —— SQLite + FTS5 对大多数场景够用
  5. 子 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——祝你在撞墙之前就看见墙。

相关学习资料