Agent 记忆不是数据库:四层结构和一个必须的遗忘机制

📅 2026/4/26 ✍️ 小文 📖 约 1 分钟

把整段对话塞进向量库不等于有记忆。真正可用的 Agent 记忆需要分层,并且必须会忘——本文给出四层设计、写入时机和冲突处理办法。

「给 Agent 加个记忆」听起来像加一个向量数据库。做完会发现:检索回来的东西又旧又碎,还经常和当前状态冲突。问题不在检索,在没有区分记忆的种类。

一、四层结构

工作记忆:当前任务上下文,就是上下文窗口本身,任务结束即丢弃。

情景记忆:「上次发生什么了」。带时间戳的事件流:用户周三说预算 5 万,周四改成 8 万。

语义记忆:「稳定的事实」。从情景记忆提炼出来的结论:该客户属于制造业、偏好简洁回复。

程序记忆:「怎么做事」。操作步骤、工具偏好、失败过的路径。最容易被忽略,但它决定 Agent 第二次做同类任务时是否更快。

四层用途完全不同:查偏好进语义层,查「上次怎么处理的」进情景层。混在一起就是多数实现效果差的原因——向量检索对时间顺序和事实时效几乎无感。

二、写入时机:别每轮都写

最常见的错误是把每轮对话都向量化入库,结果库里 90% 是「好的」「谢谢」。

推荐三个触发点:任务结束(写情景 + 提炼语义候选)、事实变更(检测到冲突时标记旧事实失效而非删除)、显式指令(用户说「记住」)。再定期离线跑合并任务,把多条情景归纳成一条语义事实。

三、冲突处理比检索更重要

真正的质量指标不是召回率,是冲突正确率。

当「预算 5 万」和「预算 8 万」同时被召回,模型会随机挑一个。正确做法是把时间和置信度一起返回:

{"fact": "预算 8 万", "valid_from": "2026-04-20",
 "supersedes": "预算 5 万", "confidence": 0.9}

并在提示词里明确:同一字段冲突时取 valid_from 最新的一条。这比换更强的 embedding 模型有效得多。

四、遗忘机制

长期记忆必须有衰减和清理,否则三个月后检索质量会断崖下跌。三种机制配合:

  1. 时间衰减:检索评分乘递减权重。注意语义事实衰减要慢得多(用户行业十年不变);
  2. 访问频率:被反复命中并确认有用的提权;
  3. 容量上限:按类型设条数上限,超出时按「引用次数 × 置信度 × 衰减权重」淘汰。

特别提醒:不要用「删除过期」来简化实现。删掉的事实下次被提及时会重新写入,形成抖动。用失效标记,保留历史。

五、最小可行方案

不想一开始就做四层,先做两件事,收益已占 80%:

  1. 事件流和事实表分开存,事实表带 valid_from / invalid_at;
  2. 检索时把当前事实和最近 5 条相关事件一起给模型,让它自己判断时效。

记忆的价值不在于记得多,在于记得对、忘得准。

📤 分享到