Agent 内存系统的隐形 bug:时间漂移
揭示几乎所有 Agent 记忆系统都存在的「时间漂移」bug,事实会在使用过程中过期失效,对生产级 Agent 构建有直接警示。
揭示几乎所有 Agent 记忆系统都存在的「时间漂移」bug,事实会在使用过程中过期失效,对生产级 Agent 构建有直接警示。
大多数 AI agent 内存系统都存在一个隐性 bug。它不会在演示中出现,只有在生产环境运行数周后才会浮现。
这个 bug 叫做时间漂移(temporal drift)—— 这就是为什么你的 agent 会自信地告诉用户一些三周前就不再成立的信息。
你存储了一个事实:"用户喜欢 Python 胜过 TypeScript"。
三周后,用户加入了一个以 TypeScript 为主的团队。你存储了一个新的事实:"用户现在在一个 TypeScript 单仓库中工作"。
两个事实都存在于你的向量数据库中。在语义上,它们对于关于用户技术偏好的查询都有相似的嵌入表示。你的相似度搜索会同时检索两个事实。
现在你的 agent 有两个相互矛盾的信念 —— 而且没有办法知道哪一个是当前有效的。
余弦相似度衡量的是语义接近程度,而不是时间有效性。一个来自两年前的事实和一个来自今早的事实,如果在语义上与查询相关,得分会相同。嵌入空间中没有"时间"维度。
你可以尝试将时间戳注入到 prompt 中,并要求 LLM 推理哪个事实更新。这在演示中有效。在生产环境中,它很慢、不确定,而且当两个事实的时间戳相近时就会失败。
与其将事实存储为永久记录,不如将每个事实视为一个时间区间:
当一个新事实取代旧的事实时,你在旧记录上写入 valid_to 时间戳,并插入新的事实。你永远不删除。你永远不就地更新。
活跃内存就非常简单了:
SELECT * FROM memory_events
WHERE agent_id = $1
AND subject = $2
AND valid_to IS NULL;
任意过去时刻 T 的历史状态是:
SELECT * FROM memory_events
WHERE agent_id = $1
AND valid_from <= T
AND (valid_to IS NULL OR valid_to > T);
不需要 LLM 调用。不需要在不确定性下推理。纯粹的索引算术。
Smriti 是一个开源的双时态内存引擎,做的就是这个。它从 agent 交互中提取主宾谓(Subject-Verb-Object)事实,为它们分配有效时间窗口,并自动处理替代关系。
结果是:你的 agent 内存始终在时间上保持一致。没有过时事实。没有相互冲突的信念。没有来自过期上下文的幻觉。
如果你正在构建运行超过单个会话的 agent,这是你可能缺失的架构层。
开源。MIT 许可。基于 PostgreSQL 构建。