loading

Loading

探索与发现

首页 Agent 工程

Agent 记忆衰减:遗忘曲线落到代码里的几个坑

分类:Agent 工程
字数: (2244)
阅读: (4)
0
摘要:给记忆加条遗忘曲线谁都会,落到线上就是另一回事:分数在哪里算、什么时候算,粗筛和精排为什么不该混在一起乘,沉默死亡和旧偏好并行检索各自怎么破。记几组现成的失败数字,再做衰减上线前的开关对比。

记忆衰减这件事,理论讲起来很顺:给每条记忆加一个时间戳和一个重要性分数,按指数曲线往下降,低于阈值就归档。真到代码里,第一个问题就不是公式,而是谁来算这个分数,多久算一次。

业内一种常见写法是把衰减直接做进检索过程。PowerMem 的遗忘分数公式大致是「初始重要性 × e^(-λ × 层级倍率 × 时间差)」,其中初始重要性由六维评估加权得出,包括关联度、事实性、可操作性、个人相关性、时效敏感性和安全关键性。六维打分走 LLM 还是规则引擎,是个成本问题:每次都调模型评一遍,写入成本翻倍;纯规则又打不出「这个人对花生过敏」和「他上周在调一个 Python 服务」之间的差距。PowerMem 的设计是双路径——模型评估为主,规则兜底,牺牲一些精度换可控的成本上限。

要注意的是时间差这一项。如果你的衰减分数只在检索时现算,那它必然是「写入时的重要性 × 当前时间距写入时刻的距离」。这里有个容易忽略的细节:时间差应该取最后一次被命中的时间,而不是写入时间,否则一条被高频使用的记忆会和一条彻底死掉的记忆以同样速度衰减。这就是访问强化的必要性,不是锦上添花,是公式本身的要求。

先过滤再排序,别把衰减乘进相似度

一个常见错误是把衰减分数直接乘到向量相似度上,作为最终排序分。看起来简洁,实际很难调。语义相似度的量纲和衰减指数不是一个尺度,乘完之后阈值失去可解释性:你无法回答「这条记忆为什么排第三」,因为它可能是语义很准但衰减很多,也可能是语义一般但很新。线上出问题时,这一层黑箱会非常难受。

更稳的做法是两阶段:先用一个很低的分数线粗筛,把长期没人碰、高于归档线一大截的记忆直接踢出候选;再在候选集里做精排,排序分是语义相关度和衰减分数的加权组合。两个阶段各有各的阈值,可以分别调、分别观测。粗筛阶段丢掉的记忆数量本身是个好指标——它突然变多,说明你的死记忆在堆积。

归档线设 0.3 还是 0.2,没有通用答案。客服场景里过时政策必须尽快退出,线条可以拉到 0.3;涉及用户长期偏好的产品可以松一点。条件允许的话把这几个参数做成可配置项,至少在 LOCOMO 这类长期对话基准上跑一轮消融,看不同 λ 对答对率的影响,比拍脑袋定值靠谱。

三种典型的衰减事故

沉默死亡。一条重要但长期没被提及的记忆,会稳定地衰减到归档线以下。「对花生过敏」这类信息如果没有保底机制,三个月后 Agent 就不再知道这件事,而它并没有任何理由下次被检索到。解法是把安全关键类信息的分数设一个下限,或者干脆不让它进入衰减队列。

写入即巅峰。高频写入的场景会形成一个偏置:最新的记忆得分最高,旧记忆永远在被新记忆淹没。曾经有位用户提过更重要的工作流约束,但被连续几十条琐碎的调试记录压过去了。这类问题靠调 λ 解决不了,得在写入侧加质量门控,判断这条新记忆是否真的提供了已有记忆未覆盖的信息。

降权但没有标记失效。用户半年前在 A 公司,三个月前换了工作。旧记忆衰减后被降权,但它在语义上仍然和「用户在哪儿工作」高度相关,于是被一起检索出来塞进 prompt。LLM 看到两条互相矛盾的事实,行为就不可预测了。这是衰减和冲突处理脱节的问题,不是衰减本身的问题。

衰减与冲突裁决要一起设计

矛盾的两条记忆,光靠时间衰减区分不了轻重,尤其是两条都是近期写入的时候。工程上的做法一般是:语义比对找到潜在的冲突候选,用 NLI 或 LLM 判断是真矛盾还是并存——「喜欢意大利菜」和「最近在吃素」并不冲突,不该互相覆盖。确认矛盾后,直接冲突做显式覆盖,旧条目写一个失效时间而不是删掉,新条目写入;时间演进类的差异做合并,保留历史版本;并存类偏好就各自独立衰减。

检索阶段的多条矛盾记忆,不建议全丢给 LLM 自己判断。MemoryAgentBench 上的对比结论比较一致:事实类问题用确定性聚合——取版本最新的那条——一致性明显好于让模型临时裁决;复杂偏好再交给模型综合。这个分工本身要写进代码里,别指望 prompt 里的几行说明能兜住。

还有一类更难的情况:A 和 B 单看不矛盾,但各自推理出的结论冲突。这属于多跳冲突,在现有基准上仍是明显的空白,多数方案没处理。老老实实承认这块没解决,比宣称全流程闭环更负责。

衰减该往哪些方案上挂

不同产品的思路差异挺大。Mem0 把过期判断推给 LLM,托管 API 接入快,但每条写入都要过一次模型,成本和延迟都在那儿。Zep/Graphiti 用时序知识图谱解决,图边显式失效、历史边保留,需要精确追溯事实变化的场景更合适。Letta 让 Agent 自己管理记忆块,适合长程自主 Agent。PowerMem 走本地优先加混合检索。AI-Memory 这类开源项目直接实现了 STM 到缓冲区再到 LTM 的漏斗,加上艾宾浩斯曲线做可视化管理,做 Go 项目时可以拿来起步。

有篇讨论归纳的数据值得记住:使用全量存储策略的 Agent 积累了 2400 多条记录,医疗推理准确率跌到 13%;改成选择性管理后只留 248 条,准确率回到 39%。存储少了一个数量级,性能反而三倍。另一个自动驾驶任务上的对比是 51% 对 32%。这组数字的意义不在绝对值,而在于说明衰减策略上线前后的对比测试必须做——不发现在的问题很容易,出事之后回溯才发现该早点做。

遗忘问题的本质是策展问题:让你的记忆库随时间改善而不是退化,靠的不是更强的存储,是更清楚该把什么丢掉。

转载请注明出处: 皮哈皮阿

本文的链接地址: https://blog.phpat.com/agent-engineering/657.html

手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

您可能对以下文章感兴趣
1 / 1
预览图