想象你走进一片名为“月影”的森林。它的奇特之处在于:路不是修好的,而是随着你的脚步长出来的。每到一个岔路口,你向左走,左边的小径便铺展开来;你向右转,右边便浮现新的风景。你没选的那条路并没有消失,只是安静地等待下一位冒险者。这种“选择即开路”的体验,正是分支剧情游戏的核心。而让这片森林“自动长路”的,就是分支剧情 AI——它既是伐木工,又是向导,还是记账员。本文将从最朴素的岔路模型讲起,一步步带你理解剧情图、分支算法、状态管理与性能优化,最后落到工程实践和未来趋势。读完它,你将明白:为什么 AI 不能把整片森林的路都修好,却能让每条路都通向不同的结局。

岗位关联

掌握分支剧情AI生成,你将具备设计千人千面互动叙事的能力——这是AIGC时代游戏策划、叙事设计与AI工程师最抢手的复合技能。

目录
  1. 可视化演示
  2. 基本概念:岔路口与指数长出的路
  3. 剧情图架构:向导的地图册
  4. 分支选择算法:偏心骰子与软最大
  5. 状态一致性:向导的日记本
  6. 性能与优化:边走边铺路
  7. 工程实践:修路队的验收
  8. 趋势与挑战:会作诗的向导
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示分支叙事树(S→A/B/C→多结局)的结构路径、AI生成流水线(ctx→LLM→gen→out)及玩家选择(3选项)对结局的影响映射。

本节配有交互动效(进入视口后自动加载,约 3KB)。

分支叙事树结构 起点S→3分支(A/B/C)→6结局(E1-E6) 高亮当前路径,数据粒子沿路径流动 tree: S→{A,B,C}→{Ai,Bi,Ci}→Ei 16节点分支树覆盖多结局

基本概念:岔路口与指数长出的路

想象你站在“月影森林”入口:面前的土路走了不到十分钟就分成两条,一条通向波光粼粼的湖边,一条钻进幽暗的树洞。你选了湖边,在岔路尽头又出现三岔口……你没选的那些路并没有消失,它们正等着下一位冒险者。这种“走过一条路,背后长出整片地图”的叙事设计,就是分支剧情。

游戏术语里,那个让你做选择的路口叫决策点,每个决策点伸出的“路”叫分支,分支通向的下一个场景叫剧情节点。与传统电影式线性叙事不同,分支剧情是“非线性”的——故事不是一条河,而是一棵不断分杈的树,节点之间可以跳转、汇合、甚至合并回主线。非线性结构的代价是:剧情规模不再按加法增长,而是按乘法爆发。

AI 要做的第一件事,是意识到这棵树会长得飞快。假设每个决策点平均有 b 条分支,玩家要经过 d 个决策点,可能的完整路线就有 b^d 条。

所以训练有素的“AI 向导”绝不会把整片森林的路都铺好——它知道路会爆炸式变多。它会怎么做?这正是接下来要解开的地图之谜。

T=bd\displaystyle T = b^{d}
通俗说:如果每次选择都有 3 条路,连走 10 个路口,潜在剧情就有 59049 条——没有 AI,编剧根本写不完。
  1. T完整路线总数:T 表示从起点到任意一个结局的“完整走法”数量,是所有可能的玩家路径之和。
    TT
  2. b平均分支数:b 是每个决策点平均伸出的岔路条数,例如“三选一”的路口则 b=3。
    bb
  3. d决策点个数:d 是玩家全程会经历的岔路口数量,也就是剧情树的深度。
    dd
  4. 指数相乘b^d 表示每过一个路口,路线总数都要整体乘以 b,所以增长是指数级的,几步之后就会爆炸。
    bdb^{d}

剧情图架构:向导的地图册

向导要去陌生的森林带路,第一步必然拿出地图:哪里是岔口、哪条路和哪条路汇合、哪条路通向营地。在分支剧情系统里,这张地图就是剧情图。

