Back to Writing
Mar 25, 2026·中文·AI & Agent·Other Ideas

Supermemory 架构拆解:当 Agent Memory 变成一张图

Supermemory 是一个 agent memory 服务。你把对话、文档、各种内容扔给它,它帮你提取事实、维护关系、处理冲突,搜索的时候返回和当前上下文最相关的记忆。定位是给 AI agent 做长期记忆的基础设施。

最近在 X 上频繁看到 Supermemory。一方面是越来越多开发者开始用它的 plugin 给 OpenClaw、Claude Code 这些 coding agent 加 memory layer,另一方面是 Supermemory 的 CEO Dhravya Shah 前两天发了一篇 article,讲他们用多 agent 编排在 LongMemEval 上打到了 ~99%,拿了 2.5M views。虽然他自己在推文里承认 "this was a stunt",那个 99% 的方案是实验性的(用 8 个 specialist agent 并行回答然后投票),不是他们的 production engine。但这篇文章确实引起了很多关注,也让我好奇 Supermemory 的 production 架构到底是怎么设计的。

之前写了 OpenClaw 的记忆系统,OpenClaw 走的是 Markdown-first 的路线:长期记忆存在文件里,搜索索引只是派生层,dreaming 把短期信号逐步提升为长期记忆。整个系统围绕文件展开,透明、可编辑、完全本地。

Supermemory 走了一条完全不同的路。它把记忆建模成一张图,每条记忆是一个节点,节点之间有版本关系和语义关系。OpenClaw 认为记忆是文本,Supermemory 认为记忆是事实的图谱。

这篇文章拆解 Supermemory production 系统的架构设计。素材来自两部分:它的 research paper 和它的 开源代码。后面会提到,这两部分之间有一些有意思的落差。

核心抽象:Document 和 Memory

Supermemory 最重要的一个设计决策是把输入和理解分成两层。

Document 是你扔给它的原始内容。PDF、网页、对话记录、文本片段。它是 stateless 的,一篇关于 Python 编程的文档对谁都一样,不会因为用户不同而改变。

Memory 是系统从 Document 中提取出来的原子化事实。"Alex 在 Stripe 做 PM"、"用户偏好深色模式"、"项目 deadline 是下周五"。Memory 是 stateful 的,绑定到具体的用户或实体,会随时间演变。

用一个不太精确但直觉上好理解的类比:Document 是书,Memory 是读完之后脑子里留下的东西。

这个分层解决的是标准 RAG 的一个根本问题。传统 RAG 直接在原始 chunk 上做搜索,但 chunk 从原始文档里拔出来之后,代词指代不清、上下文丢失,信噪比低。Supermemory 先把 document chunk 提炼成原子事实,搜索在这些高信噪比的 memory 上进行,命中后再把原始 chunk 注入结果来补充细节。

Memory 层做精准召回(高信噪比,一条记忆就是一个事实),Chunk 层补充细节(完整上下文,适合 LLM 做细粒度推理)。这个两层搜索的设计解决了"memory 太抽象丢细节"和"chunk 太嘈杂召回差"的两难。

Relational Versioning:记忆之间的关系

如果只做到 Document → Memory 的提取,那 Supermemory 就是一个稍微精细一点的 RAG。更大的区别是它在 memory 之间建立的关系。

三种关系类型:

  1. updates。新事实推翻旧事实。你上个月说"我最喜欢蓝色",这个月说"我现在喜欢绿色了"。系统不会让两条矛盾的 memory 同时存在,而是建立一个 update 关系:新 memory 标记 isLatest=true,旧的标记 isLatest=false。搜索默认只返回最新版本,但历史版本沿着版本链可以追溯。

  2. extends。新事实补充旧事实,不矛盾。"Alex 在 Stripe 做 PM" 后来又知道了 "Alex 负责支付基础设施,带 5 人团队",第二条 extends 第一条。两条都有效,搜索时能拿到更丰富的上下文。

  3. derives。系统从多条 memory 推断出新事实。"Alex 是 Stripe 的 PM" + "Alex 经常讨论支付 API 和反欺诈" → 系统推断 "Alex 大概负责 Stripe 的核心支付产品"。这条 derived memory 标记 isInference=true

