为什么 Memory 不能只是 KV?——从结构化记忆到 HyperMem 的关键一步

3 阅读22分钟

前两篇已经把这个系列最基础的两层问题拆开了。

第一篇《为什么 AI Agent 的长期记忆几乎都是错的?》讨论的是现象:为什么很多 AI Agent 的长期记忆看起来已经“接上了”,实际却还是会频繁出错。表面上像是模型忘了,往深一点看,问题通常不在“记不住”,而在“不会用”。

第二篇《Memory OS:AI Agent 不是缺记忆,而是缺一套记忆系统》讨论的是系统边界:如果长期记忆不等于“聊天记录 + 检索”,那一套真正可用的记忆系统,至少应该包括什么。写入层、状态层、组织层、重建层,这些听起来抽象,但本质上都在回答同一个问题:历史信息到底怎样才能被系统长期维护,并在需要的时候被正确调用。

写到这里,很多人会自然进入下一步思考:

既然已经有了 Memory OS,把对话整理成事件、事实、状态,再做一套分层组织,是不是问题就差不多解决了?

答案是:还没有。

确实,到了这一步,系统已经比“纯聊天记录 RAG”强了很多。信息不再只是原始对话,状态也不再完全依赖临场推断,检索也不再是简单地在日志里捞相似文本。可即便如此,很多长期记忆场景里最难的那部分,依然没真正被解决。

缺的不是更多信息,也不只是更复杂的检索,而是另一个经常被低估的能力:

结构。

这篇文章就想把这件事讲透:为什么长期记忆不能只是 KV,不能只是 chunk,也不能只是“分层之后的若干 memory object”。如果希望系统真正具备更稳定的长期推理能力,就必须开始认真处理记忆之间的关系,而一旦进入这一步,HyperMem 这类结构化记忆方案才会显得重要。


一、从“有系统”到“能推理”,中间还差一个结构

第二篇里其实已经讲过一个很重要的判断:长期记忆不是单个模块,而是一条完整链路。

原始对话进入系统之后,不该直接进入向量库,而应该先被整理成稳定的记忆单元,比如 episode、event、fact,再进一步沉淀成 profile、constraint、foresight 这类状态表达。等到用户再次发问时,系统再围绕当前问题去重建必要且充分的上下文,而不是一把梭地把 top-k 文本拼回去。这个思路在 EverMemOS 论文里被概括成三阶段:Episodic Trace Formation、Semantic Consolidation、Reconstructive Recollection。

这一套设计已经很重要了。至少,它把“长期记忆”从一个很粗糙的检索问题,提升成了一个真正的系统设计问题。

但问题也恰恰出在这里:当系统开始拥有 episode、fact、profile、constraint 这些层级之后,下一个难题就不再是“有没有这些对象”,而是“这些对象之间到底是什么关系”。

这个区别很关键。

因为一个 Memory System 只要做到了“有对象”,还不代表它已经能“沿着对象关系稳定推理”。很多系统在这一层会出现一种非常典型的状态:信息越存越多,分类也越来越丰富,结果回答质量却没有同步上升,甚至还会开始出现新的混乱。

原因并不复杂。对象有了,但对象之间仍然是松的。

一个很真实的例子

假设系统已经积累了这样一组长期信息:

  • 最近在准备面试
  • 最近睡眠不太好
  • 当前项目 deadline 很紧
  • 周末一直想出去放松
  • 前两周连续加班
  • 最近开始刻意减少社交

如果现在问一句:

“最近压力大的原因可能是什么?”

一个没有结构的系统,通常能做到的事情是:检索出几条都“挺相关”的内容。比如 deadline、睡眠问题、面试压力,甚至还可能把“周末想放松”也召回来。单看每一条,都不是错的。问题在于,系统并不知道这些内容之间的具体关系。

  • 哪些属于同一条叙事链?
  • 哪些是压力来源,哪些只是后果?
  • 哪些是长期背景,哪些是最近变化?
  • 哪些信息应该一起看,哪些只是弱相关?

如果这些问题没有结构来支撑,系统最后只能把它们当成“若干相关片段”,交给模型去临场拼。

这种做法偶尔也能答对,但很难稳定。

所以这里出现了一个特别值得重视的现象:

信息并不缺,系统也并不完全混乱,但答案仍然不稳。

这其实就是“有 Memory System,但没有 Memory Structure”的状态。系统已经开始有记忆对象了,却还没有真正建立起它们之间的关系网络。结果就是:它看起来比最初的聊天记录 RAG 更高级,但真正面对复杂推理时,依然会暴露上限。


