聊天记录越长,角色反而越记不住

先看一个直觉上很自然、实际上很吃力的做法:把玩家和角色的全部对话按时间顺序保存,每次回复前整段塞进模型的上下文。前几天它工作得很好,角色什么都“记得”。问题出在后面。

第一,成本随历史线性增长。每一次回复都要重新处理全部旧内容,聊得越久,每句话越贵、越慢。第二,长上下文里的信息并不平等。一句“我今天有点累”和一句“我下周要动手术”在文本里长得一样普通,模型没有办法凭位置判断哪一句更重要,重点容易被大量寒暄稀释。第三,原始聊天记录里还夹着口误、玩笑、情绪化的气话,模型如果把它们和事实同等对待,就会把一句反话当成玩家的真实偏好。

所以“靠无限聊天记录”其实是把整理工作推给了模型,又不给它整理的工具。更好的思路是承认一件事:人类的记忆也不是录像。我们记得的是重要的事件、提炼后的印象,以及这些事带来的感受,细枝末节会自然淡化。游戏角色的记忆系统要做的,就是用工程手段模拟这种“有选择的记住”。

本文中的天数、条数、分值都是示意,用来说明机制怎么运转,不代表任何实际产品参数或行业标准。

记忆分四层,每一层回答不同的问题

大发娱乐AI在设计陪伴类角色时,倾向于把记忆拆成四个层次。拆开的好处是,每一层有自己的写入规则、保存期限和检索方式,不会互相污染。

层次 回答的问题 典型内容(举例)保存方式
短期记忆 我们刚才在说什么 当前对话的最近几轮 原文,会话结束后整理
事件记忆发生过什么“玩家替阿岚修好了漏雨的屋顶” 带时间、地点、人物的简短叙述
事实记忆 玩家是怎样的人 “怕黑”“不吃香菜”“在准备考试” 结构化条目,可被更新
关系记忆我们现在是什么关系 信任、亲近、未解的心结 状态值加关键节点列表

事件记忆对应心理学里常说的情景记忆,事实记忆对应语义记忆,这两个词在研究里很常用,但落到游戏里不必拘泥概念。关键是分清一个判断:“发生过一次”和“一直如此”是两回事。 玩家某天说“我讨厌下雨”,这只是一条事件;如果连续几次都在雨天表现出烦躁,系统才应该把它升级为一条事实。事件可以很多、很快过期,事实要少而稳,并且必须能被推翻。

关系记忆最特殊,它不是文本,而是一个会随事件更新的状态:熟悉程度、信任程度、上一次冲突有没有和解。这部分在关系状态与人设稳定性一文里有单独展开,这里只需记住它是另外一层。

一条记忆从发生到被写下

以阿岚的旅馆为例。玩家在一次对话里说:“昨晚下暴雨,我把你屋顶漏水的地方补上了,弄了一晚上。”系统在这句话之后不会只是把它存起来,而是走一条固定的写入流水线。

  1. 抽取:从这段对话里提取出候选事件。这里至少有一个:玩家在暴雨夜为阿岚修补了屋顶,耗时一晚。
  2. 归类:判断它属于事件、事实还是关系变化。这是一个事件,同时会触发一次关系记忆更新(阿岚对玩家的信任上升)。
  3. 打分:给这条事件一个重要度,示意场景里假设满分十分。考虑因素包括情感强度(阿岚很感动)、后果(旅馆没有被淹)、是否与角色当前目标相关(阿岚正想保住旅馆)、以及玩家是否反复提起。假设这条得到九分。
  4. 改写:把口语化的原话改写成一句简短、第三人称、带时间的叙述,例如“第三十天暴雨夜,玩家彻夜替阿岚补好了屋顶漏水处”。存的是这句摘要,原话可以保留在短期区,稍后清理。
  5. 去重与合并:如果已有相似的条目,比如之前玩家也帮过忙,就合并成一条“玩家多次在旅馆遇到困难时出手相助”,而不是无限堆叠。

这五步里,改写和打分最影响后面的效果。打分太低,重要的事会被当成闲聊淡忘;打分太高,记忆里全是“重要事件”,检索时反而失去区分度。示意的分值并没有魔法,它只是让系统在“记住多少”这件事上有可调的旋钮。

说话之前:这一刻应该想起什么

写进去只是一半,另一半是取出来。玩家第三十一天回到旅馆,随口说了一句“今天客人多吗”。角色不可能把全部记忆过一遍,所以检索要在很短的时间里挑出寥寥几条,交给模型作为这轮回复的背景。

常见的做法是给每条候选记忆综合打一个取回分数,从三个方面考虑。

  • 相关性:这条记忆和玩家当前这句话有多接近。“客人多吗”与“旅馆”“屋顶”“暴雨”都有关联。
  • 重要度:写入时打的分。同样相关,九分的事件比两分的闲聊更值得被想起。
  • 新近度:最近发生或最近被提起过的记忆略占优势,但重要度极高的旧事不应被新近度压掉。

