激活#

首先, 强烈建议你将世界书全局设置和预设设置改为下图那样, 这应能带来最好的游戏体验:
(尤其是现在大家开始用酒馆助手插件提示词模板插件mvu 变量框架)

../../../../_images/%E4%B8%96%E7%95%8C%E4%B9%A6%E6%8E%A8%E8%8D%90%E5%85%A8%E5%B1%80%E8%AE%BE%E7%BD%AE.png

世界书推荐全局设置#

../../../../_images/%E9%A2%84%E8%AE%BE%E6%8E%A8%E8%8D%90%E8%AE%BE%E7%BD%AE.png

预设推荐设置#

之后对条目激活的解释, 我将默认你采用了这样的设置, 因此会忽略上下文百分比等造成的影响.

警告

此外我还会略过 "绑定到角色或标签"、"包含组" 等功能, 因为我觉得不够好用.

基本术语#

世界书条目 (entry)
../../../../_images/%E4%B8%96%E7%95%8C%E4%B9%A6%E6%9D%A1%E7%9B%AE.png
提示词 (prompt)

即世界书的内容部分. 世界书条目如果被使用, 则将会把这部分发给 AI.

../../../../_images/%E6%8F%90%E7%A4%BA%E8%AF%8D.png
1如果你的世界书界面没有下图那样的启用开关, 说明酒馆版本太老了; 相比于我同时解释老版本的界面, 你可能更应该更新酒馆.
启用 (enable) 1如果你的世界书界面没有下图那样的启用开关, 说明酒馆版本太老了; 相比于我同时解释老版本的界面, 你可能更应该更新酒馆.

表示我们打开了条目. 在没有其他扩展的情况下, 酒馆只会考虑使用打开了的条目.

../../../../_images/%E5%90%AF%E7%94%A8.png
激活/触发 (activate)

表示已经确认某世界书条目应该被使用, 它的提示词将会发给 AI.

我们从最新版酒馆助手所提供的输入框左下角魔棒 ‣ 提示词查看器中查看当前的发送结果:

../../../../_images/%E6%8F%90%E7%A4%BA%E8%AF%8D%E6%9F%A5%E7%9C%8B%E5%99%A8.png
递归 (recursion)

表示某世界书条目被激活后, 该条目的提示词又激活了其他条目. 具体将会在下文中解释.

单个条目的激活#

在不考虑递归和其他条目作用的情况下, 单个条目的激活需要考虑以下要求:

启用#

你需要启用条目才能激活它.

激活概率% (触发概率%)#

../../../../_images/%E6%BF%80%E6%B4%BB%E6%A6%82%E7%8E%87.png

条目的激活会进行一次概率判定. 如果概率判定成功且满足其他要求, 则条目将会被激活.
它默认为 100%, 即概率判定必定成功.

激活策略 (触发策略)#

../../../../_images/%E6%BF%80%E6%B4%BB%E7%AD%96%E7%95%A5.png
🔵: 常量 (constant), 俗称蓝灯

无额外要求. 只需要满足 "启用"、"激活概率%" 等别的要求即可.

🟢: 可选项 (selective), 俗称绿灯

要求欲扫描文本满足一定条件. (具体什么是欲扫描文本见下文.)

🔗: 向量化 (vectorized)

这个激活策略涉及向量存储, 我没玩过, 略.

也就是说, 激活策略设置为蓝灯意味着不在此做额外考虑; 而绿灯则意味着对欲扫描文本有一定要求.

欲扫描文本: 初次解释#

什么是欲扫描文本呢? 你现在可以认为就是你的聊天正文——你和 AI 的消息——经过一些处理后的结果. 这些处理我们在本文最后再说明, 对于你理解世界书条目的激活流程并不造成影响.

绿灯条件: 欲扫描文本中精确地包含一段文本#

我们前面提到, 将激活策略设置为绿灯就是要求欲扫描文本满足一定的条件. 这能有什么作用呢?

首先要知道的是, AI 的上下文和注意力都是有限的, 因此我们不可能将一整本《神话版三国》 (我写下这段话时, 它已连载了 2179 万字) 全部塞给 AI.

那么, 假设我们有一张人物众多的角色卡, 而其中只有一位名为络络的角色出场, 我们显然希望仅激活络络的详情条目发给 AI.
绿灯就能做到这一点: 它可以要求欲扫描文本必须精确地包含络络这段文本才激活条目.

如何告知绿灯该这么做呢? 我们展开条目, 在主要关键字 (primary keyword)中填入络络:

