← 返回资讯
苏晴
资深编辑
已审核

被用户骂“金鱼”后,我重新设计了Agent的记忆机制

上周三下午两点,我在调试一个客服Agent,眼睁睁看着它在第47轮对话时把用户3轮前说的“退货”给忘了,转头推荐了同款商品。用户直接甩了句“你是金鱼吗?”

被用户骂“金鱼”后,我重新设计了Agent的记忆机制

被用户骂“金鱼”后,我重新设计了Agent的记忆机制


上周三下午两点,我在调试一个客服Agent,眼睁睁看着它在第47轮对话时把用户3轮前说的“退货”给忘了,转头推荐了同款商品。用户直接甩了句“你是金鱼吗?”

扎心。但真说到点上了。

长序列决策里的记忆管理,这就是AI Agent的死穴。我从去年11月开始折腾一个方案,到现在快8个月了,总算有点能用的东西:渐进式状态摘要+遗忘机制。不扯论文,就说落地时踩的坑和那些歪打正着的解法。


为什么长序列这么要命

先看三个真实场景,都是我自己遇到的:

案例1:客服Agent的7天对话

我们有个电商客服Agent,用的是gpt-4-0125-preview这个版本,平均对话轮次在30-50轮。用户会反复提之前的订单号、退换货诉求、优惠券使用情况。传统做法是把所有历史消息塞进context window,结果GPT-4在超过15轮后开始“选择性失明”——第8轮用户说过“已经退货了”,第23轮Agent又去查物流状态。日志里一堆 order_status_check 的重复调用,token烧得我肉疼。

案例2:游戏NPC的剧情记忆

帮朋友做的一个文字RPG,NPC需要记住玩家在200+轮中的关键选择。一开始用全量记忆+向量检索(用的Qdrant,相似度阈值设的0.82),结果NPC经常把“你曾经偷过药水”和“你曾经买过药水”搞混。因为向量相似度太高了,两个句子就差了两个字。

案例3:代码审查Agent的上下文丢失

自己用的代码审查工具,分析一个大型PR时需要在3000行diff里追踪某个函数的调用链。Agent经常分析到一半“忘记”了函数签名,开始胡编参数类型。最离谱的一次,它把 def calculate_total(items: List[OrderItem]) -> Decimal 记成了 def calc(items: list) -> float,然后基于这个错误签名做了一整套类型检查。

这三个问题指向同一件事:信息不是越多越好,而是该记的记牢,该忘的果断忘


我踩过的三个大坑

坑1:把摘要当成压缩,而不是提炼

最开始我用了最粗暴的方案——每10轮对话让LLM总结一次,把1000字的对话史压缩成200字的摘要。看着挺合理对吧?

翻车了。

Agent在后续对话里变得跟失忆似的,只能记住摘要里的东西,细节全丢了。用户说“我上次提到的那个红色的”,Agent完全不知道他在说什么,因为摘要里只写了“用户询问商品”,把“红色”这个细节给压缩没了。

后来改成分层摘要

等等,这里我要更正一下——后来我把即时层从5轮改成了动态的3-7轮,看话题稳定性。话题稳定就留少点,话题跳跃就留多点。固定5轮在很多场景下要么多了要么少了。

关键insight:摘要不是压缩,是重新组织信息结构。客服场景的摘要格式我改过四版,最后稳定成这样:

JSON
{
 "当前意图": "退货咨询",
 "涉及订单": "ORD-20240115",
 "用户情绪": "不满-已安抚",
 "已确认信息": ["退货原因:尺码偏小", "退货方式:上门取件"],
 "待解决问题": ["退款金额需核实优惠券"]
}

这种结构化摘要让Agent后续能快速定位关键信息。之前用非结构化文本,Agent经常在500字的摘要里瞎找,现在直接读字段就行。

坑2:遗忘机制太死板

这个坑最贵。真的。

我一开始设计了很“工程师”的遗忘规则:超过30轮的信息直接丢弃、非关键实体立即遗忘、冲突信息以最新为准。逻辑清晰,边界明确。

上线第一周就出事了。有个用户在对话第5轮提到“我对花生过敏”,第35轮时Agent推荐了花生酱产品。因为我的规则把超过30轮的“非订单相关信息”全清掉了。用户发邮件投诉,客服主管找我谈话。

后来改成重要性评分+软遗忘

衰减函数用了指数衰减,半衰期大概设在15轮左右。但还加了个“唤醒机制”——如果后续对话出现了语义相似的内容,衰减值重置。这样既避免内存爆炸,又不会丢掉关键信息。