这是 Supermemory 和 OpenClaw 最根本的差异。OpenClaw 的记忆是扁平的 Markdown 文本,MEMORY.md 里一行一条,没有结构化的关系。你告诉 agent 你换工作了,它得靠自己的判断力去修改 MEMORY.md 里的旧信息。Supermemory 把这个问题内化到了数据模型里:新旧信息的关系不是文本编辑,而是图上的一条边。

和 GraphRAG 的区别

看到"graph"这个词,我最开始联想到的是前两年微软做的 GraphRAG。两者都认为 flat vector search 不够用,都在 vector 之上加了一层图结构,但图的设计其实完全不同。

GraphRAG 建的是传统的 entity-relationship 知识图谱。三元组结构:entity → relation → entity。从文档里提取出 "Microsoft → headquartered_in → Redmond" 这类关系,然后做 community detection 把紧密关联的 entity 聚类,再对每个 community 做层级摘要。它解决的是"对一个大语料做全局性问答"的问题,比如"这批文档的主要主题是什么"。

Supermemory 建的不是 entity graph,而是 versioned fact graph。节点是原子化事实,边是版本关系。Supermemory 自己的文档里有一句话直接点明了这个区别:"Unlike traditional knowledge graphs with entity-relation-entity triples, Supermemory's graph is facts built on top of other facts." GraphRAG 的图是静态快照,不处理知识冲突,也没有时间维度。Supermemory 的图是动态演进的,每条 fact 有版本链,旧事实可以被新事实 update,过期的事实会被自动遗忘。

从它开源代码里的 Zod schema 能看到完整的数据结构:

// packages/validation/schemas.ts
MemoryEntrySchema = z.object({
  id: z.string(),
  memory: z.string(),              // 原子事实
  version: z.number().default(1),
  isLatest: z.boolean().default(true),
  parentMemoryId: z.string().nullable(),  // 版本链上一个节点
  rootMemoryId: z.string().nullable(),    // 版本链根节点
  memoryRelations: z.record(            // {memoryId: relation}
    MemoryRelationEnum                  // "updates" | "extends" | "derives"
  ).default({}),
  isInference: z.boolean().default(false),
  isForgotten: z.boolean().default(false),
  forgetAfter: z.coerce.date().nullable(),
  // ...
})

版本链用 parentMemoryId / rootMemoryId 形成链表。关系用 memoryRelations 做邻接表。搜索返回结果时,会附带 context.parentscontext.children,让 LLM 能看到一条 memory 的完整演变历史。

自动遗忘

Memory 不只是会积累,也会过期。Supermemory 有两种遗忘机制。

时间过期。"我明天要考试",考试过了这条 memory 就没多大意义了。schema 里有一个 forgetAfter 字段,后端的 LLM 在提取 memory 时自动判断要不要设过期时间。后台 cron job 定期扫描过期的 memory,标记 isForgotten=true

矛盾消解。通过 update 关系自动处理。"我喜欢绿色" 被 "我现在最喜欢蓝色了" update 之后,搜索只返回最新版本。旧 memory 不是删了,而是 isLatest=false,需要的时候还能追溯。

这解决了 OpenClaw dreaming 没有覆盖的一个问题。OpenClaw 的 dreaming 做的是 promotion:什么值得从短期记忆提升到长期记忆。但它不处理反方向的问题,即旧记忆过时了怎么办。Supermemory 用 update 关系 + forgetAfter 两个机制同时解决了知识冲突和时间过期。

User Profiles:预聚合的记忆

Profile 是一个工程优化。系统从所有 memory 中自动维护一个 per-user 的摘要,分两层:

这个 profile 在每次对话开始时作为 default context 注入 LLM,不需要做搜索就能让 LLM 知道用户是谁。响应时间大约 50-100ms,因为它是预计算好的,不是实时搜索拼出来的。

这相当于把最高频召回的 memory 预热成一个 cache 层。大部分对话开头 LLM 需要知道的基础信息("用户是做什么的"、"用户最近在忙什么")都在 profile 里,不用每次都发起一次完整的 memory search。

Temporal Grounding:更精细的时间戳

Supermemory 的 research paper 重点宣传了一个叫 "Temporal Grounding" 的特性:每条 memory 有两个时间戳,documentDate(对话发生时间)和 eventDate(事件实际发生时间)。论文里画了图,写了专门的章节,把它列为 "core differentiator"。

