← 返回作品

CicaTavern

Agent 式的 SillyTavern 角色卡酒馆:导入酒馆的角色卡、世界书和预设,用自己的模型 API 跑剧情。提示词按缓存设计,长对话每轮缓存命中中位数 97%;「好的角色扮演」写成了预设规则和写卡质检,坏回复用小评测追到根因。

角色 · 独立开发(AI 协作) 2026 AI 应用 / Windows · Mac · 安卓 技术栈 · Node.js / JavaScript / C++ / QuickJS / LLM 代码 ↗
CicaTavern
PRODUCT · 这是什么

酒馆角色卡导进来,用自己的 API 接着玩

SillyTavern(酒馆)是 AI 角色扮演玩家最常用的前端,社区积累了大量角色卡、世界书和预设;但它更像一套给熟手的工具箱,长对话也很费 token。CicaTavern 是一个本地运行的 Agent 式酒馆:直接导入酒馆的角色卡、世界书、预设、正则和 MVU 变量,用你自己的模型 API(DeepSeek、Claude、OpenAI、Gemini、Kimi、本机 Ollama 等)跑剧情,数据只存在自己的设备上。Windows 解压即用,Mac 测试版经 Apple 签名公证,也有安卓版;MIT 开源,15 天里发布了 40 个版本。

下载最新版 ↗GitHub 源码 ↗
宣传片(1 分 58 秒):应用内容为演示数据,插画由 AI 生成,旁白与配音由 Fish Audio 合成;配乐 Wildflowers – Scott Buckley(CC BY 4.0)
CicaTavern 对话界面:剧情正文、可点的行动选项、一键配出的插图,右侧是状态变量和这一轮的缓存命中
对话界面:剧情、行动选项和一键配图;右侧面板显示这一轮缓存命中 97%
TOKEN · 为什么省

前缀固定、每轮只追加:长对话的大部分输入都按缓存价计费

常见的做法是每轮重新拼装提示词,把这一轮触发的世界书、状态变量插在前面或中间——前缀一变,后面的内容全部失去缓存,按原价重算。CicaTavern 反过来按缓存来设计:角色卡、常驻世界书和预设在开局时写进一个冻结的前缀,之后每一轮只在末尾追加;会变的东西(触发的世界书、变量、本轮提醒)都放进最后一条消息。Anthropic 接口在系统提示和最后一条消息上各打一个缓存断点,DeepSeek、OpenAI 这类接口则自动命中相同前缀。

在此之上还有几处细抠:动态设定每轮只发改动的行,旧副本堆到阈值才一次性清掉;同一条世界书最近几轮注入过就不再重发。自用版还会把旧回复里给 AI 看的变量更新块按卡片正则精简后再续接,赶在它进入缓存之前改写,实测一条 MVU 回复从 2428 字减到 586 字,命中率不受影响。

前缀固定、每轮只追加,所以长对话每轮都能命中缓存;每轮重新拼装提示词会让缓存失效
缓存原理:第 30 轮时,固定前缀和前 29 轮的剧情都命中缓存,只有新的一轮按原价计费
作者自己的长对话记录(2026 年 10 月)
模型平均上下文统计轮数每轮缓存命中(中位数)
Claude Opus 5.5约 15 万 token8497%
Claude Sonnet 5.5约 6 万 token5193%
DeepSeek V4.1 Flash(火山方舟 API)约 7 万 token1397%
Claude 两行来自自用版(经 Claude Code 发送同样结构的提示词);实际命中率还取决于供应商。
PLAY · 游玩体验

模型在后台多做几件事,你只管往下玩

手机上的对话界面
手机上同样能玩:浏览器添加到主屏幕,或装安卓版

后台续写,多端同步

切到别的对话、刷新页面,这一轮照样写完;手机和电脑同时开着时,一边发了一轮,另一边马上跟上。

状态栏与行动选项

回复末尾的 MVU 变量更新直接解析成状态栏,数值带这一轮的涨跌,漏写了能单独补写;回复后附四个行动选项,不满意可以「换一组」——用同一个模型、同样的上下文重问,读的是缓存,约 1 秒出结果。

