文件到了。语义没到。
一本在酒馆里跑得好好的世界书,搬进 JanitorAI 会集体沉默,搬进 RisuAI 会反着触发——没有任何人改过任何条目。我们做迁移体检器时把各家开源实现逐行读了一遍:导入默认 1% 的概率陷阱、禁用条目复活、NOT_ANY 黑名单反转成正向条件、0% 概率反转成必触发、把中文键整个吃掉的关键词归一化。这篇里每个行为断言都标了证据级:源码实证、官方文档、或者老实承认没验证。

你花三个周末打磨了一本四十条的世界书。在酒馆里它跑得漂亮:提到宗门,宗门的恩怨自己浮上来;佩剑的秘密守到有人拔剑那一刻。 朋友把它导进 JanitorAI,第二天来找你:「你这书是坏的。」什么都不触发。没有任何人改过任何条目。你们俩都没说错:你的书确实没毛病, 他跑的那本也确实是坏的。文件到了,语义没到。
关键词触发的世界书看着像一个标准:键、正文、几个开关。实际存在的是五种方言,恰好共用一个文件格式。最阴的地方在于导入几乎总是「成功」: 不报错,条目在界面里都看得见,一切好像各就各位;分歧要到三天后的剧情中段才冒头,而且冒头的样子看着像「bot 忘了我的设定」,很少有人想到是导入器动了开关。
做世界书迁移体检器的时候,我们把各家开着源的实现逐行读了一遍:SillyTavern release 分支的导入转换器、RisuAI 的世界书模块、Agnai 的记忆引擎,以及 JanitorAI 官方帮助中心发布的世界书脚本(核实于 2026-07-26)。下文每个断言带三种标签之一:源码=在对方代码里逐行核实过;文档=官方帮助中心或权威社区排障材料, 我们没跑过对方生产代码;格式=按字段对照推断,运行时未验证。拿不出比「格式」更硬的证据时,我们直说,不硬断。
第一坑:JanitorAI 的隐形 1% 和消失的键
症状是设定大约一百条消息才触发一次,玩家读出来的感觉是「随机」或者「记忆坏了」。第一个机制是个默认值:导入的条目触发概率经常停在 1%(文档,让这个坑出名的社区排障文+官方帮助中心侧证)。你的正文写得再好,骰子就是不开。
第二个机制更锋利,而且是源码级的,出自 JanitorAI 官方帮助中心发布的 Advanced Lorebook 脚本(v12):匹配前, 关键词和聊天文本都会被归一化——先转小写,然后把 a-z 0-9 _ 空格 - 之外的字符全部删掉,连字符和下划线换成空格。café 这个键会变成 caf;一个中文键会变成空字符串,等于不存在。匹配恒为整词,支持 词干* 通配, 扫描窗口是最近五条消息。一条诚实注记:这份脚本是该平台可验证的那一半,简易世界书表单的精确匹配规则没有公开文档, 体检器按脚本口径判定并如实标注。
自救按序:导入后逐条打开承重条目,把概率显式设好(关键设定给 100);每个中文或带重音的键补一个 ASCII 别名;键尽量单词化, 或者用 词干* 通配;写「要多留几轮」的设定时记得那个五条消息的窗口。
第二坑:Risu 一来一回,把你的开关全拨反
进去的方向有两个导入器行为,都在 RisuAI 代码里源码级核实过。第一:导入器不读 enabled 字段, 而 Risu 的世界书模型里根本没有逐条禁用这个概念,于是你停用的条目全部复活。被你关掉的季节线、上了闸的 NSFW 块、没写完的草稿: 全都无声地活了过来。第二:导入器不读 selectiveLogic,副键恒被当成正向必要条件。一个 NOT_ANY 守卫 ——「出现『王冠』就触发,除非『梦』在场」——反转成「只有『梦』也在场才触发」。不是变弱了,是反过来了。
书住在那边期间,匹配本身也说另一种方言(源码):Risu 的默认匹配把两边都转小写、删掉全部空格、然后做子串检查。 键 ice 会在每一次 police 出现时命中;空格删光之后,键甚至能横跨两个相邻的词命中。 整词模式有,但它按单个空格切词,粘着标点的「sword.」过不了全等检查。正则键必须写成 /pattern/flags 形态, 其它写法永不命中;从酒馆带着 use_regex 旗标过来的键,旗标被无视,正则降级成字面字符串,pattern 里的逗号还会被按逗号拆键的逻辑绞碎。
出来的方向最离奇。酒馆的 Risu 转换器用一对空值合并来映射概率:概率取 activationPercent,取不到才是 100;「是否启用概率」取 activationPercent,取不到才是 true。作者把 activationPercent 设成 0, 意思是永不触发:这个 0 从两个兜底手里都活了下来,「是否启用概率」拿到 0,按假值处理,概率检查整个被跳过,条目变成每次都触发 (源码,release 分支转换器)。零反转成一百。另外 Risu 的文件夹行会变成一堆垃圾条目进来,Risu 专属的@@decorator 会被忽略:酒馆只认识 @@activate 和 @@dont_activate。
自救:往 Risu 搬之前,删掉而不是禁用;NOT_ANY 守卫改写成独立条目;正则键换成普通键。搬回酒馆时, 凡是设过 activationPercent 为 0 的条目逐个审一遍,文件夹行准备手动清理。
第三坑:Agnai 把你的开关原样存档,然后全部无视
Agnai 的导入映射把 constant、selective、大小写敏感这些字段忠实地存进文件,而它的匹配引擎从来不读它们。 代码注释直接把这批字段叫「带过来但不支持」(源码)。结果是一本在任何编辑器里看着都完好的书,跑起来是另一套物理规则: 常驻条目不再常驻,NOT_ANY 排除词消失、条目恰好在你想挡住的场景里触发,而且概率掷骰整个不存在:你调到 30% 的条目现在是常开的。
它的关键词编译器自成一门方言(源码):每个键编译成一条正则,先剥掉(注意是剥掉,不是转义)\ ^ $ + . ( ) | [ ] { } _ 这批字符,把 * 映射成词字符通配、? 映射成单个词字符, 再整体包进 \b 词边界,恒不区分大小写。三个后果:C++ 这个键变成 C;你按字面意思写的星号获得了通配含义; 纯中文键永不命中,因为 \b 在中文文本里找不到可以锚定的词边界。回程还有一处不对称:酒馆的 Agnai 转换器把weight 带进插入顺序,却丢掉 priority,也就是 Agnai 的预算裁剪优先级(源码)。
自救:每个中文条目配 ASCII 别名;真正需要常开的世界事实,从常驻条目挪进场景或系统提示词;做预算时把所有带概率的条目当成常开的算,在 Agnai 上它们就是。
五平台方言对照表
上文的压缩版,外加被问得最多的几个开关。酒馆一列按 1.18 语义;Risu 和 Agnai 两列全部源码核实;JanitorAI 的匹配列描述的是公开发布的 Advanced 脚本,概率行是有文档的导入默认值。
| 酒馆 1.18 | RisuAI | Agnai | JanitorAI | |
|---|---|---|---|---|
| 键匹配 | 子串;大小写/整词逐条可调 | 转小写、删空格、子串——ice 命中 police | 强制词边界的正则,恒不分大小写 | ASCII 归一化整词,最近 5 条 |
| 正则键 | 支持(逐条开关) | 只认 /pattern/ 字面形态;导入旗标被无视 | 概念不存在,特殊字符被剥掉 | 不支持 |
| 副键逻辑 | AND_ANY / AND_ALL / NOT_ANY / NOT_ALL | 恒正向 AND——NOT 守卫反转 | 存在文件里,从不参与判定 | NOT / ALL 模式过不去(文档) |
| 触发概率 | 逐条百分比,每次激活掷骰 | 导入时被丢弃——每次都触发 | 概率掷骰不存在 | 尊重设置;导入常默认 1% |
| 禁用条目 | 尊重 | 复活——没有逐条禁用概念 | 尊重 | 尊重(文档) |
| 常驻条目 | 尊重 | 映射到 alwaysActive | 存在文件里,引擎无视 | 无直接对应(文档) |
Chub 值得单独一句诚实话:它的导出把 World Info 和 V2 两套字段并排双写,这一点我们对着真实导出文件验证过; 但它自家聊天端的匹配器我们没有读过,所以你在任何地方看到的关于 Chub 运行时的断言都该打格式级标签,包括我们自己的。 从 Chub 出发的旅程倒有一个已核实的怪癖:它的条目用蛇形命名写大小写敏感(case_sensitive), 酒馆引擎读的是驼峰拼写,于是这个逐条设置静默回落到全局开关(源码)。
迁移前的体检清单
搬家前花十分钟,好过搬家后三天追问「怎么全哑了」。先清点脆弱特性:禁用条目、NOT_ANY / NOT_ALL 守卫、 正则键、概率低于 100 的、常驻条目、中文或重音键,还有依赖 sticky / cooldown / delay 计时器的。再按目标改写: Risu 删掉别禁用,Agnai 和 JanitorAI 补 ASCII 别名,NOT 守卫拆独立条目,JanitorAI 导入后排队逐条设概率。 然后转换、抽查:给最重要的三个条目各发一条测试消息,导入成功不等于语义活着。或者把文件直接拖进迁移体检器:认九种格式,按目标平台逐条点名,每条发现标着源码、文档或格式, 全程在浏览器里跑。它刻意不做转换,酒馆和 Risu 本来就带导入按钮;缺的一直是起飞前那次「这些按钮会悄悄改掉什么」的体检。
标签纪律对这篇文章本身同样生效。上面关于 Risu、Agnai 和酒馆转换器的一切,都是 2026-07-26 对着它们的开源代码逐行核实的, 对方发新版就可能过期;JanitorAI 的 1% 默认值有文档背书,但我们没有复现过它的生产行为;Chub 的运行时我们干脆没读过。 凡是标着「格式」的地方,请相信你自己的抽查,别相信我们的表格。
常见问题
世界书导进 JanitorAI 之后为什么不触发了?
两个独立机制,导入的书大多至少中一个。其一,导入条目的触发概率经常停在 1% 的默认值上,写得再好也大约一百条消息才触发一次,需要逐条打开把概率显式设好。其二,JanitorAI 帮助中心发布的 Advanced Lorebook 脚本会把关键词归一化成 ASCII:a-z、0-9、下划线、空格、连字符之外的字符全部剥掉,中文、日文和带重音的键直接消失。给这些条目补一个 ASCII 别名键。
禁用的条目导进 RisuAI 还会保持禁用吗?
不会。Risu 的导入器不读 enabled 字段,而且它的世界书模型里根本没有逐条目的禁用开关,所以你所有停用的条目导入后集体复活。这一条在 Risu 的开源导入器代码里逐行核实过。要保证某条在 Risu 那边永不触发,导出前删掉它,别指望禁用态。
中文关键词在各平台之间搬家能活下来吗?
看目标平台。酒馆和 RisuAI 没问题(子串匹配)。Agnai 永远匹配不到纯中文键:它的关键词编译器给每个键强制加正则词边界,而词边界在中文字符周围无处锚定,这一条在它的开源匹配代码里核实过。JanitorAI 的 Advanced Lorebook 脚本则把非 ASCII 字符从键里整个剥掉。搬去这两家,给每个中文条目加一个 ASCII 别名键。
有没有工具能在迁移前把这些坑先查一遍?
有。世界书迁移体检器认得九种世界书格式(酒馆 World Info、Chub 双写、Risu 原生、Agnai 记忆书、JanitorAI 条目数组、V2/V3 character book、lorebook_v3、卡内嵌书、NovelAI),逐条标出搬到每个目标平台时什么会坏、什么会变、什么会丢,每条规则带证据级标签。它刻意不做格式转换:转换器到处都是,缺的一直是那个告诉你「转换途中什么被悄悄改了」的体检。