在上一篇中,我们搭建了 NPC 对话的基础架构:用角色卡(Persona)定义角色、用世界书(World Book)存储设定、用上下文编排决定哪些信息进入 AI 的视野。但那套系统有一个问题——世界是静态的。NPC 拥有丰富的背景设定,却永远活在同一个”此刻”。
本篇解决这个问题。我们会依次引入三层机制:时间系统(让世界流动)→ Author’s Note(让导演介入)→ Depth(控制导演的力度)。三层递进,后一层解决前一层留下的缺口。
核心前提:在 LLM 驱动的 NPC 对话中,一切都是基于上下文工程。LLM 没有记忆、没有状态、没有情感——它只能看到你这一次喂给它的文本(即”上下文”),然后基于这段文本生成回复。所以,要让 NPC “知道”什么、“关注”什么、“紧张”什么,唯一的办法就是把对应的信息放进上下文里,并且放在合适的位置上。本文讨论的所有机制,本质上都是在回答同一个问题:如何组装这段上下文,才能让 AI 表现得像一个活人?
第一个问题:静止的世界没有体验
我们有一份跨越 500 年的剧本。不同种族的兴衰、战争的爆发与终结——所有事件都写好了,时间线清清楚楚。
但当玩家进入游戏,他看到的是什么?
一个凝固在”此刻”的世界。
酒馆里的艾琳娜是个幽灵,她”死了很久”。铁匠说”以前打过仗”。酒保在擦杯子。所有 NPC 都像博物馆的蜡像——他们有各自的故事背景,但这些背景只是一张静态的说明牌。
玩家:你在这里待了多久了?
艾琳娜:「很久了…我已经记不清了。」
这没有问题。但如果玩家第二天来、第三天来、一个月后来,艾琳娜的回答还是一样的——“很久了”。她的世界没有在流动。
因为体验的本质是共同经历。电影之所以好看,是因为观众跟着角色一起经历了两个小时的起承转合。但在一个静止的世界里,玩家和 NPC 之间不可能建立共同经历。
解决方案:引入时间,让世界流动起来
1. 给游戏世界一套历法
游戏有自己的纪年。玩家进入游戏时,是第 500 年。时间会随着游戏推进而流动——一天天过去,年份在累积。
- 过去是有坐标的:提弗林入侵发生在第 450 年,不是”很久以前”
- 未来是可以到来的:如果剧本写了第 600 年秘境苏醒,那么游戏时间到了第 600 年,它就会苏醒
- 每个 NPC 的知识边界由出生年份决定
2. 时间决定了”谁知道什么”
这是最关键的设计:时间是角色记忆的唯一凭证。
| NPC | 出生年份 | 知道的事 | 不知道的事 |
|---|---|---|---|
| 铁匠 | 第 450 年 | 提弗林入侵(亲历) | 第 450 年之前的上古秘辛 |
| 艾琳娜 | 第 229 年(死于第 250 年) | 精灵王国鼎盛期、上古精灵的传说 | 提弗林入侵(她死后 200 年才发生) |
| 老妖怪 | 第 100 年 | 过去 400 年的所有事 | 第 100 年之前的远古纪元 |
| 酒保 | 第 470 年 | 提弗林入侵的后果、当下的世界格局 | 战争的具体过程(他没亲历) |
同样一个问题——“提弗林入侵是怎么回事?“——四个 NPC 会给出完全不同的答案:
铁匠(亲历者):「第 450 年…我那年才刚出师。提弗林的军队从北方来的时候,我连一把像样的剑都打不出来。」
艾琳娜(死于入侵前 200 年):「提弗林?入侵?…什么时候的事?我活着的时候,精灵王国还是大陆上最强盛的国度。」
老妖怪(全都知道):「第 450 年?哼,那不过是这片大陆的又一次轮回。第 200 年精灵族驱逐矮人的时候,他们也没想到自己有一天会被驱逐。」
酒保(只知道后果):「我只知道那场战争让半个大陆变成了废墟。我出生的时候,战争已经结束二十年了,但北境的城镇还是一片残垣。」
世界观不再是所有人共享的百科全书,而是每个角色基于自身生命经历的独特视角。
3. 在剧本中安排时间钩子
有了时间系统,编剧就可以在时间线上”埋钩子”——在未来的某个时间点,安排事件发生。
游戏时间线(跨越数百年):
第100年 ── 荒芜秘境被远古巫师封印,埋入地下
第229年 ── 艾琳娜出生
第250年 ── 艾琳娜被杀,成为幽灵
第450年 ── 提弗林入侵精灵王国
第500年 ── 玩家进入游戏 ←── 当前时间点
第600年 ── 秘境封印到期,远古邪物苏醒 ←── 未来钩子
钩子不是在游戏代码里硬编码的事件触发器。 它写在世界书里,带有时间约束。每条世界书条目有一个 timeConstraint 字段,标注生效的起止年份。上下文编排模块在组装 AI 输入时,会用当前的游戏年份做过滤——不在生效范围内的条目不会被注入上下文。
编剧可以在时间线上精确地布局叙事节奏,让世界观随着时间”自然生长”,而不是靠触发器硬切。
时间的力量——以及它管不了的事
玩家:你在这个酒馆待了多久了?
艾琳娜:「多久?…第 250 年,我死在这里。现在是第 500 年。你自己算。」
(翻了个白眼)
「250 年。这个数字够大了吗?够你觉得同情了吗?别费心了——你还没出生的时候,我就已经厌倦了同情。」
她说的是”第 250 年”和”第 500 年”,不是”很久了”。时间有了坐标,她的存在就有了重量。
而更关键的是——提弗林入侵发生在第 450 年,艾琳娜死于第 250 年。她根本不知道提弗林入侵这件事,也不知道酒保是提弗林。这颗定时炸弹不是刻意设计的——它是时间系统的天然产物。
但这个定时炸弹什么时候引爆、怎么引爆?时间系统管不了这件事——它只负责”世界走到了哪里”,不负责”NPC 该做什么”。
世界需要一个导演。
第二个问题:谁来引导玩家?
Author’s Note:场外的导演
在戏剧表演中有一个角色叫场外导演(Stage Director)。演员在台上即兴表演,导演不上台,但他会在幕后通过耳麦给演员提示。
Author’s Note 就是我们系统中的这个场外导演。 它不是 NPC 的台词,不是世界观设定,不是记忆——它是一条写给 AI 的舞台指示,告诉 AI:“在当前这个情境下,你应该把对话往什么方向引导。”
Author’s Note 被”伪装”成对话历史的一部分,插入到对话轮次之间。AI 不会意识到这是一条后来注入的导演指令,它只会自然地受到影响。而它插入的具体位置——离用户最新消息有多近——就是 depth 参数。
形式一:写在角色卡里的常驻导演笔记(L1)
编剧在创作角色时就写好的——只要没有更紧急的指令覆盖,这条笔记就一直在 AI 的上下文中。
{
"authorNote": "【暗线】艾琳娜偶尔会用意念在空气中写字,记录酒馆里发生的事,
写完就消散。她不知道自己在做这件事——这是她死后无意识保留的习惯。
如果玩家注意到这个现象,不要主动承认,先装作什么都没发生。",
"authorNoteDepth": 4,
"authorNoteEnabled": true
}
L1 笔记的特点是轻柔:它不要求 AI 立刻做什么,而是让 AI “知道有这回事”,在合适的时机自然地让它浮现。
玩家:等等…你手指刚才是不是在动?好像在写什么?
艾琳娜:「…什么?我的手指?」
(低头看了看自己的手,手指确实在微微颤动)
「…没有。你看错了。这里光线本来就不好。」
L1 的本质是给角色一个自己不知道的行为模式或秘密,让 AI 在日常对话中不主动暴露、但被玩家发现时合理反应。
形式二:运行时动态注入的导演指令(L2/L3)
当游戏中发生了重要事件,任务系统会实时覆盖 Author’s Note:
当玩家发现「酒保是提弗林的证据」时:
设置 艾琳娜 的 Author's Note =
"【剧情转折】玩家发现了酒保可能是提弗林的证据。
你还不知道这件事,也不知道提弗林在第450年入侵了精灵王国。
你的反应取决于玩家怎么告诉你:
- 如果玩家直接说出真相,你会困惑;
- 当玩家解释第450年发生了什么,你才会真正崩溃;
- 崩溃的核心是'我死后族人被屠杀,凶手后代就在我身边站了50年'。"
设置 depth = 2 // 250年来最大的情感冲击
| 级别 | 何时使用 | 目的 | 例子 |
|---|---|---|---|
| L1 | 角色创建时写好 | 埋伏笔、定暗线 | “她会无意识写字” |
| L2 | 任务进度变化时注入 | 引导玩家下一步 | “引导玩家去东塔” |
| L3 | 紧急事件触发 | 立刻改变行为模式 | 任务中催促玩家撤离 |
编剧预埋伏笔 ──→ L1(常驻,轻柔,等待触发)
↑ 被覆盖
任务系统推进剧情 ──→ L2(动态,明确,引导方向)
↑ 被覆盖
紧急事件爆发 ──→ L3(即时,强力,改变行为模式)
↓ 事件结束后自动回落到 L2 或 L1
用年份维度看 Author’s Note 如何推进艾琳娜的剧情线
第500年 春 ── L1生效:"偶尔无意识写字,不知道提弗林入侵"
│ 玩家闲聊,艾琳娜是个有趣的毒舌幽灵,偶尔有奇怪举动
│
第500年 夏 ── 玩家帮酒保完成任务,获得东塔钥匙
│ → L2覆盖:"注意到玩家拿到钥匙,引导去东塔"
│
第500年 秋 ── 东塔崩塌,玩家带出关键信件
│ → L3触发:"催促玩家立刻撤离,一切以活命为先"
│ → 事件结束后回落 L2:"根据玩家的告知方式展现不同反应"
│
第500年 冬 ── 事件余波
│ → L2覆盖:"你已经知道了真相,但还没决定怎么面对酒保"
▼
第501年 ── 新的故事篇章开始......
第三个问题:如何控制导演的影响力?
LLM 在处理上下文时,不是对所有内容一视同仁的。它有三种偏向:
- 首因效应:开头的信息(通常是 System Prompt / 角色设定)有较强的影响力
- 近因效应:靠近用户最新消息的信息影响力最强——因为 AI”刚刚看到”
- 中间遗忘:中间的大段内容,AI 可能只是”扫了一眼”
Author’s Note 正是利用了这个机制。 通过控制导演指令在上下文中的位置,我们可以精确调节它对 AI 的影响力——这就是 Depth 参数。
Depth 参数:控制”导演的声音离演员有多远”
depth = 1(紧贴用户消息):
messages: [sys, u, a, u, a, u, a, 【Author's Note】, u_latest]
↑
AI最后看到的就是这条指令
→ 影响力极强,几乎会被"执行"
depth = 4(隔了几轮对话):
messages: [sys, u, a, 【Author's Note】, u, a, u, a, u_latest]
↑
被几轮对话"淹没"了
→ 影响力温和,AI"知道但不急着做"
depth = 8(很远):
messages: [sys, 【Author's Note】, u, a, u, a, u, a, u, a, u_latest]
↑
几乎沉到上下文底部
→ 影响力微弱,AI"好像记得有这么回事"
| 级别 | depth | 导演的声音 | 效果 |
|---|---|---|---|
| L1(伏笔) | 4 | 像排练厅白板上的备忘录 | AI 知道这回事,但不会每句话都围绕它 |
| L2(引导) | 2 | 像导演通过耳麦轻声提示 | AI 会主动提及,但不会生硬地执行 |
| L3(紧急) | 1 | 像导演在耳边大喊 | AI 的行为会被立刻改变 |
一个具体的例子:同一条 Author’s Note,不同 depth 的效果
假设 Author’s Note 内容是:“引导玩家去东塔”
depth = 4(伏笔):
玩家:今天天气不错。
艾琳娜:「不错?对活人来说也许吧。我已经感受不到温度了——不过,看着阳光透过窗户的样子,倒是…挺怀念的。」
AI 完全按照玩家的话题在聊天气,Author’s Note 的”去东塔”被自然地忽略了。
depth = 2(引导):
玩家:今天天气不错。
艾琳娜:「嗯…确实不错。这种天气,去东塔那边走走也挺好的。听说塔顶能看到整个镇子。」
AI 先回应了玩家的话题,然后自然地把话题引向东塔。这就是 depth=2 的微妙之处:AI 有意识地往那个方向靠,但不强求。
depth = 1(紧急):
玩家:今天天气不错。
艾琳娜:「天气?——你现在马上去东塔。别问为什么。去了你就知道了。」
AI 几乎无视了玩家的话题,直接执行导演指令。depth=1 适用于任务剧情中的紧迫场景。
三个 depth 级别不是为了给开发者三个按钮,而是为了模拟一个角色对不同事情的不同关注程度。
完整的协作:时间 × Author’s Note × Depth
前面分别介绍了三层机制,但它们的真正威力在于协作。让我们跟着艾琳娜的剧情线,看三层机制如何在一年内从平静走到风暴。
第 500 年春——L1(depth=4),日常闲聊。
玩家:你对酒保怎么看?
艾琳娜:「酒保?他还行。不多话,酒调得马马虎虎,至少不会主动来烦我。在这个酒馆待了 250 年,能有一个不烦人的同事已经很难得了。」
第 500 年夏:玩家获得东塔钥匙——任务系统覆盖为 L2(depth=2),导演开始引导。
玩家:我帮酒保搞定了那件事。
艾琳娜:「哦?那他给了你什么好处?…等等。」
(目光锁定在玩家腰间)
「你身上那股气息…那把钥匙,你是从哪里得到的?」
第 500 年秋:逃出东塔——紧急事件触发 L3(depth=1),导演的声音盖过一切。
玩家:我想再找找还有没有别的线索…
艾琳娜:「不要找了!!你听到了吗——石头在裂!整座塔在——你现在就走!信件已经拿到了,别的都不重要——」
(声音在震颤中断断续续)
「求你了,出去。我不想再看着一个人死在这里。」
从春到秋,同一个角色经历了 L1 → L2 → L3 的完整升级。Depth 机制不是一个开关(有/无),而是一个旋钮(0-10)。 转到最大时,导演的声音盖过了一切;转到最小时,导演的声音只是背景里的一丝低语。
总结:三层递进
三层机制各司其职:
- 时间回答的是”世界走到了哪里”
- Author’s Note回答的是”NPC 现在该做什么”
- Depth回答的是”这件事有多急”
回头看开头那个凝固在”此刻”的世界——所有 NPC 说着不变的台词,玩家走到哪都是同一副布景。加入这三层机制后,世界开始转了:NPC 知道现在是什么年代,导演在合适的时机推一把,而推的力度由 depth 自动调节。
这不是某个角色的专属方案。只要你的游戏中有时间流逝和NPC 对话,这套 时间系统 + Author’s Note + Depth 的组合就能复用。
我们追求的体验也很明确:玩家不再是在一个静态的展览馆里点击对话框,而是走进了一个正在运转的世界。
已知局限与开放问题
- 引导的复读机风险:当 L2 指令长时间生效而玩家反复拒绝时,NPC 可能每次都尝试引向同一话题。目前的做法是在 Author’s Note 中加入条件分支,但这增加了复杂度。
- L1 伏笔被覆盖后的恢复:L2/L3 覆盖 L1 后,如果玩家恰好发现了 L1 相关线索,AI 可能无法给出预期反应——因为那条信息当前不在上下文中。
- 多 NPC 同时引导时的冲突:如果两个 NPC 同时有 L2 指令引导玩家去不同方向,需要任务系统在更高层面做协调。
- depth 的效果依赖模型:不同 LLM 对位置效应的敏感度不同,depth 的具体数值需要根据模型做调优。