数字人记忆对于时间维度的处理:使用偏移时间
数字人记忆机制的关键在于时间维度处理:采用真实时间会因跨天交互导致记忆断连,而偏移时间(虚拟时间步)能保持记忆连贯性。斯坦福Generative Agents和开源项目Fay采用偏移时间机制,通过交互轮次而非实际时间计算记忆衰减,使数字人能在长时间间隔后仍续接对话。相比真实时间方案(如豆包)存在的隔夜失忆问题,偏移时间机制更符合人类对智能体"持续记忆"的预期,为构建长期陪伴型数
随着大模型加持的数字人/虚拟智能体不断涌现,如何让智能体“记住”用户曾经交谈的信息成为产品落地中的关键问题。记忆机制不仅要让代理在当前对话中保持连贯,还要在不同时间、不同场景下复用历史经验。时间维度的处理决定了记忆的表现:如果用真实世界的时间作为记忆递减的度量,模型很容易“失忆”;如果用虚拟时间(偏移时间)做度量,就可以在离线或者长时间间隔后保持对话连续。本文结合斯坦福大学的 Generative Agents(俗称“AI 小镇”)论文、豆包大模型产品以及开源项目 Fay,探讨数字人记忆在时间维度上的差异,重点介绍偏移时间的优势。
真实时间会导致记忆断连
目前部分中文大模型产品为了控制成本,会采用 真实世界时间 来做记忆递减:模型在每条对话结束时记录一个实际的时间戳;当用户再次提问时,系统根据当前时间减去记忆时间戳来计算 “记忆新旧程度”,并对较旧的记忆降低权重。这种设计在单次会话中可以保证最近交互处于重点,但对隔日交互不友好。许多用户反馈在豆包等产品中遇到这样的情况:
第一天向智能体传递了一段背景信息,第二天再次询问相关问题时,模型已经把背景信息遗忘,只能重新输入。 这种体验上更像在聊天窗口中“清除了历史对话”。虽然豆包的官方 FAQ 说明其支持长期记忆,并允许用户关闭或删除特定记忆,但没有公开关于如何处理记忆衰减的技术细节。由于官方尚未披露具体算法,本文无法提供确切的技术引用,只能根据用户体验描述这种断连问题。
真实世界时间的缺点在于:人类的工作流往往跨天、跨周,用户希望数字人像秘书一样“随时续接”,而不是隔夜就把所有记忆忘掉。如果按照现实时间流逝直接衰减记忆,那么一天不和数字人交互,它的记忆权重就会明显降低;连续几天不交互,则之前的记忆基本失效,导致对话断连。
偏移时间:斯坦福 Generative Agents 的做法
斯坦福大学与 Google 联合发布的论文《Generative Agents: Interactive Simulacra of Human Behavior》提出了一种支持长时段连贯行为的代理架构。论文中,作者为 25 个生成式代理构建了一个模拟小镇,让代理拥有观察、计划和反思功能,并通过检索记忆来决定行为。关键在于如何衡量记忆的新旧程度。论文将记忆检索得分拆分为 Recency (近期性)、Importance (重要性) 和 Relevance (相关性) 三部分,其中近期性使用 指数衰减函数 来降低旧记忆的影响:“我们将近期性视为记忆最近被访问后的沙盒游戏小时数的指数衰减函数,衰减因子为 0.995”。这里的“沙盒游戏小时”不是现实世界的小时,而是模拟世界的时间步(game hours)。
也就是说,Generative Agents 并不关心现实时间过去了多久,而是使用模拟环境中的 时间步计数 来更新记忆的创建时间和访问时间。当代理调用检索函数时,会计算每条记忆距离当前时间步的差值,并用指数衰减函数削弱旧记忆的权重。例如某条记忆的最后检索时间为 10,当前检索时间为 14,指数因子为 0.995,则该记忆的近期性分数为 0.995^(14 - 10)≈0.98。这种按 偏移量 而非绝对时间衰减的方式具有两大优势:
-
可独立于真实时间运行:无论用户隔多久再次交互,只要“时间步”没有推进太多,模型不会因为现实时间过去一天而遗忘重要信息。
-
便于离线仿真和可控实验:在仿真环境里,研究者可以根据需要压缩或拉伸时间步,使代理在短时间内经历长周期的生活事件,而记忆衰减速度保持可控。
论文还指出,近期性只是记忆检索的一个因素,最终检索得分是近期性、相关性和重要性三者的加权组合arxiv.org。这样的设计保证了即便某些记忆很久没访问,只要与当前情境高度相关或对代理而言极其重要,也不会完全被遗忘。
Fay 数字人框架的偏移时间机制
国内开源的 Fay 数字人 项目为了支持 2.5D/3D 数字人和多模态交互,也实现了类似的记忆机制。Fay 的核心是 MemoryStream,它存储代理的记忆节点(观察与反思)并在检索时计算记忆权重。与 Generative Agents 类似,Fay 没有直接使用系统时间作为记忆的时间戳,而是将每次“时间推进”作为一个整数时间步(time_step),并在调用记忆相关接口时显式传入。
记忆节点包含偏移时间戳
在 Fay 的 MemoryStream 中,向记忆流中添加节点是通过 _add_node 方法完成的。该方法接受 time_step 参数,并将其同时赋值给节点的 created 和 last_retrieved 字段.
node_dict["node_id"] = len(self.seq_nodes)
node_dict["node_type"] = node_type # "observation" 或 "reflection"
node_dict["content"] = content
node_dict["importance"] = importance node_dict["created"] = time_step # 创建时间为当前时间步 node_dict["last_retrieved"] = time_step # 最近访问时间也初始化为当前时间步
可以看到,这里的 time_step 由调用者决定,而不是系统当前时间。例如在数字人与用户对话的每一轮中,开发者可以维护一个简单的整数计数器 t,然后在调用 remember(content, time_step=t) 时传入。这样,记忆节点的时间轴仅与交互轮次有关。
检索时更新偏移时间并计算近期性
当需要检索记忆时,MemoryStream.retrieve() 会根据当前时间步 time_step 计算每个记忆节点的近期性、重要性和相关性,并组合为最终得分。首先,它调用 extract_recency(curr_nodes) 计算每个节点的近期性,其中 recency_decay 默认为 0.99,extract_recency 会找出当前节点列表中最大的 last_retrieved,并计算每个节点与该最大值之间的差值,然后使用指数衰减:
max_timestep = max(normalized_timestamps)
recency_decay = 0.99
for node in seq_nodes:
recency_out[node.node_id] = recency_decay ** (max_timestep - node.last_retrieved)
随后,retrieve() 在非 stateless 模式下会遍历检索出的每条记忆节点,并将其 last_retrieved 更新为当前 time_step。也就是说,记忆在每次被检索后都会“刷新”访问时间步,而没有被检索的记忆随着时间步推进而逐渐衰减。这一逻辑与 Generative Agents 中的“沙盒游戏小时指数衰减”如出一辙,属于典型的 偏移时间记忆机制。由于 time_step 可由开发者自由控制,Fay 在测试环境中既可以快速推进多个时间步模拟一天的经验,也可以在实际部署中让数字人跨天对话仍保持记忆。
从真实时间到偏移时间:体验差异
从上述对比可以看到,真实时间 与 偏移时间 在记忆递减上的表现迥异:
| 方案 | 时间来源 | 记忆衰减方式 | 使用体验 |
|---|---|---|---|
| 真实时间 | 系统当前时间 | 随现实时间流逝指数衰减,隔夜未交互也会衰减 | 用户隔天回来对话时容易断连,需要重复背景信息 |
| 偏移时间 | 自定义时间步(交互轮次或模拟时间) | 按时间步差值指数衰减,只有在大量交互后才会显著衰减 | 即使相隔数日,只要时间步没有推进太多,数字人仍能续接记忆 |
Generative Agents 和 Fay 项目都采用了偏移时间方法,它们将时间步视为“交互次数”或“沙盒游戏小时”而不是现实时间,从而实现了更灵活的记忆管理。豆包等产品则更偏向于实际时间衰减,因此在跨天对话时经常需要重新输入背景信息。这种差异提醒我们,数字人产品在设计记忆机制时,需要根据使用场景权衡真实时间与虚拟时间的尺度。
结语
数字人不仅要像真人一样生成流畅自然的语言,还要拥有可持续、连贯的记忆。斯坦福 Generative Agents 提出了使用沙盒游戏小时对记忆进行指数衰减的方法arxiv.org;Fay 数字人框架在开源实践中也采用偏移时间记录记忆创建和访问时间。这些设计表明,通过 偏移时间 控制记忆衰减,可以有效解决现实时间导致的失忆问题。未来的数字人应用可以根据业务需求灵活调整时间步长度,甚至结合用户日常节奏动态调整,从而在保持记忆连贯的同时控制模型成本。对开发者而言,理解并应用偏移时间机制,将帮助我们构建更健壮、长久陪伴的智能体。
更多推荐


所有评论(0)