
看一套 Agent 的记忆设计得好不好,不用读代码,问一个问题就够:
"这个用户三个月前说过一句偏好,你现在能不能准确地把它取回来,同时不把上周已经改过的旧值也带回来?"
答不上来,通常不是检索算法的问题,而是把三种性质完全不同的东西塞进了同一个容器。
多数团队的做法是接一个向量库,所有对话切片入库,每次检索 top-k。这套在 demo 里效果很好,上线后一般会出现三类症状:检索回来的东西不相关、旧信息压住新信息、以及数据越多越慢。
拆开看,Agent 要记住的东西其实是三种,性质差别很大。
短期(工作记忆):当前任务的上下文。生命周期等于任务,载体是上下文窗口和任务状态。它不需要检索,只需要装配——预算是多少、怎么压缩、什么该保留,是装配层的事。
长期(事实与偏好):跨任务的稳定事实。"这个账号是企业版""时区是 UTC+8""金额单位用分"。特点是量少、必须准确、更新时存在冲突需要裁决。
情景(事件记忆):过去发生过什么。"上个月处理过一笔类似的退款,当时走了人工审批"。特点是量大、允许模糊、主要访问方式是相似度检索。
关键判断只有一句:只有第三层适合用向量检索。 前两层上向量库,等于给确定性数据引入不必要的不可解释性。
长期记忆的访问模式是"按需取用",不是"找一个最像的"。
你要的是 user_id → 偏好集合,而不是"和这句话语义最近的十条记录"。用向量来做这件事,会得到两个后果:一是取回来的字段不确定,二是无法做精确的覆盖更新。
我倾向于这样设计:
最后一条尤其重要。模型的一次幻觉如果直接落库,会永久污染记忆,而且后续所有任务都会读到这个脏值。正确做法是让模型输出"候选记忆 + 置信度 + 依据",再由一层规则决定是否入库。模型负责提出,规则负责裁决。
到了事件层,向量检索是对的,但它只能解决一半问题。
向量擅长语义相似:找"和当前情况看起来像的历史案例"。
它不擅长关系传导:A 和 B 相关、B 又和 C 相关,问的是"这个客户所属集团下其他子公司的处理方式"——这类问题的答案在结构里,不在语义里。向量只能找回字面相似的文本,找不回结构上的邻居。
所以情景层的常见组合是:向量做入口召回,图做多跳扩展。上图的时机不是一开始,而是当"关系型问题"在真实提问里反复出现、且向量明显答不对的时候。
拿到向量库不等于检索能用。下面四件事,做了和没做差距很大。
按事件切,不按 token 数切。 固定长度切片会把一次完整的交互(问题、决策、结果)切成三块,检索回来的时候每块都不完整。切分单位应该是"事件"。
写入时打标签。 时间、主体、动作类型这些元数据在写入时就标好,检索时先按标签过滤再算相似度。这一步能砍掉大部分噪声——比如查退款处理时,先把非退款类的事件过滤掉,再比相似度。
检索后重排。 召回的候选用一次规则或模型重排,把"语义像但实际无关"的挤下去。规则能做的别上模型,比如主体不匹配的直接降权。
加时间衰减。 默认给相似度乘一个时间权重,越近越优先。没有这一项,"三年前的偏好"和"昨天的偏好"在打分上是同权的,而它们显然不该同权。
只设计"写入"不设计"过期",是记忆系统最常见的缺失。累积到一定程度,系统表现为"越用越笨"——检索结果被陈旧内容稀释,成本和延迟同时上升。
三层的遗忘策略不一样:
上完记忆之后要有指标,否则无法判断它到底有没有用。我只认一个:
检索命中率 = 检索返回的内容里,最终被答案实际引用的比例。
这个数低,说明召回质量差或者检索时机不对;这个数高但用户满意度没变化,说明你记的东西不是用户真正需要的。它也是决定"要不要上图、要不要加 rerank"的唯一依据——先看这个数,再决定加什么。
不建议一上线就上知识图谱。
图的建设和维护成本很高——实体要归一、关系要抽取、冲突要合并,而且它会随着业务变化不断腐化。而多数 Agent 场景里真正的"关系型查询"占比不到两成。
先用向量加标签过滤扛住,等出现了明确的、向量确实扛不住的关系型需求,再上。省下来的工程资源,用在长期层的冲突裁决上收益更大。
记忆不是"存得越多越好",也不是"一个向量库解决所有"。它是一次分层:什么该被记住、记多久、怎么找回来、谁有权改。
这四问答清楚了,选型是顺带的结果。
同系列:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。