Skip to content

6. 进阶:变量、变量模式、消息规则与表达式

本节为进阶内容,可能较难

前置知识(理解消息规则需要掌握):正则表达式

首先,什么是变量?
变量可以看作一个占位符,可以存在于各种提示词中、消息规则的替换部分,在具体运行时会将这个占位符替换为变量的值。

什么是表达式?
表达式包括条件判断和条件触发两种,分别用于 “检测某个条件是否满足,满足时替换为A,不满足时替换为B”(判断) 和 “当某个条件变成被满足时,替换为A”(触发) 两种情况。

什么是消息规则?
消息规则就是按照一定的规则(正则表达式)将消息原文在展示之前进行查找和替换的工具。

注意:用 {{}} 包围的是变量/表达式,因此正常提示词请不要包含这种大括号模式。

1. 提示词

1.1. 提示词中的变量

在旧版中,大家可能就用过 {{User}} 这样的变量,用来代表当前身份的名称。

例如,你的当前使用身份名称是 透明酱,那么提示词里(摘自丰川祥子(同桌的你)

便利店的白炽灯光从玻璃门里渗出来,把她的影子拉得很长。她看了一眼手机,{{user}}的消息就亮在锁屏上。

就会被替换为:

便利店的白炽灯光从玻璃门里渗出来,把她的影子拉得很长。她看了一眼手机,透明酱的消息就亮在锁屏上。

那对于新版,变量包括:

变量含义
{{User}}当前身份名称
{{Target}}当前对话目标;私聊里是用户身份名称,群聊里是其它所有成员名称
{{DateTime}}当前日期时间
{{Language}}当前语言
{{HasLongTermMemory}}当前会话是否已有长期记忆
{{HasKnowledge}}是否有知识库
{{KnowledgeBaseCount}}知识库数量
{{KnowledgeEntryTitles}}知识库标题列表
自定义变量 {{...}}你自己在变量模式中定义的变量

这些变量可用于:人格提示词群聊提示词群聊 System AI 提示词

但注意,群聊 System AI 提示词 不支持 {{HasKnowledge}}, {{KnowledgeBaseCount}}, {{KnowledgeEntryTitles}} 这三个变量,因此具体运行时会认为 {{HasKnowledge}} = false, {{KnowledgeBaseCount}} = 0, {{KnowledgeEntryTitles}} = (空)

1.2. 提示词中的表达式

有了变量,我们就能实现一些更加高级的功能。

例子

举个栗子,以软件自带的人格 透明酱(软件助手) 为例:

{{if HasKnowledge}}
注意:询问软件相关问题时,请 **必须先调用search_knowledge工具** 再回答问题!

知识库中含有的条目有:
{{KnowledgeEntryTitles}}
{{else}}
注意:你现在无法调用工具查询文档,在用户询问软件相关问题时,请告诉用户将“软件内置帮助”这个知识库挂载给你,这样你才能根据帮助文档回答用户的问题!
{{end}}

这一段提示词表示,当透明酱挂载了知识库时,这段提示词会变成:

注意:询问软件相关问题时,请 **必须先调用search_knowledge工具** 再回答问题!

知识库中含有的条目有:
- 条目 A
- 条目 B
- ...(省略)

而如果你将知识库从人格设置里删除后,提示词会变成:

注意:你现在无法调用工具查询文档,在用户询问软件相关问题时,请告诉用户将“软件内置帮助”这个知识库挂载给你,这样你才能根据帮助文档回答用户的问题!

这样我们就通过 条件判断 语句,实现了动态的提示词。

语法

那上面是什么原理呢,需要注意 {{if ...}}/{{elseif ...}}/{{else}}/{{end}} 这些并不是变量而是条件表达式

一个条件表达式必须以 {{if ...}} 开头,以 {{end}} 结尾,中间可以加入 {{elseif ...}}/{{else}} 表示更复杂的条件关系。

表达式里支持的运算符包括:

运算符含义
!取反
&&逻辑与
||逻辑或
==等于
!=不等于
>大于
>=大于等于
<小于
<=小于等于
()括号
含义
true布尔值:真
false布尔值:假
null

例如:{{if affection==100}}当前好感度为100{{elseif affection>=50}}当前好感度大于等于50{{else}}当前好感度小于50{{end}} 实现了在不同好感度(affection)显示不同提示词。

并且表达式也支持嵌套,例如 {{if phase==1}}当前为阶段1{{else}}{{if affection==100}}当前为阶段2,好感度为100{{elseif affection>=50}}当前为阶段2,好感度大于等于50{{else}}当前为阶段2,好感度小于50{{end}}{{end}} 这样好感度只会在阶段2出现。

2. 消息规则

在上面的例子中,都是直接动态改变提示词,但这其实是很不推荐的,因为第一,如果将好感度、阶段这些变量是随聊天发展动态改变的,放到会话历史中显得更合理,也方便LLM了解不同历史位置的具体值;
第二,如果每次提示词都改变的话将无法利用LLM的缓存(尤其是在提示词中加入当前时间这类永远变化的变量),换句话说每次都必须重新计算一遍前面的文本才能开始生成,并且缓存输入价格通常是无缓存输入的 1/10,改变提示词也会导致价格上升。

因此我们可以通过消息规则来改写原始消息,由此可以实现非常自由灵活的功能。

2.1. 消息来源和目标通道

消息来源(发送者)即指定这条规则会对哪个通道的消息进行处理:

  • 用户消息:自己发送的消息
  • 角色消息:AI角色发送的消息
  • system 消息:群聊 system AI 发送的消息

消息通道(查看者)指这条消息在给谁看的时候用这条规则处理,可以让一条消息在不同地方里看起来不一样:

  • 用户通道:给用户看的时候(即在界面上显示)
  • 角色通道:给AI角色看的时候(即发送给LLM的文本)
  • system 通道:给system AI看的时候(即发送给system AI的文本)
  • 语音通道:执行语音生成时的文本(例如可以用于去除内心独白、去除特殊符号、将发音错误的词用其它词替换等)

2.2. 消息规则中的变量

变量含义
{{MessageDateTime}}这条消息的日期时间
{{MessageDate}}这条消息的日期
{{MessageTime}}这条消息的时分秒
{{SenderName}}这条消息的发送者名称
{{ReaderName}}当前读取这条消息的对象的名称
{{Random}}范围在 0~1 的伪随机值
{{Match0}}/$0正则整段命中
{{Match1}}/$1第 1 个捕获组
{{Match2}}/$2第 2 个捕获组
自定义变量 {{...}}这条消息创建时的该群聊变量值

{{Match?}}/$? 的区别:
{{Match?}} 相当于一个变量,可以用在 {{if SenderName==Match1}} 等等这类地方,或者直接写 {{Match1}} 就相当于 $1;而 $? 是正则的替换语法,可以直接被替换为捕获的内容。

2.3. 消息规则:调试

在消息中可以对消息右键/左滑弹出菜单,点击 调试,即可查看这条消息在不同通道、不同读者眼中的文本

3. 例子

可能有些概念不是很好理解,那我们来举一些具体实用的例子:

  1. 在每条消息前加入发送时的现实时间,让AI能掌握现实时间

^ -> [{{MessageDateTime}}]

通道选择:角色通道

解析:^ 代表消息的起始位置,相当于在消息起始处增加 [2026-04-20 19:46] 这样表示时间的文本

  1. 限制括号内思考只有发送者本身能看见(通常可用于猜疑推理之类的群聊):

([^)]*) -> {{if SenderName==ReaderName}}$0{{end}}

