跳转至

Versu: Agents and Utility AI

这是对交互式故事角色 AI 引擎 Versu 工作原理的简要介绍,主要是 代理/角色(Agents)基于效用的决策系统(Utility-Based Decision-Making) 部分。

内容从小组讨论会的会议材料修改而来,材料被 LLM 润色过(修改了分段和措辞,为了“更快更方便阅读”),与以往的博客语气会不太一样。

Versu 没有公开过具体实现,我所有的分析均来自 Richard Evans 和 Emily Short 的论文以及 Emily Short 博客上的零散文章,可能有不少错误。

前言

Versu 是 Richard Evans(《模拟人生》AI 架构师)、Graham Nelson(Inform 语言设计者)和 Emily Short(交互式小说领域最具影响力的设计师之一)于 2013 年开发的社交模拟系统,用于作品《Blood & Laurels》

Emily Short 的作品获得过交互式小说等领域的许多奖,总之是偷谱榜榜首。她还以顾问身份参与了 Failbetter Games 的 Storylet/QBN 架构(《Fallen London》《Sunless Sea》)。

这两套系统解决不同层面的问题:Storylet 处理内容选择,Versu 处理角色行为。两者可独立使用,也可结合。

本文就只专注于 Versu 的核心机制。

核心概念

展示概念需要一个示例故事,下面用了大家熟悉的《三顾茅庐》。由于我对剧情印象没有非常深刻,同时示例需要一些微小的改编,要是觉得和原著差别太大,就当“新新三国”来看吧。

设计目标

让角色 自主决策,而非按剧本行动。

传统做法:为每种情况编写反应

如果 张飞等待超过1小时 且 诸葛亮在睡觉:
    张飞.发怒()
    如果 刘备在场:
        刘备.劝阻()

Versu 做法:定义角色的欲望和性格,行为从中涌现

张飞 = { 欲望: [快速解决问题, 服从大哥], 性格: 暴躁 }
刘备 = { 欲望: [请出诸葛亮, 安抚兄弟], 性格: 隐忍 }

世界状态:事实数据库

Versu 用 逻辑事实 表示世界状态。

zhang_fei.location!longzhong                    // 张飞在隆中
zhang_fei.emotional_state!irritated             // 张飞烦躁
liu_bei.relationship.zhuge_liang.respect!high   // 刘备敬重诸葛亮
zhuge_liang.status!sleeping                     // 诸葛亮在睡觉

! 表示排他性:设置 zhang_fei.location!garden 会自动移除 zhang_fei.location!longzhong

角色模型

每个角色由以下属性构成(全部存储为事实):

属性 说明 示例
Wants(欲望) 想达成的目标 + 效用值 「请出诸葛亮」-> +40
Traits(性格) 稳定特质,影响欲望的效用值 暴躁、隐忍、谨慎
Relationships(关系) 对他人的多维评价 对诸葛亮:作为谋士 -20,作为学者 +10
Emotional State(情绪) 短期状态 烦躁、平静、愤怒
Beliefs(信念) 角色相信的事(可能为假) 「诸葛亮在装睡」

情境与行动:Social Practice 和 Affordance

Social Practice(社会实践):角色所处的社交场景容器

  • 提供行动选项的来源
  • 多个 Practice 并发运行(拜访 + 等待 + 观察同时进行)
  • 定义了什么行为在此情境下可用

Affordance(可用行动):Practice 提供给参与者的具体行为选项

  • Practice「正式拜访」提供 affordances:
    • 耐心等待
    • 小声抱怨
    • 发怒咆哮
    • 告辞离开
  • Practice「观察试探」提供 affordances:
    • 继续装睡
    • 醒来相见
    • 让童子打发客人

效用计算(决策机制)

核心原则:一切归于 Want 检查。

性格、关系、社交压力 不是 独立评分系统,它们通过影响 Want 来参与决策。

概念 如何影响决策
性格 修饰 want 的效用值(如:「暴躁」性格让「发泄情绪」的 want 权重更高)
关系 作为 want 的触发条件(如:只对喜欢的人才想「留下好印象」)
社交规范 通过「不想违规」的 want 实现(行动后果标记违规 -> 触发惩罚)

计算流程:

对于每个可用行动:

  1. 执行该行动的后果(真的修改数据库)
  2. 检查:哪些 want 被满足了?
  3. 累加被满足的 want 的效用值 -> 该行动的得分
  4. 撤销修改(恢复数据库)

选择得分最高的行动。

Versu 看的是真实后果,不是简化估计,避免了《模拟人生》中「角色反复尝试被占用的厕所」之类的问题。


案例:三顾茅庐

角色定义

刘备

Want 效用值 说明
请出诸葛亮 +40 最重要的目标
维护仁义形象 +30 不能失礼于贤者
安抚兄弟情绪 +20 关心手足
遵守社交规范 +25 礼贤下士的体现
性格特质 效果
隐忍 忍耐类行动效用 ×1.3
重情义 涉及兄弟的 want 效用 ×1.2

