# 酒馆角色卡使用指南 —— 从类脑取卡 → 导入 → 开聊

> 适用：本机部署的酒馆 SillyTavern **1.19.0** · **http://192.168.31.76:8000**
> 日期：2026-09-26

---

## 0. 一句话流程

```
类脑页面点「下载角色卡」（不要右键另存为）
   ↓  得到 .png 或 .json
拖进酒馆网页 → 刷新 → 点角色 → 开聊
   ↓  如果拿到的是 .webp / 导入报错
用 st-card-tool.py 验卡并救成 PNG 再导入（见 §4）
```

---

## 1. 第一步：在类脑把「真卡」下载下来（最容易踩的坑）

⚠️ **关键：不要用「图片另存为」**。网页上显示的往往是**压缩过的封面图**，存下来是 `.webp`，
里面**没有角色数据** —— 转成 PNG 也依然没有，因为转换只换像素、不会把丢失的数据变回来。

**正确做法**：在卡片页面找这些字样的按钮：
- 「下载角色卡」「下载原卡」「导出」「PNG」「JSON」「Download Card」

### 怎么判断手里的是真卡还是封面

| 特征 | 真卡 | 只是封面 |
|---|---|---|
| 扩展名 | `.png`（或 `.json`/`.charx`/`.byaf`） | `.webp` 居多 |
| 体积 | 通常 **几百 KB ~ 几 MB** | 常常 **几十 KB** |
| 内部 | PNG 里有 `chara`（V2）/ `ccv3`（V3）文本块 | 只有图像数据 |

拿不准就直接用工具验（**不会改动文件，只看不写**）：

```bash
python3 ~/Downloads/st-card-tool.py inspect <文件或目录>
```

输出示例：
```
✅ 某角色.png  →  真卡
    格式 png / 539.0 KB   数据来源 png-ccv3
    角色名 某角色   规格 chara_card_v3 3.0
    描述 2851 字   备用开场 0 条   世界书 有(4条)
❌ 某角色.webp  →  不含角色数据（只是封面图）
    格式 webp / 40.0 KB   RIFF 块: VP8X, ALPH, VP8
```

---

## 2. 第二步：导入这台酒馆

### 本机酒馆支持的格式（源码 `src/endpoints/characters.js` 实测）

| 格式 | 支持 | 说明 |
|---|---|---|
| `.png`（内嵌 chara/ccv3） | ✅ | **社区标准格式**，首选 |
| `.json` | ✅ | V1/V2/V3 都行；酒馆会**自动生成头像** |
| `.yaml` / `.yml` | ✅ | |
| `.charx` | ✅ | 卡+素材的压缩包格式 |
| `.byaf` | ✅ | |
| **`.webp`** | ❌ | **酒馆完全不认**，必须转换（见 §4） |
| `.jpg` / `.jpeg` | ❌ | 同上 |

### 方式 A：拖拽导入（最简单，推荐日常用）

1. 浏览器打开 **http://192.168.31.76:8000**
2. 把卡文件（png/json）**直接拖到酒馆页面上**
3. 左侧「**角色管理**」里出现新头像 → 点它 → 开聊

> 不用先把文件传到服务器 —— 酒馆是局域网网页应用，从你自己电脑拖进浏览器就行。

### 方式 B：从 URL 导入（卡在某个直链上）

酒馆只允许从**白名单域名**拉卡，当前 `config.yaml` 里是：

```yaml
whitelistImportDomains:
  - localhost
  - cdn.discordapp.com
  - files.catbox.moe
  - raw.githubusercontent.com
```

要加新域名就编辑 `/home/zyw/SillyTavern/config.yaml` 追加一条，然后：

```bash
bash ~/Downloads/sillytavern-ctl.sh restart
```

> 好消息：**被墙的域名也能拉**（如 GitHub、discord CDN）—— 我部署时已给酒馆配了出站代理
> `socks5://127.0.0.1:10808`，局域网地址在 bypass 里直连。所以在线导入不再需要你自己开代理。

### 方式 C：批量导入（卡多 / 拿到的是 webp）

