宏
实验宏引擎
实验宏引擎支持嵌套、稳定的替换顺序和其他改进。对于新安装,它默认启用。现有的安装可以启用它 用户设置 > 聊天/消息处理 > 实验宏引擎.
宏是动态占位符,在处理文本时会替换为实际值。它们在提示词、角色卡、知识手册、快速回复等中的整个 SillyTavern 中使用。
查找可用的宏
SillyTavern 提供所有可用宏的内置文档:
- 斜线命令:类型
/? macros在聊天输入中显示所有已注册宏及其描述的列表。 - 自动完成:参见 宏自动完成 有关在打字时获取建议的详细信息,请参阅下文。
宏自动完成
宏自动完成功能会在您键入时提供可用宏的建议。它适用于整个 SillyTavern 支持宏的所有文本字段。
类型 {{ 启动宏的自动完成,显示可用的宏及其参数,潜在的 宏标志, 变量简写,等等。
默认情况下出现自动完成的位置:
- 聊天用户输入框
- 扩展编辑器(全屏文本编辑,通过文本字段旁边的“扩展”按钮打开)
- 提示词经理编辑
在其他字段中触发自动完成:
- 新闻 Ctrl+空格键 在任何支持宏的文本字段中打开自动完成弹出窗口
- 启用 设置 → 自动完成设置 → 在所有宏字段中显示 让自动完成功能自动出现在所有宏字段中
基本语法
宏包含在双花括号中:
{{macroName}}
宏名称是 不区分大小写. {{User}}, {{USER}}, 和 {{user}} 全部解析为同一个宏。
示例:
{{user}} // Returns the current user/persona name
{{char}} // Returns the current character name
{{time}} // Returns the current time
{{date}} // Returns the current date
论点
许多宏接受参数来自定义其行为。
空间分隔符
对于具有单个参数的宏,可以使用空格将宏名称与其参数分隔开:
{{macroName argument}}
示例:
{{getvar myVariable}}
{{roll 1d20}}
{{reverse Hello World}}
双冒号分隔符
使用 :: 分隔多个参数:
{{macroName::arg1::arg2::arg3}}
示例:
{{setvar::myVariable::Hello World}}
{{random::red::green::blue}}
{{roll::2d6+3}}
无论是空间还是 :: 是宏参数的推荐语法。
单冒号分隔符(旧版)
单个 : 也可以引入参数,但此语法被视为遗留语法,不建议用于新内容:
{{macroName:argument}}
示例:
{{roll:1d20}}
宏定义中的空格
宏名称、分隔符和参数之间的空格将被忽略。这允许更易读的格式:
{{ macroName :: arg1 :: arg2 }}
{{ setvar :: myVariable :: some value }}
{{ if :: condition }}
以上所有内容都相当于它们的紧凑形式,没有额外的空格。
嵌套宏
宏可以嵌套在其他宏中。首先解析内部宏:
{{getvar::{{char}}_mood}}
这首先解决 {{char}} (例如,“Alice”),然后解析 {{getvar::Alice_mood}}.
更多示例:
{{setvar::greeting::Hello, {{user}}!}}
设置一个变量,其内容包括用户名。
{{if {{getvar::showDetails}}}}Details here{{/if}}
条件本身是一个检索变量值的宏。
作用域宏
任何接受至少一个参数的宏都支持作用域语法。开始标签和结束标签之间的内容成为 最后一个论点 的宏。
作用域语法
可以将最后一个参数放在开始和结束标记之间,而不是内联编写:
{{macroName argument}}
scoped content here
{{/macroName}}
结束标签使用 / 宏名称前的标志: {{/macroName}}.
这相当于写:
{{macroName::argument::scoped content here}}
示例
设置具有多行内容的变量:
{{ setvar backstory }}
This character was born in a small village
and grew up to become a renowned scholar.
{{ /setvar }}
使用 reverse 具有范围内容:
{{ reverse }}
Hello World
{{ /reverse }}
这将返回“dlroW olleH”。
内容修剪
默认情况下,范围内的内容会自动修剪:
- 前导和尾随空格被删除
- 一致的缩进被取消缩进(从所有行中删除第一个非空行的缩进)
这允许干净的格式:
{{ if condition }}
# Heading
Some content here
{{ /if }}
生产 # Heading\nSome content here (没有前导空格)。
要保留所有空白,包括前导/尾随换行符,请使用 # 标志。参见 宏标志 了解详情。
条件宏
的 {{if}} 宏根据值是真还是假有条件地呈现内容。
简单条件
{{ if description }}
# Character Description
{{ description }}
{{ /if }}
仅当出现以下情况时,才会显示标题和说明: description 返回一个非空值。
条件可以是:
- 宏名称(如果不需要参数,则自动解析)
- 来自嵌套宏的任何值,例如
{{getvar::flag}} - 变量简写如
.myFlag或$globalFlag(见 变量简写) - 您想要的任何文本(将根据其内容隐式解析为真或假)
虚假值:空字符串, false, 0, off, no.
在条件中使用变量简写
变量简写提供了一种检查条件中变量值的简洁方法:
{{ if .isEnabled }}
Feature is enabled.
{{ /if }}
{{ if !$globalDisabled }}
Not globally disabled.
{{ /if }}
参见 变量简写 有关速记符号的更多详细信息。
倒置条件
条件前缀为 ! 反转它:
{{ if !personality }}
No personality defined for this character.
{{ /if }}
If/Else 分支
使用 {{else}} 里面一个 {{if}} 块来定义替代分支:
{{ if personality }}
{{ personality }}
{{ else }}
No personality defined.
{{ /if }}
另一个例子:
{{ if {{getvar::details-block}} }}
# Details Block
{{ getvar::details-block }}
{{ else }}
No details currently exist.
{{ /if }}
宏标志
标志是放置在左大括号和宏名称之间的特殊符号角色,用于修改宏行为。
语法
{{!macroName}}
{{#macroName}}
标志可以组合:
{{!?macroName}}
标志和宏名称之间允许有空格:
{{ / macroName }}
{{ # macroName }}
实施的标志
| 旗帜 | 名称 | 描述 |
|---|---|---|
/ | 封闭块 | 标记作用域宏的结束标记。示例: {{/if}} |
# | 保留空白 | 防止自动修剪范围内的内容。 |
计划中的标志(尚未实施)
| 旗帜 | 名称 | 描述 |
|---|---|---|
! | 立即 | 在同一文本中的其他宏之前解析此宏。 |
? | 延误 | 在同一文本中的其他宏之后解析该宏。 |
~ | 重新评估 | 标记此宏以进行重新评估。 |
> | 过滤器 | 为此宏启用基于管道的输出过滤器。 |
类似标志的前缀运算符
变量速记语法使用前缀运算符 (. 和 $)其行为与标志类似,但本身不是标志。
请参阅 变量简写 部分了解详细信息。
保留空白标志
使用 # 当您需要保留作用域内容中的所有空格(包括前导/尾随换行符和缩进)时进行标记:
{{ # setvar code }}
function hello() {
return "world";
}
{{ /setvar }}
没有 #,内容将被修剪和缩进。与 #,所有空白都完全按照写入方式保留,包括开始标记之后和结束标记之前的换行符。
评论
使用注释宏添加不会出现在输出中的注释:
{{// This is a comment and will be removed}}
对于多行注释,请使用作用域语法:
{{ // }}
This entire block is a comment.
It can span multiple lines.
{{ /// }}
转义宏
要在没有宏分辨率的情况下显示文字大括号,请使用反斜杠对其进行转义:
\{\{notAMacro\}\}
这输出 {{notAMacro}} 作为纯文本。
变量简写
变量简写为常见变量操作提供了简洁的语法。使用 . 对于局部变量和 $ 对于全局变量。
可变速记前缀
| 前缀 | 名称 | 描述 |
|---|---|---|
. | 局部变量 | 局部变量操作的简写。示例: {{.myvar}} |
$ | 全局变量 | 全局变量操作的简写。示例: {{$myvar}} |
必须放置这些前缀运算符 就在之前 变量名称,在任何可选出现之后 宏标志。它们不被视为宏标志,而是更多指示正在插入变量速记,而不是按名称插入宏。前缀运算符不是变量名本身的一部分,而是更改变量访问方式的修饰符。
变量名称
变量名称遵循与宏标识符相同的规则:以字母开头,后跟字母、数字、下划线或连字符。最后一个角色不允许是下划线或连字符。
{{.my-var}} // Valid
{{.my_var}} // Valid
{{.myVar123}} // Valid
如果您的变量具有不符合标准规则的标识符,则必须使用完整的变量宏语法(例如 {{getvar::my§var----}}),或重命名/移动您的变量值。
值中的嵌套宏
变量值可以包含嵌套宏:
{{.greeting = Hello, {{user}}!}}
解析为保存的变量 Hello, User! 里面。 (如果 {{user}} 被命名为“用户”)
空白处理
运算符周围允许有空格:
{{ .myvar = spaced value }}
{{ .counter ++ }}
变量速记运算符
以下运算符可与变量简写一起使用。每个操作员都遵循模式 {{.varName operator value}} 或 {{$varName operator value}}.
| 操作员 | 名称 | 示例 | 描述 | ||||
|---|---|---|---|---|---|---|---|
| (无) | 获取 | {{.myvar}} | 返回变量值 | ||||
= | 套装 | {{.myvar = value}} | 将变量设置为一个值,不返回任何内容 | ||||
++ | 增量 | {{.counter++}} | 加 1,返回新值 | ||||
-- | 递减 | {{.counter--}} | 减 1,返回新值 | ||||
+= | 添加 | {{.score += 10}} | 添加到变量(数字或字符串连接),不返回任何内容 | ||||
-= | 减去 | {{.health -= 5}} | 从变量中减去(仅限数字),不返回任何内容 | ||||
| ` | ` | 逻辑或 | `{{.名称 | 来宾}}` | 如果变量为假则返回回退 | ||
?? | 空值合并 | {{.name ?? Guest}} | 仅当变量未定义时返回后备 | ||||
| ` | =` | 逻辑或赋值 | `{{.名称 | = 客人}}` | 如果变量为假则设置值,返回新值 | ||
??= | 空合并赋值 | {{.name ??= Guest}} | 仅当变量未定义时设置值,返回新值 | ||||
== | 等于 | {{.status == active}} | 比较值,返回 "true" 或 "false" | ||||
!= | 不等于 | {{.status != active}} | 比较值,返回 "true" 如果不等于 | ||||
> | 大于 | {{.score > 50}} | 退货 "true" 如果变量大于值 | ||||
>= | 大于或等于 | {{.level >= 10}} | 退货 "true" 如果变量大于或等于值 | ||||
< | 小于 | {{.health < 20}} | 退货 "true" 如果变量小于值 | ||||
<= | 小于或等于 | {{.health <= 0}} | 退货 "true" 如果变量小于或等于值 |
获取变量
使用简单的前缀检索变量值:
{{.myvar}} // Get local variable "myvar"
{{$myvar}} // Get global variable "myvar"
相当于 {{getvar::myvar}} 和 {{getglobalvar::myvar}}.
设置变量
使用 = 运算符设置变量值:
{{ .myvar = Hello World }} // Set local variable
{{ $myvar = Some value }} // Set global variable
相当于 {{setvar::myvar::Hello World}} 和 {{setglobalvar::myvar::Hello World}}。返回一个空字符串。
增量
使用 ++ 将数值变量加 1:
{{.counter++}} // Increment local variable, returns new value
{{$counter++}} // Increment global variable, returns new value
相当于 {{incvar counter}} 和 {{incglobalvar counter}}。返回递增后的新值。
递减
使用 -- 将数值变量减 1:
{{.counter--}} // Decrement local variable, returns new value
{{$counter--}} // Decrement global variable, returns new value
相当于 {{decvar counter}} 和 {{decglobalvar counter}}。返回递减后的新值。
添加
使用 += 向变量添加数值:
{{.score += 10}} // Add 10 to local variable
{{$total += 5}} // Add 5 to global variable
相当于 {{addvar::score::10}} 和 {{addglobalvar::total::5}}。返回一个空字符串。
add 运算符还支持将字符串附加到现有字符串变量(如果它们都不是数字):
{{.myvar += {{noop}} | Second block}} // Resolves to "Content | Second block" when the variable before was "Content".
// Use `{{noop}}` to be able to add whitespaces, that otherwise would be trimmed automatically.
减去
使用 -= 从变量中减去数值:
{{.health -= 10}} // Subtract 10 from local variable
{{$points -= 5}} // Subtract 5 from global variable
相当于 {{addvar::score::10}} 和 {{addglobalvar::total::5}},但带有负数/倒数。返回一个空字符串。
如果该值不是有效数字,则会记录警告并且变量不会更改。
逻辑或
使用 || 当变量为假时提供后备值(空字符串, 0, false):
{{.name || Anonymous}} // Returns "Anonymous" if .name is empty or falsy
{{$setting || default}} // Returns "default" if $setting is falsy
如果为真则返回变量值,否则返回后备值。后备方案是 仅在需要时进行评估 (惰性评估)。
空值合并
使用 ?? 仅当变量不存在时提供后备值:
{{.name ?? Guest}} // Returns "Guest" only if .name is not defined
{{$config ?? default}} // Returns "default" only if $config doesn't exist
不像 ||,这会返回变量值,即使它是假的(空字符串, 0, false) — 只要变量存在。后备方案是 仅在需要时进行评估 (惰性评估)。
逻辑或赋值
使用 ||= 仅当变量当前为假值时才将其设置为值:
{{.name ||= Anonymous}} // Sets and returns "Anonymous" if .name is falsy
{{$count ||= 0}} // Sets and returns "0" if $count is falsy
如果变量已经为真,则返回当前值而不进行修改。返回最终值(现有值或新设置的值)。
空合并赋值
使用 ??= 仅当变量不存在时才将其设置为值:
{{.name ??= Guest}} // Sets and returns "Guest" only if .name is undefined
{{$config ??= default}} // Sets and returns "default" only if $config doesn't exist
不像 ||=,这保留了虚假值(空字符串, 0, false) 如果变量已经存在。返回最终值(现有值或新设置的值)。
等于
使用 == 将变量值与另一个值进行比较:
{{.status == active}} // Returns "true" if .status equals "active", otherwise "false"
{{$mode == dark}} // Returns "true" if $mode equals "dark", otherwise "false"
执行字符串比较并返回文字字符串 "true" 或 "false".
将不存在的变量、空变量和空变量视为相同。
有用于 {{if}} 条件:
{{if {{.status == active}} }}Active mode{{/if}}
不等于
使用 != 将一个变量值与另一个值进行比较以确定是否不相等:
{{.status != inactive}} // Returns "true" if .status is NOT "inactive", otherwise "false"
{{$mode != light}} // Returns "true" if $mode is NOT "light", otherwise "false"
执行字符串比较并返回 "true" 如果值不同, "false" 如果它们相等。
将不存在的变量、空变量和空变量视为相同。
有用于 {{if}} 条件:
{{if {{.status != disabled}} }}Feature enabled{{/if}}
大于
使用 > 检查变量的数值是否大于另一个值:
{{.score > 50}} // Returns "true" if .score is greater than 50
{{$level > 5}} // Returns "true" if $level is greater than 5
执行数字比较并返回文字字符串 "true" 或 "false".
有用于 {{if}} 条件:
{{if {{.score > 100}} }}High score!{{/if}}
大于或等于
使用 >= 检查变量的数值是否大于或等于另一个值:
{{.level >= 10}} // Returns "true" if .level is at least 10
{{$points >= 100}} // Returns "true" if $points is 100 or more
执行数字比较并返回文字字符串 "true" 或 "false".
有用于 {{if}} 条件:
{{if {{$level >= 10}} }}Unlocked advanced features{{/if}}
小于
使用 < 检查变量的数值是否小于另一个值:
{{.health < 20}} // Returns "true" if .health is below 20
{{$timer < 0}} // Returns "true" if $timer is negative
执行数字比较并返回文字字符串 "true" 或 "false".
有用于 {{if}} 条件:
{{if {{.health < 20}} }}Low health warning!{{/if}}
小于或等于
使用 <= 检查变量的数值是否小于或等于另一个值:
{{.health <= 0}} // Returns "true" if .health is 0 or below
{{$attempts <= 3}} // Returns "true" if $attempts is 3 or fewer
执行数字比较并返回文字字符串 "true" 或 "false".
有用于 {{if}} 条件:
{{if {{.health <= 0}} }}Game over{{/if}}
遗留语法
为了向后兼容,仍然支持尖括号标记:
| 遗产 | 等效宏 |
|---|---|
<USER> | {{user}} |
<BOT> | {{char}} |
<CHAR> | {{char}} |
<GROUP> | {{group}} |
<CHARIFNOTGROUP> | {{charIfNotGroup}} |
这些在处理过程中会自动转换为其宏等效项。
注意: 不建议使用旧语法。使用等效的
{{macro}}语法代替新内容。
常用宏(按类别)
使用
/? macros有关可用宏的完整列表及其详细说明。
姓名及参与者
| 宏 | 描述 |
|---|---|
{{user}} | 当前用户/用户人设名称 |
{{char}} | 当前角色名称 |
{{group}} | 以逗号分隔的群组成员姓名列表(包括静音)或单独聊天中的角色姓名 |
{{groupNotMuted}} | 以逗号分隔的群组成员名称列表,不包括静音成员 |
{{charIfNotGroup}} | 角色名称(组内为空) |
{{notChar}} | 除当前发言者外的所有参与者的逗号分隔列表 |
角色卡和用户人设字段
| 宏 | 描述 |
|---|---|
{{description}} | 角色说明 |
{{personality}} | 角色个性 |
{{scenario}} | 角色场景 |
{{persona}} | 用户用户人设描述 |
{{charPrompt}} | 角色的主提示词覆盖 |
{{charInstruction}} | 角色的历史后指令覆盖 |
{{charDepthPrompt}} | 角色的@深度笔记 |
{{charCreatorNotes}} | 角色卡的创作者笔记 |
{{charVersion}} | 角色的版本号 |
{{mesExamples}} | 角色的对话示例,格式为指导模式 |
{{mesExamplesRaw}} | 来自角色卡的未格式化对话示例 |
{{charFirstMessage}} | 角色的第一条消息(问候语)。接受备用问候语的可选索引,例如 {{charFirstMessage::1}} |
{{original}} | 用于替换角色提示词中的原始消息内容覆盖 |
聊天记录和消息
| 宏 | 描述 |
|---|---|
{{lastMessage}} | 聊天中的最后一条消息 |
{{lastMessageId}} | 聊天中最后一条消息的索引 |
{{lastUserMessage}} | 聊天中的最后一条用户消息 |
{{lastCharMessage}} | 聊天中最后一条角色/bot 消息 |
{{firstIncludedMessageId}} | 当前上下文中包含的第一条消息的索引 |
{{firstDisplayedMessageId}} | 聊天中第一条显示消息的索引 |
{{lastSwipeId}} | 最后一条消息的最后一个滑动切换回复从 1 开始的索引 |
{{currentSwipeId}} | 当前滑动切换回复的从 1 开始的索引 |
{{allChatRange}} | 提供整个聊天的范围(例如 0-{{lastMessageId}}),对于接受消息范围的命令很有用 |
{{summary}} | 来自“Summarize”扩展的最新聊天摘要(如果可用) |
时间和日期
| 宏 | 描述 |
|---|---|
{{time}} | 当前当地时间 |
{{time::UTC±(offset)}} | 具有 UTC 偏移量的时间 |
{{date}} | 当前本地日期(短格式) |
{{weekday}} | 本周的当前日期 |
{{isotime}} | HH:mm 格式的当前时间 |
{{isodate}} | 当前日期(YYYY-MM-DD 格式) |
{{datetimeformat::format}} | 自定义格式的日期/时间(例如, YYYY-MM-DD HH:mm:ss) |
{{idleDuration}} | 自上次用户消息以来人类可读的持续时间 |
{{timeDiff::left::right}} | 两个时间之间人类可读的差异 |
变量
| 宏 | 描述 |
|---|---|
{{getvar::name}} | 获取局部变量值 |
{{setvar::name::value}} | 设置局部变量 |
{{addvar::name::value}} | 将值添加到局部变量(数字或字符串追加) |
{{incvar::name}} | 将局部变量加 1 并返回新值 |
{{decvar::name}} | 将局部变量减 1 并返回新值 |
{{hasvar::name}} | 检查局部变量是否存在(返回“true”或“false”) |
{{deletevar::name}} | 删除局部变量 |
{{getglobalvar::name}} | 获取全局变量值 |
{{setglobalvar::name::value}} | 设置全局变量 |
{{addglobalvar::name::value}} | 向全局变量添加值(数值相加或字符串追加) |
{{incglobalvar::name}} | 将全局变量加 1 并返回新值 |
{{decglobalvar::name}} | 将全局变量减 1 并返回新值 |
{{hasglobalvar::name}} | 检查全局变量是否存在(返回“true”或“false”) |
{{deleteglobalvar::name}} | 删除全局变量 |
随机化
| 宏 | 描述 |
|---|---|
{{random::a::b::c}} | 随机选择(每次重新滚动) |
{{pick::a::b::c}} | 稳定的随机选择(同一聊天、同一位置的结果保持一致)。可通过以下命令重新选择: /reroll-pick 命令 |
{{roll::1d20}} | 使用 droll 语法掷骰子 |
运行时状态
| 宏 | 描述 |
|---|---|
{{maxPrompt}} | 最大提示词上下文大小(提示词 token = 上下文 token - 响应 token) |
{{maxContextTokens}} | 当前生成设置的最大上下文数量token |
{{maxResponseTokens}} | 当前生成设置的最大响应数token |
{{model}} | 当前所选 API 的型号名称 |
{{isMobile}} | 如果在移动环境中运行,则为“true”,否则为“false” |
{{lastGenerationType}} | 最后排队的生成请求的类型(例如,“正常”、“模拟”、“重新生成”、“安静”、“滑动切换回复”、“继续”) |
{{hasExtension::name}} | 检查扩展是否处于活动状态(返回“true”或“false”)。按扩展名匹配,不区分大小写 |
提示词模板
| 宏 | 描述 |
|---|---|
{{systemPrompt}} | 活动系统提示词文本(可以选择被角色覆盖) |
{{defaultSystemPrompt}} | 默认系统提示词 |
{{authorsNote}} | 作者注释的内容 |
{{charAuthorsNote}} | 角色作者注释的内容 |
{{defaultAuthorsNote}} | 默认作者注释的内容 |
{{instructStoryStringPrefix}} | 指示故事字符串前缀 |
{{instructStoryStringSuffix}} | 指示故事字符串后缀 |
{{instructUserPrefix}} | 指示输入/用户前缀顺序 |
{{instructUserSuffix}} | 指示输入/用户后缀顺序 |
{{instructAssistantPrefix}} | 指示输出/辅助前缀序列 |
{{instructAssistantSuffix}} | 指示输出/辅助后缀顺序 |
{{instructSeparator}} | 指示分隔符顺序 |
{{instructSystemPrefix}} | 指示系统前缀顺序 |
{{instructSystemSuffix}} | 指示系统后缀顺序 |
{{instructFirstAssistantPrefix}} | 指示第一助手/输出前缀序列 |
{{instructLastAssistantPrefix}} | 指示最后一个助手/输出前缀序列 |
{{instructFirstUserPrefix}} | 指示第一个用户/输入前缀序列 |
{{instructLastUserPrefix}} | 指示最后一个用户/输入前缀序列 |
{{instructStop}} | 指示停止顺序 |
{{instructUserFiller}} | 指导用户对齐填充符 |
{{instructSystemInstructionPrefix}} | 指令系统指令前缀序列 |
{{chatSeparator}} | 文本补全提示词中示例聊天块之间的分隔符 |
{{chatStart}} | 文本完成中的聊天开始标记提示词 |
{{reasoningPrefix}} | 推理块之前使用的前缀字符串 |
{{reasoningSuffix}} | 推理块后使用的后缀字符串 |
{{reasoningSeparator}} | 内容和响应之间的分隔符 |
{{charPrefix}} | 角色的图像生成正向提示词前缀 |
{{charNegativePrefix}} | 角色的图像生成负向提示词前缀 |
实用性
| 宏 | 描述 |
|---|---|
{{newline}} | 插入换行符角色 |
{{newline::count}} | 插入多个换行符 |
{{space}} | 插入空格角色 |
{{space::count}} | 插入多个空格 |
{{noop}} | 不执行任何操作,生成空字符串 |
{{trim}} | 删除周围的换行符 |
{{reverse::text}} | 反转字符串 |
{{input}} | 当前聊天输入字段内容 |
{{banned::word}} | 文本补全后端禁言 |
{{outlet::key}} | 返回指定出口键对应的世界书出口提示词 |