二、为什么 KV / Chunk 天然不适合长期记忆

很多人第一次听到“记忆不能只是 KV”,会下意识觉得这句话是不是说得太绝对了。因为从工程视角看,很多系统确实就是基于 KV 或者 chunk retrieval 做起来的,而且也并非完全不可用。

这里真正想表达的不是“KV 一无是处”,而是:

KV 的表达能力,天生不足以承载复杂长期记忆。

它适合做基础存储,适合做召回入口,适合做局部检索,但不适合直接承担“长期记忆的核心结构”。

1. KV 最擅长表达的是“相似”,不是“关系”

不管说得多复杂,向量检索最后都在做一件事:根据 query 找相似内容。

这件事当然重要,而且很多场景下足够有用。问题是,长期记忆里真正难的那部分,并不等价于“找语义上最像的问题背景”。

很多长期问题真正需要的是关系,而不是相似:

  • 因果关系:因为 deadline 逼近,所以睡眠变差
  • 时序关系:先开始加班,后出现疲惫和社交回避
  • 归属关系:多个片段都属于“工作压力”主题
  • 约束关系:某条当前状态会限制某些偏好的适用性

这些关系,语义相似度表达不了,至少表达得很弱。

一个 chunk 可能和 query 很像,但这并不意味着它在当前问题中处于正确的位置。它可能只是结果,不是原因;可能只是背景,不是关键;也可能本该和另一个 episode 一起看,而不是被孤立召回。

这也是为什么仅靠 embedding 相似度,经常会出现一种非常微妙的错误:看起来都相关,但相关得不够对。

2. Chunk 会把原本完整的语义结构打散

很多系统喜欢讨论 chunk size、overlap、window strategy,这些当然都有价值。但无论切得多精细,chunk 本质上仍然是为了处理文本长度而设计的切分单元,不是为了表达长期事件而设计的认知单元。

现实中的一件事,很少会规规矩矩地落在一个 chunk 里。

一个长期状态的形成,可能跨越很多轮对话。一个主题的演化,可能要等到几天后才真正完整。一个关键约束,也可能先以很轻的方式出现,过几轮才变得明显。

一旦这些内容被切散,它们在系统里的存在方式就会变成:

  • 多个彼此独立的文本片段
  • 若干相似度不稳定的向量点
  • 每次调用时都要重新拼接的碎片

这在短问答场景里问题不大,在长期记忆里就会越来越明显。因为长期记忆最怕的,就是每次回答都要临时拼一个新的世界模型。

拼得出来一次,不代表下次还能以同样方式拼出来。

3. KV 不擅长表达“多对多”的组合关系

真实世界里的很多结论,都不是“一条 query 对应一段 answer”。

更常见的情况是:

  • 多个事件共同塑造当前状态
  • 多个事实共同支撑一个判断
  • 一个约束会影响多个主题
  • 同一个事件会同时改变偏好、状态和计划

这类关系不是一对一的,也不只是简单的一对多。它更接近一种多对多的结构网络。

而 KV 天然偏向什么?偏向“一个 key 找若干 value”。哪怕把 top-k 调大,它做的也还是“从很多独立片段里找一批相关内容”。它没有原生能力去表达“这几个节点应该作为一个语义整体被看待”。

这就是为什么很多系统越往后做,越会感觉 top-k 越调越大,rerank 越加越重,但真正复杂的问题依然不稳定。因为问题从一开始就不是“找不够多”,而是“缺少把多个节点组织成一个结构单元的能力”。

4. 没有结构,就没有可控的推理路径

这一点对工程实现尤其重要。

如果系统内部没有明确结构,那么所谓“推理路径”本质上只能依赖模型在上下文里临场发挥。模型得自己决定:

  • 哪几条信息应该先看
  • 哪几条应该合并
  • 哪些是背景,哪些是关键
  • 哪些关系应该被建立起来

这类能力模型当然有,但它不稳定,也不透明,更不好控制。

当问题简单时,这种模糊性还可以接受。可一旦进入长期、多跳、跨主题场景,推理路径本身就会成为核心能力。如果系统完全不提供结构支撑,那就等于把最难的部分全部丢给模型现场 improvisation。

从工程视角看,这显然不是一个稳妥设计。

所以这里可以把结论说得更直接一点:

没有结构的记忆,本质上只是“可检索的数据”,还不是“可推理的知识”。


三、长期记忆真正需要的,不是一堆点,而是关系网络

理解了 KV 的局限之后,下一个问题就自然浮现出来了:

既然长期记忆不该只是孤立的 key-value 或 chunk,那更合理的形态是什么?