剧情图用有向图 G=(V,E) 建模:V 是节点集合,每个节点是一段剧情节拍,比如“在湖边拾起火把”;E 是有向边,表示从一段剧情允许跳转到哪些下一段剧情。系统里还运行着一个状态机,它像一个指针,记录“玩家现在站在图的哪个节点上”。只要知道当前位置,就能查出所有候选的下一步。

顺着这条思路,剧情转移可以抽象成一个条件概率:下一步走到节点 v 的可能性,取决于当前所处的节点 u。

当然,现实中的剧情转移不会这么“健忘”,玩家背包里的火把也会影响下一步能去哪。于是剧情图只管“路通不通”,至于“走哪条、怎么写”,要交给算法和状态管理——它们分别是向导的骰子和日记本。

P(st+1=v∣st=u)\displaystyle P(s_{t+1} = v \mid s_t = u)
这个式子的意思是:向导做决定时主要看“你现在站在哪”,它认为下一步只和当前位置有关——这就是马尔可夫假设,它让状态机变得简单高效。
  1. P转移概率:P(A|B) 读作“在 B 发生的条件下 A 的概率”,这里是“在当前位置为 u 时到达 v 的概率”。
    PP
  2. s_t当前剧情节点:s_t 表示 t 时刻玩家所在的剧情节点,即状态机的当前位置。
    sts_t
  3. s_{t+1}下一剧情节点:s_{t+1} 表示 t+1 时刻将要进入的节点,是状态转移的目标。
    st+1=vs_{t+1} = v
  4. 竖线表示条件s_t = u 是已知条件,说明概率只依赖当前节点,而不依赖更早的历史——这是“马尔可夫”的关键。
    ∣st=u\mid s_t = u

分支选择算法:偏心骰子与软最大

岔路口有三条路,向导必须决定推荐哪条。资深向导不会每次都抛均匀硬币,而是往骰子里灌铅——哪条路安全、风景好、还顺路,骰子就往哪边偏。这种“有偏好的随机”正是 AI 分支决策的直觉原型。

系统先为每个可选分支算一个分数,分数高的分支被选中的概率大,但分数低的也不是绝对没机会——保留一点惊喜感。这个把分数变成概率的机制叫软最大化(softmax)。

在掷骰子之前,向导还要核对日记:如果玩家根本没拿到火把,向导绝不会把他引向伸手不见五指的洞穴——所以实际系统中,softmax 之前还有一道“前置条件闸门”。而当选定了某条路,大模型补写技术才会登场:它负责现场写出路边的风景与对白,而不是每次都从写好的剧本里复制粘贴。

P(e∣s)=exp⁡(score(e))∑e′∈Eexp⁡(score(e′))\displaystyle P(e \mid s) = \frac{\exp(\mathrm{score}(e))}{\sum_{e' \in E} \exp(\mathrm{score}(e'))}
翻译成人话:每条分支先打分,分数取指数后,除以所有分支分数之和,就得到“选中它”的概率。高分不一定必选,但大概率胜出。
  1. score(e)分支得分:score(e) 是分支 e 的原始分数,通常由玩家状态、剧情主题、玩家画像等特征加权求和得到。
    score(e)\mathrm{score}(e)
  2. 指数放大用 exp 把分数做指数变换,让 2 分和 3 分的差距被放大成明显不同的选中机会。
    exp⁡(score(e))\exp(\mathrm{score}(e))
  3. 分母归一化分母遍历所有可选分支 e',把分子除以总和,保证所有分支概率加起来恰好等于 1。
    ∑e′∈Eexp⁡(score(e′))\sum_{e' \in E} \exp(\mathrm{score}(e'))
  4. 最终概率整个式子输出 0 到 1 之间的概率,算法按这个概率掷骰子即可。
    P(e∣s)P(e \mid s)

状态一致性:向导的日记本

向导有个小本子,记录每位冒险者走过哪条路、捡到过什么、答应过谁。没有这本日记,玩家就会在同一棵树下被同一个 NPC 质问:“你刚才答应帮我去湖边,怎么又反悔了?”——剧情“打架”是互动叙事最致命的硬伤。