```bash
# 先把卡上传到下载中心（网页 8899 → 用户上传 目录），或 scp 到本机，然后：
python3 ~/Downloads/st-card-tool.py import <文件或目录> --out ./converted
```

工具会自动：**跳过封面图** → **把带数据的 webp 救成 PNG** → 调酒馆导入接口写库。

---

## 3. 第三步：开聊

1. 刷新页面（`Ctrl+F5`），左侧「角色管理」点开
2. 选中角色 → 头像出现在左侧栏 = 已激活
3. 输入框发消息即可；想换开场白点角色卡里的「**其他开场**」（Alternate Greetings）
4. **世界书（Lorebook）**：卡里自带的世界书**导入时会自动带进来**，不用手工配
5. 上下文/输出长度已按这个模型调好：`65536` 上下文、`4096` 输出上限、显示思维链

> 这个模型是无审核档 `bucoid-heretic-27b`，角色扮演不拒答。它**带思维链**，
> 回复前会先"想"一段（点开可见），所以第一次回复稍慢是正常的。

---

## 4. 救卡：webp 转 PNG 为什么没用，以及正确做法

**为什么没用**：酒馆从 PNG 的 `tEXt` 文本块里读角色数据（`chara`=V2，`ccv3`=V3）。
普通格式转换只重编码图像，**不会凭空生成这些元数据块**。所以：

```
webp 封面 ──转格式──> PNG（依然没有 chara 块）──> 酒馆说"无法解析"
```

**正确做法**（工具已实现）：

```
webp（含数据的真卡）
  ├─ 从 RIFF/EXIF/base64 里抠出角色 JSON
  ├─ ffmpeg 把图像转成普通 PNG
  ├─ 手工写入 chara + ccv3 两个 tEXt 块（含 CRC32）
  └─ 得到酒馆可直接吃的 PNG
```

实测（构造了一个含数据的 webp 验证）：

```
ℹ️  with-data.webp：已救成酒馆可用 PNG → converted/WebP救卡测试角色.png
✅ 已导入：WebP救卡测试角色
```

⚠️ 但**如果 webp 里本来就没有角色数据（只是封面），神仙也救不回来** —— 必须回类脑重新下载原卡。

---

## 5. 工具速查

```bash
T=~/Downloads/st-card-tool.py

python3 $T inspect <文件或目录...>        # 验卡：真卡/封面、角色名、规格、世界书条数
python3 $T import  <文件或目录...>        # 批量导入（自动救 webp、自动跳过封面）
python3 $T import  <目录> --dry-run       # 只看会导入什么，不真写
python3 $T list                          # 列出酒馆里已有的角色
python3 $T list --detail                 # 附带头像大小/规格/备用开场/世界书条目
```

补充说明：
- `import` 走的是酒馆**官方导入接口**（`POST /api/characters/import`），与网页导入完全同一条代码路径，
  所以 json/yaml/charx/byaf 都能正确处理，不是"绕过酒馆"的野路子。
- 救卡产物默认落在当前目录的 `./st-cards-converted/`，可用 `--out` 改。
- 目录参数会**递归**查找 `.png/.webp/.json/.yaml/.yml/.charx/.byaf/.jpg`。
- 删除角色：直接删 `data/default-user/characters/<角色名>.png`，刷新页面即可。

---

## 6. 常见问题

| 现象 | 原因 / 解决 |
|---|---|
| 导入后提示「无法解析角色卡」 | 多半是封面图不是真卡 → `inspect` 验一下 |
| webp 转 PNG 后仍导入不了 | 见 §4：缺 `chara` 元数据块，用工具救卡 |
| 从网址导入报域名不允许 | 把域名加进 `config.yaml` 的 `whitelistImportDomains` 并重启 |
| 拖进去没反应 | 确认格式是 png/json；文件名别带 `/ \ : * ? " < > \|` |
| 两个卡同名 | 酒馆会自动加 `1` 后缀；建议先改名再导入 |
| 卡里的世界书没生效 | 到「世界书」面板确认已绑定到该角色（一般导入即自动绑定） |
| 回复很慢或先出一段英文思考 | 该模型带思维链，属正常；想关可调 `--reasoning`（GPU 机侧参数，需重启服务） |
| **对话里出现一大段 HTML 代码** | 这是「HTML 状态栏卡」的正常表现，需要前端渲染扩展 → **见 §8**（本站已装酒馆助手，刷新页面即可） |

