跳到正文
ChatGPT Pro 俱乐部
博客

SillyTavern 角色卡怎么写:V1 到 V3 字段逐个拆,附可抄模板

11 阅读约 11 分钟读完

上一篇SillyTavern 酒馆入门把「酒馆是什么」讲完了,但真正劝退新人的是下一步:SillyTavern 角色卡到底该往哪几个字段里填什么。站内搜了一圈没人讲这个,这篇就专门拆字段。

我不复述二手教程,而是直接把三份格式规范(V1、V2、V3)和 SillyTavern 的解析源码放在一起对照。看完你应该能做到两件事:看懂别人卡里的每个字段在起什么作用,以及照着模板写出自己的第一张卡。

一句话结论:SillyTavern 角色卡就是一段 JSON,被塞进 PNG 的文本块里

  • 格式分三代:V1 是六个字段的扁平结构,V2 在外面包了 spec / data 一层,V3 再加素材、昵称、多语言备注。
  • 装进 PNG 的方式:PNG 有个 tEXt 文本块,关键字 chara 存 V2 数据、ccv3 存 V3 数据,值都是 base64 编码的 JSON。所以你能”换头像”却不丢设定。
  • 最容易写错的两处:description 写成了说明书(它其实是给模型的提示词),以及 system_prompt / post_history_instructions 不知道会覆盖你自己设的系统提示词。

1)一张 PNG 里到底藏了什么

这是新人最困惑的一点:为什么角色卡是图片,拖进去却能读出一整份设定?答案在 PNG 文件格式本身。PNG 由一个个「块」组成,其中 tEXt 块专门放文本,格式是「关键字 + 值」。

SillyTavern 的做法是:把整份角色 JSON 用 UTF-8 转成字节,再做 base64 编码,塞进关键字为 chara 的 tEXt 块。图像像素和这段文字互不干扰,所以卡片头像可以是任意一张画,设定照样跟着走。

V3 出来之后多了一个关键字 ccv3。我直接看了 SillyTavern 的 src/character-card-parser.js,写和读的逻辑很明确:

  • 写:先写入 chara(V2 内容),再把同一份数据改成 chara_card_v3 / 3.0 写进 ccv3。
  • 读:先找 ccv3,找到就用它;没有才回退到 chara。V3 优先。
  • 覆盖写:两种块都会先被删掉再加新的,避免一张卡里残留两代数据互相打架。

源码注释里还有一句值得注意的话:「Writes only ‘chara’, ‘ccv3’ is not supported and removed not to create a mismatch.」 这说明实际实现有过一致性方面的取舍。你只要记住结论就行——现在导出的卡通常是双块并存,读的时候以 V3 为准。

2)V1:最早那六个字段

V1 是扁平结构,六个字段全是字符串,缺省为空串:name、description、personality、scenario、first_mes、mes_example。语义上:

字段填什么常见误区
name角色名写成一长串头衔,模型会在回复里照抄
description外貌、性格、背景、行为习惯写成给人看的介绍文,而不是给模型的指令
personality性格关键词的浓缩和 description 重复堆同一套词
scenario当前所处情境、你和它的关系写成整个世界观,把设定全塞进来
first_mes角色说的第一句话写成旁白,缺少台词和动作
mes_example示范对话,用 <START> 分隔只写一轮,模型学不到节奏
字段名与必填性依据 character-card-spec-v2 仓库对 V1 的说明。

V1 最大的问题是没有命名空间。别的工具想加自己的字段,只能往顶层塞,老编辑器读到不认识的就可能直接丢掉,一存一读设定就没了。这就是 V2 要包一层的原因。

3)V2:多包一层 data,换来了什么

V2 在外面加了 spec(固定为 "chara_card_v2")和 spec_version("2.0"),真正的字段全部挪进 data。规范里写得很直白:这样做的目的是让旧版编辑器无法静默加载一张 V2 卡并删掉它的新字段。

