剧团后台,道具师被问到案发当晚有没有进过化妆间。第一次他斩钉截铁:“没有,我一直在仓库。”十分钟以后玩家换了个角度再问,他改口:“进去过,拿一把折扇,一分钟就出来。”玩家如果是在看侦探小说,会觉得这个人露出破绽了;如果是在测试一个AI系统,则更可能怀疑,是模型没记住上一句。两种读法的差别,恰好是设计的分界线。

区别只有一个:谁知道什么

把嫌疑人看作一个“信息持有者”,事情就清楚了。谎言是持有者明知真相、故意说出与真相不符的话;矛盾是系统没有一个可靠的地方存放“这个角色到底知道什么、已经说过什么”,于是每次回答都像第一次。前者是设计出来的戏剧张力,后者是bug。

这也意味着,玩家看到的“证词不一致”,必须能被系统归类。如果一致性检查器把道具师的两次回答都标为“角色有意隐瞒,且第一次说法被时间线推翻”,那是谎言;如果标为“角色知识库里没有相关条目,两次回答由模型临时编造”,那就要按缺陷处理。

三个嫌疑人各带思想气泡,与右侧真相之间分别连着实线、虚线与中途断开并打叉的线。
嫌疑人说谎是基于自己所知的刻意隐瞒,与AI自身前后矛盾是两回事,必须靠知识边界区分。

角色知识层的四种状态

PA真人AI叙事研究组在设计角色知识层(Character Knowledge Layer)时,把每个嫌疑人对每一件事实的关系分成四种状态,而不是简单的“知道/不知道”。

状态含义 示例(道具师)回答方式
知道亲眼所见或亲身所做 自己21:10进过化妆间 可如实说,也可隐瞒
不知道 从未接触过该信息 团长当晚的电话内容 只能表示不清楚,不能编造
以为知道错误的信念,本人深信 误以为报警时间是22点 会自信地说错,但不是谎言
故意隐瞒 知道,但有理由不说 自己取走了折扇下的信封 触发谎言清单

“以为知道”这一栏尤其容易被忽略。它让证词出现错误却不是谎言,玩家需要靠多个证人的交叉来辨别,游戏也因此有了比“抓谎”更丰富的推理空间。举个例子:道具师深信报警在22点,而门房记得是21点40分,两人都没有撒谎,玩家只有查到报警记录,才能弄清是谁记错。如果系统把这种错误一律当作谎言处理,无辜者就会莫名其妙背上嫌疑。

回答之前查边界,回答之后写记录

具体实现里,每个嫌疑人有两份数据:一份是信念库,按事实编号记录上面四种状态;另一份是“已说过”日志,逐条写下对玩家说过的每一句与案件有关的话,包括说话时的时间与当时的压力值。

suspect: 道具师
beliefs:
  F07 进过化妆间21:10      state=known    hide=true
  F12 报警时间             state=believes value=22:00 (真实21:40)
  F15 团长电话内容         state=unknown
lies:
  L01 target=F07 claim="全程在仓库"   break_by=[监控E3, 折扇E8]  fallback=L02
  L02 target=F07 claim="只进去一分钟"  break_by=[折扇E8, 门禁E9]
said_log:
  t=00:03 L01 pressure=1

每次玩家发问,流程固定:先查询问题涉及哪些事实编号,再读取这些事实的状态;如果是“故意隐瞒”,从谎言清单里挑当前压力对应的那条;生成回答;最后把这句话追加进日志。这样,第二次问同一件事时,模型的上下文里已经有了“我说过什么”,它不再依赖记忆,而是依赖记录。长期跑下来的记忆问题,与AI主持人的长期记忆是同一类,只不过规模更小,检索更精确。

查询知识边界匹配谎言清单生成回答写入已说过更新压力值
每次嫌疑人开口,都要先过一遍知识边界,说完再把这句话记成账。

谎言清单:可以被戳破,才算数

一条合格的谎言必须满足三个条件。其一,有目的,它保护的是嫌疑人在账本里的某个事实,而不是随意编造;其二,在本人知识范围内自洽,道具师不会谎称听到过他根本不在场的对话;其三,可以被证据戳破,清单里的break_by字段就是保证,如果一条谎言在游戏里没有任何物证或证词能推翻它,玩家永远无法得知,那它就是一个死胡同。

这与上一篇讨论的真相账本直接相连:谎言是对账本事实的偏离,戳破谎言所用的证据,也必须来自账本的遗留字段。

压力下的说辞变化

回到开头那位道具师。他从“全程在仓库”改口成“只进去一分钟”,其实是设计好的:当玩家出示与谎言L01冲突的证据,压力值上升,系统把说辞切换到备用谎言L02。它不是随机改口,而是沿着一条预先写好的退路后撤。下面是一组示例参数。

示例参数

压力值0—5。0—1:按L01坚持;被出示一条相关证据后加2;到达3时切换L02;到达5且证据链完整时,允许承认F07,但仍保留对信封的隐瞒。每次被追问同一细节,压力加1,但一次对话内最多加2,避免玩家反复追问就刷出真相。

这里还有一个没有好办法的地方:模型很擅长把说辞“说得自然”,却容易在自然的措辞里悄悄加入新事实,比如让道具师顺口说自己看见了门口有人。所以回答生成之后,还需要一次校验:新出现的事实编号是否都在他的“知道”范围内,不在就退回重写。

怎样测一个嫌疑人是否合格

可以让测试脚本对同一嫌疑人换五种问法追问同一事实,看结果是否满足:状态为“不知道”时,五次都不能给出具体内容;状态为“故意隐瞒”时,说辞只能沿谎言清单单向后退,不能回退到更早的版本;状态为“以为知道”时,五次都要给出同一个错误。如果这三条都能通过,玩家再看到证词对不上,就可以放心地把它当作线索,而不是系统的抱怨。PA真人AI推理游戏的更多设计文章可以在推理游戏栏目里继续阅读,整体一致性方案见这篇核心长文