同一句"是会员"Agent问了两遍?给记忆层一次搭明白

简介: 从Agent反复失忆的现实问题出发,梳理上下文窗口与无状态会话两个根因,讲清短期、长期、团队三层记忆的存储设计与治理方法,用Redis和向量库实操演示记忆层搭建,给出异步写入、按人隔离、记忆清理等避坑清单。

大家好,我是数据库小学妹👋 我踩过的坑,你别再踩。

上个月帮一个客服产品团队调Agent,碰到一个挺典型的例子。用户头天晚上留过一句话:"我是会员,短信通知关了,只留邮件。"结果第二天Agent一上来,张口就问:"请问需要短信通知吗?"用户当场就炸了,工单里骂了整整五分钟。

这不是模型笨,是Agent压根没记住昨天说过的话。问题不在模型,在它没有长期记忆。今天就来聊聊Agent搭记忆层的全过程:存哪、怎么存、坑在哪。一次讲完,帮大家少走弯路少踩坑。

一、Agent为什么记不住

Agent失忆,根子上是两个原因叠一起。

一是上下文窗口。模型一次能处理多少内容是固定的。对话一长,早期信息就被挤掉,或者被压成一团糊。窗口再大,也装不下用户全部历史。

二是会话无状态。Agent每次对话是独立的,聊完就清空。昨天的会话和今天的会话,中间没有桥。关掉页面再打开,它什么都不记得。

数据库在这件事里,角色变了。以前数据库存订单、存用户、存流水,是业务的账本。现在它多了一个活:存Agent的记忆。谁说的、什么时候说的、结论是什么,都得落库。不然下次还得重问。

厂商也看到了这个变化。今年圈里最热的词之一,就是Agent Memory。2026年5月,腾讯云正式开源了TencentDB Agent Memory,做短期压缩、长期沉淀、团队共享三层。信通院也直接把数据库定位成AI Agent的“长效记忆中枢”。意思很直白:Agent能不能记住事,得看数据库给不给力。

二、记忆分三层,别混着存

一开始我以为,记忆嘛,找个地方存起来就行。试了几天发现,全塞一个地方,查起来又慢又乱。后来我按生命周期拆成三层:短期、长期、团队。每层存的东西不一样,用的存储也不一样。

层级 存什么 用什么存 为什么
短期记忆 当前会话摘要、临时状态 Redis,带TTL 快,自动过期
长期记忆 用户偏好、历史结论 向量库,比如pgvector 按相似度召回
团队记忆 规则、口径、共享知识 关系库或文档 结构化,权限清楚

短期记忆最简单。一次任务里Agent要记住"刚才算到哪了",用Redis存个key,设个过期时间就行。

SETEX agent:{
   session_id}:state 3600 "{\"step\":3,\"last_query\":\"...\"}"

3600秒过期。任务结束或超时,自动清掉。这块用关系库反而笨。频繁读写,还占地方。

长期记忆是重头。用户说过的话、做过的选择、偏好,跨会话要能想起来。这种"像不像"的查询,向量库最合适。把用户的话转成向量存起来,下次来新的,按相似度把相关的旧记忆捞出来。

下面是我建的记忆表,可以照着改。

-- 1536是OpenAI embedding的维度,实际使用时根据你的embedding模型调整。
CREATE TABLE agent_memory (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  agent_id VARCHAR(64) NOT NULL,
  user_id VARCHAR(64) NOT NULL,
  content TEXT NOT NULL,
  summary VARCHAR(500),
  embedding VECTOR(1536),
  confidence DECIMAL(3,2) DEFAULT 0.5,
  source VARCHAR(32),
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  expires_at DATETIME
);

召回的时候,先按人过滤,再做相似度排序,取前几条。

SELECT content, summary
FROM agent_memory
WHERE agent_id = 'cs_agent'
  AND user_id = 'u_10086'
  AND expires_at > NOW()
ORDER BY vector_distance(embedding, :new_input)
LIMIT 3;