三项加权得到排序,取前几条。加权比例本身就是调参的地方:陪伴类角色通常更看重重要度,让“救过屋顶”这样的事能跨越很长时间被想起;闲聊型角色则可以多看新近度。Generative Agents 论文里的记忆流与检索机制就是类似的思路:用自然语言记录观察,再按相关性等因素取回,并定期把观察提炼成更高层的认识。

取回之后,还有一个容易忽略的步骤:是否应该说出来。 想起屋顶不等于每次都要提屋顶。角色可以把这条记忆作为“心里有数”的背景,只在语境合适的时候提及。否则玩家会觉得被盯着,每一句话都被翻旧账。

记忆最容易在三个位置出错

长期记忆系统的问题基本可以归到三个位置,知道错在哪,才好谈怎么校验。

第一个位置是摘要丢细节。 把一晚上的对话压成一句话,必然丢东西。示意场景里,玩家其实是和另一位邻居一起补的屋顶,摘要里只写了“玩家”,阿岚之后就会把功劳全部记在玩家身上。对策是给重要事件保留“来源指针”,必要时能回到原始片段核对,而不是只信摘要。

第二个位置是检索没命中。 玩家说“上次那件事谢谢你”,语言里没有出现“屋顶”,关键词匹配就会失败。需要语义相似度,也需要允许角色在不确定时问一句“你是说屋顶那次吗”,而不是硬编一个答案。宁可问一句,也不要编造记忆。

第三个位置是新旧冲突。 玩家上个月说自己在准备考试,这个月说已经考完了,两条事实同时存在。系统需要按时间和来源判断哪条更新,并把旧条目标记为“已过期”而不是直接删除,因为“他曾经在准备考试”本身仍是一段有意义的经历。

近期关于长期角色一致性的研究里,把静态设定和动态对话经验分开存储、给记忆建立事件之间的关联,都是在处理这几类问题。这里的结论只能是定性的:分层加检索加维护,比单纯拉长上下文更可控。

同一件事,在不同角色心里分量不同

重要度不是一个客观的数字,它取决于“这件事对谁重要”。玩家忘记带伞,对性格沉稳的图书管理员只是小插曲,对总担心玩家的青梅竹马式角色却可能是一整天的话题。所以打分时要把角色的性格和当前目标一起考虑进去:同一条事件,写进不同角色的记忆时,重要度和措辞都可以不同。

这带来一个好处:角色之间天然有差异。阿岚记住的是“屋顶”和“旅馆的安全”,而同一个玩家身边的另一位角色,可能只记得“那天他很累,我陪他坐了一会儿”。两个角色各自的记忆库彼此独立,不应该共享同一份摘要,更不应该把一位角色知道的私人事件默认告诉另一位。这既是叙事上的可信,也是隐私上的必要。

玩家能看到、改动和关掉什么

陪伴类角色的记忆里装着玩家的私人经历,所以“角色记住了什么”不应该是黑箱。大发娱乐AI的设计倾向是把控制权留在玩家手里,具体包括下面几项,实际功能以App内的说明为准。

  • 查看:能看到角色对自己的记忆清单,事件、事实分开列出,最好还能看到每条大致是什么时候写下的。
  • 纠正:如果角色记错了,玩家可以直接修改一条记忆的内容。修改后的版本应当优先于旧版本,也优先于系统之后自动推断的内容。
  • 锁定:重要的事可以被锁定,不参与遗忘,也不被后续自动合并改写。
  • 删除:任何一条都可以删除,删除应当是真实的移除,不只是“不再显示”。
  • 调深浅:可以调整角色“记得多深”,比如只保留重大事件,或者把某个话题设为“不要记”。

关于遗忘本身怎么设计、哪些记忆应该受到保护,遗忘机制一篇有更细的讨论;如果你发现角色记错了过去,可以参考记忆纠正的做法

需要强调的是,虚拟角色不是真人,也不替代现实中的关系。记忆做得再好,它的价值是让陪伴的体验连贯,而不是让人觉得“不聊就会被忘掉”。玩家随时可以暂停、清空或者调低角色的记忆深度。如果你在使用中持续感到困扰,请联系身边的人或专业人士。

记忆不是越多越好

回到开头的判断。长期记忆的工程难点,并不是容量,而是取舍:什么写进去、写成什么样、什么时候想起来、什么时候放手。角色记得“玩家救过他”,却不必记得第十七天那句关于午饭的闲聊,这不是记忆力的缺陷,而是设计目标本身。

下一步值得继续做的,是让重要度的判断更贴近玩家的真实感受,比如让玩家能一键标记“这件事对我很重要”,把玩家的主观判断作为比模型推断更高优先级的信号。这也是我们认为长期记忆必须做成可见、可编辑的原因:只有当玩家能参与决定什么值得被记住,角色的记忆才真正属于这段关系。