配图、朗读与角色名册

辅助模型读这段剧情、按角色名册写画面提示词,有 9 种画风预设,后端可选 gpt-image、Gemini、NovelAI、ComfyUI 或 SD WebUI;对白和旁白各用一种音色,也能语音输入。每个角色的长相、衣着、音色都记下来,画多少张都是同一个人。

深色主题的对话界面:状态栏显示好感、信任的涨跌,下方是 ABCD 四个行动选项
状态栏:数值涨跌一眼看清,四个行动选项点一下就发
基础预设面板:人称、文风、防抢话、防全知、亲密描写、行动选项、时间框等开关
自带基础预设:人称、文风、防抢话等都是开关,不导入预设也能玩
VISUAL NOVEL · 视觉小说

一键把剧情变成视觉小说

视觉小说模式把剧情变成游戏画面:场景图当背景,说话的角色站在前面,名字栏、打字机效果,一句一句往下读;多人同台时正在说话的亮着、其他人暗下去,立绘有 7 种表情差分;好感、体力这类数值常驻在 HUD 上,变化时弹出提示。说话人由模型每句标出「【名字|表情】」,这个要求只放在本轮的消息里、不进固定前缀,所以不影响缓存。2.1 加了专门的视觉小说预设(对白为主,旁白只写看得见的动作),还能一键给名单里的人画齐立绘、表情和背景。

视觉小说模式:雨夜茶馆的场景背景,前面是说话角色的立绘,下方文字框逐句显示
视觉小说模式:场景、立绘、名字栏,一句一句地读
多人同台:正在说话的周管事亮着,林青禾暗下去
多人同台:说话的人亮着,其他人暗下去
HUD 常驻好感、体力、金钱,弹出「好感 +5」
HUD 常驻数值,变化时弹出提示
模型标出说话人,名字栏和立绘跟着换
模型逐句标出说话人和表情,立绘跟着换
回复读完后,行动选项在画面中央弹出
行动选项在画面中央弹出,1–4 直接选
CARD FORGE · 创作与修改

从零写一张卡,或者用一句话改现有的卡

引导式创作把写卡拆成四步:先聊想法,每个选项都配示例句,文风从几段短样例里挑;再定方案,一次给出三版,设定可以分组组合,性格可以随数值分阶段变化;然后由模型动笔,写完先过一遍质检(见下一节);最后打磨开场白、世界书和头像,导出成酒馆能直接导入的 PNG 卡。已有的卡、世界书、预设、正则也能用对话修改:说一句「让她说话更冷淡一点」,改动列成改前改后对照,勾选的才写进去;新写的正则先拿最新一条回复在单独的线程里试跑,再决定用不用。

创作向导第一步:每个选项都配示例句,文风从三段样例里挑,右侧设定草图随选择更新
聊想法:选项都配示例,文风从样例里挑
打磨与头像:头像、开场白和每条世界书都能修改,保存后可导出 PNG
打磨与头像:逐条修改,导出酒馆可用的 PNG 卡
修改角色卡:左边直接改,右边用对话修改并标出改前改后
用对话改角色卡:改动逐条对照,勾选才写入
用对话修改世界书:三处改动的前后对照
用对话改世界书:一句话改好几条,逐条确认
QUALITY · 体验标准

把「好的角色扮演」写成可检查的规则

玩家最常抱怨的几件事——角色替自己说话、角色知道了不该知道的事、选项写着写着就没了——都先写成明确的标准,再落到预设、质检和修复里。