除了原有六个字段,data 里新增了这些:

  • creator_notes:给用户看的说明,不会进入提示词。
  • system_prompt:默认会替换你自己设的全局系统提示词,留空则回退。
  • post_history_instructions:默认会覆盖前端的「越狱 / 后历史指令」位置,同样留空回退。
  • alternate_greetings:字符串数组,多个开场白供切换。
  • character_book:可选,内嵌的一本世界书。
  • tags:只用于分类和筛选,不参与提示词。
  • creator、character_version、extensions:署名、版本、扩展数据。规范要求未知的 extensions 字段必须原样保留。

这里有个很多人没意识到的坑:system_prompt 的默认行为是「替换」而不是「追加」。你装的那套精心调过的全局预设,可能被作者写死在卡里的一句话直接顶掉。拿到一张卡觉得”怎么突然变笨了”,先去看这两个字段。

4)内嵌世界书:character_book 怎么填

这是角色卡里最有价值、也最少人讲清楚的部分。当角色的设定量超过几百字,全塞进 description 会白白消耗每一轮的 token。正确做法是把设定拆成世界书条目,只在关键词出现时才注入。

character_book 的书级字段有:name、description、scan_depth、token_budget、recursive_scanning、extensions、entries。条目级字段有 keys、content、extensions、enabled、insertion_order,此外还有一批可选项:case_sensitive、name、priority、id、comment、selective、secondary_keys、constant、position。

这几个字段的实际含义,官方世界书文档讲得很清楚:

  • 只有 content 会进提示词,标题、备注、关键词本身不占上下文。
  • scan_depth 控制往回翻几条聊天找关键词。0 表示只看递归和作者注释,1 只看最新一条。
  • token_budget 是硬上限,预算用完就不再激活任何条目,哪怕关键词命中了也进不去。
  • insertion_order 是加入顺序,数字越大越靠后。而且常驻条目(constant)会最先参与预算分配,用多了每轮都白烧 token。
  • recursive_scanning 允许一条条目的内容点名触发另一条,用来做多层展开,但层数要限,否则会和预算打架。

V2 规范里还特别提到:character_book 应该和全局世界书叠加使用,不是替代。所以你的通用设定书不用为了写给某张卡就搬家。

5)V3 又加了什么

V3 的 spec 是 "chara_card_v3",spec_version 是 "3.0"。在 V2 基础上主要加这几项:

新字段作用注意点
assets素材数组,每项含 type、uri、name、ext内嵌路径拼写是 embeded://,规范明确说不是 embedded://
nickname替代 {{char}}、<char>、<bot> 在提示词里的显示名只影响提示词,不改角色列表里的名字
creator_notes_multilingual多语言备注,键是 ISO 639-1 语言码没有 en 时回退到 creator_notes
source来源数组,字符串数组规范要求用户不可编辑,应用只能追加
group_only_greetings只用于群聊的额外开场白必须存在,可以是空数组
creation_date / modification_dateUnix 秒级时间戳不可由用户改;0 表示未知
依据 character-card-spec-v3 仓库的 SPEC_V3.md。

世界书部分在 V3 里也收紧了:新增必填条目字段 use_regex,constant 从”可选”变成”必须实现”,position 明确限定为 before_char 或 after_char 两个值。

还有一个容易忽略的点:assets 缺失时,应用应当视为只有一张名为 ccdefault: 的 icon 素材。所以老卡没有 assets 也不会出错,只是没有额外素材。

6)照着抄:一份 V3 模板

下面这份是结构模板,字段名全部对照规范写,内容留给你自己填。注意 mes_example 用 <START> 分轮,{{user}} 和 {{char}} 是占位符,会被自动替换成实际名字。