../../../../_images/%E7%BB%BF%E7%81%AF%E6%9D%A1%E4%BB%B6-%E5%8D%95%E4%B8%AA%E4%B8%BB%E8%A6%81%E5%85%B3%E9%94%AE%E5%AD%97.png

这样一来, 仅当欲扫描文本中存在络络这段文本时, 这个络络-详情条目才会激活.

警告

绿灯条目必须要有至少一个关键字, 否则将永远不满足激活策略.

欲扫描文本: 扫描深度#

但消息楼层可能很长, 我自己玩过 2000 楼消息. 显然, 当我们玩第 2000 楼时, 我们不希望仅仅在第 0 楼出现过的青空莉文本依旧激活对应世界书条目. 为此, 酒馆允许你为所有世界书或单个世界书条目设置扫描深度: 如果设置扫描深度为 n, 则激活将仅扫描最后 n 条消息.

我的世界书推荐全局设置将扫描深度设置为 2, 而通常我们是发送一条输入来请求 AI 生成, 则游玩时绿灯将仅扫描你的最后一条输入和 AI 的最后一条回复; 你也可以像下图那样单独设置某个条目的扫描深度:

../../../../_images/%E6%89%AB%E6%8F%8F%E6%B7%B1%E5%BA%A6.png

绿灯条件: 欲扫描文本中精确地包含文本A或文本B#

可是我们不仅希望正文中提到络络时激活络络-详情条目, 还希望提到女皇笨蛋时也激活它.
为此, 我们可以用英文输入法下的逗号 , (半角逗号) 来间隔这些文本, 将它们全都填入主要关键字中, 即络络,女皇,笨蛋; 当然你也可以加空格显得好看一些: 络络, 女皇, 笨蛋.

../../../../_images/%E7%BB%BF%E7%81%AF%E6%9D%A1%E4%BB%B6-%E5%A4%9A%E4%B8%AA%E4%B8%BB%E8%A6%81%E5%85%B3%E9%94%AE%E5%AD%97.png

这样一来, 只要欲扫描文本中出现这三个关键字中任意一个, 就会激活这个条目.

绿灯条件: 关键字的显示模式#

如果你害怕自己将逗号错误地输入为中文输入法下的逗号而没能正确分割关键字, 可以切换关键字的显示模式为标签模式:

../../../../_images/%E5%88%87%E6%8D%A2%E5%85%B3%E9%94%AE%E5%AD%97%E7%9A%84%E6%98%BE%E7%A4%BA%E6%A8%A1%E5%BC%8F.png

这样一来每个关键字都将被独立显示. 此外, 你将有一个下拉框, 这个下拉框中会列出世界书中包含的所有关键字.

../../../../_images/%E5%85%B3%E9%94%AE%E5%AD%97%E6%A0%87%E7%AD%BE%E6%A8%A1%E5%BC%8F.png

绿灯条件: 欲扫描文本中精确地包含文本A和文本B#

假设络络是一名学生, 我们也许希望她在社团活动室时才触发某个事件. 这意味着我们希望欲扫描文本中同时存在络络社团活动室时才激活条目.

要做到这一点, 我们需要使用逻辑可选过滤器. 将逻辑设置为与任意, 在可选过滤器中填入社团活动室:

../../../../_images/%E7%BB%BF%E7%81%AF%E6%9D%A1%E4%BB%B6-%E5%8D%95%E5%AF%B9%E5%8D%95%E4%B8%8E%E4%BB%BB%E6%84%8F.png

这样一来, 只有欲扫描文本中同时出现了络络社团活动室, 这个条目才会被激活.

你当然可以填写更多, 例如你也许希望只要络络处于 社团活动室天台 时才激活该条目, 而络络本身可以由 络络女皇笨蛋 激活:

../../../../_images/%E7%BB%BF%E7%81%AF%E6%9D%A1%E4%BB%B6-%E5%A4%9A%E5%AF%B9%E5%A4%9A%E4%B8%8E%E4%BB%BB%E6%84%8F.png

也就是说, 当右边的可选过滤器填写有关键字时, 绿灯除了在左边的主要关键字中任意匹配到一个关键字, 还需要按照规定的逻辑满足右边的可选过滤器. 具体地:

  • 与任意 (and any): 要求右边任意一个关键字能在欲扫描文本中匹配到

  • 与所有 (and all): 要求右边所有关键字都能在欲扫描文本中匹配到

  • 非所有 (not all): 要求右边至少有一个关键字在欲扫描文本中没能匹配到

  • 非任何 (not any): 要求右边所有关键字都没在欲扫描文本中匹配到

