记忆不是向量数据库:为什么 AI 代理需要信念,而不是存储
Source: Dev.to
请提供您希望翻译的完整文本内容(除代码块和 URL 之外),我将为您翻译成简体中文并保持原有的 Markdown 格式。
Source: …
不断出现的模式
如果你构建了一个能够在多个会话中与用户交互的 AI 代理,你可能已经遇到过这样的壁垒:代理不断忘记它本该记住的内容。
你存储了用户偏好。代理却忽视它们。你纠正它。它第二天又犯同样的错误。你在提示中加入更多上下文。它暂时有效,随后又崩溃。
于是你想到显而易见的解决方案:向量数据库。把所有信息存进去,检索相关内容,注入提示。问题解决了,对吧?
其实并非如此。
我已经构建代理有一段时间了,始终看到同样的模式。向量检索可以帮你完成约 70 % 的工作。剩下的 30 % 正是事情崩溃的地方——而且这部分才是真正影响用户体验的关键。
我反复看到的情景
- 用户对你的代理说:“我更喜欢暗色模式。” 你把它存下来。很好。
- 一周后,用户说:“其实,我已经改成亮色模式了——白天看起来更舒服。”
会发生什么?你的向量库现在拥有两条相互矛盾的陈述。当代理检索 用户显示偏好 时,它可能得到其中一个,或者两个。它根本无法判断哪个是最新的,哪个已经过时,或者对哪一个应该有多大的置信度。
于是代理会前后摇摆,甚至更糟——自信地断言错误的偏好。
这不是检索问题,而是表征问题。我们把记忆当作存储来处理,而它本应被视为信念。
另一种失败模式
一个客服代理发现,在提出解决方案之前先询问澄清问题可以降低流失率。你手动观察到这个模式,但代理从未这样做。
你可以存储过去的对话。你可以检索相似的对话。但向量库里没有任何东西能把“这种方法有效”转化为“以后多用这种方法”。
那不是记忆,那是日志。
我把这称为 存储谬误:错误地认为持久化会自动产生理解。
嵌入列表并非记忆
向量数据库在一件事上表现出色:寻找语义相似的内容。但相似并不等同于相关,检索也不等同于记忆。
人类记忆并不像文件柜,你可以随时抽出文档。它是一个主动的系统,能够:
- 强化 你反复遇到的事物
- 遗忘 你不再使用的事物
- 更新 当新信息与旧信息相冲突时
- 加权 记忆的可信度,而不仅仅是相似度
当你对某人说同样的话三次时,他们会对其真实性更有信心。当你自相矛盾时,他们对两种说法的确定性都会下降。当你几个月不提及某件事时,它会逐渐淡去。
这些都不会在向量存储中发生。每个嵌入都会以相同的权重永久存在,除非你手动将其删除。
记忆即信念
改变我对这件事看法的转折点:不再把记忆当作事实,而是把它们当作 信念。
信念具有存储事实所不具备的属性:
| 属性 | 描述 |
|---|---|
| 置信度 | 我们对其真实性的确定程度。一次随口提到的偏好与三次强调后提到的偏好不同。 |
| 强化 | 当我们再次遇到相似信息时,置信度应提升。“用户喜欢暗色模式”与“用户偏好暗色主题”应加强同一个信念,而不是生成两个条目。 |
| 衰减 | 未被访问或强化的信念应随时间淡化。不是被删除,而是被降级。两年前的偏好可能不如上周说的那样重要。 |
| 冲突处理 | 当新信息与已有信念冲突时,两者都应受到影响。旧信念的置信度下降;新信念以中等置信度开始。系统承认不确定性,而不是假装不存在。 |
信念是随时间变化的函数,而非静态行。
示例
"User prefers dark mode" → stored with confidence 0.6
User mentions dark mode again → confidence rises to 0.75
User later says "I prefer light mode" →
- "dark mode" drops to 0.45
- "light mode" created at 0.65
现在代理不再看到“两个事实”。它看到的是不确定性,并可以说:“我认为您现在更倾向于浅色模式,虽然您以前偏好暗色模式”,而不是自信地断言错误的内容。
具体表示
{
"content": "User prefers dark mode",
"confidence": 0.45,
"last_verified_at": "2024-01-12",
"reinforcement_count": 3,
"source": "user_statement"
}
不是文档。不是嵌入。是一个有状态的对象。
记忆不是单一的东西
另一个领悟:我一直把截然不同类型的记忆归为同一个标签。认知科学几十年来一直知道,人类记忆并非单一整体。它由服务于不同目的的独立系统组成。对智能体而言,最重要的四种类型是:
-
语义记忆 – 事实性知识。
“用户是一名后端工程师。”
“他们在一家金融科技公司工作。”
“他们偏好使用 Python 进行脚本编写。” -
情景记忆 – 体验性上下文(何时、何地、情绪基调、结果)。
“上周二,用户因部署失败感到沮丧。我们帮助他们设置了监控。他们感到满意。” -
工作记忆 – 活跃的草稿板。当前的目标是什么?现在相关的上下文是什么?这属于会话范围,容量有限——不可能一次性保持所有信息活跃。
-
程序性记忆 – 已学会的技能和成功行动的模式。
“当用户表示想要取消时,先提供折扣再处理通常能促成留存。”
理解并建模这些不同的记忆系统——而不是把一切都当作静态向量存储——就能弥补那缺失的 30 %,并提供更出色的用户体验。
代理随时间提升工作能力的方式
这并非学术上的纯粹概念。每种类型都可以直接映射到工程职责:
| 记忆类型 | 工程职责 |
|---|---|
| Semantic(语义记忆) | 长期知识存储 |
| Episodic(情景记忆) | 仅追加的经验日志 |
| Working(工作记忆) | 主动上下文组装器 |
| Procedural(程序记忆) | 策略选择系统 |
我见过的大多数“记忆”实现都把所有内容都当作 semantic memory(语义记忆)。它们忽略了情景记忆的时间丰富性、工作记忆的主动聚焦以及程序记忆的技能累积。
更大的模型并不能解决记忆问题
更大的上下文窗口可以让代理记住更多信息,但并不能让它们记得 更好。
- 没有强化、衰减和矛盾处理机制,增大的上下文只会导致更多杂乱。
- 你可以在提示中放入 100 k token,但仍然无法表达 “我过去相信 X,但现在以中等置信度相信 Y”。
许多看似推理错误的代理失效实际上是记忆问题。模型的推理本身没有问题——只是因为检索提供了过时或相互矛盾的信息,且没有任何信号指示该信任哪部分,从而导致在错误的上下文上进行推理。
我们正在构建的内容
这正是我创建 Engram——一个为 AI 代理提供认知记忆层的动机所在。
**核心理念:**记忆应当表现得像记忆,而不是像存储。
可以把它看作位于代理与其底层存储之间的认知操作层。目前的重点是正确性和认知行为,而非功能广度。
- 当你存储一个信念时,它会带有置信度。
- 当你再次遇到它时,它会得到强化。
- 当你与之相矛盾时,两个信念都会进行调整。
- 当你不再访问它时,它会衰减。
- 检索返回的不仅是相似度,还会给出一个加权分数,综合考虑置信度、近期性和相关性。
你可以存储带有完整上下文的情节——实体、情感价值、结果——并让系统自动提取语义信念。你可以记录哪些方法有效、哪些无效,让过程模式自行显现,从而随时间提升代理的表现。
我们始终观察到,代理在进行几十次交互后会停止重复相同错误。这并不是因为我们调优了什么,而是记忆系统在做记忆本该做的事。
Engram 是一个 HTTP API。将其接入任何代理框架即可;它负责认知复杂性,让你的代理代码保持简洁。
这不是
以下是 Engram 明确 不 做的几件事,因为范围很重要:
| ❌ 不是 … | 说明 |
|---|---|
| 代理框架 | 我们并不与 LangChain、CrewAI 等竞争。我们是它们可以使用的基础设施。 |
| 向量数据库 | 我们内部使用向量,但那是实现细节。接口是认知的,而非几何的。 |
| 长期上下文填充 | 我们不构建巨大的提示。我们构建能够识别重要信息的系统。 |
我们的目标是 成为记忆层——专注于一件事,做到极致。
适用对象
如果你正在构建能够随时间与用户交互的代理,并且对以下问题感到沮丧:
- 上下文限制迫使你舍弃重要信息
- 代理重复同样的错误
- 偏好无法持久保存
- 没有学习或改进的感觉
……那么 Engram 可能会对你有帮助。
它仍处于早期阶段。API 正在趋于稳定,我们正在寻找想要使用它并提供反馈的开发者。
接下来
我们正在发布示例和基准,展示学习动态的实际运行情况。演示中可以看到,错误率会随着代理累积 程序性记忆 而下降,这并不是因为我们调了参数,而是记忆系统在做它应当做的事。
Repo:
如果这与你对代理记忆的思考产生共鸣,欢迎告诉我你的想法。如果你认为我在某些方面说错了,也请不吝指教。
公开构建意味着在公开场合出错。这是为了打造真正有效的产品所必须付出的代价。 :)