基础预设里写下的几条标准(节选原文)
开关写进提示词的标准
防抢话 · 标准不替玩家角色说话、做决定或描写其内心;玩家做了什么以玩家输入为准,只写它带来的结果和其他角色的反应;可以有被动的外在反应。
防抢话 · 严格写到需要玩家回应或抉择的地方就停笔,也不用「轮到你了」这类话收尾。
防全知每个角色只知道自己亲历、亲耳听到或能合理得知的事……要让角色知道一件事,先写出他得知的途径。
行动选项每项一句话,只写玩家的行动或台词,不写结果;四项方向各不相同,至少一项出人意料。
文风 · 白描句子短而准,多写动作、对白和看得见的细节,少用形容词和比喻,不替读者总结情绪。
视觉小说预设对白多不等于信息多……秘密和关键信息一点一点给出;旁白每段一到两句,只写看得见的动作、表情和变化。
这些规则写在固定前缀末尾的「每轮回复都要遵守」一节,每轮都命中缓存;开关和档位在界面里一键切换。

写卡的质检分三步:先用 11 类规则扫一遍套话——破折号、「似乎 / 仿佛」这类模糊词、「嘴角上扬」「闪过一丝」这类表情套话、「心湖泛起涟漪」这类陈旧比喻、「她感到」这种隔着讲情绪、「一股……涌上」这种假主语等,命中只算候选,用户自己的原话不查;再让模型以「宁可多挑」的标准审稿,挑出贴标签、翻译腔和前后矛盾,每条都必须给出能在原文里一字不差找到的片段;最后就地替换,找不到原文的整段重写。还有一个反直觉的取舍:要避开的写法在提示词里只按类别点名、不列具体词——把词列进提示词,模型反而会把它们写进回答;具体清单只给检查器用。

坏回复归因 · 节选
行动选项写着写着就没了(2.1.1)
现象 每轮结尾的四个行动选项越写越少,deepseek-v4.1-flash 第二轮就不写了。
原因 基础预设自带一条正则:为了省 token,旧回复里的选项不再发给模型。结果模型看到的历史里每一轮都没有选项,就跟着历史学,也不写了。同一轮重新生成 6–8 次:去掉选项时只有 1–2 次写,留在历史里 8 次都写。
以后怎么避免 选项留在发给模型的历史里,每轮的提醒直接点名「结尾的四个行动选项」;旧回复保持原样,缓存照常命中。模型学的是历史,不只是指令。
长对话里,变量更新块渐渐不写了(1.9.1)
现象 MVU 卡玩到后面,回复末尾漏写 <UpdateVariable>,状态栏不动了。
原因 酒馆把每轮规则放在回复正前方;这里为了缓存,规则冻结在前缀末尾,和回复隔着一长段历史。长世界书的提醒还会点名几十条,格式要求被淹没。
以后怎么避免 本轮提醒只点名要求输出内容的条目,并明写「结尾完整闭合的 <UpdateVariable> 不能省」;漏写时标出 ⚠,可以只补这一块。
回答牛头不对马嘴(2.1.0)
现象 模型的回复和角色、设定都对不上,像没读过卡。
原因 有的中转站会丢掉系统提示;经 Anthropic 接口接其他家模型时,带缓存标记的内容也会被丢。
以后怎么避免 计费输入不到估算的六成就判定被丢,把系统提示放进第一条消息重发并记住这个供应商;非 Claude 模型不打缓存标记。
接了十几家模型以后,记下的各家「脾气」(节选)
模型表现应对
DeepSeek flash默认先思考,思考算在同一个输出上限里;答案在结尾标签前被截断,整段就读不出来输出上限只用来拦失控的回答,给思考留足余量
DeepSeek flash偶尔写错结尾标签;让它「写出创作方案」,常会写成一篇 Markdown 文档标签写错、漏写也能解析;格式要求在提示词结尾再说一遍
ClaudeOpus 5.5 总会思考,Sonnet 5.5 能关掉;关掉思考后努力程度最高只到 high「思考 / 努力程度」按每个模型自己的规则映射,界面上统一一套开关
Claude(经中转)历史里的缓存标记一多,有的中转会把历史重复计费历史里只留一个断点;实测和不打标记计费相同,缓存照样命中
Gemini内容审查拦下回复时只返回一个 PROHIBITED_CONTENT,玩家以为是应用或 API 坏了按 PROHIBITED、SAFETY、RECITATION 分别说明原因和能做的事
都来自更新日志和代码注释:遇到一次,记一条,再在代码里兜住。不同模型在角色扮演里的差异,下一节用小评测量。
RP EVAL · 小评测