---

## 7. 相关文件

| 用途 | 路径 |
|---|---|
| 验卡/救卡/导入工具 | `/home/zyw/Downloads/st-card-tool.py` |
| 角色卡存放目录 | `/home/zyw/SillyTavern/data/default-user/characters/` |
| 酒馆配置（含 URL 导入白名单） | `/home/zyw/SillyTavern/config.yaml` |
| 酒馆启停/自检 | `bash ~/Downloads/sillytavern-ctl.sh {status\|restart\|test}` |
| 下载中心（可网页上传卡） | http://192.168.31.76:8899/ → `用户上传/` |

---

## 8. HTML 状态栏卡：对话里满屏 HTML 代码（**已解决**）

> 现场案例：类脑的 `涩涩提瓦特` 卡。导入成功、也能聊，但每条回复底下出现一大段 HTML 源码。

### 8.1 原因（本站实测的完整证据链）

这类卡是「**前端美化 / HTML 状态栏**」卡，靠三段配合：

1. **两条常驻世界书**（`美化状态栏(无选项)`、`格式增强Plus[防止掉格式极简,勿动]`）强制模型按固定格式输出：

   ```
   <maintext>角色对话</maintext>
   <Status_block>…… YAML 状态数据 ……</Status_block>
   ```
   该卡的开场白本身就是以 `<maintext>` 开头、以一大段 YAML 的 `</Status_block>` 结尾。

