AI数据库的两个时间字段我漏了一个,Agent 的旧记忆盖住了新的

简介: 从一次"Agent 记住了却用错"的真实故障切入,讲清 AI数据库做记忆底座时真正要过的两关:写入端的丢、重、乱序,和召回端只按相似度排序的三个坑。含幂等写入、带时效衰减与去重的召回 SQL,以及记忆的有效时间与写入时间的处理方法。

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

上个月帮一个客服 Agent 排查问题。用户前天说过一句话:"我搬到北京了,别按老地址派单。"这句被写进了记忆表,第二天派单,用的还是上海的老地址,用户直接投诉。我把记忆表翻出来,新记忆在,旧记忆也在,召回的时候,旧的那条排在了前面。Agent 不是没记住,是记住了、用错了。

很多人选 AI数据库,只问一句"能不能存向量"。存得下当然要,但真正决定 Agent 靠不靠谱的,是记忆写得对不对、取得准不准。关于 Agent 记忆,我早先写过一篇,讲的是记忆存哪,短期、长期、团队三层怎么分。今天这篇往下再挖一层,也只打两件事:写和取,这也是我踩坑最疼的地方。

一、AI数据库做记忆底座,写和取是两套逻辑

我一开始的想法很朴素:记忆嘛,写进去、查出来,就完了。真的做过一轮才发现,写和取是两套逻辑,目标还常常打架。写的时候要的是一条不漏、一条不重;取的时候要的是把最该想起的那条排到最前面。为了写得快就得异步,异步一开顺序就乱;为了取得全就得多存,存多了重复记忆又把有用的那条挤出去。

后来我把两条链路分开设计。写入链路只管一件事:把干净、有序、不重复的记忆落好。召回链路管另一件事:把该用的那条挑出来,排到最前。

二、写入这一端:AI数据库的记忆,异步一开丢、重、乱序全来了

记忆大多不能同步写。Agent 答完话,得先把结果还给用户,记忆在后台慢慢落,同步写会让用户干等两秒,这个上一篇说过。可异步的代价我当时没想清楚,它一口气带来三个麻烦。

一是丢,后台任务是异步的,进程重启、队列抖动都可能吃掉一条记忆,用户说了"我要退款",这条没落库,下次还得重问。二是重,Agent 一次任务可能连着触发几次写入,同一句话被拆成两三条存进去,这些重复记忆会占满召回的名额。三是乱序,用户先说在"上海",后说搬到"北京",两条都异步写,要是后发的先落库,"上海"反而成了最新的,Agent 就按旧地址干活了。

幂等:给每条记忆一个唯一键

重复最好治,给写入加一个唯一键,重复的直接冲突掉。键我这么定:agent_id、user_id、来源,再加一个内容哈希。同一件事、同一来源、哈希一致,就当成同一条。

-- 记忆表:用唯一键挡住重复写入
CREATE TABLE agent_memory (
  id           BIGINT PRIMARY KEY,
  agent_id     VARCHAR(64)  NOT NULL,
  user_id      VARCHAR(64)  NOT NULL,
  topic        VARCHAR(64)  NOT NULL,   -- 归一化主题,召回时用来去重
  source       VARCHAR(32)  NOT NULL,   -- 来源:对话/工单/文档
  content_hash CHAR(64)     NOT NULL,   -- 内容指纹,用来做幂等
  content      TEXT         NOT NULL,
  confidence   DECIMAL(3,2) DEFAULT 0.5,
  valid_from   TIMESTAMP    NOT NULL,   -- 这条记忆何时开始为真
  created_at   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
  expires_at   TIMESTAMP,
  embedding    VECTOR(1536),
  UNIQUE (agent_id, user_id, source, content_hash)
);
-- 幂等写入:重复的自动忽略,不报错
INSERT INTO agent_memory
  (agent_id, user_id, topic, source, content_hash, content, valid_from, embedding)
VALUES
  (:agent_id, :user_id, :topic, :source, :hash, :content, :valid_from, :embedding)
ON CONFLICT (agent_id, user_id, source, content_hash) DO NOTHING;

这里我搞错过一次。我第一版只拿 content 去重,结果同一个人先后两次说"要发票",措辞几乎一样,被当成重复合并了,那其实是两个订单。所以唯一键里得带上来源和业务标识,不能只认文本。

顺序:旧记忆不能盖住新记忆

乱序没法靠键解决,它是时间问题。我在表里存两个时间:一个 created_at,是我什么时候写进去的;一个 valid_from,是这条信息什么时候开始为真。

