一次写到第三十轮的“自由续写”
设想一个虚构的悬疑故事:海边小镇“雾港”的灯塔看守人被人发现死在塔里,玩家扮演来调查的侦探。故事的第一轮,作者(或者说初始提示)交代了三件事:死者是老看守,身边有一块停摆的怀表,嫌疑人有三个——管家、渔夫和杂货铺老板娘。
接下来的续写完全交给模型,玩家每一轮输入一句话,模型接着写。我们把这个过程按示意的方式回放一遍,大致会出现这样几种常见的失控:
- 主题漂移:第八轮起,模型觉得“暴风雨夜”很有气氛,于是不断加码,故事从“谁杀了老看守”变成了“小镇的诅咒”,最初的悬疑问题不再被追问;
- 角色矛盾:第十五轮,管家还是一个谨小慎微的老人,第二十轮,他忽然说出一段狠话,语气与此前完全相反,因为最近的上下文里没有再提到他的性格;
- 伏笔消失:停摆的怀表在第一轮出现,之后再没有人提起,因为它已经被更靠近当前位置的内容挤到了模型注意力的边缘;
- 高潮提前:玩家随口问了一句“你是不是在撒谎”,模型觉得这是个戏剧性的时刻,于是第十二轮就让嫌疑人认罪了。真正应该压轴的对峙,被一句无心的话提前消耗掉。
这些问题有一个共同点:模型没有“错”,它每一轮都写得通顺。问题出在没有人替整个故事负责。自由续写天然只看眼前这一步,而一个故事之所以是故事,恰恰在于有人知道最后要去哪里。
谁写什么:作者、导演、生成三层分工
更成熟的做法不是让模型写得更保守,而是把“谁负责什么”重新划分。大发娱乐AI倾向于三层结构:
| 层 | 负责的问题 | 典型内容(示意) |
|---|---|---|
| 作者层 | 什么必须成立 | 世界规则、角色动机、关键节点、不可破坏条件 |
| 导演层 | 现在该发生什么 | 读取剧情状态,选择片段,控制节奏,向生成层下任务 |
| 生成层 | 怎么写出来 | 对白、场景描写、角色语气 |
作者层写的东西比想象中少,但都是“硬”的。以雾港为例,作者可能只写下这些:
- 真凶是杂货铺老板娘,动机是老看守知道她曾伪造过一份遗嘱;
- 怀表停在三点十分,是解开时间线的关键,必须在第四幕之前被玩家注意到;
- 真凶身份在第五幕之前,不允许被任何角色以肯定语气说出;
- 玩家可以怀疑任何人,但不可以在没有证据的情况下让案件“自动结案”。
这几条不是剧本,而是边界。边界之内,玩家往哪里走、问什么、怀疑谁,全部保持开放。导演层的工作,就是在边界之内把故事往有意义的方向推。
Storylet:用条件而不是顺序来编排内容
有了边界,导演需要“备用内容”来推动剧情。这里一种常见的结构叫 Storylet:把故事拆成许多小片段,每个片段带着触发条件,谁满足条件谁就有资格出场,而不是按固定顺序排列。
在雾港的例子里,作者预先写好一批片段(示意):
- “渔夫的旧船票”:条件是玩家去过码头,并且和渔夫谈过话;
- “老板娘的反常热情”:条件是玩家连续两次没有询问她;
- “怀表的裂纹”:条件是玩家检查过尸体,并且紧张度低于某个阈值;
- “暴风雨切断电话线”:条件是故事进入第三幕,且玩家试图向外界求援。
一项把 Storylet 与大语言模型结合的研究(Drama Llama)提出,让作者可以用自然语言来描述触发条件,并在故事合适的时机触发内容,目标是既保留作者对叙事的控制,又利用生成式AI让叙事对玩家的行为有响应。我们借鉴的正是这个思路:条件用人话写,判断交给模型,但片段库和边界始终由作者掌握。
这样做的好处是,玩家的路径不必被提前穷举。同一批片段,玩家先去码头还是先去杂货铺,会得到不同的排列,而每个片段本身都是作者认可过的。
导演每个回合做的五件事
导演层不是一个“更大的提示词”,而是一段在每个回合都会运行的流程。以雾港为例,它大致做这些事:
- 读状态:当前是第几幕,玩家掌握了哪些线索,各嫌疑人的态度如何,哪些伏笔尚未回收;
- 判张力:这一幕的紧张度是否偏低或偏高,想让节奏往上还是往下;
- 选片段:从 Storylet 库里筛出条件满足的候选,按“与当前节奏的匹配度”和“与尚未回收伏笔的相关度”排序;
- 下任务:把选中的片段、需要保持的事实、需要避免的内容打包成任务书交给生成层;
- 验产出:生成之后检查,有没有提前泄露真凶,有没有违反角色设定,有没有把伏笔悄悄丢掉。
其中第五步最容易被省略,也最重要。没有验证的导演只是一个漂亮的提示词,验证不通过时,宁可让生成层重写,也不要放行。关于伏笔怎样登记与回收,可以参考剧情长期状态里的伏笔管理,那里把“种下、回收条件、过期策略”作为一张可查的账本来讲。
一个具体的示意回合
假设第十二轮,玩家问“你是不是在撒谎”。导演读到状态:当前第三幕,玩家只有一条弱线索,紧张度偏高,真凶身份尚未到公开的阶段。它判断这时不该让任何人认罪,于是选了“老板娘的反常热情”,并向生成层下达任务:嫌疑人回避这个问题,转而抱怨小镇的闲话;不得承认,不得提及遗嘱。玩家得到的是一个更耐人寻味的反应,而不是一个提前用光的高潮。
当玩家偏离主线:导演的三种回应
导演层最考验设计的时刻,是玩家做了一件作者完全没有预料的事。假设玩家在第二幕突然决定:“我不查案了,我去帮渔夫修船。”按剧本,这条路径根本不存在。导演大致有三种回应方式,从轻到重:
- 吸收:把玩家的行动当作新的场景素材。修船的时候,渔夫自然会闲聊,一句无心的话正好透露他那天夜里并不在家。玩家没有离开故事,只是换了一条路进入;
- 牵引:故事保持自己的节奏,让外部事件来敲门。修到一半,警长派人来找玩家,说灯塔那边又发现了新东西。主线没有被强行拉回,但玩家很难对它视而不见;
- 收束:如果偏离的时间过长,超过了作者设置的窗口,导演才会让世界作出更明显的反应,比如怀表相关的线索因为无人跟进而被人取走,玩家将失去一个关键证据。
三种方式的顺序是有意安排的:优先吸收,其次牵引,最后才收束。反过来做,先用强制手段把玩家拉回主线,就会重新变成按钮式的“你必须走这条路”,玩家感到的不是被引导,而是被管教。
为什么不是一台纯粹的状态机
有人会问,既然要控制,为什么不直接用状态机:每一幕、每个节点写死,玩家只在节点之间选择?状态机的确稳定,但它的稳定来自对输入的限制。玩家说出任何未被列举的话,系统就只能回答“无法理解”。
导演层保留了状态机里最有价值的部分,也就是显式的、可检查的剧情状态:当前是第几幕、哪些节点已完成、哪些条件不可破坏。同时把“节点之间怎么连”从固定的边,换成了由 Storylet 条件和生成能力共同决定的动态连接。可以这样理解:节点和边界像是骨架,片段和生成是骨架上的血肉。骨架不动,血肉随玩家的行为改变。
也正因为如此,作者的工作方式会发生变化:不再一条一条地写分支,而是写约束和素材。先写清楚“这个故事必须是关于什么的”,再准备足够丰富的片段,最后在测试里反复检查,导演有没有在某些路径上让故事跑偏。
自由与控制:一张对照表
把两种做法放在一起看,差别更清楚:
| 维度 | 完全自由续写 | 有导演层的生成 |
|---|---|---|
| 主题 | 随上下文漂移 | 由作者的核心问题锚定 |
| 角色 | 以近期文本为准,容易失真 | 人设与关系状态显式保存 |
| 伏笔 | 靠模型“记得” | 登记后由导演定期检查 |
| 高潮 | 可能被随口一句提前触发 | 受节点条件与节奏约束 |
| 玩家自由 | 表面很大,后果容易散 | 边界内很大,后果连贯 |
需要强调的是,导演层并不等于把故事“写死”。玩家依然可以怀疑管家、放走渔夫、甚至说“我不想查了”。导演处理的是这些输入之后怎样回到故事的主线上,而且回去的路不只一条。这也是我们理解的“自由”:不是可以说任何话,而是无论说什么,世界都会作出有意义的回应。对于世界规则本身为什么不宜由模型现场改写,可以再看为什么不追求完全自由生成。
作者怎样开始:先写“不可破坏条件”
如果要为一个新故事搭导演层,我们建议作者按下面的顺序动笔,而不是先写一大堆对白:
- 用一句话写下故事的核心问题,例如“谁、为什么杀了老看守”;
- 列出不可破坏条件,通常不超过十条,每条都能被程序或模型明确判断“违反”或“没违反”;
- 写出关键节点及其前置条件,只写“必须发生”的,不写“怎样发生”;
- 再补充第一批 Storylet,每个片段写明触发条件、能改变的状态、以及退场条件;
- 最后用几种极端的玩家行为(完全不查案、连续追问同一个人、拒绝所有线索)去跑,看导演能否把故事带回来。
第五步之所以关键,是因为导演层的问题往往不出现在“正常玩家”身上,而出现在那些最不按预期行动的人身上。
还没有解决的问题
这套设计并不是没有代价,至少有三件事仍需要持续打磨:
- 触发条件的误判:用自然语言描述条件很方便,但“玩家紧张度偏低”“玩家显得不信任”这类判断本身就会出错,导致片段在不合适的时刻出场;
- 作者的工作量:Storylet 库越丰富,故事越有弹性,但写片段、写条件、写不可破坏条件都需要作者投入,成本不低;
- 导演本身的一致性:如果导演层也交给模型判断,它同样可能“读错状态”。因此关键节点和不可破坏条件尽量用显式规则检查,而不是全凭模型判断。
回到开头的问题。AI可以随便续写,恰恰意味着“写什么”不再稀缺,稀缺的是“为什么写这个”。导演层的意义,就是让每一次生成都有一个理由,而这个理由,来自作者一开始想讲的那个故事。