长期记忆如何存储和召回?
未标记
考查重点:长期事实的范围与召回。提取跨会话有用事实,带主体、来源、范围与时间持久化;按当前任务过滤检索并注入,过期/冲突可更新删除
本题目录
参考答案
核心回答
长期记忆的实现,可以分成写入表示、持久存储、按需召回和上下文注入四步。
写入时,从交互中选出有跨会话价值的偏好、事实、决策或经验,整理为可更新的记录,保存主体、内容、来源、适用范围、有效时间和版本。存储可用数据库、KV 或文件;需要语义查找时,再为相应文本建立向量索引,不是只存一串向量。
召回时,先根据可信身份确定用户、租户和任务范围。固定偏好按用户与字段精确读取;开放式历史经验按当前问题做语义或混合检索,再检查时效、状态、来源并去重,选择有限结果放入本轮上下文。向量相似说明相关,不代表它一定属于当前用户、仍然有效或可以直接执行。
例如“以后项目报告先给结论,再给依据”可以存为用户的报告风格;新会话写报告时按用户读取即可。如果问“上次为什么选择那个方案”,则更适合检索相关项目的历史决策及证据。
展开说明
1. 先确定记忆记录怎样表示
稳定偏好可以使用 Profile:按用户或应用保存一份结构化资料,字段对应语言、报告风格等当前有效设置。历史决策和经验可以使用 Collection:每条信息有自己的记录 ID,允许按主题、项目和时间检索。两者可以共用同一数据库,不要求分别部署系统。
一条记忆记录可包含:
- 定位信息:
memory_id、用户或事实主体、租户,以及记忆类别。 - 内容与范围:规范化字段和值,或一段独立可理解的事实、决策与适用条件。
- 来源与时间:证据消息或文档引用、记录时间、事实生效时间和必要的失效时间。
- 维护信息:当前状态和版本,便于后续更新、撤回以及检查索引是否过期。
主体不一定总是当前用户本人,例如用户转述同事的偏好,不能自动存成自己的设置。原始聊天、阶段摘要和长期记忆可以分别保存并建立引用;抽取后的记录负责便于检索,原消息负责在需要时核对细节。
明确要求记住的信息可以在当前交互中处理,其他内容也可在任务结束或后台增量整理。写入应先检查是否有足够依据、是否适合跨会话保留,再去重、更新或新增;一次临时要求不必覆盖长期设置。用户只是在询问“你还记得我的偏好吗”,也不应因此生成一条新的偏好。
2. 正文、元数据和检索索引各做什么
正文与结构化记录保存实际信息,是更新和回查的依据。元数据索引帮助按用户、项目、类别、状态和时间定位。向量索引帮助找到意思相关、但用词不同的历史记录;关键词索引则适合项目名、编号或特定术语。
向量可以与正文、元数据一起放在支持这些能力的存储中,也可以分开存放,通过稳定的 memory_id 关联。向量不是原始事实的可读替代物,只保留向量而没有正文或引用,找到相似项以后仍然无法可靠使用。
同一条事实更新时,要让当前记录和派生索引保持一致。若向量库更新晚于主记录,检索到候选后可以回查其状态和版本,再决定是否使用。重复写入也应按来源与业务主键识别,不能让后台重试产生多份相同事实。
存储选择按需求决定:少量本地记忆可用结构化文件和目录索引;多用户服务常用数据库或 KV 保存可精确定位的记录;语义检索量大时再配置相应索引。不能只因为叫“长期记忆”就默认需要向量数据库,也不能默认内存 Store 能在服务重启后保留数据。
3. 一次召回具体怎样执行
第一步,读取可信用户身份及当前业务范围,确定允许访问的记忆空间。用户 ID 的作用是限定“查谁的信息”,语义 Query 的作用是确定“查什么内容”,它们不是二选一。
第二步,根据需求选择查询方式。报告风格等已知字段可以直接按键读取;回顾某次项目决策,可用当前问题及已知项目名称构造查询,结合关键词、语义和元数据筛选。语义查询与入库向量应处于兼容的 Embedding 空间;更换模型后需处理已有索引兼容性。
第三步,得到候选后检查主体、范围、有效期、删除或更新状态,去重并按任务相关性排序,必要时重排。不能只取全库向量 Top-K,再期待模型自行忽略其他用户的数据;访问范围要在检索和读取链路中落实。
第四步,将选中的内容整理为带来源、时间和适用条件的背景块,与当前问题和必要历史一起提供给模型。无匹配结果时可以不注入;当前信息与历史冲突时先判断适用范围,具体处理可参见记忆与当前上下文冲突。
召回可以在会话开始或后续需要历史信息的步骤发生,不必每轮全量加载。保存成功只说明记录进入了存储;它是否被本轮找到、是否实际注入模型、模型是否正确使用,还需要分别观察。
4. 用一个偏好例子说明存储到使用
假设用户明确要求“以后项目报告先给结论,再给依据”。可以将报告风格字段与用户、适用场景和证据消息关联,写入持久记录;这类少量固定字段可以直接读取,不必每次做向量搜索。
新会话收到“帮我写这次项目复盘”时,系统按用户与报告场景取到该偏好,确认仍有效后,将它作为历史偏好提供给模型。若用户本轮要求“这次按时间顺序详细展开”,本轮就按这次任务要求组织,不需要每次例外都重写长期设置。
验证时至少检查跨会话能读取、其他用户不能读到、记录更新后不会继续使用旧索引,以及无匹配时不会编造历史。对于语义查询,还要用用词不同的追问验证候选是否正确,并检查最终实际进入模型的记忆。
常见追问
只用用户 ID,没有向量匹配,算长期记忆召回吗?
算。少量 Profile、确定字段或已知记录按键读取很合适。语义检索主要解决“知道大致意思,但不知道记录在哪”的情况;当历史条目较多、问法多样时更有价值。是否需要向量匹配取决于查询需求,而不是长期记忆的名称。
存在文件系统里,和存在 Store 里有什么区别?
文件系统便于查看和按路径读取;Store 提供按命名空间、键和内容组织数据的接口,实际后端可以是内存或数据库。教程的跨线程 StoreBackend 示例将文件操作映射到同一个 InMemoryStore,展示进程存活期间跨 thread_id 读取同一份资料。部署时若要重启保留或跨机器访问,应选择相应持久后端,并按用户和应用确定读取范围。
超出窗口的历史,必须全部变成长期记忆吗?
不必。可以保留原始历史及可检索索引,按会话、时间、实体或语义找到相关消息,再将必要内容补入上下文。长期记忆是经过筛选、便于复用的记录;需要精确复述旧对话时,应回查原始消息,不能只依赖摘要重构原话。
对应教程
- 深度研搜:长期记忆与 Backend 存储:阅读文件工具与 Backend 的关系、StoreBackend 的路径到 KV 映射及跨线程示例,理解存储接口、实际介质和使用范围的区别。
- LangGraph 高级特性:阅读 Checkpointer 与 Store 的分工,区分线程内执行状态和跨会话资料,以及内存后端与持久后端的能力边界。
参考资料
- 国内:JavaGuide:Agent 记忆系统:参考 Record 与 Retrieve 两条链路,以及正文、向量、元数据过滤和候选排序的职责,组织存储到召回的实现过程。
- 国内:zero2Agent:记忆与上下文工程:参考有价值信息的选择、外部存储和按需取用,说明长期记录如何与当前任务及近期上下文配合。
- 国内:WeThinkIn:Agent 记忆与上下文工程:依据记录主体、范围、证据和版本及读写分离的设计,说明正文中更新后旧索引与查询误写的处理。
- 国外:LangChain:Long-term memory:依据 Store 的 JSON、命名空间和键以及精确读取、过滤与语义查询的区别,说明正文中长期记忆的访问方式和内存、数据库后端的持久性边界。
- 国外:LangMem:Core Concepts:参考 Profile 与 Collection 的表示方式、直接访问与语义检索,以及同步或后台形成记忆的选择,说明表示和查询方式如何对应。
相关面经
6 篇蚂蚁集团
长期记忆如何存储?如果历史记录量非常大,怎么优化查询效率?
百度
Go 后端开发工程师(Agent)长期记忆是怎么匹配的?用了向量数据库吗?
鼎捷数智
Agent 开发工程师记忆检索是怎么做的,没有语义匹配?
百度
Java 开发工程师(智能客服)美团
后端开发如果我需要用到超出你上下文窗口的那些历史记录,该怎么办呢?
展开剩余 1 篇面经
快手
AI 应用 / Agent 开发那长期记忆是怎么检索的?长期记忆除了存在本地的文件系统当中还存在哪里?
收录题集
展开剩余 1 份题集
Agent与工具调用
Agent综合理解与设计 「京东、字节Seed、字节跳动、美团、腾讯、腾讯混元、蚂蚁集团、阿里巴巴」


