组合和命名提示词#

帖子: 类脑/旅程

很多时候我们需要:

将多个条目视为一块提示词

从而告知 AI 它们之间的联系比其他提示词更紧密, 让 AI 能更好地理解它们

给提示词设定一个名称

从而在其他提示词中能引用它们, 便于制作模块化的额外输出格式或让 AI 回忆它们 (如输出格式强调)

这并没有固定的方法, 我只是记录我常用的几种.

前置#

压缩系统提示词#

然而酒馆默认会将不同条目作为不同消息发送, 而模型在实际接收时可能存在 <|im_start|>system 之类的对消息进行隔离:

../../../../_images/%E4%B8%8D%E5%90%8C%E6%9D%A1%E7%9B%AE%E6%8F%90%E7%A4%BA%E8%AF%8D%E8%A2%AB%E9%9A%94%E7%A6%BB.png

为了让条目在发送时被发送成一条消息, 你应该勾选预设里的压缩系统消息. 它会将相邻的 system 身份消息压缩成一条:

../../../../_images/%E5%8E%8B%E7%BC%A9%E7%B3%BB%E7%BB%9F%E6%B6%88%E6%81%AF.png

或者, 你可以用压缩相邻消息. 它可以:

  • 压缩所有相邻同身份消息, 使得 AI 对内容理解更连贯;

  • 将正文压缩成一个消息里的 A 和 B 对话, 自建对话语境, 免受模型有关 user 和 ai 对话理解的影响从而避免模型关于 AI 和用户对话的影响.

../../../../_images/%E5%8E%8B%E7%BC%A9%E7%9B%B8%E9%82%BB%E6%B6%88%E6%81%AF.png

条目的顺序#

既然多个条目应该被视为一块, 那么我们需要确保条目按序发送.

  • 如果是预设中的条目, 它们一般是按相对顺序排列的, 因此直接排列好即可.

  • 如果是世界书中的条目, 建议按照世界书条目的插入来确保条目按序发送.

建议#

我的实时编写角色卡、世界书或预设脚本提供了 "合集文件" 功能, 你可以在一个文件里编写多个条目的提示词, 便于管理一整块提示词.

方法#

XML 标签#

我们可以用 <你自己定一个名字></你自己定一个名字> 包裹提示词从而区分提示词的作用, 而提示词本身的写法不受限制. (Claude 官方介绍)

比较经典的是一些预设的思维链写法, 注意它是如何用 <thinking_format> 包裹思维链输出要求, 又用 <thinking> 包括思维链具体内容的.

思维链开始#
<thinking_format>
[在输出正文前,你必须在<thinking>内用拉丁语思考]
<thinking>
某个思维链条目#
- 略
另一个思维链条目#
- 略
思维链结束#
</thinking>
</thinking_format>

有了 XML 标签, 我们也能引用这块提示词. 例如, 某些预设的底部可能有一句话来强调输出思维链:

我必须先输出<thinking>再输出<content>,然后输出其他要求的内容

YAML 结构化提示词#

如果你看过手写mvu变量卡或我的其他提示词写法, 你可能已经见过 YAML:

---
角色阶段:
  descritpion: 角色阶段基于各角色的`角色关键信息`和`角色详情`词条,描述了经过剧情发展后角色成长得到的新人设
  associated variable: 各角色的阶段关联有不同的变量,仅用于判断其角色阶段是否应该发生变化,不影响阶段的具体人设

此处不会教 YAML 具体怎么写, 你可以自己阅读!yaml.info等; 但不会 YAML 并不影响你理解 YAML 如何帮助我们组合和命名提示词的.

文档#

我的几乎所有提示词都用 YAML 书写, 而用 --- 分隔不同部分:

---
角色详情:
  夏霖:
    ...
  夏乃:
    ...
rule: 你必须在之后理解`角色关键信息`时recall角色对应的`角色详情`词条
---
角色关键信息:
  夏霖:
    ...

--- 在 YAML 中是文档 (document) 起始符, 因此上面的提示词就构成了两个 YAML 文档: `角色详情`document`关键信息`document.

由此, 你已经组合和命名了角色详情和角色关键信息提示词:

角色详情开始#
---
角色详情:
角色详情-夏霖#
  夏霖:
    ...
角色详情-夏霖#
  夏乃:
    ...
角色详情结束#
rule: 你必须在之后理解`角色关键信息`时recall角色对应的`角色详情`词条

这样完全结构化的提示词不仅仅命名了整块提示词为`角色详情`document, 你还可以精确地说`夏霖`mapping inside `角色详情`document.

提示

你可以试试直接输入停止扮演,回忆夏霖在`角色详情`document中的内容,原封不动地输出到代码块中, AI 很可能会输出与角色详情中内容几乎一致的结果.

现在你应该清楚为什么你会在角色阶段里见到角色阶段基于各角色的`角色关键信息`和`角色详情`词条这样的提示词了.

如果你像我一样几乎所有提示词都是 YAML 文档, 那么当前 YAML 文档以 --- 开始后, 显然在下一个 --- 出现时结束.