张飞

Want 效用值 说明
保护大哥尊严 +35 不能让大哥受辱
快速解决问题 +25 不喜欢拖延
服从大哥命令 +30 听大哥的话
遵守社交规范 +10 不太在乎
性格特质 效果
暴躁 「发泄情绪」类行动效用 ×1.4
忠诚 「服从大哥」的 want 效用 ×1.2
关系 评价
对诸葛亮 作为谋士:-20(不耐烦,摆什么架子)
对刘备 作为兄长:+50(绝对忠诚)

诸葛亮

Want 效用值 说明
试探来者是否明主 +35 需要验证
不轻易出山 +25 保持身价
展示才华 +20 有机会就想表现
遵守社交规范 +20 有分寸
性格特质 效果
谨慎 「观察等待」类行动效用 ×1.3
傲气 「不轻易出山」的 want 效用 ×1.2

场景设定

  • 地点: 隆中草庐
  • 时间: 第三次拜访
  • 状态: 诸葛亮午睡(实际在暗中观察),刘备张飞已等待两个时辰

当前活跃的 Practices:

  • 「正式拜访」(刘备、张飞参与)
  • 「观察试探」(诸葛亮参与)

回合 1:张飞决策

情境:等待两个时辰,诸葛亮仍在「午睡」

可用 Affordances(来自「正式拜访」 Practice):

选项 A:发怒咆哮

行动后果(Postconditions):

add zhang_fei.venting_anger!true
add zhang_fei.voice_volume!loud
add norm_violated.respect_guest_etiquette.zhang_fei
add might_wake.zhuge_liang

Want 检查:

Want 是否满足 得分
保护大哥尊严(大哥被怠慢,要出头) 满足 +35
快速解决问题(能把人吵醒) 满足 +25
服从大哥命令(大哥说要等) 违背 0
遵守社交规范 违背 0

性格修正:「暴躁」×1.4 应用于发泄情绪相关得分

总分:(35 + 25) × 1.4 = 84


选项 B:忍耐等待

行动后果:

add zhang_fei.waiting!true
add zhang_fei.emotional_state!suppressed

Want 检查:

Want 是否满足 得分
保护大哥尊严 无关 0
快速解决问题 违背 0
服从大哥命令 满足 +30
遵守社交规范 满足 +10

性格修正:「暴躁」对压抑类行动无加成

总分:30 + 10 = 40


选项 C:小声抱怨

行动后果:

add zhang_fei.mumbling!true
add zhang_fei.emotional_state!slightly_venting

Want 检查:

Want 是否满足 得分
保护大哥尊严 部分(表达不满但不激烈) +15
快速解决问题 无关 0
服从大哥命令 部分违背 +10
遵守社交规范 基本满足 +10

总分:15 + 10 + 10 = 35


决策结果

选项 总分
A. 发怒咆哮 84
B. 忍耐等待 40
C. 小声抱怨 35

张飞选择:发怒咆哮

“这村夫好大的架子!待俺去屋后放一把火,看他起是不起!”


回合 2:刘备决策(响应张飞咆哮)

情境:张飞爆发,可能破坏求贤大计

可用 Affordances

选项 A:严厉呵斥

行动后果:

add liu_bei.reprimanding.zhang_fei!harshly
add zhang_fei.emotional_state!chastened
add norm_violated.brotherly_bond.liu_bei
Want 是否满足 得分
请出诸葛亮(控制局面) 满足 +40
维护仁义形象 满足 +30
安抚兄弟情绪 违背(伤了张飞面子) 0
遵守社交规范 违背(兄弟失和) 0

性格修正:「重情义」×1.2 但此行动伤害兄弟关系,无加成

总分:40 + 30 = 70


选项 B:温和劝阻

行动后果:

add liu_bei.persuading.zhang_fei!gently
add zhang_fei.emotional_state!calming
Want 是否满足 得分
请出诸葛亮 满足(稳住局面) +40
维护仁义形象 满足 +30
安抚兄弟情绪 满足 +20
遵守社交规范 满足 +25

性格修正:「隐忍」×1.3 应用于温和处理,「重情义」×1.2 应用于安抚兄弟

总分:40 + 30 + (20 × 1.2) + 25 = 119


选项 C:放任不管

行动后果:

add liu_bei.ignoring.zhang_fei_outburst
add zhuge_liang.impression.liu_bei!negative
Want 是否满足 得分
请出诸葛亮 违背(印象变差) 0
维护仁义形象 违背 0
安抚兄弟情绪 无关 0
遵守社交规范 违背 0

总分:0


决策结果

选项 总分
A. 严厉呵斥 70
B. 温和劝阻 119
C. 放任不管 0

刘备选择:温和劝阻

