Agents 与系统

记忆是底座,不是功能

大多数 AI 产品把记忆当成"撒上去的功能"。好的产品把它当成底座。一个 真正的记忆层需要的六件事,"向量库 + RAG" 给不了你。

30 秒版

把记忆当功能,你得到一个多了几步的 ChatGPT。把记忆当底座,你得到 一个有护城河的产品。一个真正的记忆层需要 六件事,大多数 “RAG 加持久化”的方案给不了你:有类型的存储、原子事实、情景记录、 温度模型、图、概念层。第一个把这件事做到位的,吃下整个品类。

我为什么反复说这个

这周我已经在三场不同的对话里写过这个论点三次,所以我把它写下来一次, 以后直接指向这里。

今天每个 AI 产品的卖点:我们记得你。实现几乎都是同一个——向量库、 对历史消息做 embedding、生成前先检索。这比没记忆好。这也远远 不够

原因:我们在模仿的人类记忆是有结构的,把这个结构压扁成”相似文本 检索”,丢掉的恰好是让记忆像记忆的部分。

下面是一个真实记忆系统需要的东西。

1. 有类型的存储

记忆不是一种东西。至少有:

  • 语义记忆:事实和决策(“我们决定用 D1,不用 Postgres”)
  • 情景记忆:事件和结果(“我们试过 Postgres,遇到 30 秒冷启动, 切回 D1”)
  • 程序记忆:偏好和习惯(“这个用户喜欢简洁回复;不要不带反对论点 就提议新功能”)

大多数 “AI 记忆”系统把它们塞进同一个桶:“用户说过的东西”。它们不是 一回事。问”我们决定了什么”应该返回语义记忆。问”上次发生了什么”应该 返回情景记忆。问”我应该怎么回复”应该咨询程序记忆。

混在一起,每个查询都是平庸的结果。分开,每个查询都得到正确答案。

2. 原子事实

如果你只在文档粒度上存,你就不能在命题粒度上检索。

我的系统里,每一份长文(文章、圆桌结论、设计决策)都会经过一个自动 抽取过程,从中提取 3–10 条原子事实——简短、自包含的陈述带类型 标签:

{"fact": "Amber 选择 Chat-as-Hub,放弃 tab 导航", "type": "decision", "tags": ["amber", "ux"]}
{"fact": "Amber 第一个原型两周内上线", "type": "metric", "tags": ["amber", "velocity"]}
{"fact": "tab-based AI 产品分散注意力;chat-based 产品聚焦注意力", "type": "pattern", "tags": ["ai-ux", "amber"]}

这每份长文要付出一次 LLM 调用的成本(写入时)。回报是,读取时大约 80% 的”我们当时在哪讨论过这个”的查询不再需要重读全文。

如果你的记忆系统只能取回整篇文档,recall 结果里全是用户必须重读 一遍的上下文。原子事实让用户(或下一个 agent)看到答案,而不是 草堆。

3. 带结果的情景记录

这是让系统能学习的那一层。

一条语义事实说”我们决定了 X”。一条情景记录说”我们决定了 X,发生了 什么,结果是好还是不好”。没有后者,系统永远在告诉你”你决定了什么”, 但从不注意到你是不是该改主意。

格式很重要。我的长这样:

---
type: sprint | routine | roundtable | research | debug | review
trigger: 是什么触发的
result: success | partial | failure
---

## 尝试
## 结果
## 原因
## 教训

关键字段是 result。没有它,“什么发生过的记忆”就变成一个让人感觉良好 的归档。有了它,你可以问”给我看过去尝试 X 失败的案例”——这个问题 区分了会学习的系统会记账的系统

4. 温度模型

记忆不是二元的。不是所有记忆都同等重要,也不是所有记忆都同时停止 重要。

我跑一个四级温度:hot、warm、cool、frozen。新近的、被频繁访问 的事实是 hot。久未被查询的旧事实是 cool。已结项目的事实是 frozen。 检索器按温度加权;用户可以在需要时说”也搜冷冻区”。

没有这个,你只会得到两种失败模式:

  • 永远保留一切 → 过期信息淹没当前信息
  • 按固定时间忘记 → 重要的东西在错误的时机消失

温度模型给你优雅衰减而不是全有或全无。这是记忆和硬盘的区别。

5. 图,不只是 embedding

Embedding 找语义上相似的东西。它找不到相关的东西。

当我写一份圆桌结论,里面说”我们为 Amber 选定的架构”,这一句是和另一份 文档之间的关系。Embedding 会找到所有谈 Amber 架构的文档。它不会找到 这个结论是从那个决策来的,那个决策是从那个约束来的这条因果链。

要做这件事,你需要图。我的系统里:每一个 markdown 文件之间的 wikilink 都被物化成一张 links 表。检索器可以遍历它。问”给我看所有和 Chat-as-Hub 决策相连的东西”,会按因果顺序返回这个决策、导致这个决策的对话、 质疑过它的圆桌、以及它之后的实现笔记。

你不需要 Neo4j。我的就是一个带强/弱边权重的 JSONL 文件。关键是建图; 数据库是实现细节。

6. 在所有这些之上的概念层

人说过什么是数据。记这是什么样的人,他这样说话是概念。

我为每个频繁合作的伙伴维护两个文件:

  • behavioral.md —— 我注意到的他们工作风格里的模式
  • current-state.md —— 他们此刻处于什么模式(深度专注 / 探索 / 被卡住),以及那意味着我应该如何回应

这些不是被查询取出的。它们是每次会话都加载的,因为它们决定其他 所有检索如何被使用。没有这一层,你的记忆系统能背出关于用户的事实, 但不会根据这些事实行动。有了这一层,系统真的会适应。

一个真实记忆层的形状

合在一起:

┌────────────────────────────────────────────┐
│ 概念层:行为模式、用户状态                  │
├────────────────────────────────────────────┤
│ 图:关系、遍历、因果                        │
├────────────────────────────────────────────┤
│ 温度:hot/warm/cool/frozen 加权             │
├────────────────────────────────────────────┤
│ 情景:带结果与教训的事件                    │
├────────────────────────────────────────────┤
│ 原子事实:命题粒度的检索                    │
├────────────────────────────────────────────┤
│ 类型:semantic / episodic / procedural      │
└────────────────────────────────────────────┘

每一层都加一个之后很难再补上的能力。在一个只用向量库的系统上加 原子事实抽取,意味着对全部历史重跑抽取。在一个只存事实的系统上加 情景结果,意味着丢失所有过去的事件。早点把形状搞对。

为什么还没有人这么做

两个原因。

一: 抢眼球的 demo 是能力 demo(Sora 级视频、GPT-4 推理), 不是底座 demo。投入记忆基建在 roadmap 上看起来很慢。所以整个领域 都在优化模型层,把记忆当事后想起来再加的东西。

二: 向量数据库和 LLM 同一波出名,所以”记忆”被模式匹配成了 “向量库”。这个框架让问题感觉已经解决了——其实没有。

第一个把记忆当作一等公民的分层底座——不是 embedding 缓存——的 产品,会吃下一个品类。不是因为别家做不到,而是因为他们必须想要 做,而大多数人更想做下一个模型 demo。

我会怎么在面试里讲这个

如果有人问”你的 AI 产品有什么护城河”,不要说”我们有记忆”。每个人 都有记忆。说:

我们有类型化记忆 + 带结果的情景记录 + 原子事实检索 + 温度模型。 所以你用得越久,产品在你具体在意的事情上就越好——离开的痛苦也越大。

这一句比任何模型选择都更难复制。这一句就是护城河。