消息来源:角色消息
通道选择:角色通道

解析:[^)]代表除了中文右括号以外的所有字符,*代表零个或多个,整体合起来就匹配中文括号以及内部的所有内容。
替换表达式限制了只有 发送者(SenderName) 等于(==) 查看者(ReaderName) 时,才显示这部分内容($0相当于我们匹配到的所有内容,替换回去相当于不变);对于其它角色而言由于条件不匹配这部分就会直接变成空字符串,相当于不可见。

  1. 增加自定义指令

/save([\s\S]*)$ ->

 $1

system: 现在请直接输出当前会话的所有内容的完整详细总结

消息来源:用户消息
通道选择:角色通道

解析:([\s\S]*)代表匹配并捕获/save到消息结尾($)的所有任意字符,$1代表这个小括号捕获的内容,替换后相当于再原有消息的末尾增加了一条 system 消息要求执行总结。

  1. 将模型输出的括号消息转换为斜体

(?<!\*)((.*?))(?!\*) ->  *$1* 

消息来源:角色消息
通道选择:用户通道角色通道(可选,选择角色通道将在下次请求中将斜体内容也返回给模型,可以使模型学会将括号内容变为斜体)

解析:(?<!\*)代表前面不存在*(?!\*)代表后面不存在*((.*?)) 代表匹配并捕获中间的中文括号及其内部内容, *$1* 代表将捕获的内容加上*包围(变为斜体),并再用空格包围(避免斜体失效)

  1. 将列表转换为对话选项