这俩不是一回事。用户昨天说"我在上海",今天说"我搬到北京了",北京这条的 valid_from 是今天,上海那条是昨天。哪怕上海晚一点落库,按 valid_from 一比,北京还是更新的。召回时同一个字段有冲突,就认 valid_from 最新的那条,异步的先后问题就这么绕开了。

三、召回这一端:AI数据库的记忆,只按相似度排序迟早出事

写干净了,只是及格。真正决定 Agent 靠不靠谱的,是召回。我见过不少记忆层,召回就一句"按相似度取前三条",这一句里藏着三个坑。

坑一,旧记忆压新记忆。老记忆和用户现在说的话语义上可能更接近,因为它属于同一个话题、反复出现过,相似度一算,旧的分反而高,被排到了前面。坑二,重复记忆挤名额,上一节那个重复,写的时候没挡住,召回时就会爆发,三条来自同一次对话的记忆内容差不多,把 top-3 占满了,真正有用的第四条进不来。坑三,过期记忆混进来,场景变了,老记忆还没失效,去年的活动规则、今年的问题,它照样被捞出来。

这三个坑,说到底是同一个错:把"相似"当成了"该用"。相似只是条件之一,不是全部条件。

修法:把治理条件塞进同一次查询

修法不复杂,召回的时候,除了相似度,再带上三样东西:时效、置信度、去重。时效是给记忆做时间衰减,越新的权重越高,我一般取 30 天半衰期;置信度是给记忆打分,来源可靠、被反复印证的分数高,低于阈值直接排除;去重是在召回里做,同一个主题只留最新那条。

这些条件如果能和向量检索放进同一条 SQL,最省事,不用先去向量库拿 top-K、再回业务库过滤。那种跨库写法,排序和过滤是分开的,前面那三个坑一个都躲不掉。

-- 召回:相似度 + 时效衰减 + 置信度 + 去重,一次完成
SELECT
  m.content,
  VECTOR_DISTANCE(m.embedding, :qvec, COSINE) AS dist,
  -- 30 天半衰期的时间衰减系数
  EXP(-LN(2) * EXTRACT(DAY FROM NOW() - m.valid_from) / 30) AS freshness
FROM agent_memory m
WHERE m.agent_id = :agent_id
  AND m.user_id  = :user_id
  AND m.confidence >= 0.3
  AND (m.expires_at IS NULL OR m.expires_at > NOW())
  -- 同一个主题只留最新那条
  AND m.valid_from = (
    SELECT MAX(m2.valid_from)
    FROM agent_memory m2
    WHERE m2.agent_id = m.agent_id
      AND m2.user_id  = m.user_id
      AND m2.topic    = m.topic
  )
-- dist 距离越小越像,freshness 越大越新;相除之后,越靠前越是"又像又新"
ORDER BY (dist / freshness) ASC
LIMIT 3;

关键是 ORDER BY。我不再只排相似度,而是排"距离除以时效"。旧记忆语义再像,被衰减一压也上不来;低置信度和重复的,在 WHERE 里就被挡掉了。

这段 SQL 有个前提:向量检索、标量过滤、主题去重,得在同一个引擎里跑,不然就得拆成两查一拼。金仓 KES 的向量是内核里的能力,不是外挂插件,向量和标量能放进同一条 SQL,相似度和时效一次就排出来了。距离函数的写法各家不同,照自己库的文档改。

这两种召回,差的不是算法,是 AI数据库肯不肯把治理条件放进同一条 SQL。

召回维度 只看相似度 相似度 + 治理
排序依据 语义距离 距离 ÷ 时效
旧记忆 可能排到前面 被时间衰减压低
重复记忆 挤占 top-K 查询内按主题去重
过期记忆 混进结果 WHERE 直接过滤
跨库代价 两次往返 + 应用层拼 一条 SQL 一次完成

四、再深一层:AI数据库的记忆有两个时间

上一节提了 valid_from,这事值得单独说,它是 AI数据库做记忆底座时最容易被忽略的一层,也最像数据库的老本行。记忆有两个时间:一个是我什么时候写进去的,叫写入时间;一个是这条信息什么时候开始成立,叫有效时间。很多人表里只存一个 created_at,两个就混在一起了。

混了会怎样。用户 3 月 1 日说"我在上海",这条 3 月 5 日才落库;3 月 3 日他又说"我搬到北京了",当天落库。只看 created_at,上海那条更"新",因为它落库晚,可事实上北京才是后来发生的事。把两个时间分开存,冲突就能按"事情何时发生"来消解,而不是按"我何时入库",带时点的版本处理,本来就是数据库的强项。