但我翻遍了开源代码里的 Zod schema,没有找到 documentDateeventDate 这两个字段。实际的时间模型是:

这意味着什么?有两种可能。一种是 temporal grounding 确实存在,但实现在闭源的后端代码里,开源的 schema 只是客户端验证用的子集,不包含所有字段。另一种可能是 temporal grounding 更多是 LLM 在提取 memory 时通过 prompt engineering 实现的,不是一个独立的结构化字段,而是 memory 文本本身就包含了时间信息(比如 "Alex 在 2026 年 3 月搬到了 Seattle")。

不管哪种情况,论文里描述的"双层时间戳"和实际代码之间有明显的 gap。这不影响对整体架构的判断,但可能会影响 benchmark 结果的置信度。

Benchmark:怎么看那些数字

Supermemory 在 LongMemEval_s 上的表现确实很强,尤其是在 multi-session(71.43% vs Zep 57.9%)和 temporal-reasoning(76.69% vs Zep 62.4%)两个 category 上。这两个恰好是 relational versioning 和时序理解直接解决的问题。

CategorySupermemoryZepFull ContextDelta vs Zep
single-session-user97.14%92.9%81.4%+4.6%
single-session-assistant96.43%80.4%94.6%+19.9%
single-session-preference70.00%56.7%20.0%+23.5%
knowledge-update88.46%83.3%78.2%+6.2%
temporal-reasoning76.69%62.4%45.1%+22.9%
multi-session71.43%57.9%44.3%+23.4%

但有几点得注意。

第一,他们选择 session-by-session 而不是 round-by-round 的 ingestion 方式,和 LongMemEval 原论文的评估方法不同。这对做了 session-level 记忆提取的系统有利。第二,Zep 的数据直接引用自 Zep 自己的论文,不是在完全相同的条件下复现的。第三,500 道题的 benchmark 在统计上不算特别大,单个 category 的 delta 可能有噪音。

这不是说他们的结果有问题。relational versioning + 图结构在 knowledge-update 和 multi-session 场景上应该确实比扁平存储强,这个方向上的优势是符合直觉的。只是 benchmark 数字本身的精确对比要打个折。

和 OpenClaw 放在一起看

维度SupermemoryOpenClaw
记忆本体知识图谱(节点 + 关系)扁平 Markdown 文本
知识冲突updates 关系自动处理靠 agent 自己编辑文件
自动遗忘forgetAfter + 矛盾消解无(dreaming 只做 promotion)
搜索Memory-first → Chunk 补充Hybrid(vector + BM25)直接搜 chunk
User Profile自动维护 static/dynamic
部署云端 SaaS完全本地
透明性黑盒 API打开文件就能看
真相源云端 memory graph你的文件系统

OpenClaw 信任文件系统和用户。MEMORY.md 你随时能打开看,能直接编辑。记忆的最终裁判是人。整个系统的复杂度是有上限的,因为 truth 始终锚定在可读可改的文本文件上。

Supermemory 信任算法和图结构。关系检测、冲突消解、自动遗忘,这些都交给系统自动处理。结果可能更准确(benchmark 数据确实更好),但你没办法打开一个文件看到所有记忆,也没办法直接改一行文字来纠正一条记忆。

最值得借鉴的一个 idea

抛开产品形态不谈,Supermemory 架构里最值得带走的一个思路是:把记忆之间的关系显式建模

大部分记忆系统(包括 OpenClaw、Mem0、大多数 RAG 方案)把记忆当成独立的条目。每条记忆自己存在,搜索时按相似度排序返回。但现实中的记忆不是独立的,它们之间有版本关系(旧事实被新事实取代)、补充关系(一条信息给另一条增加细节)、推理关系(多条信息组合产生新理解)。

Supermemory 用三种边(updates / extends / derives)把这些关系编码进了数据模型。这让系统能回答一类其他方案回答不了的问题:"Alex 现在在哪工作?"(需要知道哪个版本是最新的)、"Alex 的职业经历是什么?"(需要沿版本链追溯)、"Alex 这份工作具体做什么?"(需要找到 extends 关系的补充信息)。

这个思路不需要 Supermemory 的整套基础设施也能用。哪怕是在 Markdown 文件里,也可以用 frontmatter 或者 link 来标记一条 note supersedes 另一条。关键不是具体的技术实现,而是记忆不是孤立的点,而是有关系的图这个认知。

References: