如果你正在用不带长期记忆的 AI 编程工具,下面的场景应该不陌生。
你说过 PPT 用 HTML 写、别给 pptx,下次开新会话它照样丢给你一个 pptx 文件。你纠正过一次的毛病,它下次照犯;你提过的偏好,它下次清零。
这类事的本质都一样:对话一结束,上下文就被销毁,模型没有任何跨会话的持久状态。
腾讯云数据库把一套叫 TencentDB Agent Memory 的记忆系统开源了。官方仓库文档写着它能把碎片对话自动沉淀成可检索的长期记忆。到了 7 月,团队又加强了 Memory Hub 的团队记忆能力,把 Skill、Wiki、CodeGraph、Chat Memory 四类资产汇入同一个 AI 协作团队池。现在,Github 仓库已经 1.1w Star了。

开源地址:https://github.com/Tencent/TencentDB-Agent-Memory
作为一个真正为 Agent 打造的记忆系统,腾讯云数据库Agent Memory的效果怎么样。我们绕过上层的 AI 编程工具,直接调用 TencentDB Agent Memory 自带的服务入口,输入对话、观察提取、验证检索,把记忆机制还原成可见的输入输出。
同时,按 Agent 记忆的全生命周期,对 TencentDB Agent Memory 进行了深度实测和技术解读。
一、腾讯把 Agent 记忆系统开源了,从个人记忆一路做到团队记忆
Agent Memory 个人记忆的维度划分
如果我们要理解 Agent 的记忆到底怎么发挥作用,我们就要从四个维度来看。
能被共享的前提,是这份记忆本身足够完整。一条记忆从产生到被用上,要经过写入、提炼、检索、更新四步。
这四步在链路上前后依赖,前一步的输出就是后一步的输入。哪一步掉链子,结果都是这一轮拿不到该有的记忆。
而且掉链子的方式往往不是报错,是安静地返回空结果。
写入、提炼、检索都走公开接口,整条链都可见:写进去什么、提炼成什么、召回了什么、各环节耗时多少。截图里看到的就是真实发生的事,不是黑盒推断。
腾讯云数据库团队7月发布的Team Memory 版本把关注点拉到团队层面。多个 Agent、多个成员共用一套记忆时,知识怎么迁移、权限怎么划分、资产归谁所有,是另一组系统性的问题。
Memory Hub 把个人记忆推到团队层
官方方案是把四类资产汇入同一个池子。Skill 存的是验证过的操作流程,Wiki 存团队文档,CodeGraph 记录代码仓库知识,Chat Memory 保留历史交互。这四类资产经过审核和共享,再挂给新的 Agent,新 Agent 就能接着团队已有的进度往下做,不用每次都从零摸索。
团队记忆不是个人记忆的放大版。个人记忆错了自己纠正,团队记忆错了会被所有人继承;个人记忆没有权限边界,团队记忆里存着谁能看、谁能改、谁能删。
二、实测TencentDB Agent Memory
第一层:实测时效性
跟 Agent 说完一件事,这件事多久能被它记住,这是我们的第一层测试。
写入分两层。第一层是落盘,你的话说完,原文当场原样存进本地流水账,毫秒级完成,这一层保证的是不丢。第二层是提炼,系统在后台调一次模型,通读这段对话,分出场景,抽出重点,做成一张结构化卡片,这一层保证的是能查。
我们写入一条作息偏好,每 5 秒查一次,同时盯着后台日志里的各环节耗时。
用户说”我习惯早上 6 点起床跑步,晚上 11 点前睡觉”。助手确认后,系统立刻把这轮对话写进原始记录,这一步没有等待。
查询词用”跑步”,第 5 秒还查不到,第 10 秒卡片出现。后台日志显示,原始对话落盘后几乎立刻触发了提炼任务,模型整理这段对话耗时约 6 秒。卡片几乎原样保留了这两条作息,措辞和用户原话基本一致。
两层都达标了。原文刚刚说完存到记忆里面了,不会因为提炼没跑完就被删掉;从一句话到一条能被检索的结构化记忆,全程 10 秒,而且不用你手动整理、不用手动触发。自然聊天几乎感觉不到这个延迟,你说完下一句,上一句的卡片已经做好了。唯一要留意的是批量场景,写脚本载入历史对话时空窗期得算进去,写完不能立刻查。
第二层:实测提炼质量
同样三条约束,一口气说完和分三次说,系统整理出的卡片会有差别吗?
我们设计了两组对照,刻意让两组主题不同,因为主题相同时后跑的一组会被去重机制判为重复,整组被拦下来,对照就做不成了。A 组一次性说完三条项目规范,B 组分三轮说另外三条文档格式规范。两组都手动触发了一次提炼,确保后台任务跑完。
A 组一轮对话写入后,后台只提炼出 1 张规则类卡片,三条约束全都写在里面,分别是包管理器用 pnpm 不用 npm、代码注释用中文、提交记录以中文动词开头。
B 组分三轮写入,后台提炼出 2 张规则类卡片。第一张把第 2、3 轮的两条约束合在了一起,分别是避免第一人称、章节标题用陈述句而非疑问句。第二张单独保留了第 1 轮的约束,统一用 Markdown 格式而不用 Word。
B 组这两张卡片共享同一个场景名,说明系统把分批提炼的结果判定为同一主题。差别只在组织粒度。一次说完,系统倾向合成一张卡片;分多轮说,系统会按提炼批次拆成多张。但拆出来的卡片仍然落在同一个场景下,不会被打散。
所以你不必为了“让系统记得准”而刻意憋着一次说完。分多轮自然表达,同一个主题下的约束仍然会被归到同一场景,检索时也能一起被召回。两种说法的信息完整度没有差别,三条约束一条都没丢。
第三层:实测检索命中
真实对话里换个说法是常态。你今天说”完全不能吃辣”,明天问”附近有什么川菜馆”,系统认不认得出这是同一件事,是检索这一环的关键。
我们先把”用户完全不能吃辣,对辣味食物有严格禁忌”存进记忆库。等后台提炼完成,用八种不同说法去查。结果是带”辣”字的说法都能查到,”川菜””忌口””spicy food”一条都召不回。
我们发现 TencentDB Agent Memory 的语义召回默认是关着的,就会分不清”川菜”和”不能吃辣”有关联。如果打开语义召回,系统会同时跑第二条路,把问题和卡片各自转成”语义指纹”,也就是把文字含义变成一串数字坐标,两段话含义越接近坐标越接近,查询时就会按语义距离,去判断说的是不是有关联的。
第四层:实测更新演化
人的偏好是会一直变的。前面说必须用 PostgreSQL,后面改口说改用 MySQL,系统会怎么处理旧记录?
我们专门选“数据库选型”作为话题,是为了避开第二组已经写入的包管理器规范。同主题的内容会被去重机制判为重复而拦掉,那样就测不出真实的更新行为。
这一组一共写入四轮对话。第一轮用户立下规矩“项目数据库必须使用 PostgreSQL”,中间两轮聊无关内容,确保旧卡片已经固化,第四轮用户改口“改用 MySQL”。
我们查库以后发现,旧卡片和新卡片都还在库里。旧卡片的内容和编号原样保留,是原封不动的同一张,没有被删除也没有被改写。新卡片内容明确记录了“决定将数据库从 PostgreSQL 切换到 MySQL”。时间顺序和变更动因都被保留下来。
写新卡片之前,系统会做一次冲突仲裁,先在现有记忆里找出几张相似的老卡片,再交给模型判断该新增、跳过、覆盖还是合并。
这次语义召回没开,找候选就只能靠关键词。新旧两条记录除了”数据库”三个字,字面上几乎没有重叠,没能找到足够相似的候选,新内容就直接存成了一条新的变更记录。旧偏好没有被删掉,新偏好也连着时间戳和变更原因一起存了进去。后续 Agent 同时看到两张卡片时,可以从时间线和内容里判断哪一条是现行偏好。
四组测下来,大家看到了 TencentDB Agent Memory 的表现。这些现象为什么会发生,要回到机制里找答案,下面我们来深度拆解 TencentDB Agent Memory 的机制设计。
三、TencentDB Agent Memory 背后的核心机制设计
我们拆解了整个 TencentDB Agent Memory的源码,发现它的设计一共七块。底座是四层分层,往上是写入、检索、注入三条主干,再加上冲突仲裁、短期记忆、故障降级三处兜底。
记忆金字塔:L0 → L3 四层分层
先问一个问题。既然记忆就是一堆事实,为什么不直接存成一个列表?
记忆就是一堆事实,但它没法存成一个列表。你想要证据完整,就得把原话一字不改地存下来;你想省 Token,就得把它们压缩成精简摘要。同一份数据没法既是原文又是摘要。
这套系统的解法是拆成四层,从底到顶越来越精简,官方把这个结构叫做记忆金字塔。
L0 是流水账。每次对话结束,系统把你和助手的原话写进本地文件,再同步落一份到数据库。一字不改,不做任何提炼。
L1 是记忆卡片。也就是构建一份会议纪要。系统在后台把对话通读一遍,先按情境分段,再从每段里抽出结构化事实。每张卡片只记一件事,类型只有偏好、事件、规则三种,还带一个优先级,重要的排前面。
L2 是场景档案。把同一情境下的卡片打包成一份文件,按情境组织,不按日期。文件头里记着创建时间、更新时间、摘要和热度值,每被检索命中一次热度加 1,用得多的排前面。
L3 是人格摘要。从所有场景档案里提炼出的稳定画像,描述的是”这个用户是谁”,不落在某一次对话上。它是四层里唯一不需要检索的。前三层都得查到了才用得上,只有它每次新会话无条件注入。也正因为如此,它必须足够短、足够稳定,它占的是每一轮对话的固定成本。
四层各管一段,L0 留证据,L1 保精度,L2 保情境,L3 保效率。底层存数据库,全量可检索;高层写成 Markdown,人能直接读、直接改。四层还能串起来,从人格摘要往下查到场景档案,再查到记忆卡片,卡片带着来源标记,一路能追到原始对话。平时给你高密度摘要,纠错时给你完整证据链。
写入与提炼:分离式处理记忆数据
分层解决的是怎么存的问题,接下来是什么时候存。
往记忆库里写一条只需要一个动作,把这一轮的用户输入和助手回复交给系统,原始对话毫秒级落盘。这一步只是录音,不做任何理解。
记忆卡片没有顺手一起做,是因为提炼绕不开模型。”我不吃香菜”是长期偏好,”今天中午吃了火锅”是一次性事件,这两句话在文本上没有任何区别,只有理解了内容才能分开,规则和关键词统计都做不了这个判断。而模型调用有成本也有延迟,放进主流程,你说完一句话得干等着它跑完才有回复,所以只能挪到后台异步跑。
实测时效那组为什么会等待 6 秒,就是因为尽管原始对话毫秒级落盘,但要等模型跑完提炼,卡片才进得了检索范围。凡是做语义提炼的记忆系统都有这段时间差,区别只在长短。
提炼默认有两个触发条件,每满 5 轮对话,或者你停止输入 10 分钟,也可以手动立即触发。新会话开头有个例外,系统默认开了预热,前几轮的阈值从 1 开始递增,1 轮、2 轮、4 轮,之后才稳定到 5 轮。所以刚开始聊,第一轮就会触发一次提炼,不用等满 5 轮。
每张卡片的类型和优先级由模型根据内容判断,没有写死的规则。好处是灵活,代价是不可预测,同一句话在不同上下文里可能被判成不同类型。
检索与注入:平衡了精度和成本
存下来只是第一步,你需要它的时候,系统得能从一堆记忆里挑出该用的那几张,再把它们塞进对话。
这里 TencentDB Agent Memory 设计了三种方式:
第一条是字面匹配。底层用全文索引加关键词稀有度打分,中文查询先交给分词器切成若干词,再用”或”的关系去匹配卡片,命中稀有词的排在前面。这条路快、省钱,但会很死板。
卡片总量很少时还有个副作用,稀有度分数会失真。腾讯云数据库 agent memory 的源码为此留了一条补救路径,遇到这种情况就放弃阈值过滤,直接信任索引排序。实测检索时「你能吃吗」那次的意外命中,就是这条补救路径起效了。
第二条是语义指纹。系统把问题和卡片各自转成一串数字坐标,两段话含义越接近坐标越接近,查询时按坐标远近判断说的是不是一回事,所以字面上一个字都不重叠也能命中。这条路需要额外配一个模型服务,默认没开,打开之后换说法、跨语言都能召回。
第三条是混合检索。前两条路同时跑,再用排名叠加器把两份排名合成一张榜单。规则很简单,一张卡片在自己那份排名里越靠前加分越多,两边都出现的分数累加。
叠加器只看名次,不看原始分数。因为字面匹配和语义相似度是两套计分方式,这边的 0.8 分和那边的 0.8 分不是一回事,直接比大小没有意义。只比名次,两套结果才能合到一张榜上。
这里有个容易踩的坑。策略的默认值是混合检索,但语义能力的默认值是关闭,两个凑在一起,检索实际降级成纯关键词。零配置装完跑的其实是字面匹配,混合检索是配了语义服务才生效的默认值。
找到之后是注入。检索不是给你看的,是给模型看的。每轮对话开始前,系统先把你当前这句话和记忆库做一次匹配,召回最相关的几张卡片,全程有 5 秒超时保护,超时就跳过注入。
召回的内容会放到两个地方。一处在用户消息前面,是本轮动态召回的记忆卡片,每轮都变;另一处在系统提示末尾,是人格摘要、场景导航和工具指南,几轮才变一次。分开放是因为大模型服务商会缓存系统提示这段稳定前缀,命中缓存就不用重复计费,把每轮都变的卡片塞进系统提示,缓存立刻失效,Token 消耗和延迟一起上升。
注入还有预算控制,单条记忆有长度上限,本轮注入也有总字符上限。另外系统会在提示词里约束 Agent,每轮主动检索合计不超过 3 次。这是软约束,靠模型自觉遵守,不是代码层面的硬限流。
冲突仲裁:解决记忆更新问题
找得到、用得上,还剩一个问题,你今天说的和昨天说的矛盾了,系统该听哪一个。
这种判断在工程上比我们想的要难很多。「必须用 PostgreSQL」和「改用 MySQL」字面上矛盾,但矛盾不一定是只有改主意,至少有三种可能:
-
你改主意了,该覆盖旧的
-
你在说两个不同项目的事,该两条并存
-
你自己前后不一致,该留两条让人类来判断。
这三种在文本上长得一模一样,只有理解了上下文才能分开,所以写一条记忆要多调一次模型。
系统的做法是冲突仲裁,分两个阶段。
第一阶段是候选召回,不调模型。系统先把新卡片转成语义指纹,在已有卡片里找距离最近的几张,语义能力不可用就降级到关键词召回,两条路都不可用就跳过这一步。
第二阶段才交给模型。把新卡片和候选老卡片一起打包,一次性问模型这条该新增、跳过、更新还是合并。
关键在于第二阶段的判断质量完全取决于第一阶段召回到了什么。模型只能在给它看的候选里做判断,没召回到的老卡片,在它眼里等于不存在。
兜底设计:记忆系统坏了也不影响对话
前面讲的都是正常路径。但记忆系统挂在对话主链上,任何一环卡住,你收到的结果就是 Agent 不回话。这其实是我们引入记忆系统最现实的顾虑,因为很有可能会把主流程拖慢、拖垮。
源码里有一条明确的降级路线,原则很明确,故障容忍优先于功能完整。
检索侧,语义和关键词都可用就跑混合,只有一条可用就降级成那一条,两条都不可用就返回空结果。写入侧,去重判断超时就全部存为新卡片,语义指纹写入失败不影响已经落盘的原始对话,召回超时就跳过本轮注入。最坏情况是这一轮没有记忆可用,但对话还能继续。
这套系统还准备了另一件事,单次任务本身太长怎么办。你让 Agent 改一个跨十几个文件的 bug,它调工具、读报错、再调工具,几十轮下来上下文就撑爆了。
解决这个问题的做法是把详细过程转存到外部文件,上下文里只留一张任务地图。这张图用节点和箭头呈现状态怎么流转,每个节点标着编号和下一步动作,Agent 要核对细节就按编号回到那份详细记录。思路和长期记忆一样,平时给折叠视图,需要时再展开细看。官方在 WideSearch 这项长任务基准上测试的数据是 Token 消耗从 2.21 亿降到 8500 万,通过率从 33% 提升到 50%。
四层分层、写入与提炼、三条检索路径、双区注入、冲突仲裁、任务地图、降级路线,串起来就是 TencentDB Agent Memory 的完整机制。
写在最后:上手 TencentDB Agent Memory
默认配置下它用本地 SQLite 存储,安装完就能用。如果想换成自己的大模型来做提炼和画像生成,只需要填三项信息,分别是模型的访问凭证、服务地址和模型名称。
从接入方式看,它支持三种路径:装成 Agent 平台插件、通过统一网关调用、或者在自研项目里直接引用。
装完之后有一个配置值得先想清楚,就是要不要开语义召回。如果你的 Agent 只需要记住格式规范、工具偏好这类说法固定的东西,就不用开;如果它要理解自然语言表达的偏好,就需要开这个功能。
放在以前,这个系统背后的一整套东西都得自己写,向量化、相似度检索、结果重排序,全是应用层的任务。现在它变成了安装时的一个选项。Agent 需要的记忆能力,正在从应用层下沉到数据库层。
数据库给人存了几十年数据,现在要开始给 AI 存记忆了