答案其实不算神秘:它应该更像一个有关系的网络。

也就是说,系统里保存的不是一批彼此独立的“点”,而是一个由主题、事件、事实、状态相互连接起来的结构。

这一步之所以重要,是因为它改变的不只是存储形式,而是系统对“记忆”这件事的理解方式。

1. 记忆不该只是一堆被动对象

在很多朴素设计里,episode 是 episode,fact 是 fact,profile 是 profile。它们当然都被保存了,但保存之后,系统对这些对象的默认态度通常还是“有需要时再检索出来”。

这就导致这些对象即便被分层了,本质上仍然像平铺数据库里的多种记录类型。

可如果长期记忆要支持更复杂的推理,那么这些对象不能只是并列存在。它们之间应该有明确连接:

  • 某个 fact 属于哪个 episode
  • 某些 episode 共同构成哪个 topic
  • 某个状态由哪些历史事件演化而来
  • 某些约束会影响哪些偏好或计划的适用范围

一旦这种关系被显式表达出来,系统就不再只是“保存对象”,而是在“维护结构”。

2. 一个更接近长期记忆的基本形态

如果先用最简单的方式去画,可以大概长成这样:

Topic(主题)
 ├── Episode(事件)
 │    ├── Fact(事实)
 │    └── Fact
 ├── Episode
 │    ├── Fact
 │    └── Fact
 └── State / Constraint(状态 / 约束)

哪怕只是这种非常朴素的层级结构,也已经比“若干独立 chunk”强很多了。因为它至少表达出了三件事:

  • 有主题归属
  • 有事件边界
  • 有事实落点

系统不再需要每次都从零去猜“这些东西是不是有关”,而是已经拥有了一部分显式关系。

3. 但树结构仍然不够

问题在于,真实世界里的长期记忆往往不是树。

一条事实可能同时关联多个事件。 一个事件可能影响多个状态。 一个状态的形成,可能依赖分散在不同时间点的多个 episode。 同一个主题,也可能跨很长时间周期反复出现。

这时候,单纯的父子层级就不够用了。因为树结构擅长表达单一归属,不擅长表达交叉依赖。而长期记忆里最难的部分,恰恰经常是交叉依赖。

也正因为如此,长期记忆真正需要的,不只是“分层”,而是:

一个能够表达多对多关系、跨层关系和跨时间关系的结构网络。

这也是 HyperMem 这类方法开始变得重要的地方。


四、HyperMem 的关键思想:为什么是超图,而不是普通图

如果说前面还在讲一个比较通用的工程问题,那么到了这里,就开始进入 HyperMem 这篇论文最有辨识度的地方了。

HyperMem 的核心观点可以概括成一句话:

长期记忆不应该只被建模成若干 pairwise relation,而应该被建模成一种能够表达高阶关系的结构。

论文选择的答案是:超图(hypergraph)

1. 先直观理解一下什么是“超图”

普通图大家比较熟悉:节点和边,一条边通常连接两个节点。

这种结构已经能表达不少关系了,比如 A 和 B 有关联,B 和 C 有关联。但长期记忆的问题在于,很多重要语义单元并不是“两两关系”的累加,而是一组节点共同组成的整体。

比如:

  • 一个主题可能同时由多个 episode 构成
  • 一个 episode 又由多个 fact 共同支撑
  • 某个长期状态,可能来自多个分散事件的共同作用

如果还坚持用普通图,就会把这些本来属于一个整体的关系,拆成很多 pairwise edges。拆完之后当然也能连起来,但语义上会更脆弱,因为“整体”被打散成了很多局部关系。

超图的不同之处在于:一条超边可以同时连接多个节点。 这意味着它更适合表达“这几个元素共同属于同一个语义单元”这样的关系。

2. 这为什么会对长期记忆特别重要

长期记忆最难的地方之一,就是很多问题不是靠一条信息回答的,而是靠一组彼此相关的记忆共同支撑。

比如一个“工作压力”主题,可能横跨几周,涉及 deadline、睡眠变化、社交回避、周末恢复计划等多个 episode。对系统来说,这些东西如果只是多个两两相关的边,仍然很容易在调用时被拆散。

而如果它们被建模成同一个更高阶的结构单元,那么系统在检索和推理时,就更容易把它们作为“一个整体背景”来使用。

这件事听起来像只是数据结构上的变化,实际影响非常大。因为一旦结构表达能力提升了,系统后面的检索、扩展、重建方式都会随之变化。

3. HyperMem 的三层设计为什么有意义

