世界书是一组带触发条件的文本片段:只有当最近的对话里出现了指定关键词, 对应条目才会被塞进提示词。它解决的是角色卡解决不了的问题:设定太多, 而上下文放不下。
角色卡里的内容每轮都发,世界书里的内容按需发。把「主角的剑叫什么」这种偶尔才提到的 细节放进世界书,只有聊到剑的时候才占用 token,其余时间那段字根本不存在于提示词里。
世界书的关键词是怎么触发的
酒馆会扫描最近若干条消息,用条目的主要关键词去匹配。命中了,条目就 入选;条目若还配了次要关键词,则再按设定的逻辑做第二轮判定。
次要关键词的四种逻辑定义在
public/scripts/world-info.js
的 world_info_logic 里:
| 值 | 名称 | 含义 |
|---|---|---|
0 | AND_ANY | 命中主关键词,且次要关键词中任意一个也命中 |
1 | NOT_ALL | 命中主关键词,且次要关键词不全命中 |
2 | NOT_ANY | 命中主关键词,且次要关键词一个都没命中 |
3 | AND_ALL | 命中主关键词,且次要关键词全部命中 |
NOT_ANY 常被用来做排他:比如「提到城市名,但没提到已经离开」时才注入城市描写。
默认值是 AND_ANY。
条目会插到提示词的什么位置
条目命中之后还要决定插在提示词的哪里,这由 position 决定,共八个取值。
位置直接影响权重:越靠近对话末尾,模型越容易照做。
| 值 | 名称 | 插入位置 |
|---|---|---|
0 | before | 角色定义之前 |
1 | after | 角色定义之后 |
2 | ANTop | 作者注释之前 |
3 | ANBottom | 作者注释之后 |
4 | atDepth | 按指定深度插入对话历史中间 |
5 | EMTop | 对话示例之前 |
6 | EMBottom | 对话示例之后 |
7 | outlet | 插入到具名的自定义位置(outlet) |
atDepth 是其中最灵活的一个:深度 0 表示插在最新一条消息之后,深度越大越往前。
用它做「临时指令」很有效,放在浅深度处,模型几乎一定会遵守。它还能指定说话人角色,
取值来自
public/script.js
的 extension_prompt_roles:SYSTEM 为 0、
USER 为 1、ASSISTANT 为 2。
角色世界书和全局世界书谁先插
由插入顺序策略决定,三种取值:evenly(0,按各自顺序混合排)、
character_first(1,角色卡自带的优先)、global_first(2,全局的优先)。
默认是 character_first(world_info_character_strategy 的初始值)。
这个设置只在两类世界书同时命中、且预算不足以全部放下时才看得出区别:排在后面的会被 先裁掉。角色卡自带的世界书随卡走,全局世界书由你自己挂载,两者可以同时生效。
三个常见误解
「世界书里的内容模型一直记得。」不是。没被触发时它完全不在提示词里, 模型无从知晓。想让某条始终生效,要么把它设为常驻,要么写进角色卡。
「关键词写得越多越好。」关键词过宽会导致大量条目同时命中,反而挤占上下文, 把真正相关的内容顶出去。宁可精确。
「条目内容可以很长。」可以,但它一旦触发就要占预算,和角色卡竞争同一份 上下文。长条目更适合拆成几条分别触发。