提示

在本文最后的一些进阶世界书条目技巧中将会有一些简化这些关键字的技巧.

绿灯条件: 欲扫描文本能被某个正则表达式匹配#

绿灯的关键字除了用络络这样的精确文本之外, 还可以是正则表达式——满足一定格式的一串文本.

想象一下, 如果我们要用精确文本来匹配 000 到 100 的数字, 需要怎么做? 000, 001, 002, 003, 别列了人麻了😨, 100.
而如果使用正则表达式, 你只需要在绿灯关键字中填写 /正则表达式/设置, 此处即是 /\d{1,3}/

../../../../_images/%E7%BB%BF%E7%81%AF%E6%9D%A1%E4%BB%B6-%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F.png

这是一个容易入门但难以精通的计算机工具. 我在此不会展开解释. 我个人推荐使用《正则表达式必知必会》来学习它, 用 regex101 来测试匹配情况, 而非完全依赖 AI 编写.

通过用正则表达式作为关键字, 你可以做到分阶段激活不同条目等效果.

时效功能: 黏性、冷却、延迟#

时效功能允许我们用上一次世界书的激活情况影响下一次世界书的激活: 上一次激活了所以这次继续激活, 上一次激活了所以这次不准激活.

酒馆提供了如图所示的三种时效功能:

../../../../_images/%E6%97%B6%E6%95%88%E5%8A%9F%E8%83%BD.png
黏性 (sticky)

条目激活后, 在之后 n 条消息内始终激活, 无视激活策略、激活概率%.

黏性: 5, 激活概率: 50%
================================================================================
[0] AI 消息
[1] 玩家消息: 开始游戏
[2] AI 消息: 50% 激活概率判定未通过, 激活失败
[3] 玩家消息
[4] AI 消息: 50% 激活概率判定通过, 激活成功, 触发黏性 5
[5] 玩家消息: 黏性 5
[6] AI 消息: 因黏性而继续激活, 黏性 4
[7] 玩家消息: 黏性 3
[8] AI 消息: 因黏性而继续激活, 黏性 2
[8] 玩家消息: 黏性 1
[8] AI 消息: 50% 激活概率判定未通过, 激活失败
冷却 (cooldown)

条目激活后, 在之后 n 条消息内不能再激活.

冷却: 5
================================================================================
[0] AI 消息
[1] 玩家消息: 开始游戏
[2] AI 消息: 激活, 触发冷却 5
[3] 玩家消息: 冷却 5
[4] AI 消息: 因冷却而不能激活, 冷却 4
[5] 玩家消息: 冷却 3
[6] AI 消息: 因冷却而不能激活, 冷却 2
[7] 玩家消息: 冷却 1
[8] AI 消息: 激活

它可以和黏性一起使用, 则激活的条目在一定消息数内先保持激活, 再进入冷却

黏性: 3, 冷却: 3
================================================================================
[0] AI 消息
[1] 玩家消息: 开始游戏
[2] AI 消息: 激活, 触发黏性 3
[3] 玩家消息: 黏性 3
[4] AI 消息: 因黏性而继续激活, 黏性 2
[5] 玩家消息: 黏性 1
[6] AI 消息: 因冷却而不能激活, 冷却 3
[7] 玩家消息: 冷却 2
[8] AI 消息: 因冷却而不能激活, 冷却 1
[8] 玩家消息
[8] AI 消息: 激活
延迟 (delay)

聊天中至少有 n 楼消息时, 才能激活条目.

延迟: 5
================================================================================
[0] AI 消息
[1] 玩家消息: 开始游戏
[2] AI 消息: 因延迟而不能激活
[3] 玩家消息
[4] AI 消息: 激活

它们的效果仅作用于当前聊天, 并有以下特点:

  • 如果消息发生重 roll 或删除, 所有目前已被触发的时效功能全部失效: 例如, 络络-详情 条目的黏性时效功能已经触发, 因而下几条消息中该条目将会被始终激活; 重 roll 或删除消息之后, 这个效果将不再存在.

  • 如果条目被修改, 它已经被触发的时效功能失效.

正文? 递归? 一次完整的世界书扫描#

有了对单个条目如何激活的认识, 我们接下来开始了解我所推荐的世界书全局设置中启用的一个重要功能: 递归扫描. 简单来说, 它允许你用一个已激活条目的内容来激活另一个条目:

../../../../_images/%E7%BB%BF%E7%81%AF%E8%A2%AB%E5%A7%8B%E7%BB%88%E6%BF%80%E6%B4%BB.png

这是怎么做到的呢?

欲扫描文本: 在递归中变化#

我们前面提到, 欲扫描文本是规定扫描深度下的正文经过一些处理后的结果——这其实只构成了世界书扫描的第一轮激活.

当第一轮激活结束后, 所有被激活条目的提示词将会加入到欲扫描文本中 (同样经过一些处理), 进行第二轮激活尝试.

然后, 新激活条目的提示词也会加入到欲扫描文本中, 继续尝试新的激活……这样的激活尝试会直到有一轮不再有条目被激活时才结束. 这就是整个递归扫描.

需要注意的是, 如果条目设置了激活概率%, 只要在其他条件满足的情况下概率判定失败过一次, 酒馆在本次世界书扫描中就不会再考虑激活这个条目.

条目递归相关设置#

../../../../_images/%E6%9D%A1%E7%9B%AE%E9%80%92%E5%BD%92%E7%9B%B8%E5%85%B3%E8%AE%BE%E7%BD%AE.png
不可递归 (exclude recursion)

该条目不会被其他条目递归激活.

防止进一步递归 (prevent recursion)

该条目不会递归激活其他条目.

延迟到递归 (delay until recursion)

该条目只在至少第 n 次递归及以后才能被激活.

../../../../_images/%E9%80%92%E5%BD%92%E7%AD%89%E7%BA%A7.png

这个选项的使用需要特别注意, 为什么呢?
递归扫描的停止条件是直到有一轮不再有条目被激活, 而并不考虑有条目被延迟到第 n 次递归才激活.
极端地说, 如果我们在此处填写 999, 则条目很可能永远不被激活——世界书扫描很可能在第 2 次递归时就不再激活任何条目而停止了!

绿灯逻辑: 非所有非任何的局限性#

非所有为例. 作为实际例子, 让我们取络络非所有学校, 则它是欲扫描文本匹配到了络络且没有匹配到学校时才激活条目.

