SillyTavern 角色卡怎么写:V1 到 V3 字段逐个拆,附可抄模板
上一篇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> 分隔 | 只写一轮,模型学不到节奏 |
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_date | Unix 秒级时间戳 | 不可由用户改;0 表示未知 |
世界书部分在 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。俱乐部那边的拼车方案可以覆盖常见的几家,具体按你的用量挑就行,不必为了试水直接开全套订阅。
下一篇打算拆世界书的完整机制(扫描深度、递归、预算优先级怎么协同),如果你正在写卡,那篇会比这篇更实用。