HyperMem 论文把长期记忆拆成三层:

  • Topic
  • Episode
  • Fact

然后通过超边把同一 topic 下的多个 episode 连接起来,把同一 episode 下的多个 fact 连接起来。

这套设计本身并不复杂,但它做对了一件特别关键的事:让长期记忆真正具备了层次结构和整体性。

相比平铺 chunk,它不再只是“保存哪些文本”; 相比普通图,它不再只是“保存哪些局部关系”; 它开始明确表达:

  • 哪些事实属于哪个事件
  • 哪些事件共同构成哪个主题
  • 哪些节点在回答时应该一起被看待

对长期记忆来说,这一步其实就是从“可检索”走向“可组合、可推理”的起点。


五、从“检索片段”到“沿结构搜索”,调用方式也会改变

当记忆开始拥有结构之后,系统调用它的方式就不可能继续停留在“query → top-k chunk”。

因为这时系统面前已经不是一堆独立文本,而是一个有关系的网络。

1. 传统方式的本质

传统 RAG 调用,本质上在做:

query → embedding → top-k → 拼接

不管中间有没有 rerank,这条链路的核心逻辑没有变:先用 query 去找最像的内容,再把找到的内容交给模型。

这种方法的优点是简单,缺点是它对结构几乎没有利用。系统不知道应该先经过哪个主题,再展开哪些事件,也不知道哪些事实应该成组进入上下文。

2. 结构化调用会变成什么样

如果系统内部是 topic / episode / fact 的结构网络,那么更合理的流程会接近这样:

query → 定位相关主题
     → 扩展相关事件
     → 下钻到关键事实
     → 组合成当前问题所需上下文

这其实就是一种 coarse-to-fine 的结构化搜索。HyperMem 的检索流程也正是沿着这个思路展开:先检索 topic,再在 topic 内检索 episode,最后在 episode 内检索 fact。

这一步非常重要,因为它意味着系统不再只是“找相似内容”,而是在“沿结构找到答案所依赖的关系路径”。

3. 这带来的变化不是小修小补,而是能力形态改变

从外面看,可能只是检索链路复杂了一点。但从能力上看,变化其实很大。

系统原本做的是:

找一些像的东西,交给模型临场组织。

现在开始做的是:

先找到正确的语义区域,再沿结构逐层扩展,最后把相关节点作为有组织的证据一起交给模型。

两者最大的差别在于:后者会给模型一个更接近“已经组织过的世界”。模型不是在一堆碎片里即兴拼装,而是在一个更有秩序的结构中继续推理。

这也是为什么结构化记忆一旦建立,系统的稳定性会明显提升。因为它减少了模型在上下文中临场建图的负担。

所以更准确地说,结构化记忆真正改变的是调用范式:

系统不再只是检索文本,而开始沿着记忆结构搜索与重建。


六、Memory OS 和 HyperMem 不是替代关系,而是上下两层

很多人看到这里,容易产生一个误解:既然 HyperMem 提供了更强的结构,是不是就可以替代 Memory OS 那一层?

实际上不是。

这两者处理的,根本不是同一个层级的问题。

1. Memory OS 解决的是“记忆怎么形成”

Memory OS 更关注的是整个运行时链路:

  • 对话怎么被切成稳定单元
  • 哪些内容被写入长期记忆
  • 事件、事实、状态怎么被抽取
  • 当前问题来了之后,如何围绕 sufficiency 去重建上下文

它回答的是“记忆从哪里来、怎样被维护、怎样被调用”。

2. HyperMem 解决的是“这些记忆之间怎么连接”

HyperMem 更关注的是结构表示本身:

  • topic、episode、fact 之间如何组织
  • 多个节点如何通过超边形成高阶关系
  • 检索如何沿着层级结构下钻
  • 多跳和时序类问题为什么因此更稳定

它回答的是“这些记忆对象一旦存在之后,应该怎样组成一个真正可推理的网络”。

3. 两者拼在一起,才更像完整长期记忆系统

如果用一句更直白的话说:

Memory OS 负责“让记忆存在”,HyperMem 负责“让记忆可推理”。

前者更像 runtime,后者更像 structure。 前者解决写入、状态和重建,后者解决关系表达和结构搜索。

把这两层拼起来,长期记忆系统的轮廓才会真正完整:

对话 → MemCell / Episode
     → Fact / State
     → 结构化组织(Topic / Episode / Fact)
     → 沿结构搜索 / 重建
     → 回答

从这个角度看,HyperMem 不是在否定 Memory OS,而是在补足它。


七、如果不做结构,系统迟早会被自己的记忆拖垮