{
  "spec": "chara_card_v3",
  "spec_version": "3.0",
  "data": {
    "name": "角色名",
    "nickname": "你在提示词里希望它显示的名字",
    "description": "外貌、性格、说话习惯、身体特征。写行为,不要写评价。",
    "personality": "三到五个性格关键词,用逗号分隔",
    "scenario": "当前情境与你和它的关系,控制在两三百字内",
    "first_mes": "第一句台词,带动作描写",
    "mes_example": "<START>\n{{user}}: 你来啦。\n{{char}}: (把手里的杯子放下)来啦,坐。\n<START>\n{{user}}: 今天不太想说话。\n{{char}}: 那就不说,我陪你坐一会儿。",
    "alternate_greetings": ["另一种开场白", "第三种开场白"],
    "system_prompt": "留空则沿用你自己的全局预设",
    "post_history_instructions": "留空则沿用你自己的越狱设置",
    "creator_notes": "给用户看的说明,不会进提示词",
    "creator": "你的名字",
    "character_version": "1.0",
    "tags": ["标签只用于筛选"],
    "character_book": {
      "name": "内嵌世界书",
      "scan_depth": 4,
      "token_budget": 500,
      "recursive_scanning": false,
      "entries": [
        {
          "keys": ["回廊", "地下"],
          "content": "只有关键词出现时才会插入的设定段落。",
          "use_regex": false,
          "enabled": true,
          "insertion_order": 100,
          "position": "before_char",
          "constant": false
        }
      ]
    },
    "extensions": {}
  }
}

两点提醒:system_prompt 和 post_history_instructions 这两个位置故意留空,让别人用这张卡时自己的预设仍然生效。除非你确实要强制接管,否则别填。

7)在酒馆编辑器里,这些字段对应哪里

不用手写 JSON 也行。SillyTavern 的角色编辑器按官方文档的顺序是:名字是唯一必填字段,然后是描述、性格、情境、第一条消息与额外开场白、示例对话(用 <START>、{{char}}、{{user}})、角色备注(带插入深度和角色位置)、话痨程度。

「高级定义」里折叠着的才是提示词覆盖项和创作者信息:创建者、角色版本、创作者备注、要嵌入的标签。官方文档明确写了创作者备注不参与提示词构建,只出现在角色列表和角色页上。

顺带一个格式细节:creator_notes 在 V2 里是纯字符串,V3 里主字段仍是字符串,多语言版本走 creator_notes_multilingual。所以别在 creator_notes 里塞 JSON,会显示成一坨。

8)五个实际会踩的坑

  • 把 description 写成介绍文。「她是一位温柔善良的少女」对模型没用。写「说话时会先停顿一下再回答」「从不说脏话」这种可执行的行为约束。
  • 卡里写死 system_prompt。别人用你的卡,自己的预设全失效,体验断崖。留空是最稳的默认值。
  • 常驻条目开太多。constant 条目每轮必进、还优先吃预算,几条就能把 token_budget 吃光,后面命中的条目反而插不进去。
  • token_budget 设太紧。预算耗尽后关键词命中也不生效,表现就是”设定突然失忆”。先给宽一点,压测后再收紧。
  • 手改 PNG 后直接重命名成 .json。PNG 里的 base64 块和 JSON 是两种东西。要导出 JSON,用编辑器里的导出功能,别指望改后缀。

小结:字段是壳,写卡是写提示词

拆完三份规范你会发现,格式本身没什么难的——真正决定一张卡好不好用的,是 description 和 mes_example 这两处写得好不好。前者是长期生效的行为约束,后者是模型模仿的节奏样本。格式保证你的设定不会丢,内容决定模型像不像。

至于模型,酒馆本身不提供——这是上一篇的重点,这里不重复。想让角色稳定跑起来,最后还是要接一个够稳的 API。俱乐部那边的拼车方案可以覆盖常见的几家,具体按你的用量挑就行,不必为了试水直接开全套订阅。

下一篇打算拆世界书的完整机制(扫描深度、递归、预算优先级怎么协同),如果你正在写卡,那篇会比这篇更实用。

参考来源

发表评论

邮箱不会公开,带 * 的是必填项。