智能体记忆设计:短期上下文、长期记忆与缓存一致性
引言
给智能体增加记忆,常见的第一步是把历史消息存进 Redis,再接入一个长期记忆服务。但真正进入业务场景后,问题很快会变成:每轮对话都要读取长期记忆吗?每次问答都要写 Mem0 吗?用户修改偏好后,Redis 中的旧画像什么时候失效?
这些问题不能靠“短期放 Redis,长期放 Mem0”一句话解决。需要先区分记忆的作用域、数据的权威来源,以及读取、写入和上下文组装各自的职责。本文围绕这些边界展开,讨论一种适用于 AgentScope 等智能体运行时的设计思路。
先区分记忆、上下文和业务事实
记忆是可保存和检索的信息,上下文是本次模型调用实际接收的信息。 数据已经存储,不代表模型会自动知道它;只有通过检索、筛选和组装进入当前请求,才会影响这次推理。
短期和长期主要描述信息的使用范围,不是数据库产品分类。Redis 可以承载会话状态,也可以承担画像缓存;关系数据库可以保存会话检查点,长期记忆也不必全部放进向量数据库。
| 信息类别 | 主要作用 | 示例 | 读取与更新方式 |
|---|---|---|---|
| 短期记忆 | 保持当前会话或任务连续性 | 当前目标、最近消息、已确认约束、工具结果摘要 | 按会话隔离,随任务推进更新 |
| 长期记忆 | 在不同会话之间复用有价值的信息 | 用户长期偏好、历史处理经验 | 按范围授权,按需召回,选择性写入 |
| 用户画像 | 对当前有效偏好的结构化表示 | 座位偏好、输出语言、默认展示方式 | 明确字段归属,维护生效时间与修订记录 |
| 实时业务事实 | 支撑业务操作的当前状态 | 订单状态、库存、账户权限 | 从权威业务系统读取并校验 |
例如,“刚才那个订单”需要会话上下文帮助定位订单编号;“订单是否还能取消”必须查询订单系统,不能用上次对话里记住的状态直接决定。
长期记忆也不只是用户偏好。可以按内容区分事实知识、历史经历和流程经验,但这些分类是组织信息的方式,并不意味着必须分别引入三套存储系统。LangChain 记忆概念
每轮模型调用应该带哪些记忆
短期上下文通常需要,但不应全量注入
对于有状态、多轮交互的智能体,当前任务和必要的前文通常需要进入上下文;独立问答、任务重置等情况则不必强行携带历史。即使是同一会话,也不应该每轮都发送所有消息和完整工具输出。
比较实用的组织方式是保留当前目标、尚未完成的步骤、用户已经确认的约束,以及理解当前指代所需的最近消息。较早的过程可以压缩为摘要,大型工具结果可以保存引用,在需要时重新读取。
压缩时应保留来源、关键标识和未解决的问题。例如将“订单状态查询成功”的完整响应压缩为状态摘要时,应同时保留订单编号和查询时间;不能把一次历史查询结果压缩成没有时间限制的事实。
长期记忆按任务召回
用户问“按照我平时的习惯推荐行程”,长期偏好可能有帮助;用户问一个独立的计算问题,读取出行偏好通常没有收益。召回策略应考虑当前任务需要什么信息,以及会话里是否已经有足够的信息。
“刚才”“平时”等关键词可以帮助判断,但不能作为唯一规则。“上次出差住的酒店”可能跨越多个会话,仍然需要长期检索;“以后都用中文回答”则同时涉及本轮约束和长期偏好候选。
一次上下文组装可以概括为:
1 | 系统与应用指令 |
这里表示内容组成,不规定所有模型的消息角色或排列顺序。工程上还要限制 Token 预算、去重、处理冲突,并避免将检索出的历史内容提升为高优先级指令。
尤其要注意:检索相关性不等于事实可信度,相关性分数也不能直接解释成事实为真的概率。 一条“相似度很高”的旧偏好,仍可能已经被用户的新要求取代。
Redis、Mem0 和智能体运行时各负责什么
下面是一种逻辑架构示意。会话状态、画像缓存和长期记忆访问分别受应用策略控制,不能因为都叫“Memory”就合并成一个读写接口。