这一点非常现实,也很值得提前说透。

很多团队在做长期记忆时,前期往往不会立刻感受到“结构”的重要性。因为在数据量还不大、主题还不复杂的时候,只靠分层存储和混合检索,也能跑出还不错的效果。

但随着系统持续积累记忆,问题会逐渐暴露出来,而且通常是以一种很难快速修补的方式暴露。

1. 信息越来越多,但质量没有同步提升

系统存下来的内容越来越多,memory types 也越来越丰富,可回答质量却并没有显著上升。因为这些信息只是更多了,不是更有组织了。系统每次调用时,仍然在重复“从很多碎片里拼一个局部答案”的动作。

2. 多跳问题越来越不稳定

越是需要跨事件、跨状态、跨时间推理的问题,越依赖结构。没有结构时,系统只能寄希望于模型在上下文中自己把路径补出来。偶尔能答对,但波动会很大。

3. 状态冲突会越来越难处理

长期偏好、短期限制、历史事件、当前计划,这些东西越多,彼此之间的冲突和依赖就越复杂。如果没有关系网络,系统很难明确判断“谁影响谁”“谁优先谁”“哪条信息属于哪条叙事链”。

4. 检索会越来越重

结构缺失时,最直观的补救办法通常只有一个:加大 top-k,增加 rerank,补更多上下文。短期看像是在增强系统,长期看其实是在用计算和噪声掩盖结构缺陷。

这也是为什么很多系统做到后面,会明显感受到一种疲态:memory 明明在增长,系统却没有越来越聪明,反而越来越臃肿。

所以这里的结论其实很残酷,但很真实:

没有结构,系统迟早会被自己的记忆拖垮。


八、结构不是“更复杂的理论”,而是让长期记忆真正可工程化的那一步

很多人听到图结构、超图、关系网络这些词,会下意识觉得这是不是又在把问题学术化。可如果从实际工程角度看,情况恰好相反。

真正让长期记忆开始可工程化的,不是“多加一个 retriever”,而是终于承认:

  • 记忆不是平铺文本
  • 记忆对象之间真的有关系
  • 这些关系不能永远依赖模型临场脑补
  • 一旦希望系统长期稳定,就必须把关系显式表达出来

换句话说,结构不是在把事情变复杂,而是在把原本一直存在、却被隐藏的问题摆到台面上,然后开始用系统手段去解决它。

从这个意义上说,HyperMem 代表的其实不是某个孤立技巧,而是一种方向变化:

从“把记忆当成可检索文本” 走向“把记忆当成可推理结构”。

这一步一旦迈出去,长期记忆系统的上限才会真正被打开。


结尾:下一步,不是再谈概念,而是谈怎么把它做出来

到这一篇为止,这个系列已经走了三步:

第一篇讲的是:为什么长期记忆会错。 第二篇讲的是:一套真正的 Memory System 应该长什么样。 第三篇讲的是:为什么系统还不够,记忆必须进一步结构化。

如果继续往下走,下一个问题就不该再停留在概念层面了。

真正值得继续追问的是:

  • 这种系统在工程里到底怎么实现?
  • 存储层该怎么拆?
  • 检索层怎么设计才不失控?
  • 状态更新和结构更新怎么做?
  • 线上成本怎么控制?

也就是说,下一步不再是“为什么要这样”,而是“怎样把这套东西真正做出来”。

这也正是接下来最值得展开的话题:

Memory Engineering:如何把长期记忆系统真正落到工程实践里。


引用论文

  1. Hu, C., Gao, X., Zhou, Z., Xu, D., Bai, Y., Li, X., Zhang, H., Li, T., Zhang, C., Bing, L., & Deng, Y. EverMemOS: A Self-Organizing Memory Operating System for Structured Long-Horizon Reasoning. arXiv:2601.02163, 2026. arxiv.org/pdf/2601.02…
  2. Hu, C., Gao, X., Xu, D., Zhou, Z., Li, X., Bai, Y., Li, T., Zhang, H., Zhang, C., Bing, L., & Deng, Y. HyperMem: Hypergraph Memory for Long-Term Conversations. arXiv:2604.08256, 2026. arxiv.org/pdf/2604.08…
  3. Hu, C., Gao, X., Xu, D., Zhou, Z., Bai, Y., Li, X., Zhang, H., Li, T., Zhang, C., Bing, L., & Deng, Y. MSA: Memory Sparse Attention for Efficient End-to-End Memory Model Scaling to 100M Tokens. arXiv:2603.23516, 2026. arxiv.org/pdf/2603.23…