但也许你会混用 YAML 文档和其他文本, 那么可以用 ... 明确表示文档结束:

上面有些不是 YAML 的条目
---
角色阶段:
  descritpion: 角色阶段基于各角色的`角色关键信息`和`角色详情`词条,描述了经过剧情发展后角色成长得到的新人设
  associated variable: 各角色的阶段关联有不同的变量,仅用于判断其角色阶段是否应该发生变化,不影响阶段的具体人设
...
下面有些不是 YAML 的条目

或者……代码块!

上面有些不是 YAML 的条目
```yaml
角色阶段:
  descritpion: 角色阶段基于各角色的`角色关键信息`和`角色详情`词条,描述了经过剧情发展后角色成长得到的新人设
  associated variable: 各角色的阶段关联有不同的变量,仅用于判断其角色阶段是否应该发生变化,不影响阶段的具体人设
```
下面有些不是 YAML 的条目

锚点#

也许你会为角色卡制作插图. 为了让 AI 生成它, 显然你需要将插图文件列出来发给 AI:

背景列表:
  背景:
    - 地铁内/白天
    - 地铁内/黄昏
    - 地铁内/夜晚开灯
    - 海滩/白天
    - 海滩/黄昏
    - 海滩/夜晚关灯
    - 男生房间/白天
    - 男生房间/黄昏
    - 男生房间/夜晚开灯
    - 男生房间/夜晚关灯
    - 女生房间/白天
    - 女生房间/黄昏
    - 女生房间/夜晚开灯
    - 女生房间/夜晚关灯
    - 女生房间/夜晚夜灯
    - 地铁站内/地铁站内
    ...略去其他一百多个图片
  调用格式: ${背景}.jpg
  调用示例:
    - 地铁内/白天.jpg
    - 女生房间/夜晚夜灯.jpg

上面是一个简化的例子, 因此看上去使用的 token 并不多; 但在日记络络中有 130 个背景图片、15 个 CG、77 个 NSFW CG!

你当然可以使用额外输出格式所介绍的方法减少一定的 token 开销, 但配合 YAML 的锚点语法来命名 YAML 某个部分能为你节省更多 token.

具体地, 在 YAML 中, 我们可以用 &名字 来将某个部分设置成锚点, 而用 *名字 来在别的地方使用这个锚点:

---
背景列表:
  地点情况:
    - &day_dusk  <-- 将下面的 `[白天, 黄昏]` 设置成锚点
      - 白天
      - 黄昏
    - &common_lights
      - *day_dusk  <-- 使用锚点, 因此 common_lights 锚点会是 `[白天, 黄昏, 夜晚开灯, 夜晚关灯]`
      - 夜晚开灯
      - 夜晚关灯

有了 day_duskcommon_lights 锚点 (你也可以用中文设置锚点), 我们可以这样在列表中列出背景:

  背景:
    地铁内:
      - *day_dusk  <-- 地铁内会是 `[白天, 黄昏, 夜晚开灯]`
      - 夜晚开灯
    海滩:
      - *day_dusk
      - 夜晚关灯
    男生房间:
      - *common_lights
    女生房间:
      - *common_lights
      - 夜晚夜灯
    ...略去其他十多种情况

    # 以下是无情况变化的背景
    地铁站内: 地铁站内
  调用格式: ${地点}/${地点情况}.jpg
  调用示例:
    - 地铁内/白天.jpg
    - 女生房间/夜晚夜灯.jpg

或者, 变量的设定相近, 你不想复制粘贴文本:

---
变量更新规则:
  好感度:
    type: number
    range: 0~100
    check:
      - 如果角色注意到了<user>的行为,根据他们的态度将更新±(1~4)
  失望度:
    type: number
    range: 0~200
    check:
      - 如果角色注意到了<user>的行为,根据他们的态度将更新±(1~4)

或者, 你只是想给变量添加相同的一条 check:

---
变量更新规则:
  好感度:
    type: number
    range: 0~100
    check:
      - 如果角色注意到了<user>的行为,根据他们的态度将更新±(1~4)
  失望度:
    type: number
    range: 0~200
    check:
      - 如果角色注意到了<user>的行为,根据他们的态度将更新±(1~4)

这只是提示词

虽然我们用了 YAML 的锚点功能, 但它依旧只是提示词. 我们只是在利用 AI 知道 YAML 的锚点有什么作用, 从而避免复制粘贴、节省 token. 因此, 即便你写锚点出现轻微的语法错误 (当然最好不要), AI 也不会在乎.

此外, 我的实时编写角色卡、世界书或预设脚本也有锚点功能, 允许你统一管理多个条目的设置, 比如一键修改所有角色详情的插入方式、一键修改某个人物的激活策略.

混合使用 XML、YAML#

你当然可以混合 XML 标签和 YAML 文档.

将几个 YAML 文档用 XML 标签包裹#
<世界信息>
---
文档1: ...
---
文档2: ...
</世界信息>
在 YAML 文档内使用 XML 标签#
---
状态栏:
  rule: ...
  format: |-
    <status>
    状态栏内容
    </status>