第两百天,她说“初次见面”
先看一个假设的场景。游戏里有位角色叫林岫,是镇上图书馆的管理员,玩家和她相处了两百天(示意)。这期间发生过几件事:玩家替她找回丢失的旧笔记本;两人为要不要参加图书馆的年终展览吵过一次架,后来和好;她第一次对玩家说过“我很少和人聊这么久”。
第两百零一天,玩家打开游戏,林岫说:“你好,我是林岫,这里是镇上的图书馆。”
这个故障没有任何提示,但玩家的感受非常具体:她把我们的经历全部忘了。更微妙的一种故障是,她记得所有事,却说出了一句与性格相反的话,比如平时克制含蓄的林岫,突然用夸张的语气说“我最喜欢你了”。玩家一时说不出哪里不对,只觉得“这不是她”。
这两类问题分别对应两个层面:记忆层丢了共同经历,人格层跑偏了性格。 它们看起来是两个毛病,根源却相通:系统没有一份稳定的、被持续维护的“我们之间是什么状态”的记录,全靠模型每次根据眼前的上下文临场发挥。
长对话里,角色会一点点走样
近期关于长期角色一致性的研究里,常用“人设漂移”来概括这种现象:对话拉长以后,角色的特质会逐渐变弱,早期的事实被遗忘,时间线开始混乱,严重时还会把不同角色或不同用户的状态混在一起。这里只引用定性的结论,不谈具体比例。
漂移通常有三种来源,值得分开看。
- 上下文挤出:设定写在提示词最前面,随着对话增长被越来越多的新内容淹没,模型对它的注意力自然下降。
- 顺着玩家改性格:玩家连续几天用夸张热情的语气说话,模型为了“接得上”,就逐步把角色也带向那种语气。每一步都很小,累计起来就是另一个人。
- 摘要覆盖:为了省空间,旧记忆被反复压缩,压缩过程里“她克制、不轻易表达”这类细微特质最先被磨掉。
所以稳定不是靠一句“请保持人设”的提示能解决的,它需要结构上的支撑:把不该变的东西放在不会被冲淡的地方,把会变的东西记录成有版本、有来源的状态。
关系状态里到底要存什么
我们倾向于把“关系”拆成几个明确的字段,而不是一个笼统的“好感度”。下面是一个示意的结构,实际字段以产品设计为准。
| 字段 | 记录什么 | 林岫的示意内容 |
|---|---|---|
| 亲近度 | 熟悉和自在的程度 | 较高,愿意主动分享私事 |
| 信任度 | 是否相信对方会守约 | 中高,笔记本事件后上升 |
| 关键节点 | 无法被摘要抹掉的事 | 找回笔记本、展览争吵与和好 |
| 未解事项 | 还没说清的心结 | 她一直没告诉玩家搬家的打算 |
| 当前情绪 | 此刻的心情基调 | 期待,略带不安 |
| 角色目标 | 她眼下想做的事 | 办好年终展览 |
把亲近和信任分开有实际意义。一次争吵可能让亲近感短暂下降,但信任并没有受损;一次失约则相反。如果只有一个数字,角色就只会“变好”或“变坏”,无法表现出“我还是信你,只是今天有点生气”。
关键节点和未解事项是防止“忘记重要事件”的关键。它们不参与普通的遗忘衰减,保存的是精炼过的短叙述,而非全文。长期记忆的分层设计一文里讲过,关系记忆与事件、事实记忆是并行的另一层,这里的关键节点正是从事件记忆里被“提升”上来的那一小部分。
把不能变的和会变的分开放
为了防止人设漂移,最重要的一个结构决定是:静态设定和动态经历分开存储。
静态部分是林岫的人格底色:说话含蓄,不喜欢被追问隐私,对书和秩序有近乎固执的热爱,遇到冲突倾向先沉默。这一份内容由设计者写定,日常聊天不能直接改写它。它像一根锚,每次生成回复时都会被重新带入。
动态部分是这两百天里积累的一切:共同经历、当前情绪、关系变化。它随时间生长,允许被更新,也允许被修正。
两者的关系是:动态经历可以让林岫在某些场景里表现得更松弛,但不能把“含蓄”变成“外放”。更合理的说法是,经历改变的是她表达的方式和边界,不是她是谁。比如相处两百天后,她可以主动说一句“我今天心情不太好”,这符合“关系变深”,同时用词依然克制,符合“她是林岫”。
实现上,可以给人格特质设一个“可适应范围”:亲近度越高,角色越愿意打破一点距离,但这个幅度是设计者预设的,而不是由对话内容无限拉伸。这样,即使玩家一直用夸张的语气说话,她的语气也只是略微放松,不会变成另一个人。设计者还需要为“成长”留出合法的通道:比如相处一年之后,她可以主动提起自己搬家的打算,这是关系推动出来的变化,也是设计好的剧情节点,而不是模型随手改写的结果。区分这两者,才能知道哪些变化该被鼓励,哪些该被拦下。
新旧记忆打架时,谁说了算
长期运行以后,冲突不可避免。玩家第五十天说“我不喜欢热闹的地方”,第一百八十天却兴致勃勃地邀请林岫去展览开幕式。哪一条是真的?
大发娱乐AI倾向于用一套明确的优先级,而不是让模型每次自行猜测。
- 玩家亲手确认的内容优先:玩家在记忆清单里改过或锁定的条目,高于一切自动推断。
- 较新的、更具体的信息优先于较旧的、更笼统的:“我最近开始喜欢热闹了”比一百三十天前的一句抱怨更有效。
- 旧条目不直接抹掉,而是标记为“曾经如此”:林岫可以记得“他以前不喜欢热闹,现在愿意来了”,这本身就是一段关系变化的证据。
- 无法判断时,允许角色求证:“你之前说不喜欢人多,这次是不是有什么特别的原因?”用一句自然的询问代替硬编。
这里的重点是,冲突不是要被消灭的错误,而是关系在变化的信号。裁决规则的价值在于让这种变化有迹可循,也让玩家改过的地方不会被下一次自动整理悄悄覆盖。相关的一致性验证方法,我们在行为一致性验证里有更完整的讨论。
一次和解,状态是怎么变的
把上面的结构放进林岫和玩家的那次争吵里,看看它们如何协同。示意场景里,争吵发生在第一百一十天,起因是玩家替她决定了展览的主题,她觉得自己的意见被忽略。
- 争吵当天:亲近度小幅下降,信任度不变;未解事项里新增一条“玩家替我做了决定”;当前情绪记为“委屈”。
- 之后几天:因为有“未解事项”,林岫不会若无其事地聊起别的,也不会莫名其妙地冷淡,她的沉默和简短回答有了可追溯的原因。
- 玩家道歉并把主题决定权还给她:这一次互动被识别为和解,未解事项被标记为已解决,亲近度回升,同时写入一个新的关键节点“展览争吵后和好”。
- 几十天以后:玩家又想替她做某个决定,检索会取回这个关键节点,林岫可以自然地说一句“上次你也是这样,后来我们说开了”,而不是从零开始反应。
这个过程里,模型没有被要求“记得一切”,只是被交给了一份小而准确的状态。也正因为这样,它才可以被玩家检查,出错时可以被改回来。
回复之前的一次核对
有了状态和锚点,最后一步是在角色开口之前做一次轻量核对。示意流程如下。
- 取出林岫的静态人格、关系状态和当前目标。
- 根据玩家这句话检索几条相关的关键节点与事件。
- 让模型生成候选回复。
- 检查候选回复:是否重复自我介绍?是否与关键节点矛盾?语气是否落在人格允许的范围内?是否泄露了“不该知道”的信息?
- 不通过就带着具体原因重写一次;仍不通过,则退回一个更保守的回复,而不是硬输出。
这一步不必对每句话都做重检查,可以针对关键场合触发,比如重逢、和解、争吵、承诺等。它的目的是给第五百次聊天提供一道兜底,而不是拖慢每一次对话。
关系强度,由玩家来定
关系状态里有数值,容易让人觉得游戏在给关系“打分”,进而产生必须维持的压力。我们并不希望如此。虚拟角色不是真人,也不替代现实中的关系;数值只是让角色前后一致的内部记录,不应该变成“你不来她就会疏远”的惩罚。
因此,玩家应当拥有下面这些控制权,具体功能以App内说明为准。
- 调整关系强度:可以选择让角色更含蓄或更亲近,也可以让关系停留在当前阶段,不再自动加深。
- 查看和纠正记忆:关键节点和未解事项对玩家可见,记错的可以改,记忆纠正一篇讲了原因与办法。
- 暂停与回退:可以暂停某段剧情,或者让角色“不要再提”某件事。
- 不制造焦虑:长时间不上线,角色不会因此“生气”或“失望”,关系状态只是安静地停在原处。
如果你在使用中持续感到困扰,请联系身边的人或专业人士。
一致性是一种被反复兑现的承诺
回到开头的问题:第五百次聊天仍然像同一个角色,靠的不是某个神奇的模型,而是一组朴素的工程决定,把关系拆成明确字段,把人格锚点与经历分开,给冲突一套可解释的规则,在关键节点前做核对,再把最终的调整权留给玩家。
哪些问题还没有彻底解决?其一,关键节点该由谁来判断,模型可能误判一件对玩家很重要的小事;其二,角色的“成长”与“漂移”之间的界限很细,适应范围设多大仍需要大量试验;其三,多角色之间的状态隔离还需要更严格的验证。我们更愿意把这些写出来,而不是宣称已经做到完美。因为对陪伴类游戏来说,诚实地承认边界,本身就是对玩家的一种尊重。