“三弟不可无礼。孔明先生乃当世大贤,我等理当诚心等候。”


回合 3:张飞决策(响应刘备劝阻)

情境变化:刘备已开口劝阻

新增事实:

liu_bei.gave_direct_order.zhang_fei!calm_down

这改变了 want 检查的结果:

选项 A:继续发怒

Want 是否满足 得分
保护大哥尊严 大哥已表态,继续闹反而让大哥难堪 0
服从大哥命令 直接违背(大哥刚下令) 0
遵守社交规范 违背 0

性格修正:「忠诚」×1.2 对违背大哥有惩罚效果

总分:接近 0,甚至为负


选项 B:不情愿地闭嘴

Want 是否满足 得分
服从大哥命令 满足 +30
遵守社交规范 满足 +10

性格修正:「忠诚」×1.2

总分:(30 × 1.2) + 10 = 46


决策结果

张飞选择:不情愿地闭嘴

张飞虽然不情愿,但还是退到一旁,脸色铁青。


回合 4:诸葛亮决策

情境:诸葛亮暗中观察到——

  • 刘备等待两个时辰不失态
  • 张飞爆发时刘备温和但坚定地控制住局面
  • 三顾之诚已充分体现

可用 Affordances(来自「观察试探」Practice):

选项 A:继续装睡

行动后果:

add zhuge_liang.still_testing!true
Want 是否满足 得分
试探明主 已完成,继续无额外收益 0
不轻易出山 满足 +25
展示才华 无法展示 0
遵守社交规范 继续装下去开始显得失礼 +10

总分:25 + 10 = 35


选项 B:醒来相见

行动后果:

add zhuge_liang.meeting.liu_bei
add conversation_started!true
add opportunity_to_discuss_tianxia!true
Want 是否满足 得分
试探明主 已满足,可进入下一阶段 +35
不轻易出山 三顾已足够体面 +15
展示才华 可以开始谈天下大势 +20
遵守社交规范 满足 +20

性格修正:「谨慎」已满足(观察够了)

总分:35 + 15 + 20 + 20 = 90


选项 C:让童子再打发

行动后果:

add zhuge_liang.dismissing_again!true
add risk_losing_opportunity!true
Want 是否满足 得分
试探明主 已完成,继续无意义 0
不轻易出山 满足 +25
展示才华 无法展示 0
遵守社交规范 四次拒绝过分了 0

总分:25


决策结果

选项 总分
A. 继续装睡 35
B. 醒来相见 90
C. 让童子打发 25

诸葛亮选择:醒来相见

诸葛亮翻身而起:“有客来此,何不早报?”(早就报了,诸葛标志)


涌现

这段剧情中,以下行为是涌现的,没有显式编程:

涌现行为 来源
张飞先爆发 暴躁性格 + 低社交规范权重
刘备选温和而非严厉 重情义性格 + 安抚兄弟的 want
张飞被刘备压住 忠诚性格 + 服从大哥的 want 在直接命令后激活
诸葛亮此刻出山 试探明主 want 已满足 + 继续拖延的收益递减

如果把张飞换成关羽(性格:沉稳、傲气),关羽可能根本不会爆发,诸葛亮需要等更久才能观察到“明主如何驾驭部下”。


变体:改变初始条件

假设出发前发生了以下事件:

改变 原值 新值 原因
张飞对诸葛亮的评价 -20 +10 路遇司马徽,闻“卧龙之才十倍于我”
服从大哥的 want +30 +45 刘备出发前叮嘱“此行万万不可失礼”
新增 want 「不在二哥面前丢人」 +20 关羽也在场

回合 1 重算:张飞决策

选项 A:发怒咆哮

Want 是否满足 得分
保护大哥尊严 满足 +35
快速解决问题 满足 +25
服从大哥命令 违背 0
不在二哥面前丢人 违背(失态) 0
遵守社交规范 违背 0

关系修正:对诸葛亮评价变正,减少攻击冲动

总分:\<= 60(比原来的 84 低很多)


选项 B:忍耐等待

Want 是否满足 得分
服从大哥命令 满足 +45(提高了)
不在二哥面前丢人 满足 +20
遵守社交规范 满足 +10

总分:45 + 20 + 10 = 75


决策结果

选项 原版得分 变体得分
A. 发怒咆哮 84 50
B. 忍耐等待 40 75

变体中张飞选择:忍耐等待

同一个角色,因为初始条件不同,做出完全相反的选择。


总结

传统状态机 Versu Utility AI
枚举所有情况 定义角色属性
添加新情况需要新代码 改变属性即可产生新行为
角色行为可预测 角色行为会涌现
复杂度随情况数爆炸,呈指数级增长 复杂度随角色数线性增长

类似将 Utility AI 应用于叙事对话的游戏还有:《矮人要塞》、《十字军之王 3》等。

相关资料