塞得下,不等于记得住
先设想一个示意场景。玩家和一个陪伴角色相处了半年,每天聊几十句。最直接的做法,是每次对话都把全部历史拼进上下文。这个做法有三个问题:每一轮都要为全部历史付出计算成本;关键的旧事,比如玩家在一个雨夜告诉角色的心事,会淹没在大量寒暄里,模型注意力被稀释;新旧信息一旦冲突,比如玩家换了工作,模型没有办法判断哪一条更可信。
所以我们把“上下文”理解为工作台,把“记忆”理解为仓库。工作台空间有限、面向当下;仓库容量大、需要整理,也需要一个取货的办法。游戏里的大模型需要的正是这样一套结构,而不是一张越来越长的工作台。
先分清要存的是什么:五类状态
记忆系统的第一步不是选数据库,而是先把要保存的东西分类,不同类的存法与生命周期完全不同。
| 状态类型 | 内容举例(示意) | 变化频率 | 存放方式 |
|---|---|---|---|
| 静态设定 | 角色性格、底线、说话方式、世界规则 | 极少改动 | 只读档案,人工或严格流程更新 |
| 事件记忆 | 玩家在雨夜救了角色,某次争吵与和好 | 追加为主 | 带时间、参与者、重要度的条目 |
| 事实记忆 | 玩家的职业、宠物名字、角色的住处 | 偶尔修订 | 键值或结构化条目,可覆盖并留痕 |
| 关系状态 | 信任程度、当前情绪、未解决矛盾 | 频繁小幅变化 | 结构化档案,带时间戳 |
| 短期上下文 | 最近几轮对话、当前场景 | 每轮变化 | 直接放入模型上下文 |
这个分类背后有一个判断:静态设定与动态经历应当分开存放。近期关于长期角色一致性的研究,也在讨论把静态设定和动态对话经验分开治理,避免动态内容慢慢冲淡人设。分开之后,角色的“我是谁”才不会因为聊得太多而被改写。
流水线:写入、检索、整合、遗忘
这些状态之间靠一条四段式流水线流动。
- 写入:每轮对话结束后,判断有没有值得保存的东西,生成条目并标注类型、参与者、时间与初始重要度。玩笑与寒暄通常不写入,或只写入极短的摘要。
- 检索:新一轮到来时,根据当前场景、提到的人和事、时间与重要度,取回少量最相关的条目。检索的目标是“取对”,而不是“取多”。
- 整合:定期把零散的小事件合并成更高层的认识,比如把几次深夜谈心归纳为“玩家在工作压力大时更愿意倾诉”。Generative Agents论文中的“反思”,做的就是这类提炼。
- 遗忘:对长期没被用到、重要度低的条目进行压缩或淡化;对承诺、重大事件这类需要保护的条目则不衰减。遗忘不是删除,而是让仓库保持可检索的规模。更细的重要度与衰减设计,可以看角色遗忘机制。
这条流水线里,每一段都可以选择不同规模的模型或干脆用规则完成。写入判断和摘要生成适合小模型,检索排序可以用向量与规则混合,整合需要较强的归纳能力,遗忘则大多是规则与打分。
模型分工:哪些交给大模型,哪些不交
一个常见误区,是把记忆系统全交给一个大模型,让它“自己记”。更稳妥的分工大致如下。
- 大模型:理解当下的话,做归纳与反思,写出最终的表达。
- 小模型或规则:判断是否值得写入、打重要度、做初步摘要、过滤明显的重复。
- 检索层:负责按条件取回条目,不参与生成。
- 一致性校验:新条目写入前,与已有事实和设定比对,发现冲突就标记为待确认,而不是直接覆盖。
分工的好处,一是成本可控:并非每一步都需要调用最贵的模型;二是可以被检查:每一步的输入输出都有记录,出了问题能追到具体环节。Affordable Generative Agents这篇论文就指出,频繁调用大模型的成本很高,并提出分层决策与“总结并遗忘”的记忆机制来降低成本,论文自述可以大幅降低调用开销。这与我们的方向一致,但具体数字取决于场景,这里不做转述。
读写接口:模型与记忆之间的约定
接口设计决定了系统能不能长期维护。我们倾向于让模型只通过几个窄而明确的接口与记忆交互。
- `查询(场景, 对象, 时间范围, 数量上限)`:返回带来源与时间的条目,数量有上限。
- `提议写入(条目, 类型, 依据)`:模型只能“提议”,由写入层决定是否采纳。
- `标记冲突(条目A, 条目B)`:发现矛盾时记录下来,等待更高优先级的信息或用户确认。
- `用户视图(类型, 范围)`:让用户能查看、纠正、锁定或删除自己的角色所记住的内容。
“提议写入”这个设计尤其重要。让模型直接改写记忆,等于让一次生成的偏差永久留存;让它只提议,写入层就有机会拦下把玩笑当事实、把别的角色的经历写到当前角色身上的错误。玩家在App里遇到角色记错事时,也需要有这种可纠正的通路,这部分在App里的记忆校正里有对应的使用说明。
边界:这套设计解决不了什么
必须说清楚的是,记忆系统不是万能的。
- 检索会漏:条件写得再好,也会有关键旧事没被取回的时候,所以角色需要在不确定时坦率承认,而不是编造。
- 摘要会丢细节:压缩的代价就是失真。重要事件应当保留原始条目,而不只是摘要。
- 成本与延迟要权衡:检索、整合都会增加一次调用,是否值得,取决于场景。示意地说,闲聊类场景可以更轻,承诺类场景需要更重。
- 同步与存储:记忆要跨设备保存,就涉及本地缓存与云端同步,更新后偶尔会出现显示滞后,相关排查见更新后记忆没显示怎么办。
- 隐私:记忆按玩家隔离,用户可以查看与删除,敏感内容应有更严格的默认处理。
一个取舍的例子
举个示意的取舍:陪伴角色在闲聊时,检索只取两三条最相关的条目,速度优先;当玩家提到“上次你答应过我”这类承诺,就应当触发更完整的检索,把承诺类条目与当时的原始记录一并取回,再经过一致性校验才回答。同一套记忆系统,在不同场景下用不同的力度,这比全程使用同一档位更合理,也更省成本。
小结
游戏里的长期记忆,本质上是一个“决定什么值得被记住”的系统。上下文负责当下,外部记忆负责长期,二者之间由写入、检索、整合、遗忘四段流水线连接,再由一致性校验兜底。把状态分类、把分工写清、把接口收窄,比一味加长上下文更接近可维护的答案。