工程上,日记就是状态变量。系统用一组布尔标志(flag)记录关键事件:拿到火把、见过村长、已经答应帮忙……每次剧情转移前,都要用前置条件检查这些标志。只有条件满足,分支才允许开放;条件不满足,就把那条路暂时封起来。

实践中还会给状态配一个长程摘要窗口:把很多轮之前发生的旧事件压缩成一句话放进状态,这样既保持长程一致,又不让状态变量无限膨胀。一旦某次生成校验失败,系统还会触发冲突回退策略——退回上一个合法节点重新选择。有了闸门和日记,向导就能在“岔路自动生长”的同时保证每条新路都对得上旧路。但全森林的路线都逐一验证,会不会把向导累垮?下一节讨论效率问题。

Ce(s)∈{0,1},选择e合法  ⟺  Ce(s)=1\displaystyle C_e(s) \in \{0, 1\}, \quad 选择 e 合法 \iff C_e(s) = 1
这个式子把“合法性”变成一道 0/1 闸门:玩家状态 s 喂进条件函数 C_e,输出 1 就放行,输出 0 就拦下——故事再也不会前后矛盾。
  1. C_e(s)前置条件函数:C_e 接收玩家状态 s,判断“走分支 e 的所有前提是否满足”,是则返回 1,否则返回 0。
    Ce(s)C_e(s)
  2. 取值 0 或 1合法结果只有两种,像闸门一样非开即关,不允许“半合法”的模糊状态。
    ∈{0,1}\in \{0, 1\}
  3. 双条件等价符号 ⟺ 表示“当且仅当”——分支 e 可选,当且仅当条件函数返回 1,两者互为充要条件。
      ⟺  \iff

性能与优化:边走边铺路

两个修路方案:方案 A,提前把森林里所有岔路全部铺好,游客随到随走;方案 B,游客走到哪个路口,才现场铺出接下来几米的路。前者省心但成本爆炸,后者省材料但要求施工队足够快。

分支剧情早期常用方案 A(全量预生成),把剧情树一次性塞进内存。但随着决策点增多,内存与制作成本按 T=b^d 指数上升。于是现代系统转向方案 B:在线动态生成,配合剪枝、合并与缓存复用。合并是指把两条会回到同样局面的分支汇成一条;缓存复用是指相同的“剧情片段”在不同路线里直接复用,不再重复生成。

聪明的向导总是“边走边铺路”:只把眼前三米铺扎实,后面的大片路交给算法现算。省下的内存,就是玩家换取更丰富路由的资本。