如果我们只对正文进行世界书扫描, 这不会有任何问题; 但引入递归后就不再是这样.
酒馆只会激活条目, 不会取消已激活条目的激活(SillyTavern/SillyTavern#2213): 假设对正文的扫描确实匹配到了络络且没有匹配到学校, 显然条目应该被激活; 之后即便递归扫描时欲扫描文本中有了学校这个文本, 这个条目仍然会保持激活状态!

因此, 我的建议是:

  • 只针对正文部分使用非所有非任何.

  • 如果非要针对递归情况使用它们, 务必保证左边的匹配和右边的不匹配都在同一轮递归扫描中发生.

欲扫描文本会经历的处理#

我们最开始说欲扫描文本就是你的聊天正文, 之后又提到了扫描深度 n 和递归. 你也许认为, 至少最初的欲扫描文本会是最后 n 条聊天正文, 而递归时将加入那些激活了且没有勾选防止进一步递归 的条目……不, 这还不太对.

宏替换#

我们在第一条消息中, 很可能见到过 {{user}}<user>这样的文本, 它将会被替换为你所写的用户名.
其实除了 {{user}} 以外, 酒馆还有如 {{char}}{{getvar::变量}} 等需要替换的文本, 它们被称为宏 (macro).

在提示词作为欲扫描文本之前, 酒馆会对这些宏一一进行替换:

../../../../_images/%E7%AC%AC%E4%B8%80%E6%9D%A1%E6%B6%88%E6%81%AF%E4%B8%AD%E7%9A%84%E5%AE%8F.png

第一条消息中的宏#

仅格式提示词正则#

此外, 我们还需要考虑酒馆正则对欲扫描文本的影响.

../../../../_images/%E9%85%92%E9%A6%86%E6%AD%A3%E5%88%991.png

回想一下你目前所使用的预设, 其中是否有思维链 (<thinking>)、摘要/总结等功能?

为了实现这些功能, 作者通常需要提供配套的酒馆正则让你导入. 这些正则可能实现以下效果:

影响界面显示

比如让你在聊天界面中看不到思维链. 这由正则设置中的仅格式显示控制.

影响发送给AI的内容

比如实现 "不发送6楼以上除摘要外的文本" 的效果. 这由正则设置中的仅格式提示词控制.

../../../../_images/%E6%AD%A3%E5%88%99%E6%A0%BC%E5%BC%8F%E9%80%89%E9%A1%B9.png

仅格式提示词既然是要影响 AI 会接收到什么内容, 自然也会影响我们用来判断是否激活世界书条目的欲扫描文本.

总结#

也就是说, 最初的欲扫描文本是我们的聊天正文经过宏替换和仅格式提示词正则处理后的结果; 而在递归过程中, 新激活的条目也会经过宏替换和仅格式提示词正则处理, 然后加入到欲扫描文本中.

这也许带来思维上的繁琐, 但我得提醒你它们的好处:

宏替换允许我们动态化提示词

这意味着我们可以让世界书条目内容动态变化.

此外, 这里所说的提示词不仅限于世界书, 还包括其他所有会发给 AI 的部分.
Lyean 预设就是这样允许你自行设置的!

../../../../_images/Lyean%E9%A2%84%E8%AE%BE%E6%8F%90%E7%A4%BA%E8%AF%8D%E8%AE%BE%E7%BD%AE.png
仅格式提示词正则允许我们用正则表达式调整欲扫描文本和最终发送给 AI 的内容

略.

一些进阶世界书条目技巧#

一次性条目#

我们将冷却值设置为 9999, 则条目激活后, 在之后 9999 条消息中都不能再激活该条目.

提示

为了延长这个条目的效果而不是只在一次回复里生效, 你可以设置一个适度的黏性值.

这种方法简单但容易因重 roll 或删除消息而失效. 你也许需要用变量等其他手段, 见下文给出的一些跳转链接.

绝对激活的绿灯#

正则表达式 /./s 能够匹配任意字符, 因此使用它作为绿灯的关键字将让绿灯始终激活.

仅当正文里不包含某些文本才激活的绿灯#

左边设置为 /./s, 逻辑选择非所有非任意, 右边填写正文中不应包含的关键字.

专门用于激活其他条目的条目#

很多时候, 我们的多个条目会共用同一组关键字. 一个经典的例子是角色分为 "详情"、"关键信息"、"阶段1"、"阶段2"、"阶段3" 等.
但这样一来每次需要更改关键字时都需要手动复制粘贴它们, 还需要人工检查是否都改对了.

我对此的简单解决办法是, 新建一个络络-激活条目, 而用这个条目的内容递归地去激活其他络络条目:

../../../../_images/%E6%BF%80%E6%B4%BB%E6%9D%A1%E7%9B%AE.png

这样一来, 我只需要调整络络-激活条目, 就能做到蓝灯、排除递归等激活调整.

分阶段条目? 动态世界书?#

绿灯的关键字可以是正则表达式, 由此衍生出了分段好感度等写法: 一个条目的关键字匹配好感度 0~19, 另一个条目的关键字匹配好感度 20~39……
此外, 我们提及了欲扫描文本是宏替换和仅格式提示词正则作用后的结果, 在这两个环节我们也能做很多有意思的事情……

但我已经不推荐你自己闭门造车, 你可以使用 mvu 变量框架, 阅读络络的 mvu 教程.

mvu 变量框架
络络的 mvu 教程

此外, 我的角色世界书条目写法见于: 这个链接开头部分.

自行编写代码控制条目的激活#

你可以使用以下方式, 自行编写代码来激活条目:

提示词模板
  • 可以编写 <%_ if (条件) { _%> 来控制一部分提示词是否发送. 例如:

    • <%_ if (matchChatMessages(['络络', '笨蛋'])) _%> 来只在正文文本包含络络笨蛋时发送

    • <%_ if (getvar('stat_data.角色.络络.好感度') > 30) { _%> 来只在络络的好感度大于 30 时才发送一段提示词, 当然你需要学会写变量卡

  • 提供的 <%= await getWorldInfo("世界书名称", "条目名称") _> 将会被替换为对应的条目文本. 这实际不涉及条目本身的激活, 因此无所谓条目是否被启用

  • 提供的 <%_ await activateWorldInfo("世界书名称", "条目名称") _%> 将会激活对应的条目. 用它激活的条目仍会受除激活条目以外

酒馆助手所提供的……怎么没有直接的方式! 没事,
官方 STScript

它所提供的 /inject position=none scan=true id=填写一个唯一名称 "关键字" 相当于在正文中加入一串欲扫描文本, 可用于激活绿灯条目; 但这个与扫描文本除非主动用命令移除, 否则将会永久存在
如果你只是需要仅在下一次扫描中激活条目, 可以加上 ephemeral=true.