2. **卡自带正则脚本**（`data.extensions.regex_scripts`），其中「美化状态栏[只美化状态栏]」默认启用，
   负责把 `<Status_block>…</Status_block>` 整段替换掉。替换内容是**一整个 HTML 文档，75900 个字符**：
   `<!DOCTYPE html>` + `<head>` + Tailwind CDN + jQuery + js-yaml + 内联 `<script>`（渲染状态栏、绑定行动选项按钮）。
   ⚠️ 而且它被 **`` ```text `` 代码围栏包住**。

   > 卡自带正则会自动生效，不需要手工注册 —— 酒馆 `regex/engine.js:115-118` 会读取
   > `characters[chid].data.extensions.regex_scripts`，前提是该卡在
   > `extension_settings.character_allowed_regex` 里（导入时自动加入）。

3. 酒馆的渲染管线是：**正则替换 → Markdown 解析**。而代码围栏在 Markdown 里就是**代码块** →
   酒馆忠实地把这份 HTML 当**源码**显示。`power_user.encode_tags=false`（默认转义 `<`/`>`）让它更只能是纯文本。

**所以这不是 bug**：代码块里的前端界面需要**前端渲染扩展**在沙箱 iframe 里执行。

### 8.2 解决方案：酒馆助手（JS-Slash-Runner）—— **本站已装好**

| 项 | 值 |
|---|---|
| 扩展 | `N0VI028/JS-Slash-Runner`（酒馆助手）**v4.11.0** |
| 位置 | `data/default-user/extensions/JS-Slash-Runner/` |
| 浏览器加载 | `/scripts/extensions/third-party/JS-Slash-Runner/dist/index.js`（实测 HTTP 200，1.13 MB） |
| 是否需要编译 | **不需要**，仓库自带预编译 `dist/index.js` + `dist/index.css` |
| 渲染开关 | 扩展面板「**开启前端渲染 / Enabled Fontend Renderer**」；源码里 `render.render_enabled` **默认 true**，一般无需手动设置 |
| 配置存储 | 酒馆 `settings.json` 的 `extension_settings.tavern_helper` |
| 识别规则 | 源码函数：`['html>','<head>','<body'].some(t => 内容.includes(t))` —— 命中任一即渲染 |

**你要做的只有一件事：在酒馆页面按 `Ctrl+F5` 刷新。**
刷新后扩展被加载，回复里的状态栏会渲染成真正的界面（Tailwind 样式、YAML 自动解析、**可点击的「行动选项」**）。

### 8.3 注意事项

- **CDN 可用性**：状态栏的样式/脚本来自 `cdn.tailwindcss.com`、`cdn.jsdelivr.net`、`code.jquery.com`。
  本机实测**直连三个都通**（HTTP 302 / 200 / 200），**不需要挂代理**。
  若出现「有内容但没样式」，先查这三个域名；扩展自己也内置了 `lib/tailwindcss.min.js` 可兜底。
- **首次渲染较慢**：要下载 Tailwind 等资源，第二次起走缓存。
- **不想要状态栏**：关掉卡自带正则（正则扩展里取消该脚本）+ 关掉上面两条常驻世界书，
  就退化成纯文字角色扮演，最省 token。
- **自动更新已配通**：该扩展仓库写入了 repo 级 git 代理（`git config http.proxy`），
  所以酒馆的「自动更新扩展」也能用（否则 GitHub 直连不通会更新失败）。
- ⚠️ 在酒馆里安装/更新扩展都走 GitHub，**一旦失败先想到代理**。

---

## 9. 进阶卡：MVU 变量框架 + 提示词模板语法（**已配齐**）

> 现场案例：`【怀孕DLC】关于从福利院领养侄女后的甜蜜孕妻生活这件事`。
> 卡内自带的《必备工具》清单里列了 5 项，下面逐项对账 —— **只有 1 项是真缺的**。

### 9.1 清单对账（结论：只有「提示词模板语法」需要额外装）

| 卡上写的 | 实际是什么 | 状态 |
|---|---|---|
| 酒馆助手（前端助手）· Kakaa佬 | `N0VI028/JS-Slash-Runner` | ✅ 已装 v4.11.0（见 §8） |
| **提示词模板语法** · zonde306佬 | `zonde306/ST-Prompt-Template`（EJS 模板） | ✅ **本轮新装 v1.17.9** |
| MVU / Moli佬教程 | 变量框架 `MagVarUpdate` | ✅ **卡自带，无需安装**（见 9.3） |
| Genimi：kemini / Deepseek：夏瑾 | **聊天补全预设**（不是扩展） | ⚪ 可选，只影响出戏质量 |
| 制卡预设 Nova Creator | **制卡**用的预设 | ⚪ 聊天不需要 |
| MVU 教程 | 文档 | ⚪ 不用装 |

### 9.2 为什么「提示词模板语法」是硬需求（实测证据）

该卡两条**常驻**世界书 `分阶段人设`、`分阶段性爱态度` 里写的是 **EJS/JavaScript**：

```javascript
associated_variable: 好感度 (<%= getvar('stat_data.姜桃.好感度[0]') %>)
<%_ if (getvar('stat_data.姜桃.好感度[0]') < -75) { _%>
...
<%_ } else if (getvar('stat_data.姜桃.好感度[0]') >= 175) { _%>
<%_ } _%>
```

全文命中：**`<% %>` 4 处、`stat_data`/MVU 55 处**。

**不装会怎样**：这些 `<% %>` 不会被求值，会**原样拼进发给模型的提示词** ——
既污染上下文（白白烧 token、模型困惑），又让「分阶段人设 / 分阶段性爱态度」整套机制**完全不生效**。

| 项 | 值 |
|---|---|
| 扩展 | `zonde306/ST-Prompt-Template` v1.17.9（AGPL-3.0，457 star） |
| 位置 | `data/default-user/extensions/ST-Prompt-Template/` |
| 预编译 | ✅ 仓库自带 `dist/`，无需构建 |
| 浏览器加载 | `/scripts/extensions/third-party/ST-Prompt-Template/dist/index.js`（实测 HTTP 200） |
| 能力 | 在提示词/角色卡/世界书里跑完整 JS：`getvar`/`setvar`、条件、循环、注入控制 |
| 代理 | ✅ 已写 repo 级 git 代理，自动更新可用 |

### 9.3 MVU 变量框架：卡自带，不用装

卡里的 `extensions.TavernHelper_scripts[0]` 就是 MVU：

```javascript
import 'https://cdn.jsdelivr.net/gh/MagicalAstrogy/MagVarUpdate@master/artifact/bundle.js'
```

它作为**酒馆助手脚本**自动加载（需要能访问 jsdelivr —— 实测 **HTTP 200 / 573 KB** ✅）。
变量结构由卡内世界书的 `MVU变量规则` + `[InitVar]` 条目定义。

**刷新后要做一次初始化**：进入酒馆助手的脚本面板，找到 `var_update临时` 脚本，
点它自带的 **「重新读取初始变量」** 按钮（另一个按钮是「重新处理变量」）。

### 9.4 这张卡的结构（判断"卡是否完整"的参考）

| 组成 | 内容 |
|---|---|
| 基本字段 | `description`/`personality`/`scenario`/`system_prompt` **全空**，`first_mes` 仅 16 字 |
| 世界书 | **15 条**：`人物设定`、`人生轨迹`、`被霸凌轨迹`、`MVU变量规则`、`[InitVar]`、`分阶段人设`、`分阶段性爱态度`、`好感度计算规则`、`月经期生理变化`、`SFW/NSFW CG列表`、`[渲染] CG插入规则`、`[渲染] AI输出格式`、`孕期生理变化`… |
| 正则 | **21 条**：`开场白`(8.1k)、`状态栏`(28.6k 含 `<script>`)、`去除变量更新`、`对ai隐藏状态栏`、`[CG渲染]SFW`×5、`[CG渲染]NSFW`×12、`姜桃-美化面板`(23k 含 `<script>`) |
| 酒馆助手脚本 | 1 个（MVU） |

> 所以「字段全空、开场白只有 16 字」是**正常**的：正文靠 `开场白` 正则渲染，人设靠世界书 + MVU 变量驱动。

### 9.5 这张卡运行时的外部资源（已实测，均可达）

| 资源 | 用途 | 直连结果 |
|---|---|---|
| `cdn.jsdelivr.net/gh/MagicalAstrogy/MagVarUpdate@master/...bundle.js` | MVU 框架本体 | **200**（573 KB） |
| `gitgud.io/Sycamore/jiangtao` | **CG 图源**（SFW/NSFW CG 图片） | **公开仓库**，raw 匿名 **200**，**无需登录** |
| `fonts.googleapis.com` | 美化面板字体（ZCOOL 快乐体） | **200** |
| `cdn.tailwindcss.com` / `code.jquery.com` | 面板样式/交互 | **302 / 200** |

### 9.6 使用步骤

1. **`Ctrl+F5` 刷新酒馆页面**（加载两个扩展）。
2. 若扩展面板里 `Prompt Template/提示词模板` 是关的 → 打开它（本机实测 `disabledExtensions` 为空，默认就是开的）。
3. 进酒馆助手脚本面板 → `var_update临时` → 点 **「重新读取初始变量」**（初始化 MVU 的 `[InitVar]`）。
4. 开聊。状态栏/CG/美化面板由正则 + 酒馆助手前端渲染负责。

### 9.7 ⚠️ 安全边界（必须知道）

**ST-Prompt-Template 会在你的浏览器里执行角色卡/世界书里写的 JavaScript。**
这是所有「MVU + 模板语法」类卡的前提能力，但等价于**卡作者可以在你的酒馆会话里跑任意 JS**。
只装你信任来源的卡；不确定的卡，可以先在 `st-card-tool.py inspect` 里看看它带了多少条正则和脚本。

### 9.8 以后再遇到「卡要求一堆插件」

按这个顺序自查，别盲目全装：

1. 用 `st-card-tool.py inspect <卡>` 看 `extensions` 里有什么：
   - `TavernHelper_scripts` → 卡自带酒馆助手脚本（**不用装**，MVU 通常在这里）
   - `regex_scripts` → 卡自带正则（**会自动生效**，不用手工注册）
2. 全文搜特征语法判断依赖：
   - `<% %>` → 需要 **ST-Prompt-Template**
   - `{{getvar::}}` / `{{setvar::}}` → 酒馆**原生**变量，**不需要**扩展
   - `stat_data` / `MVU` → MVU 框架（一般卡自带；没有就问作者要）
3. 预设（预设/破限/世界书预设）基本都是**聊天补全预设**，属于"效果优化"而非"能否运行"。