放到现实里更直观。金融对账按交易日,不按入库时刻;政务办件按受理时间,不按同步时间。这些和"记忆什么时候为真"其实是同一个问题。所以我挑 AI数据库时,会多看一句:这个库对时间和版本的支持,够不够细。

五、避坑清单:选 AI数据库做记忆底座,先记这四条

第一条,别只拿文本去重。我第一版只用 content 当唯一键,两次提到"要发票"被误合并,键要带上 agent_id、user_id、来源和业务标识。

第二条,时间字段存两个。只存 created_at,异步乱序一来旧信息会盖掉新信息,加上 valid_from,冲突按事实发生的时间判,这个坑我查了两个晚上才定位到。

第三条,召回别只排相似度。相似只是条件之一,时效衰减、置信度过滤、去重,尽量塞进一条查询,拆到应用层去拼,等于把坑留在了最外层。

第四条,别让记忆无限长大。过期记忆要清、重复记忆要并、低置信度的归档备查不参与召回,我这边每周清一次,数据涨得快就缩到每天,不然向量索引越建越大,召回只会越来越慢。

写在最后

复盘这个坑,我改了一个认知:我原先以为记忆层的难点在"存",其实难点在"取",存得下不算本事,取得准才算。写和取是 AI数据库当记忆底座的两条腿,写这一端挡住丢、重、乱序,取这一端把相似、时效、置信度、去重的顺序做对,两件事都尽量收进一个库、一条 SQL,就少一处出错的地方。

所以挑 AI数据库做记忆底座,我会问三件事:向量和业务数据能不能同库、同事务?记忆的写入能不能做到幂等?召回能不能把时效、置信度、去重塞进同一条 SQL?这三问过了,这套库才算真的接住了 Agent 的记忆。

这也是我选型时会看的一点。记忆要的分层存储、向量召回、标量过滤、时间版本,要是散在几个组件里拼,链路就长,故障面也大。还有一条我盯得更紧,向量和业务数据能不能在同一个事务里更新。记忆最怕写一半成功、一半失败,最后留一堆对不上的记录;金仓 KES 在这一层是把向量和标量放进同一个事务的,故障时不丢数据,金融、政务这类场景很吃这一点。对不对得上你的场景,还是拿真实数据跑一遍最实在。

你们给 Agent 搭记忆底座,卡在写,还是卡在取?评论区聊聊。很多人是不是正被重复记忆顶着,召回永远翻不到第四条。

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

相关文章
|
8天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
7386 12
|
6天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
1545 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
7天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
1008 8
|
3天前
|
人工智能 JavaScript 芯片
DeepSeek 官方偷偷上传 Harness 桌面端安装包,我已经用上了。。附最新下载地址
DeepSeek Harness 官方的桌面端安装包被网友扒出来了,2 分钟讲明白如何使用,体验如何,适合作为 AI 编程工具么?附最新 Windows 和 Mac 双端的下载地址
1200 1
|
20天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
3581 10
|
15天前
|
缓存 IDE Java
【保姆级】Android Studio下载、安装和汉化教程(2026最新)
Android Studio 是 Google 官方推出的免费 Android 应用开发集成环境,基于 IntelliJ IDEA,内置模拟器、调试器、性能分析及 Compose 界面工具,功能全面,文档丰富,是安卓开发首选工具。(239字)
1611 1
|
4天前
|
编解码 缓存 PyTorch
16G 显卡能跑 Qwen-Image 2.1 吗?
9月20日,阿里Qwen开源Qwen-Image-2.1:7B DiT图像模型+8B文本编码器+VAE,单模型支持文生图与图像编辑,原生输出2K PNG(含Alpha通道),支持10张参考图。在自建Qwen-Image-Bench达60.28分(开源模型第一),GenAI Showdown文生图排名7/15。16G显存可跑1024×1024(需INT8量化+ComfyUI优化),但2K需24G以上。注意其Qwen Research License限非商业用途。
506 1
|
5天前
|
人工智能 编解码 并行计算
MiniMax-H3 一键整合包技术文档:8G 显存运行 AI 漫剧制作 —— 角色替换 / 动作迁移 / 文图生视频部署与调参指南
MiniMax H3 是 MiniMax 开源的全模态视频生成模型,支持文/图/音/视多条件输入,输出最高2K、15秒带双声道音频视频。本文档详述其Int8量化版在8GB显存下的本地一键部署、三段式工作流(EDIT/REPLACE/CONTINUE)、参数调优及常见问题排查。(239字)