O(bd)  ⟶  O(d⋅bˉ),ρ=1−∣E′∣∣E∣\displaystyle O(b^{d}) \;\longrightarrow\; O(d \cdot \bar{b}), \qquad \rho = 1 - \frac{|E'|}{|E|}
完整枚举所有分支的代价是 O(b^d),而只沿玩家当前路线现场生成只需 O(d·b̄)。剪枝率 ρ 衡量砍掉了多少不必要分支,越接近 1 越省。
  1. 全量枚举复杂度O(b^d) 表示把所有分支都生成出来的开销随深度指数增长,几步之后就无法承受。
    O(bd)O(b^{d})
  2. 在线生成复杂度O(d·b̄) 表示只沿当前一条路生成,开销与深度 d 和沿途平均分支数 b̄ 成正比,呈线性增长。
    O(d⋅bˉ)O(d \cdot \bar{b})
  3. 剪枝率 ρ|E| 是设计的总分支数,|E'| 是剪枝后保留的分支数,二者之比被 1 减去后就是被砍掉的比例。
    ρ=1−∣E′∣∣E∣\rho = 1 - \frac{|E'|}{|E|}
  4. 省到极致当保留的分支远小于全量时,|E'| ≪ |E|,ρ 趋近于 1,内存与制作成本随之大降。
    ∣E′∣≪∣E∣|E'| \ll |E|

工程实践:修路队的验收

一座会自动长路的森林,不能只靠一个天才向导维护,还要有一支“修路队”:编剧负责设计节点与分支,程序员负责状态机,测试员负责把每条路都走一遍。工程化就是把这套流程固定下来。

团队里最常用的工具链包括:可视化剧情编辑器(拖拽节点连线)、状态调试面板(查看玩家 flag 快照)、回归测试脚本(自动遍历所有分支)。其中“分支覆盖率”是质检的核心指标:项目发布前,测试脚本走过的分支占设计分支的比例,必须有硬性要求。

除了覆盖率,还要做玩家画像调参——喜欢探索的玩家和喜欢速通的玩家,应该看到不同的分支权重;以及内容安全审查,防止生成到敏感题材。AI 新生成的分支同样进入覆盖率清单和审查流程。至此,从画地图到验收的完整工程闭环成型了。

R=∣Ecovered∣∣Edesigned∣\displaystyle R = \frac{|E_{\text{covered}}|}{|E_{\text{designed}}|}
覆盖率 R 表示“被测过的路”占“设计好的路”的比例。R 越接近 1,隐藏 bug 的角落越少。
  1. 已覆盖分支数E_covered 是被自动化测试实际走过一遍的分支集合,它的元素个数就是分子。
    ∣Ecovered∣|E_{\text{covered}}|
  2. 设计分支总数E_designed 是编剧在工具里规划的全部分支集合,是验收的基准分母。
    ∣Edesigned∣|E_{\text{designed}}|
  3. 覆盖比率两个集合大小的比值就是覆盖率,通常要求接近 100% 才能发布。
    RR

趋势与挑战:会作诗的向导

传统的向导有一摞写好的地图册;新一代向导则干脆当场编故事——手上只剩一支笔和一本日记。大语言模型(LLM)让动态叙事成为可能:玩家问“山洞里有什么?”,模型现场生成描写,再按状态约束选择分支。

趋势集中在三个方向:LLM 动态叙事(剧情不再是预写文本而是实时生成)、多模态剧情联动(画面、语音、演出与分支同步响应)、个性化改编(同一段剧情按玩家习惯换表达)。但它们都面对同一个挑战:如何评估生成质量?理论上讲,模型对下一句剧情的把握程度可以用困惑度 PPL 衡量。

明天的森林向导,将一边翻日记、一边现场作诗,还要时刻记得玩家没拿火把。这棵会自己长路的故事树,正在从游戏走向互动影视、教育模拟和一切“千人千面”的场景——而每一个读懂这篇指南的人,都能成为给它修路的人。

PPL=exp⁡(−1N∑t=1Nlog⁡p(xt∣x<t))\displaystyle \mathrm{PPL} = \exp\left(-\frac{1}{N}\sum_{t=1}^{N}\log p(x_t \mid x_{<t})\right)
困惑度 PPL 越低,说明模型对“下一段话该怎么说”越有把握。但 PPL 低只代表措辞流畅,不代表剧情一致——它必须与前置条件校验、覆盖率测试搭配使用。
  1. 条件概率p(x_t | x_{<t}) 是模型在已知前面所有句子的前提下,认为第 t 句话出现的概率,概率越大代表越“有把握”。
    p(xt∣x<t)p(x_t \mid x_{<t})
  2. 取对数再平均对每个位置的概率取对数后累加,再除以总句数 N,得到平均对数概率;负号保证数值越小越好。
    −1N∑t=1Nlog⁡p(xt∣x<t)-\frac{1}{N}\sum_{t=1}^{N}\log p(x_t \mid x_{<t})
  3. 指数还原外层 exp 把对数空间的值还原回原始量纲,得到一个方便比较的“困惑度”数值。
    PPL=exp⁡(⋅)\mathrm{PPL} = \exp(\cdot)

AI 应用场景

开放世界 RPG 动态支线任务

阶段:内容生成与在线调度

解决的问题:传统支线任务由策划人工编写,数量有限且与玩家状态脱节。AI 根据玩家当前持有道具、已完成事件等状态 flag,用 softmax 挑选并即时生成适配的支线分支,再经前置条件闸门校验,保证新任务与玩家过往经历不矛盾。

具体案例:某开放世界 RPG 中,玩家背包里有“火把”且从未去过“夜啼洞”,AI 现场生成一条“夜啼洞探秘”支线;若玩家已经屠龙,则改为“龙鳞锻造”线。玩家每开一局,支线组合都不同。

互动影视与虚拟预演

阶段:叙事生成与一致性校验

解决的问题:互动电影(如《黑镜:潘达斯奈基》)的脚本规模巨大,人工保证所有分支自洽几乎不可行。AI 用剧情图建模 + 状态一致性校验,自动检测“这条分支是否与观众已见情节矛盾”。

具体案例:制片方在拍摄前用 AI 遍历剧情图,统计分支覆盖率 R 并标红所有前置条件冲突的路线,编剧据此补写节点,让 6 小时素材收敛成 90 分钟可交互影片。

客服对话训练模拟器

阶段:流程仿真与考核

解决的问题:新客服练习沟通时,需要应对“客户愤怒、要求赔偿、提出无理要求”等不同走向。AI 维护客户情绪状态 flag,按 softmax 生成下一步客户反应,前置条件保证逻辑不跳戏。

具体案例:学员说错话把客户“激怒”后,AI 在后续分支中提高“投诉升级”分支的权重,学员必须通过道歉话术把状态扳回,否则走向“差评结局”。

Python 演示

python86 行
# -*- coding: utf-8 -*-"""branch_story.py - 用软max与前置条件生成一条合法分支剧情路线"""from math import expimport random STORY = {    "村口": {        "desc": "你站在月影森林的村口,面前有两条路。",        "choices": [            {"to": "湖边", "pre": {}, "logits": {"体力": 2.0}, "flags": ["去过湖边"]},            {"to": "森林", "pre": {}, "logits": {"勇气": 2.0}, "flags": ["进入森林"]},        ],    },    "湖边": {        "desc": "湖边捡到一支火把。",        "flags": ["火把"],        "choices": [            {"to": "山洞", "pre": {"火把": True}, "logits": {"火把": 2.0}, "flags": []},        ],    },    "森林": {        "desc": "树洞里找到一把古剑。",        "flags": ["古剑"],        "choices": [            {"to": "祭坛", "pre": {"古剑": True}, "logits": {"古剑": 2.0}, "flags": []},        ],    },    "山洞": {        "desc": "洞中巨龙盘踞,火把照亮了龙目。",        "choices": [            {"to": "结局-屠龙", "pre": {"火把": True}, "logits": {"火把": 3.0}, "flags": []},        ],    },    "祭坛": {        "desc": "祭坛封印松动,古剑斩碎了符石。",        "choices": [            {"to": "结局-封魔", "pre": {"古剑": True}, "logits": {"古剑": 3.0}, "flags": []},        ],    },} PLAYER = {"火把": 0.0, "古剑": 0.0, "体力": 1.0, "勇气": 1.0} def softmax_choice(choices, state):    scores = []    for c in choices:        if not all(state.get(k, False) for k in c["pre"]):            continue        logit = sum(float(state[k]) * v for k, v in c["logits"].items())        scores.append(logit)    if not scores:        return None    mx = max(scores)    weights = [exp(s - mx) for s in scores]    total = sum(weights)    r = random.random() * total    acc = 0.0    for i, w in enumerate(weights):        acc += w        if r <= acc:            return choices[i]    return choices[-1] def run_once(seed=None):    random.seed(seed)    state = dict(PLAYER)    node = "村口"    path = [node]    while node not in ("结局-屠龙", "结局-封魔"):        info = STORY[node]        for f in info.get("flags", []):            state[f] = 1.0        choice = softmax_choice(info["choices"], state)        if choice is None:            break        for f in choice.get("flags", []):            state[f] = 1.0        node = choice["to"]        path.append(node)    return path, state if __name__ == "__main__":    for seed in range(4):        path, state = run_once(seed)        print("路线 %d: %s" % (seed, " -> ".join(path)))        print("  状态: %s" % sorted([k for k, v in state.items() if v]))
目的:用一张小型剧情图和“前置条件 + softmax”两步决策,模拟 AI 为不同玩家生成不同结局的完整流程。
  1. STORY = {用字典定义剧情图,每个节点都挂着自己的“岔路”和“收获道具”。
  2. "choices": [一个决策点的所有可选分支,每条分支包含目标节点、前置条件和打分特征。
  3. def softmax_choice(choices, state):核心“偏心骰子”:把分数变成概率再随机挑选。
  4. if not all(state.get(k, False) for k in c["pre"]):前置条件闸门:不满足就直接跳过该分支。
  5. logit = sum(float(state[k]) * v for k, v in c["logits"].items())用玩家状态给特征加权,算出这条分支的原始分数。
  6. weights = [exp(s - mx) for s in scores]指数放大并减去最大值防溢出,这是 softmax 的标准实现。
  7. random.seed(seed)固定随机种子,让每次运行的路线可复现,方便测试。
  8. while node not in ("结局-屠龙", "结局-封魔"):只要没到终局就继续向前走。
  9. path.append(node)把走过的节点记进“行程单”,最终打印成玩家的完整剧情路径。

常见误区

误区我刚做分支剧情,觉得选项越多越丰富,于是给每个决策点塞 6 个选项,结果玩家根本记不住前面选过什么,制作量还爆炸。

正解分支数量按 b^d 指数增长,每加一个选项,全图工作量和内存都翻倍。玩家在 3-5 个“有意义”的岔路间犹豫,比面对 6 个雷同选项更有沉浸感。少而精、能引出不同结局的分支才是好分支。

为何常见:直觉上“多=丰富”,却忽视了认知负荷与指数成本,只有吃过分支爆炸的亏才会醒悟。

误区有了 LLM,我把上文的剧情直接丢给它,它就能续写,不用再维护什么 flag。

正解大模型没有“长期记忆”,上下文窗口外的火把它根本记不住。真实系统必须让 LLM 与状态管理配合:状态变量决定“能走哪条路”,LLM 只负责填充路边的风景。否则前后矛盾会连环出现。

为何常见:LLM 的对话体验给人“很懂”的错觉,容易让人忽略它在长程一致性上的天然短板。

误区我习惯把所有剧情分支事先写好、全部加载进内存,觉得这样最稳定、不会卡顿。

正解全量预生成只在分支极少时可行。决策点一多,内存与制作成本按 T=b^d 爆炸。业界主流是“在线生成 + 剪枝 + 缓存复用”:只生成玩家附近的分支,用剪枝率 ρ 控制规模。

为何常见:早期游戏确实全量预生成,惯性思维让人忽略了今天的实时生成能力已经足够快。

误区我在决策点用 random.choice 选分支,这应该就是 AI 生成剧情了吧?

正解纯随机等于“没有偏好地掷硬币”,既不能回应玩家状态,也无法控制节奏。AI 叙事至少要“打分再随机”:用 softmax 把状态特征映射成概率,并让前置条件先过滤非法分支。随机只是最后抖一下的骰子,不是决策本身。

为何常见:随机输出确实肉眼可见地“每次不同”,容易误以为“多样”就等于“智能”。

面试题

Q1. 下列哪项是“决策点”在分支剧情中的核心作用?

单选题 · easy

  • A.为玩家提供可选择的剧情方向← 正确答案
  • B.记录玩家的全部历史操作
  • C.压缩剧情文本以减少加载
  • D.统计每条路径的游玩难度

答案:A。决策点就是森林里的岔路口,作用是让玩家做出选择、引出不同方向。B 是状态管理的职责,C 是性能优化的手段,D 是测试统计范畴,都与“提供选择”无关。

Q2. 分支剧情与线性叙事最本质的差别是?

单选题 · easy

  • A.分支剧情包含多选一的岔路← 正确答案
  • B.分支剧情的文案一定更长
  • C.线性叙事必然包含战斗
  • D.线性叙事没有对话机制

答案:A。线性叙事是一条河,观众只能顺流而下;分支剧情是一棵树,玩家在每个岔路都可以选择方向。B、C、D 都是对线性叙事的刻板印象,并非本质差别。

Q3. 一个分支剧情有 5 个决策点,每个点平均 3 个分支,可能的完整路径数量约为?

单选题 · mid

  • A.约 15 条路线左右
  • B.约 125 条路线左右
  • C.约 243 条路线左右← 正确答案
  • D.约 1024 条路线左右

答案:C。根据分支爆炸公式 T=b^d,b=3、d=5,则 T=3^5=243。B 是 5^3 的混淆结果,A 是加法而非乘法,D 是 2^10 的误算。

Q4. 马尔可夫性质在剧情转移中的含义是?

单选题 · mid

  • A.下一节点由当前剧情节点决定← 正确答案
  • B.下一节点完全随机且不可预测
  • C.剧情必须由人工事先写死
  • D.玩家状态永远不会影响剧情

答案:A。P(s_{t+1}|s_t) 表示只看当前节点即可决定下一步转移,这是状态机的简化假设。B 否定了依赖关系,C 与在线生成矛盾,D 忽略了状态变量对分支的影响。

Q5. 为保证分支剧情前后一致,常用手段包括?

多选题 · mid

  • A.使用状态标志记录关键事件← 正确答案
  • B.为分支设置前置条件闸门← 正确答案
  • C.只保留玩家的最近一次选择
  • D.用长程摘要压缩旧情节信息← 正确答案

答案:ABD。A 的 flag 记录、B 的前置条件、D 的长程摘要都是保证一致性的标准做法。C 只保留最近一次选择会丢失关键历史,反而导致剧情前后打架。

Q6. 软最大化(softmax)在分支选择中的主要作用是?

单选题 · mid

  • A.将分支打分变成可选概率← 正确答案
  • B.消除随机性保证输出稳定
  • C.把概率直接当作剧情文本
  • D.统计玩家在线的游玩时长

答案:A。softmax 把每条分支的分数做指数变换并归一化,得到“被选中”的概率。它不消除随机性而是保留有偏随机,B、C、D 都是对它作用的误解。

Q7. 哪些做法能缓解分支爆炸带来的内存压力?

多选题 · mid

  • A.全量预生成并加载所有分支
  • B.边走边生成的在线扩展← 正确答案
  • C.对低价值分支做剪枝合并← 正确答案
  • D.缓存并复用已生成的结构← 正确答案

答案:BCD。在线生成只铺眼前的路,剪枝合并砍掉低价值分支,缓存复用避免重复生成,三者都显著降内存。A 全量预生成恰恰是爆炸的根源。

Q8. 玩家状态变量的“摘要窗口”最适合用于?

单选题 · hard

  • A.压缩过长的历史事件影响← 正确答案
  • B.替代脚本实现全部战斗逻辑
  • C.提高游戏画面的渲染帧率
  • D.统计剧情的总字数与行数

答案:A。摘要窗口把海量历史事件压缩成关键摘要放进状态,让长程一致性可维护。B、C、D 分属战斗系统、渲染和统计范畴,与叙事状态无关。

Q9. 使用大模型在线生成分支剧情的主要风险包括?

多选题 · hard

  • A.生成内容与前置状态产生矛盾← 正确答案
  • B.单次生成的推理延迟与成本← 正确答案
  • C.完全替代规则与测试体系
  • D.拒绝接受一切的预置脚本

答案:AB。LLM 会遗忘上下文,可能生成与玩家状态矛盾的剧情,同时在线推理带来延迟与算力成本。C、D 是绝对化表述,真实系统仍保留规则与人工脚本作为约束。

Q10. 设全量分支数为 |E|,剪枝后保留 |E'|,则剪枝率 ρ = 1 − |E'|/|E| 的含义是?

单选题 · extreme

  • A.被剔除分支占全量的比例← 正确答案
  • B.保留分支占全量的比例
  • C.玩家通关路径的绝对长度
  • D.生成内容的平均句长占比

答案:A。1 减去保留比例(|E'|/|E|)得到的正是被剪掉分支的占比。ρ 越接近 1,说明砍掉越多、内存越省。B 是保留比例而非剪枝率,C、D 与分支数量无关。