你在酒馆里看到的每一条回复,背后都是一段被拼装好的长文本。 角色卡、世界书、作者注释、聊天历史被按固定顺序组合,再一次性发给模型。 搞不清这个顺序,就没法解释「为什么我明明写了它却不照做」。
提示词的拼装顺序是什么
不同后端类型(文本补全 / 聊天补全)细节有别,但骨架一致,从前到后大致是:
- 系统提示:来自预设,或被角色卡的
system_prompt覆盖 - 角色定义:
description、personality、scenario - 对话示例:
mes_example,预算紧张时会被优先裁掉 - 聊天历史:从旧到新,越旧越先被裁
- 作者注释:默认插在倒数第 4 条消息的位置,深度可改
- 历史后指令:
post_history_instructions,位置最靠后
世界书不是独立的一层,它按每个条目自己的 position
插进上面的相应位置,详见世界书那一篇。
为什么位置比措辞更重要
模型对靠近末尾的内容更敏感。同一句指令,写在角色卡开头和写在
post_history_instructions 里,服从程度可以差很远。
这解释了几件事。写在 description 里的行为约束,聊了几十轮之后往往就淡了,
因为它离末尾越来越远,中间隔着大量对话。而作者注释之所以有效,正是因为它被硬插在
倒数第 4 条的位置(默认值 DEFAULT_DEPTH = 4,见
public/scripts/authors-note.js),
无论聊多久都紧贴着当前对话。
同理,post_history_instructions 被放在历史之后,是整段提示词里最靠后的
位置之一。中文社区所说的「破限位」通常指的就是这里。它的效力来自位置,不是来自
写了什么魔法句式。
注入深度与角色
酒馆的扩展注入用 extension_prompt_types 区分注入方式:NONE
为 -1、IN_PROMPT 为 0、IN_CHAT
为 1、BEFORE_PROMPT 为 2。深度上限
MAX_INJECTION_DEPTH 是 10000,实际用不到这么深:深度
一旦超过现有消息数就会被夹到上限,等同于插在最前面。这几个常量都在
public/script.js。
上下文不够时先丢什么
顺序大致是:对话示例最先被丢,然后是最旧的聊天记录。角色定义和靠后的指令通常保留 到最后。
所以当你发现模型「忘了前面说过的事」,多半不是它记性差,而是那部分内容已经被裁出了 提示词。此时加大上下文长度、精简角色卡、把长设定挪进世界书,都比反复叮嘱有效。
在手机上跑端侧模型时这一点尤其明显:端侧模型的上下文窗口通常远小于云端模型,可裁的 余地更少。写卡时把篇幅控制住,比事后调参更管用。