- (.+) -> - [$1](rengeguan://chat/send?text=$1)

消息来源:角色消息
通道选择:用户通道

并且在提示词中加入(不一定最好,可以自行优化):

【选项】
在每次输出最后**必须**额外增加一条选项消息,根据当前剧情发展给{{User}}接下来的动作语言等提供1~4个选项,人称必须使用{{User}}的角度(在选项部分中,用“我”代指{{User}},用“你”代指你的身份),可使用中文括号表动作,格式如下:
- 选项内容1
- 选项内容2

解析:[$1](rengeguan://chat/send?text=$1) 是一种特殊的链接,在会话/嘎啦给木模式中会变成选项形式,点击后将直接发送对应消息

  1. 变量设置

【好感度上升】 -> $0{{set affection=affection+5}}
【好感度下降】 -> $0{{set affection=affection-5}}

或者更复杂:【好感度上升】 -> $0{{if affection>=80}}{{set affection=affection+5}}{{else}}{{set affection=affection+10}}{{end}}(代表当好感度大于等于80时每次好感增加5,否则每次增加10)

或者加入随机数:【好感度上升】 -> $0{{set affection=affection+5*Random+5}}(代表随机增加好感度 5~10)

或者根据模型设置的值:【好感度:(\d+)】 -> $0{{set affection=Match1}}(指当遇到【好感度:10】时设置当前好感度为10)
【好感度:\+(\d+)】 -> $0{{set affection=affection+Match1}}(指当遇到【好感度:+5】这样的内容时将当前好感度增加5)
【好感度:-(\d+)】 -> $0{{set affection=affection-Match1}}(指当遇到【好感度:-5】这样的内容时将当前好感度减5)

消息来源:角色消息
通道选择:用户通道

解析:是否包含$0取决于你是否希望这个设置好感度的文本显示出来给用户查看。

  1. 在每次发送消息后方显示好感度

$ ->



*当前好感度:{{affection}}*

消息来源:用户消息
通道选择:用户通道, 角色通道(取决于是否在UI上展示,和是否每轮发送给AI提醒当前的好感度)

解析:选择 角色通道 相当于在每次会话后插入一段提示词给AI提示当前状态的好感度,选择 用户通道 代表每次用户发送消息后会在后面以斜体显示当前好感度

  1. 随机事件

$ ->

{{if phase==2}}

{{if Random<0.3}}(触发事件1的提示词){{else}}(触发事件2的提示词){{end}}{{end}}

消息来源:用户消息
通道选择:角色通道(取决于是否在UI上展示,和是否每轮发送给AI提醒当前的好感度)

解析:代表如果当前阶段(phase)等于2时,有30%概率触发事件A,70%概率触发事件B,而触发事件相当于插入一段提示词

注意:为了保持稳定,同一条消息中 Random 变量的值是相同且稳定的;它基于这条消息自己的 ID 计算,因此发送当下与之后重新读取历史时会保持一致。若需要整数随机,可用 {{expr RandomInt(1, 6)}}{{set dice=RandomInt(1, 6)}}

  1. 好感度事件

需要至少两个消息规则,以及 affection(好感度,数值类型), affection_event(好感度事件1,布尔类型,默认为false)

  • $ -> {{if affection>=80}}{{set affection_event=true}}{{end}} 消息来源:角色消息
    通道选择:用户通道
  • $ -> {{when affection_event==true}}\n\nsystem: 这里写一些好感度达到80时触发的提示词,例如特殊剧情特殊路线等等{{end}} 消息来源:用户消息
    通道选择:角色通道

解析:第一条规则是在好感度达到80时将好感度事件设置为true 第二条规则是在触发好感度事件时,在用户消息下方注入特殊的提示词,以触发对应事件 而when是条件触发语句,只有在affection_event变化时才会触发,后续即使好感度始终超过80affection_event也会一直为true,这条提示词也只会触发一次。

  1. 语音处理

消息来源:角色通道
通道选择:语音通道

  • 去除特殊符号:[^a-zA-Z0-9\u4e00-\u9fff\u3000-\u303f\uff00-\uffef\s.,!?;:'"()\-/@] -> (空)
  • 去除括号的独白内容:[((].*?[))] -> (空)
  • 去除斜体独白内容:\*.*?\* -> (空)
  • 纠正一些特殊的词语的读音:例如(设置不区分大小写) MyGO -> my goTomorin -> 偷摸零 等等