十小时前,玩家在一个雨夜对旅店老板娘说过一句“我其实不是本地人,我在找一个人”。十小时后,玩家站在城门口被守卫盘问,老板娘恰好路过,说了一句“他是我的房客”。这一句话并不复杂,但要让它自然出现,系统必须在十小时之间保存、筛选,并在合适的时候取出那条信息。长期记忆让 NPC 像一个真实的人,同时也让它成为整个游戏里最容易出错的系统之一。

别把聊天记录当记忆

最直接的做法是把历史对话总结一下,塞进下一次的提示词里。它在前一个小时管用,到第十个小时就会崩:摘要被反复压缩,细节丢失;无关闲聊挤掉关键事实;上下文长度成本随时间线性上涨。更稳的做法是把记忆拆成不同类型,各自有各自的生命周期:

  • 关系(Relationship):好感、信任、恩怨,用少量数值加标签保存,变化要有来源。
  • 任务(Quest):任务阶段、玩家承诺过什么、欠了谁的人情,需要精确,不能靠语言模型回忆。
  • 玩家历史(Player History):玩家说过的自我介绍、做过的选择、用过的称呼,是可被引用的事实。
  • 世界状态(World State):某个地方被烧毁、某个人已死亡,这是客观的,不属于任何一个 NPC 的主观记忆。

写入:什么值得记

不是每句话都要写入。我们更倾向让系统在对话结束后做一次“事件抽取”:这次对话里有没有承诺、揭示、情绪转折、价值观表态?只有这些才会变成带时间戳、来源、重要度和可披露范围的记忆条目。“今天天气不错”这类话可以留在短期上下文里,让它自然过期。写入时还要区分“玩家说的”和“玩家做的”:玩家说自己是个好人,NPC 记下的应当是“玩家声称”,而不是事实。

检索:此刻该想起什么

NPC 不需要记得所有事,只需要在正确的场景想起相关的事。检索可以按三个信号组合:当前对话主题的语义相似度、在场人物和地点的关联、以及条目的重要度与新近度。守卫盘问玩家时,老板娘应该想起“他是找人的外乡人”,而不是三天前他买了一份烤肉。检索到的条目数量要设上限,通常几条就够,过多反而让对话变得像在背档案。

遗忘:不是删除,是降权与合并

遗忘让 NPC 显得真实,也让系统可持续。合理的遗忘策略有两种:一是降权,长期没被引用的低重要度条目逐渐排到检索之外;二是合并,把“玩家三次请我喝酒”合成“玩家很大方”,保留倾向、丢掉琐碎。任务承诺与重大事件应当免于遗忘,或者只降低被主动提起的频率,而不删除。

一致性:剧情分支怎么跟着变

假如玩家在第一小时欺骗了老板娘,第十小时她刚好收到线索发现真相,剧情就应当出现分歧:信任值下跌,相关任务线关闭或转成对抗线,甚至影响其他 NPC 对玩家的态度。这要求记忆更新触发的不是一句台词,而是结构化的状态变更:关系数值、任务阶段、世界旗标同时写入。语言模型负责把状态变化说得像人话,状态本身由游戏系统持有。这样才能避免“嘴上说翻脸了,任务列表里却还是好友”的错位。这些状态字段,也是玩家二次跑不同分支时的比较依据,可参考语音意图判断里对高代价指令的确认思路,对不可逆的关系变化同样要谨慎。

记忆越多,套话风险越大

有研究指出,LLM NPC 可能被玩家通过诱导式提问“套话”,泄露本不该知道或不该说的设定与秘密。记忆丰富之后,这个问题更严重:老板娘知道玩家的秘密,也知道另一位客人的秘密。防护可以放在两处。写入时给每条记忆标注可披露对象和条件,比如“只对玩家本人可提及”“需信任度超过阈值”;生成前再做一次过滤,把不符合披露条件的条目从候选中移除,而不是指望模型自己守口如瓶。金沙娱乐在 AI VR 方向的设计思路,也是把“记得”和“说得”分成两个环节,中间放一道规则检查。

想验证一套记忆系统是否可用,可以做这样一个测试:连续玩十小时,随机抽三个早期事件,检查它们是否在合适时机被想起、是否被不当地泄露、是否与任务与关系状态相互一致。空间感知部分可参考物品指代解析,那里产生的“玩家指过什么、拿过什么”也会成为玩家历史的一部分。