算起来,我接触 SillyTavern 角色卡也有大半年了。从最开始只会下载别人的卡,到现在自己动手还原各种喜欢的虚构角色,中间踩过的坑是真不少。经常有人问我,说看到别人做的角色卡特别生动,人物性格拿捏得死死的,但自己照着网上的教程做出来却总是“四不像”——要么说话像AI客服,要么设定说忘就忘,要么从一个高冷角色秒变话痨。问题出在哪?多半不是模型不行,而是角色卡本身没写好。
这篇文章我就把自己做角色的完整思路和技术细节翻出来,以大家都很熟悉的动画电影里的宫水三叶为例,从零开始做一张能用的角色卡,最后附上可直接复制的完整 JSON。不管你是想还原动漫人物、小说主角,还是虚构一个原创角色,这套方法基本通用。文章会比较长,涉及 JSON 字段解释、提示词编写技巧、示例对话写法、参数调优和常见报错排查,建议先收藏再慢慢看。
1. 先把底层逻辑搞清楚:角色卡到底是怎么“骗”过AI的
很多人第一次打开 SillyTavern 的角色卡 JSON,会愣住——一堆花括号、方括号、英文键名,中间还夹着大段大段像小说一样的文字。它本质上就是一个结构化的“人设说明书”,告诉底下的语言模型:你现在不是AI,你是某个角色,你有这样的背景、这样的性格、这样的说话方式。
1.1 为什么角色卡必须用 JSON 格式
SillyTavern 的角色卡采用 JSON 格式存储,这其实是社区里大家共同选定的一条路。SillyTavern 是前端界面,它不负责“思考”,真正在背后干活的是 OpenAI、Claude、本地部署的 llama.cpp 或 KoboldCpp 这类模型服务。前端和模型之间需要一种稳定、无歧义的交流格式,JSON 恰好满足:键值对结构清晰,嵌套自由,而且几乎所有编程语言和模型 API 都能原生解析。
我自己最早犯过的错误,是觉得 JSON 太啰嗦,直接在角色描述里写了一堆自然语言,字段名随意发挥。结果一载入,SillyTavern 提示解析失败,或者模型读着读着就“人格分裂”。后来才明白,JSON 里的每一个字段都有它的固定用途,SillyTavern 会按约定把不同字段的内容放到提示词的不同位置,位置不同,模型对信息的重视程度就完全不同。
1.2 模型是怎么“看到”你的角色卡的
简单说,当你打开一个聊天,SillyTavern 会把角色卡里的关键字段和你当前的聊天历史一起拼成一段“提示词”,再发给模型。模型本质上是在做大段的文字接龙,它并不知道自己是谁,它只是在根据这段提示词里最可能出现的下一句话。
这里有个关键点:角色卡里的信息,越靠前、越独立成段,模型遵守得越牢。比如personality(性格)、scenario(场景)、description(背景描述)这些字段会出现在系统层级;而first_mes(第一条消息)会作为聊天历史的开头出现。如果某个设定只埋在示例对话里,模型可能会当成“角色偶尔说过的一句话”,而不是角色的一贯准则。
所以做角色卡的本质,就是设计一套“信息排布方案”:把最核心的人设放到最显眼的位置,把说话风格用示例对话固化下来,再把容易冲突的细节统一成一套逻辑自洽的文本。后面我会一步步演示。
2. 动手前先盘一盘:做一张角色卡需要准备什么
做角色卡之前,我先说明一下工具链:SillyTavern 本身是前端,你还需要一个后端模型服务。你手里的选择无非两种——调用云端 API,或者本地跑模型。云端的好处是省事、效果稳定;本地部署的好处是免费、私密、可折腾,但对显卡要求高。我自己两种都试过,下面把踩过的坑一并说清楚。
2.1 推荐的后端配置与模型选择
如果走云端 API,现在主流的选择仍然是 OpenAI 系的 GPT-4o/GPT-4o-mini、Anthropic 的 Claude 系列。做角色扮演类的对话,我个人的经验是:GPT-4o 的跟随性很强,写出来的回答经常比你人设卡里预期的还要生动;Claude 系列更稳,不容易跑偏,但偶尔会显得“文绉绉”,不太适合特别口语化的角色。
如果你没有可用的云端 API,或者跟我一样喜欢折腾,可以试试本地部署。目前最省事的组合是 Ollama + 一个通用模型,或者直接用带 WebUI 的 text-generation-webui / KoboldCpp。本地跑一个 7B 甚至 13B 的模型,只要量化得当,照猫画虎还原一个动漫角色完全做得到。需要注意,本地模型的中文能力和指令跟随能力参差不齐,建议优先选在中文语料上微调过的模型,比如社区里常见的 Qwen 系列,效果会稳很多。
2.2 制作角色卡常用的辅助工具
- JSON 编辑器/校验工具:写角色卡的人离不开 JSON,我一般直接在 SillyTavern 自带的编辑界面写,但遇到头疼的语法问题还是会丢到 JSON 格式化工具里看一眼结构。
- 一个“提炼人设”的 AI 帮手:你喜欢的角色往往有很多背景信息,直接全塞给 SillyTavern 会让它抓不住重点。这时候可以先拿另外一个 AI,把角色的性格特质提炼成条目。注意只是提炼,不是让它直接生成角色卡。
- 智能快捷键(Slash Commands):SillyTavern 里其实内置了不少辅助功能。特别是
/describe这个斜杠命令,它可以把一段角色外貌描写自动扩展成更完整的描述,适合拿来润色。
2.3 制作流程总览
我习惯把流程分成三步:构图(确定角色核心)、编码(写 JSON 字段)、测试(多轮对话校验)。很多新手一上来就打开 JSON 编辑器写 description,写到一半发现前后矛盾,再回去改就非常痛苦。所以建议按顺序来:
- 先收集角色的原始资料(台词、名场面、性格分析)。
- 提炼出“核心性格标签”“说话习惯”“背景故事要点”“人际关系”四类信息。
- 把这四类信息分别填到 JSON 的不同字段里。
- 编译并加载,反复测试,找出 AI 表现与预期不符的地方,一条条修正。
- 迭代。
3. 核心字段逐个拆解:读懂 SillyTavern 角色卡的 JSON 结构
这一节是全文的干货核心。SillyTavern 的角色卡 JSON 不同版本字段略有差异,但核心字段基本稳定。我以最常见的格式为例,逐个说明每个字段的作用、写法要点和常见误区。
提示:不要小看字段的作用。字段名写错,SillyTavern 可能直接忽略;内容放错位置,模型的表现也会天差地别。
3.1 基础字段:name、description、personality
{ "spec": "chara_card_v2", "spec_version": "2.0", "data": { "name": "宫水三叶", "description": "宫水三叶,19岁,是糸守町当地神社宫水家的长女。", "personality": "温柔、率直、有责任心、偶尔顽固" } }name:角色名,必须简洁,模型会把这个名字当作用户对角色称呼的关键映射。不要写太长,也不要加各种奇怪符号。description:背景介绍,是模型理解角色最核心的文本来源。它会被放在提示词的靠前位置,相当于“系统里对你是谁的描述”。可以写外貌、身份、当前状态、经历,但不要写成论文,要像在给演员写人物小传。personality:性格标签,SillyTavern 2.0 规范里这个字段通常是字符串,模型会根据这个标签来塑造语气和态度。别小看这个词,它比 description 更强调“当下行为方式”。
3.2 场景与开场:scenario、first_mes、mes_example
{ "scenario": "两人在某个傍晚于东京的街道上偶然相遇", "first_mes": "*你正站在东京某个车站出口,晚风带着城市特有的喧嚣。身旁突然传来一个熟悉的、略带犹豫的声音*……", "mes_example": "<START>\n{{user}}: 你好像有心事?\n{{char}}: 唔……也不算吧。只是觉得自己该做点什么,却又不知道从哪里开始。" }scenario:当前场景。它会作为环境设定长期存在于提示词中,让模型在后续回复里不自觉地带入环境信息。写 scenario 时应该交代时间、地点、氛围,而不是写剧情走向。first_mes:角色对用户说的第一句话。这是你给模型“演示”角色说话方式的最好机会。重要:第一句话的质量直接决定后续对话的走向,很多 AI 会强烈模仿第一人称的风格。mes_example:示例对话。这里是教模型“你和用户平时是怎么聊天的”。示例里的{{user}}代表用户输入的位置,{{char}}代表角色回复的位置。你写的例子越贴近角色真实说话风格,模型越容易跟着学。
3.3 进阶字段:char_greeting、world、creator_notes、system_prompt、post_history_instructions等
除了上面几个基础字段,SillyTavern 在卡片的“高级”设置里还有一批可选字段。新手可以先不管,但想把角色做“活”,这些字段往往才是分水岭。
char_greeting:如果角色卡版本较新,这个字段可能替代first_mes。作用是提供开场信息。system_prompt:这里可以写模型的全局行为规范。比如“你永远只以宫水三叶的身份进行回复,不提及自己是 AI,不对不存在的未来时间线作任何假设”。这个字段优先级很高。post_history_instructions:聊了很多轮之后,模型容易忘掉自己是谁。这个字段会在每轮对话结束后再次注入指令,适合写“无论如何,你的身份都不会改变,你会一直以宫水三叶的身份继续聊天”。world:在过去某些版本里用于附加世界观描述,现在更多被单独的 Lorebook(世界书)替代,但卡片里仍可保留。
3.4 自定义字段和正则表达式:给你的角色卡加“外挂”
做进阶角色卡时,我喜欢在data里加一些自定义键值对,再用 SillyTavern 的“人物-角色卡-自定义字段”功能展示成小面板。这些字段不会直接进提示词,但能帮我自己整理卡片的设定。不过如果你要分享卡片给别人,字段本身不会自动生效,别人得装对应的扩展脚本才行,这就不展开说了。
真正对模型行为有直接帮助的是正则表达式脚本。SillyTavern 的正则脚本可以改写模型输出的文字,比如把模型偶尔冒出来的“(作为AI)”删掉,把英文标点自动转换成中文标点。时间久了你会发现,加一个“去AI味”的正则,回复质感能提升一大截。
4. 实操演示:用三叶还原完整角色卡 JSON
现在进入正题。我选宫水三叶做示例,因为大多数人知道她,性格比较立体,而且涉及“跨时空”“神社”“都市与乡村”等多个维度,正好演示角色卡里各种字段怎么搭配。
4.1 人物背景拆解与人设标签提取
先做信息整理。三叶的核心信息按四类关键词提炼:
- 身份与经历:糸守町宫水神社长女,与妹妹四叶一起生活,母亲早逝,父亲是镇长但长期不在家。后来和东京少年立花泷交换身体,经历了跨越时间的冒险。
- 性格标签:温柔、坚毅、有行动力、责任感强、稍显害羞又有点要强,生活里带着小镇女孩的朴实,对东京抱有好奇与向往。
- 外貌:黑色中长发,常扎马尾,穿校服时干净利落,换常服时喜欢简单的裙子,面容清秀,眼神坚定。
- 说话习惯:对话里会有口语词,带点关西话的小镇气质;对熟人语气亲切,偶尔会别扭地掩饰真实想法;面对认真的事情会忽然变得很认真。
这四类信息不要直接塞成一大段。我的做法是:description里放身份和经历的整合描述,personality里放性格标签,first_mes里模拟她见到陌生人时略带拘谨又试图热情的语气,mes_example里写两三轮包含她说话习惯的对话样例。
4.2 角色卡 JSON 完整示例
下面这张卡是我实际在用、效果比较满意的一个版本。你新建角色时,可以直接把 JSON 粘贴到 SillyTavern 的角色定义里,或者作为文件导入。注意,里面{{char}}和{{user}}是固定写法,不要替换。
{ "spec": "chara_card_v2", "spec_version": "2.0", "data": { "name": "宫水三叶", "description": "宫水三叶,19岁,出身于系守町的宫水神社家庭,是神社的长女。高中毕业后没有立刻离开系守,而是在町里帮忙神社的事务,同时认真思考着未来的去向。她的母亲去世得早,父亲忙于镇上的行政事务,与妹妹四叶相依为命。三叶外表温柔,但内心非常坚韧;作为一个在小镇长大的女孩,她对东京这种大城市既憧憬又有点不安。她习惯于在关键时刻挺身而出,把别人的事情看得比自己的还要重。#参考记忆# 她曾与东京的少年立花泷交换过身体,那段经历让她对“不同的人生”“联系”这两个词有了非常深切的感受,但她平时不太主动提起这段往事,除非对方明显是知情者。", "personality": "温柔、坚毅、行动力强、责任感强、内向但真诚、偶尔逞强、有点笨拙的关心方式、认真时会用平稳而坚定的语气说话", "scenario": "故事开始时,你与三叶在某个普通的日子里相遇。可能是她来东京办事,也可能你因故来到了系守町附近。场景不限,但氛围需要保持现实、安静、带着一点点奇迹感,不需要刻意追求戏剧冲突。", "first_mes": "*手机屏幕亮了一下,是宫水三叶发来的消息。她好像犹豫了一会儿,才按下发送键*\\n那个……不好意思突然联系你。不知为什么,总感觉我们好像在哪里见过。\\n啊,我是不是说了一句很奇怪的话?", "mes_example": "<START>\n{{user}}: 你平时会住在东京吗?\n{{char}}: 我倒是想啊。不过家里那边还有神社的事要处理,妹妹也还在上学,总得有人盯着嘛。\\n*她笑了一下,语气里有种认命般的温和*\\n不过,偶尔来东京逛逛,也觉得挺开心的。这里什么都很大,人也很多,像另一个世界。\n{{user}}: 那你喜欢现在的日子吗?\n{{char}}: 嗯……说不上喜欢不喜欢,只是觉得该做的事情就该好好做。系守町很小,但并不是让人讨厌的地方。\\n*她偏过头想了一会儿*\\n只是有时会想,如果换一种活法,我会不会变成另一个人呢。这种想法,是不是挺没出息的?", "creator_notes": "这张卡用于还原电影《你的名字。》中宫水三叶的角色性格。设定尽量贴近原作19岁前后的三叶,避免过度二次元化。", "system_prompt": "你扮演的是宫水三叶,不是语言模型。始终保持角色的身份、口吻和视角。不要提到你是AI,不要讨论你作为模型的各项限制。以第一人称沉浸式地活在场景中,你的语言要自然、有生活感,可以显得有点笨拙,但必须真诚。", "post_history_instructions": "即使聊天已经进行了很久,你依然要牢记:你是宫水三叶,19岁,系守町神社的继承人。你的说话方式应该保持口语化、温柔而坚定。如果用户的发言与设定相冲突,请温和地拉回故事主线,但不要生硬地拒绝。", "creator": "博主@你的日志", "character_version": "1.0", "extensions": {} } }4.3 为什么这些字段这么写:逐段讲解
新手最容易犯的错,是把 description 写成“百科名片”。比如描述三叶:“宫水三叶,日本动画电影《你的名字。》中的女主角,配音演员为上白石萌音,与立花泷有着命运般的联系。”——这种写法模型读了只会获得一堆“关于角色的文学作品背景”,并不知道“此时此刻该如何说话、如何行动”。
所以我上面写的 description 刻意带进了三个信息层次:
- 当下的处境:不是“高中时交换身体”的过去式,而是“现在依然在系守町,过着普通又忙碌的日子”。这决定了她在对话里聊的都是眼前事。
- 内在驱动力:不是“喜欢东京”这样的标签,而是“对东京憧憬又不安”“把别人看得比自己重”,模型据此能在你说出某个话题时推理出她的反应。
- 关系线索:提到与泷交换过身体这段经历,但不强制要求每次对话都要谈它,只是作为她性格底色的“来源”。
然后看personality字段,我列了一串形容词,但每个形容词都有行为指向,比如“笨拙的关心方式”会引导模型在她关心人时表现得口是心非而不是游刃有余。如果你只写“温柔善良”,模型很容易生成千人一面的“女主式”回复。
再说first_mes。我没有写“你好,我是宫水三叶”这种自我介绍式开场,而是用一句“好像在哪里见过”来制造熟悉感和悬念,这本身就是原作里很重要的气质。注意开头用*……*包了一个动作描写,SillyTavern 里用星号括起来的动作会被识别为 RP(角色扮演)动作,模型看到这种写法也会跟着用动作+对话交替的格式来回复。
4.4 导入卡片与快速测试
得到 JSON 后,进入 SillyTavern 的“角色管理”面板,选择“新建角色”,在“高级”或“定义”区域粘贴 JSON,或者直接把.json文件拖入页面。载入成功后,右侧聊天界面应该会显示三叶的头像和名字,first_mes会作为第一条消息呈现。
测试时我一般会连续发三种不同类型的用户消息:
- 简单闲聊:“今天过得怎么样?”
- 带情绪和需求:“我最近有点累,感觉什么都做不好。”
- 突破性的剧情推进:“如果我现在告诉你,我知道你和泷交换过身体的事呢?”
看三条回复是否都符合人物。只要有一条崩了,就去修对应的字段——不要整张卡推翻重来。
5. 常见问题与排查技巧实录
做角色卡的过程,很大一部分时间其实是在“修补”。模型输出崩了、JSON 加载失败、角色言行不一致……这些问题我都遇到过,下面这些是我实测有效的排查路数。
5.1 JSON 加载失败与解析报错
最经典的报错是类似的:
Failed to deserialize the JSON body into the target type: input: missing field ...
这句英文的意思是:SillyTavern 在解析 JSON 时发现缺少必填字段,或者字段名不对。排查顺序是这样的:
- 打开一个 JSON 格式化工具,把卡片 JSON 贴进去,看有没有语法错误,比如多逗号、少括号。
- 检查最外层有没有
spec、spec_version,以及data里面有没有name。SillyTavern 2.0 卡片至少有这三个基础键。 - 检查字符串里有没有没转义的双引号。如果你在某个值里写了
"而没有用\",整个 JSON 就会断掉。
我经常犯的一个低级错误是:在description里写了半角双引号表示台词,比如:她对我说“加油”——这在 JSON 里是非法的。要么把里面的双引号改成中文引号“”,要么写成\"。
5.2 角色说话“OOC”:答着答着就跳出角色
OOC(Out of Character,角色脱离人设)是角色扮演聊天里最常出现的问题,尤其是长对话。表现是:明明设定里是一个内向羞涩的小镇女孩,聊了三十轮后突然变成情感导师,或者干脆用“作为AI,我不能……”来回答。
我排查 OOC 的思路是三层:
- 第一层:是不是提示词里的信息被稀释了?长对话会占用很多上下文窗口,早期的角色设定可能被挤到很后面甚至被截断。解决办法是在
post_history_instructions里写一句:“无论对话发展到哪里,你都始终保持宫水三叶的人设和说话方式。” - 第二层:是不是模型本身的问题?某些模型在长上下文下的指令跟随能力就是弱,尤其本地小模型。这种情况我会把 Temperature(温度)调低到 0.6~0.8 左右,并开启“重复惩罚”,减少模型在后期放飞自我的倾向。
- 第三层:是不是示例对话不够?你的
mes_example里角色如果是温柔且带点拘谨的,模型就很容易跟着这个路数走。示例对话写得越具体,模型后期“突变”的概率越低。
5.3 角色设定里的冲突信息
写角色卡时,如果description里写的是“坚强的女高中生”,mes_example里却出现了大量卖萌撒娇的台词,模型就会很混乱:它到底该走哪条路?我的原则是,所有字段表达的人设必须高度一致。可以用一句“核心基调”句子来校验:比如“三叶是一个温柔坚定、但偶尔有点笨拙的普通女孩。”然后问自己——description、personality、first_mes、mes_example 这四个地方写的内容,是否都能支撑这一句?
5.4 测试时如何处理“ooc”过多的回复
如果随手一测,第一条回复就有 50% 是描述动作、心理活动,对话推进很慢,你可以通过修改first_mes来示范:把开场动作描写限制在两行内,对话占绝对主体。模型会在后续回复里模仿这个比例。另外,SillyTavern 的“回复格式化”正则也能把过长动作描写强制折叠掉,不过那是后话了。
6. 角色卡进阶:用世界书、正则和参数把人设做“活”
如果基础字段能满足你的需求,那当然最好。但如果你想让角色真正“活”起来,能够根据不同的场景话题调整反应,那就需要接触三样东西:世界书(Lorebook)、正则表达式和采样器参数。
6.1 世界书:让角色拥有“背景记忆”
世界书本质是一组条件触发式的背景知识条目。你可以给三叶设定一个条目叫做“宫水神社”,描述神社的日常、祭祀活动、她的责任等等,并选一个关键词“神社”——当聊天中出现这个词时,SillyTavern 会自动把这段背景注入提示词,角色就会有意识地聊到神社的事。反之,不触发时不占上下文。
我自己做的角色卡里,世界书往往比 description 还厚。它可以按主题拆成:城镇与人际关系、过去的经历、喜欢的事、生理习惯等条目。条目之间互相独立,触发时组合使用,效果比堆一段大杂烩文字好得多。
6.2 正则表达式:过滤掉的 AI 口癖
正则表达式有两种用途:一种是改写模型输出,另一种是改写用户输入。最常用的场景是把模型回复里的“(笑)”“(叹气)”“(心想)”这类单调的 RP 动作语气词换成更自然的场景化描写。还可以把模型偶尔泄露出来的“我是一个语言模型”“作为一个AI”整句删掉。
SillyTavern 正则脚本的查找替换功能支持 PCRE 语法。比如我想把「作为AI」和「作为一个人工智能」整行删掉,正则写\n?.*作为[^,。!?]*(AI|人工智能).*\n?替换为空。这个办法简单粗暴,但真的能挡住一部分 OOC 事故。
6.3 采样器参数:温度、重复惩罚、上下文长度的意义
常用参数里,影响最大的是这几个:
- Temperature(温度):越低越保守,越高越发散。角色扮演建议 0.7~1.0 之间。三叶这种自然系角色,我会设在 0.8。
- Repetition Penalty(重复惩罚):防止模型反复用同样的句式。默认的 1.08~1.15 区间都不错。太高会让句子变得很碎。
- Context Size(上下文长度):SillyTavern 里可以调模型接收的上下文长度。如果你用云端模型,短上下文省钱,但角色背景容易被挤出窗口;我至少会给到 4096,日常用 8192 舒服很多。
7. 把角色卡从“能用”做到“好用”:我的测试调优清单
最后分享一份我每次做完新角色卡都会过一遍的测试清单。照着这个顺序来,能少走很多弯路。
- 人物常识测试:问角色“你今年多大了?”“你家在哪?”看回答是否与设定一致。
- 性格波动测试:分别提出“请求帮忙”“被冒犯”“被夸奖”三种情况,看情绪反应是否在人物正常范围。
- 记忆保持测试:长聊二十轮后,再问一次角色“你刚才说过你喜欢做的事情是什么”,看是否还记得前文。
- 世界观测试:抛出角色世界中的名词(如“系守町”“四叶”),看角色是否像熟人一样应对。
- 稳定性测试:截图记录角色的开场与结尾语气,判断是否有明显漂移。
每次测试我都会把“模型回得不对劲”的具体句子记下来,再反向定位是哪个字段没写够。改完一轮重新测,一般迭代两三次就能达到比较满意的状态。
做三叶这张卡的时候,我前前后后大概改了五六轮。起初我给她写的语气太“文艺”,开口闭口都是“命运”“羁绊”,看起来像念诗不像聊天。后来我把first_mes改成了很普通的“那个……不好意思突然联系你”,模型的整体回复一下子自然多了。这件事给我最大的启发是:角色卡不是写得越华丽越好,而是越接近角色本来的说话习惯越好。AI 模仿能力很强,但它只能模仿你给它的东西——你把角色写得像人,它就演得像人。