我觉得这个半衰期参数还挺关键的。设太短了信息丢太快,设太长了内存扛不住。目前15轮是我试出来的经验值,不一定普适。

坑3:状态摘要的更新时机

固定窗口(每10轮)看起来很合理。

实际上很蠢。

两个问题:一是用户在第9轮说了关键信息,第10轮就生成摘要,但第11轮用户又补充了相关细节——摘要里信息不完整。二是用户在3轮内快速切换了3个话题,固定窗口把三个不相关的事硬塞进一个摘要。

后来改成事件驱动的动态窗口

这个改动让摘要的“信息密度”提升很明显。之前一个摘要里可能混杂了闲聊、咨询、投诉三个话题,现在每个摘要都是单一主题的完整记录。

嗯...这个比较复杂,因为话题检测本身也不准。我的embedding阈值调了好久,0.65这个数是我在自己的数据集上试出来的,换别的场景可能需要重新调。


一个意外的发现

做了半年后我发现一个反直觉的事:Agent遗忘的内容本身也值得记录

我们在日志里加了个“遗忘日志”,记录Agent主动丢弃了哪些信息以及丢弃原因。本来只是想方便debug,结果这个日志比任何监控都好用:

现在我们的遗忘日志已经成了调优importance评分模型的核心数据源。这算是踩坑踩出来的feature。我们内部管这叫“元遗忘”,听着挺唬人,其实就是日志。


落地建议

1. 先上监控,再上优化:在改记忆机制之前,先把Agent的“遗忘率”“重复询问率”“信息冲突率”监控起来。不然你根本不知道改完是变好了还是变差了。我们用的是Prometheus + Grafana,三个指标挂了半年,现在回头看那些数据曲线,能清晰看到每次改动的效果。

2. 结构化摘要格式让业务方确认:我第一次设计的摘要JSON有20个字段,觉得自己想得特周全。结果业务方看了说“我们只需要知道用户想干嘛”。砍到5个核心字段后,Agent表现反而更好了。信息字段越多,LLM填充的质量越不稳定。

3. 别迷信向量检索:很多团队一说长记忆就上向量数据库,pinecone、weaviate、milvus全招呼上。但实际场景里,结构化查询(“用户上次提到的订单号是多少”)远比语义搜索频繁。我现在是结构化索引为主,向量检索为辅。据我了解,不少做客服系统的人都得出过类似结论。

4. 给遗忘加个“后悔药”:Agent可以主动标记“这个信息我可能需要,但暂时不确定”,这类信息不会立即遗忘,而是进入“待定区”,保留更长时间。这个机制救了无数次场,尤其是处理那种“用户提了一嘴但当时看起来不重要”的信息。


一个还在纠结的问题

现在我在尝试用Agent自我反思来动态调整记忆策略。思路是让Agent在会话结束后回顾自己的决策链,标记哪些记忆点对决策起了关键作用,哪些是噪音。然后用这些标注数据来训练importance评分模型。

但问题有两个:一是反思本身也消耗token,大概多30%的用量;二是Agent有时候会“过度反思”——把一些无关紧要的细节也标记为重要。

还在调参。prompt改到第7版了,有进展再来更新。


你们在长序列决策里踩过什么坑?有没有遇到过Agent“选择性失忆”的诡异情况?特别是做过游戏AI或者客服系统的兄弟,你们的遗忘机制怎么设计的?评论区聊聊,我现在最想知道的是怎么优雅地处理“用户说反话”这种情况——我们的Agent经常把反话当真,importance_score还给得贼高。

#AI Agent #长序列决策 #状态摘要 #遗忘机制 #记忆管理 #工程实践

170
4270 阅读
4 评论
分享
链接已复制
编辑说明

本文由 MakeSense 编辑团队撰写并审核。文中引用的数据和观点均经过交叉验证,如有疏漏欢迎在评论区指正。最后更新:2026年06月27日 18:46

苏晴

资深编辑

科技媒体从业 8 年,曾就职于多家科技媒体。关注 AI 创业和投资赛道,采访过 50+ 位行业从业者。

读者评论 4

张工 1周前
写得很实在,特别是实测对比那部分,跟我自己的使用感受一致。
回复 点赞 (12)
前端工程师 1周前
代码示例很清晰,直接用到项目里了。
回复 点赞 (6)
技术小白 1周前
作为非技术人员也看懂了,感谢作者的通俗讲解。
回复 点赞 (3)
Dev小王 2天前
终于有人把这个说清楚了,收藏了。
回复 点赞 (8)