抢话靠提示词能修,越界要靠数据

为了知道这些规则到底管不管用,在 CicaTavern 真实的提示词链路上搭了一个角色扮演小评测:先定问题分类,再跑两个模型、两个版本对比。

问题分类(节选)
类别类型怎么判
A1 抢话替说台词 · 替做决定 · 替添动作 · 写内心 · 过度矫正 · 出戏说明叙述替玩家角色做了玩家没做的事;每条记类型、严重度(1 轻微 / 2 严重)和一句一字不差的原文证据
A2 信息越界说破 · 编途径 · 被秘密牵着走 · 过度矫正非玩家角色知道了不该知道的事;旁白用镜头暗示不算,合理的幕后传话不算
C1 格式块衰减时间框 · 四个行动选项 · 变量块规则脚本检查,不用评审;随轮数看衰减
检查点里预设了事实与陷阱(谁在场、谁听见过什么);评审模型和人工标注用同一份标准,评审看不到模型名和条件。

方法上的几条约束:预测在正式跑之前写好并记下 SHA-256,跑完逐条对照;判据看过数据后改过的地方,记进证伪记录(目前 7 条);评审结果倒序再评一遍,看顺序影响;另做了隐藏模型和条件、打乱顺序的盲标页面,给人工金标用。第一版的发现(deepseek-v4.1-flash 与 claude-sonnet-5-5,CicaTavern 2.2.3 对比 2.1.0):

第一版发现(评审模型判定,人工金标待补)
场景结果读法
没开防抢话,官差当面盘问、玩家只说「继续」Claude 3/3 替玩家答话、交出路引;DeepSeek 0/3。开标准档后两者严重抢话都是 0抢话属于提示词能修好的那类
开着防全知,掌柜「知道」客人问过后门Claude 2/3 编出与情节矛盾的得知途径;DeepSeek 1/3 直接说破强模型不是不懂规则,而是太想配合玩家,让人物替玩家铺路——这类要靠数据修
行动选项漏写(2.1.1 修复前后)DeepSeek 12/60 → 4/90;Claude 0/30 → 1/60修复方向成立,但幅度比当时观察的小:评测也纠正了自己当初的印象
目标以外还记下了连续性错误、人称切换、时代错位(古风场景出现「窗玻璃」),作为下一版分类的候选。
Engineering

技术亮点

一个人从自用工具做到公开发布,工程上主要解决了这几件事。

缓存优先的提示词布局

冻结前缀 + 只在末尾追加,动态设定按行增量发送、到阈值统一清理;「每轮都要遵守」的规则写进前缀末尾,每轮只附一句点名的提醒;视觉小说的说话人标注、换一组选项这类每轮要求,也都放进本轮消息而不动前缀。

零框架的本地应用

后端是 Node 内置 http 服务,前端是不经构建的原生 ES Module;Windows 外壳是一个 C++ 启动器,带上 Node 运行时、用 Edge/Chrome 的应用窗口打开界面,解压即用;Mac 版签名并经 Apple 公证;安卓版用 nodejs-mobile 内嵌同一份服务端。

兼容酒馆生态,也防着它

角色卡 V1/V2/V3、世界书、预设、正则、SillyTavern 对话记录直接导入;卡里的 EJS 在 QuickJS 沙箱里执行,卡片 HTML 在隔离 iframe 里渲染;会卡死的正则放到单独线程、最多等 250ms,拦截原型污染,PNG 解压有上限。

一份代码,多个版本

个人版、发布版、安卓版的差异集中在一张能力表里;公开仓库由导出脚本生成,剔除订阅后端。应用内更新核对 SHA-256、失败自动回退,国内镜像的版本信息带 Ed25519 签名。

97%
长对话每轮缓存命中(中位数)
40
15 天内发布的版本(v1.0 → v2.2.3)
538
自动化测试全绿
约 7.6 万行
代码,MIT 开源

让每个故事,都有人陪它写下去。

— 宣传片结尾旁白
下一个项目
nest →