不同数据库的向量距离函数名不一样。pgvector用<=>,MySQL 8.4+和OceanBase用<->,照着你的库改就行。expires_at > NOW()是为了别让过期的记忆被捞出来。

三、团队记忆,最容易漏的一层

短期和长期,很多人都在做。真正容易漏掉的,是第三层:团队记忆。

什么叫团队记忆?多个Agent共享的那部分知识。客服团队里,"会员优先处理"是规则,"退款口径以工单为准"是标准。这些要是每个Agent各记各的,迟早口径打架。放一个共享的地方,大家读同一份。才不会一个说能退,一个说不能退。

团队记忆我用关系库,加简单权限。结构化,好管,谁改了有记录。这块不太需要向量。规则和口径是明确的,精确匹配就行。查询时做分页和权限过滤。比如只返回当前Agent角色允许访问的团队记忆,避免越权。

四、光会存没用,治理才是大头

存进去只是开始。真正折磨人的,是记忆怎么管。四个坑我挨个踩过。

先说写入。我第一版是Agent答完话,等记忆落库了才返回。结果用户等了两三秒,体验稀碎。后来改成异步,回答先返回,记忆后台慢慢写,一次搞定。

再说隔离,这个坑最狠。我一开始只建了向量索引,没管user_id。结果A用户的记忆,有时被B用户的查询召回来。隐私直接串了,线上出了事我才反应过来。现在强制按agent_id加user_id过滤,隔离放查询第一位。

还有记忆污染。旧记忆和用户现在的话矛盾了,听谁的?我见过一个Agent,用户早在工单里更新过收货地址,Agent安排上门还是按老地址走,客户直接火了。我的办法是给记忆打置信度,冲突时新的覆盖旧的,但保留来源记录方便追溯。判断规则就一条:同一来源以最新时间为准,不同来源以置信度高的为准。

过期也得管。设了expires_at不算完,根据数据量定清理周期。不然库越来越胖,召回越来越慢。我这边每周清一次,数据涨得快就缩短到每天。

五、避坑清单

写入别卡主流程。Agent答完话,先把结果还给用户,记忆后台慢慢写。我第一版图省事同步落库,用户等两秒就火大,改异步立刻好了。

隔离别等出事再补。建表时就把agent_id、user_id和向量索引一起规划好。只建索引不管人,迟早出隐私事故,我就是这么过来的。

记忆得清理,也得会处理冲突。expires_at过期的直接删,confidence低于0.3的归档备查但不召回,我每周清一次,数据涨得快就缩短到每天。旧记忆和当前说法打架时,新的覆盖旧的,来源记录留着方便追溯。

写在最后

Agent要落地,记忆这关绕不过去。窗口再大也有边,会话再长也有限,总得有个地方把东西存下来。数据库干这个正合适,能装、能查、还能管。厂商也都在往这个方向加码。关系库加向量,已经是2026年的标配动作。国产这边,金仓KES也把向量检索做进去了,当记忆底座够用。以后选型,Agent记忆跑不跑得动,可能得算一个硬指标。

对DBA来说,这是新机会。以前管业务数据,现在多了一种:Agent的记忆。管得好不好,直接决定Agent靠不靠谱。这活儿,目前会的人真不多。

你们给Agent搭记忆了吗?踩过什么坑?评论区聊聊。我猜不少团队还在用“把对话记录全丢给模型”的土办法,短期能糊弄,对话一长就露馅。

我是数据库小学妹,帮你少走弯路少踩坑,咱们下篇见👋

相关文章
人工智能 缓存 前端开发
11711 59
人工智能 JavaScript 开发工具
4682 17
Web App开发 人工智能 API
1197 1
开发工具 Swift git
1899 6
人工智能 Java BI
1312 1
人工智能 JavaScript 测试技术
2164 2
人工智能 JavaScript 测试技术
1106 4
缓存 JavaScript Shell
2059 3