图中“选择性记忆写入”封装了对长期记忆服务的调用和完成状态跟踪;只有相关数据就绪后,才推进画像解析与缓存更新。箭头表达调用或处理方向,不表示所有节点都必须独立部署。
| 组件 | 负责的事情 | 需要保持的边界 |
|---|---|---|
| AgentScope 等运行时 | 执行智能体流程,衔接工具和记忆访问 | 不假定框架自动实现所有画像与缓存策略 |
| 应用记忆策略 | 决定何时召回、保存什么、如何处理冲突 | 业务规则和身份范围由应用明确表达 |
| 会话状态存储 | 保存当前会话与任务状态,可用 Redis 或持久化检查点 | 按会话隔离,不把缓存过期等同于业务任务完成 |
| Mem0 等长期记忆服务 | 提取、保存和检索长期记忆 | 不是订单、权限等业务事实的权威来源 |
| 画像权威存储与投影逻辑 | 决定当前有效偏好及其版本 | 具体实现可选,不假定 Mem0 原生提供应用版本字段 |
| Redis 画像缓存 | 加速已解析的结构化画像读取 | 缓存应可由权威数据重建 |
如果采用 Mem0 保存长期记忆,可以将它作为该类记忆记录的主要存储;但不能进一步推导出“所有用户数据都以 Mem0 为准”。对于用户在设置页明确修改的默认偏好,业务资料库可能才是权威来源。
同样,Redis 中的会话状态也不一定是可丢弃缓存。如果它保存的是尚未持久化的任务进度,就必须单独考虑持久化、恢复和过期策略。短期记忆的“短期”,不等于数据可以随意丢失。
长期记忆写入:选择信息,而不是记录每一句话
保存聊天记录和形成长期记忆,是两个不同动作。聊天记录可以按业务留存规则保存,长期记忆则应挑选未来仍有使用价值的信息。
| 用户表达 | 通常的处理方式 |
|---|---|
| “查一下订单状态” | 执行工具查询,更新当前任务状态 |
| “刚才那个结果换成表格” | 更新本轮任务约束 |
| “以后给我的技术说明优先用中文” | 作为长期偏好候选,按应用策略保存 |
| “这次给同事订票,选靠窗” | 作为当前任务要求,不能直接改成用户长期偏好 |
| “以后座位改成过道,不再选靠窗” | 识别为偏好修订,并处理旧值和生效范围 |
提取时至少要考虑主体、作用域、有效时间和来源。用户替别人提出的要求、模型自行猜测的偏好,以及工具返回的无关文本,都不能直接当成用户已经确认的长期事实。
写入可以放到后台,降低回答链路的等待时间;但异步处理不能让当前会话继续使用已经明确被用户否定的值。用户说“以后改成过道”时,当前任务应立即采用这个要求,并将其作为待持久化的会话覆盖值;长期写入失败则需要有可观察的失败状态和补偿流程。
原始对话、长期记忆、画像投影还应有各自的删除与保留策略。用户要求删除一条记忆时,相关缓存和派生画像也要处理,不能只删除检索记录,却继续从画像缓存里注入相同内容。
缓存一致性:先决定缓存什么,再决定 TTL
优先从结构化画像开始
把“用户全部记忆”缓存为一个大对象,通常会同时增加更新成本和无关数据。对稳定且高频读取的字段,可以缓存按业务域拆分的画像,例如输出习惯或出行偏好;复杂、低频、强任务相关的记忆,则按需检索。
下面是应用自定义的画像缓存示意,不是 Mem0 的响应结构:
1 | { |
其中版本号由应用的权威画像或投影逻辑维护,来源引用用于追溯。缓存读取到版本 28 本身并不证明它最新;还需要可靠的版本来源或更新流程,才能做新旧比较。
搜索结果也可以缓存,但其键不能只有用户 ID。至少需要考虑租户、用户、查询语义、过滤范围及相关索引或画像版本。只有当命中收益足以覆盖失效复杂度时,才值得增加这层缓存。
不能在异步写入刚开始时就删除缓存
下面的顺序会产生陈旧回填:
1 | 提交异步记忆写入 |
更合理的顺序是等待所依赖的数据真正可读,再刷新画像或失效缓存。若应用维护独立画像投影,就以画像修订提交为依据;若从记忆服务派生画像,就先确认相关处理完成,并实际解析当前有效值。
这仍然不能消除所有并发竞争。即使写入完成后再删除缓存,先前已经读取旧版本的请求也可能稍后回填。对这类场景,可在应用中采用修订号和条件写入,拒绝低版本覆盖高版本;需要时使用原子操作完成检查与更新。具体复杂度应由允许的陈旧窗口决定,不能只添加一个 version 字段就宣称实现强一致。
下面以“新画像按修订号原子刷新缓存”为例,展示更新顺序和旧值回填防护:

图中缓存已存在 r28 时,应用实现的原子版本比较会拒绝 r27 覆盖;若缓存已经过期或不存在,仍需通过权威修订信息约束回填,不能仅靠比较缓存里的版本判断新旧。该图展示一种缓存刷新策略,不代表 Redis 或长期记忆服务自动完成整套流程。
TTL 是生命周期与兜底机制
“缓存多久合适”没有统一数字,应先回答业务最多能接受多长时间的旧值,以及事件失败后如何恢复。
| 数据 | 设计依据 |
|---|---|
| 当前会话状态 | 会话恢复、任务持续时间和持久化要求 |
| 普通偏好画像 | 最大允许陈旧时间、访问频率、变更频率 |
| 用户刚刚明确修改的偏好 | 会话内立即覆盖,并推进权威数据更新;不能只等 TTL |
| 权限、余额、订单状态 | 操作前从对应业务系统校验,不能依赖长期记忆缓存 |
TTL 只能限制某次缓存写入的存活时间。如果每次未命中都从一个落后的画像投影读到旧值,短 TTL 也不会自动恢复正确数据。因此还需要监控投影进度、处理失败和重试积压。
多实例场景再考虑事件传播
已有 Kafka 等基础设施时,可以在权威画像更新后传播应用自己的变更事件,让相关缓存消费者刷新或失效。事件应包含可定位的主体与修订信息,并处理重复、乱序、失败重试和漏投补偿;不假定 Mem0 会直接产生适合业务消费的 Kafka 事件。
单体或单服务场景未必需要引入消息中间件。先用清晰的数据归属、可靠的变更完成判断和可恢复的缓存策略解决问题,再根据真实的跨服务同步需求扩展。
用一次偏好变更串起完整流程
用户在会话里说:“这次帮我订明天的机票,今后座位也改成过道。”
- 应用解析当前订票任务与长期偏好修订两个意图。本轮明确要求先覆盖旧画像,避免继续使用“靠窗”。
- 按身份与业务范围读取必要会话状态;航班和库存等实时信息通过工具查询。
- 选择性召回相关长期记忆,去除无关内容,并对冲突值保留来源和时间判断。
- 在授权范围内推进偏好持久化,区分提交、处理完成和画像修订完成;若后台失败,记录并执行补偿,不把它当成已经永久记住。
- 当前有效画像更新后,刷新或失效对应缓存,并防止旧版本并发回填。下一会话从新的有效画像或相关记忆继续工作。
这里的记忆只帮助理解和个性化决策;创建订单、付款等业务动作仍遵循各自的授权、确认和事务规则。
验证这套设计时,应覆盖跨用户隔离、偏好修订、异步失败、事件重复与乱序,以及缓存陈旧回填。除了延迟、Token 成本和命中率,还应观察错误记忆写入率、无关召回率、画像陈旧时间和删除后的残留情况。缓存命中率高,不代表智能体记得正确。
总结
短期记忆维持当前任务连续性,长期记忆按需提供跨会话信息,画像表达当前有效偏好,Redis 加速读取;记忆策略决定何时读写,而业务系统继续掌握实时事实与操作权限。
先明确这些职责,再选择存储与缓存策略,才能避免把历史消息、当前偏好和实时业务状态混为一谈。智能体记忆的价值,在于合适的信息能在合适的时候被正确使用。