全新原生 Android 酒馆客户端——以 SillyTavern 兼容为核心,参考官方源码翻译重写,不做 WebView 壳,不搬运旧项目代码。
ember(余烬/炉火)+ inn(酒馆):每一个角色都是一炉火,故事在余烬里继续。
- 放弃 RikkaHub fork 路线:酒馆格式属于“重实现”,与官方行为持续漂移,上游合并代价高,历史包袱重。
- 否决“官方服务端当引擎”:源码实证——SillyTavern 的兼容内核(世界书扫描、宏展开、斜杠、提示词组装、群聊)全部位于前端 JS(
public/scripts/world-info.js、macros/engine/、slash-commands/、script.js),与 DOM 焊死;Node 服务端只是存储 + API 转发层。只保留服务端并不能白拿兼容性。 - 否决 WebView 壳:要求真原生客户端与全新 UI,不套官方网页。
- 最终路线:新项目、Kotlin + Compose、参考官方源码翻译 + 重写酒馆逻辑层;官方 Node 服务端仅作为可选的存储/API 辅助进程(无浏览器界面)。
- 角色卡:PNG V2/V3(tEXt/ccv3)与 JSON 导入导出(对齐官方:官方只导出 PNG/JSON)、CharX/YAML/BYAF 导入、从 URL 导入(对齐官方 content-manager)、V3 assets(icon/background/voice)
- 世界书:关键词扫描、注入位置(before/after char)、深度、递归、粘性/冷却、分组评分、向量化、全字段(secondary_keys/insertion_order/selective/priority/probability/delay)、三级世界书(全局 / 会话 / 角色)
- 宏系统:
{{user}}、{{char}}、{{random}}、{{pick}}、{{roll}}、{{if}}、变量宏等(对齐 Macros 2.0) - 斜杠命令:官方常用命令全量,行为一致
- 群聊:多角色、多种响应模式
- 提示词组装:角色字段 + 示例对话 + 世界书 + 作者注释 + 历史消息(与官方
script.js行为一致) - 预设 / 人设 / regex 脚本 / tokenizer / SSE 流式
组件清单见 docs/COMPONENTS.md(有现成/没现成分表)。官方数据格式总表见 docs/FORMATS.md(5 种导入/导出对齐现状)。PNG 卡片内嵌规范见 docs/PNG_FORMAT.md(官方 1:1)。功能覆盖总清单见 docs/FEATURES.md(对照官方 release 8172dcd,含优先级与 UI 映射)。本地官方源码:~/sillytavern-ref(release 分支,供翻译与回归对照)。
做这个 App 的初衷:多数开源项目功能强但操作逻辑反直觉。以下守则对所有界面生效,是验收标准,不是建议。
- 打开即聊:导入卡或「直接开始聊天」前,不需要先研究设置;没配模型时给友好引导(“先选一个模型”→ 一键跳转模型页),而不是报错
- 一步到位:导入角色卡自动带世界书 / 主题 / 开场白,直接可聊,不需要再手动挂载任何东西
- 默认值合理:所有设置默认即可用;高级项默认收起,绝不一上来要求用户配置
- 全中文 + 官方术语括号:按钮、设置、报错全中文;官方英文术语保留括号,方便对照社区资料
- 人话报错:错误只说人话(“网络不通,请检查地址或 Key”),不抛代码/裸异常;能重试的一键重试
- 可撤销、有确认:删除角色 / 聊天 / 世界书条目二次确认;误操作能撤销或恢复
- 手势符合直觉:返回手势、长按菜单、滑动切回复、下拉刷新——跟主流 App 的直觉一致,不发明新手势(交互参考 AI 陪伴类标杆:Character.AI 式沉浸对话、微信式返回/长按)
- 搜索无处不在:角色、会话、世界书条目、设置项全部可搜索(设置搜索尤其重要)
- 状态可见:生成中(流式 + 停止按钮)、导入进度、后台任务通知,每一步都有反馈
- 空状态引导:任何空页面都给出“下一步做什么”的按钮,绝不白屏
- 数据透明:导出路径中文提示(“已导出到 下载/EmberInn”);备份位置可见;数据默认只存本地
- 不做功能陈列馆:默认界面只放高频操作,低频功能收进菜单;新功能不堆按钮
app Compose UI(角色列表、聊天、设置、主题)
engine 酒馆领域引擎(纯 Kotlin,不依赖 UI)
├─ 领域模块(各带官方差分):CardParser / WorldBookScanner / MacroEngine /
│ SlashParser / RegexEngine / 提供商转换器 / 媒体 / 群聊 / 表情 …
└─ 编排层(总装入口):PromptPipeline —— 对齐官方 prepareOpenAIMessages,
一个入口把 世界书扫描 + 人设 + 作者注释 + 示例 + 历史 + 控制提示
组装成最终 CompletionMessage;只编排不写算法(算法都在领域模块)
data Room / DataStore / 文件存储
provider LlmProvider 接口 + 服务商注册表(数据驱动 JSON)
services TTS / STT / 图像 / 向量 / 翻译 接口
theme 全局主题 + 角色卡驱动主题
| 接口 | 说明 |
|---|---|
LlmProvider |
OpenAI-compatible / Anthropic / Gemini / 自定义,协议实现类很少变 |
CardParser |
V2 / V3 / CharX,为未来 V4 留口子 |
TtsProvider / ImageGenProvider / VectorStoreProvider / TranslatorProvider |
后端可插拔 |
ThemeSource |
全局预设 / 角色卡取色 |
| 扩展执行层 | 先做自己的插件 API;ST 前端扩展兼容按三分类分级推进(见下),不承诺全兼容 |
ST 扩展兼容三分类(对照社区扩展调研后分级):
- 纯逻辑类(regex 脚本、宏计算、部分记忆/摘要逻辑,不碰 DOM):QuickJS 沙箱 + ST 全局 API shim(
getContext()/eventSource/chat/generateRaw()),目标“自动可跑” - 轻量 UI 类(只在设置抽屉加开关/滑块的插件):逻辑复用 QuickJS,UI 原生重绘,为每个目标插件写设置读写适配层(非自动兼容)
- 结构性不兼容(依赖 ST Node 服务端插件、ST-Extras Python 服务、复杂 DOM 交互如拖拽面板/节点编辑器):明确排除,必要时提供原生重实现替代 开发顺序:先对官方及社区扩展做 DOM 依赖/服务端依赖分类统计,按占比定投入优先级。
每条记录为数据而非代码:id / display_name / protocol / auth_type / base_url / region_variants / extra_headers / api_version / models_endpoint / default_models / requires_key。
注册表现有 22 家(2026-08-07 联网核实 + 官方 chat_completions.js 端点对照):
OpenAI(gpt-5.5 / 5.4)、Anthropic(claude-opus-5 / sonnet-5 / haiku-4-5)、
Gemini AI Studio / Vertex(gemini-3.6-flash / 3.5-flash / 3-pro)、DeepSeek(deepseek-v4-flash / pro,官方走 /beta)、
OpenRouter、Groq、Ollama(本地)、Mistral、xAI(grok-4.3)、Moonshot(kimi-k3)、
智谱(glm-5.2)、通义 DashScope(qwen3.7)、硅基流动(国内/国际)、Z.AI(通用/编码)、
MiniMax(国际 minimax.io / 国内 minimaxi.com)、Fireworks、Perplexity(无 /models,走最小对话探测)、
Cloudflare Workers AI(账户 ID + /ai/v1)、Azure OpenAI(deployment + api-version 2024-12-01)、火山方舟(豆包 Seed 2.1)、自定义。
模型列表拉取按官方 /status 逻辑实现:openai data[].id、google models[].name(过滤 generateContent)、
workers result[].name、azure value[].id;拉不到时用 default_models 兜底。
远期:注册表可做成远程可更新(版本号 + 增量拉取),新厂商无需发版。
- Material 3 Expressive + 动态取色 + 移动优先分层导航
- 信息架构:底部导航(角色 / 聊天 / 设置)+ 独立二级设置页;不照搬 ST 桌面多面板
- 大屏自适应:手机单栏底部导航;平板 / 折叠屏双栏(列表 + 聊天)
- 渲染:Markdown(mikepenz renderer 0.43.0)、LaTeX(huarangmeng/latex)、代码高亮(Highlights)、图片/GIF(Coil3 + coil-gif)、音视频附件(Media3 ExoPlayer 1.10.0)、Mermaid / 复杂 HTML 用局部 WebView 兜底、流式消息增量渲染
第一层 全局主题(用户设置):浅色 / 深色 / 跟随系统 + 预设主题 + 视觉氛围(标准/柔和/清冷/明快/自定义:饱和度、冷暖、光效)+ 字体(系统/衬线/霞鹜文楷下载)/ 圆角 / 密度 / 气泡样式 / 背景模糊开关
第二层 角色卡驱动(核心卖点):每张卡一套观感 —— 配色 / 背景 / 气泡色 / 名字色 / 形状 / 字体
第三层 状态微调:流式生成微光、深水区/夜间可单独锁深色
优先级:角色卡 > 全局预设 > 系统默认
- 卡图 → Palette 取色(浅色取
Muted低饱和色,深色取Vibrant高饱和色) - 取到的颜色作为 seed → MaterialKolor 生成整套 M3 配色(light / dark 两套)
- 无头像卡 / 未取到色 → 用卡名哈希生成稳定 seed 色(可复现、每卡不同)
- 显式主题配方 seed 优先级最高;结果随卡持久化
- 切换角色:配色
animateColorAsState过渡 + 背景 crossfade(200–300ms)
- 默认 = 氛围渐变:从卡图取 2–4 个颜色 → 低饱和 Mesh Gradient + 光晕(不是主图,是主图的光),浅色/深色下都干净
- 实现:官方
androidx.compose.ui.graphics.MeshGradient(已入 Compose UI,无需第三方库);动画版参考 ComposeMeshGradient
- 实现:官方
- 可选 = 卡图玻璃背景:主图 + 模糊 + 遮罩(深色叠 60–75% 暗色,浅色叠 25–35% 白/纸色),保证文字可读
- 未设显式背景时,角色头像自动作为玻璃背景(模糊 + 遮罩);显式背景(会话/主题配方)优先级最高
- 遮罩可全局设置:头像玻璃开关 / 模糊五档(无/轻/标准/重/极) / 深色遮罩颜色+强度 0-90% / 浅色遮罩颜色+强度 0-60% / 一键恢复默认(外观与主题 → 视觉与质感)
- 每张卡独立记忆,可随时切换 / 关闭
- 顶栏 / 输入栏 / 浮层 / 对话框:
blur+ 半透明 + 1px 高光描边 + 轻微内阴影- 实现:skydoves/Cloudy(KMP 模糊 + 液态玻璃,GPU 加速 + 旧设备 CPU 降级);备选 Haze(可调降采样)、miuix-blur(自适应降采样)
- 正文区保持干净,不全屏玻璃(可读性优先)
- 依据:iOS 26 Liquid Glass 引发全行业跟进,国产安卓 2026 年集体上新玻璃 UI;安卓官方暂不跟进 → 第三方 App 的差异化机会
- 形状:每张卡可带 圆润 16dp / 方正 4dp / 浑圆 24dp
- 动效:M3 Expressive spring 弹性动效
- 字体:中文氛围字体可下载(霞鹜文楷、思源宋体等),默认系统字体
- 表面染色:背景表面带角色主色 tint(Android 16 / Expressive 方向),纯黑仅作可选
| 主题 | 风格 | 浅色底 | 深色底 | 点缀色 |
|---|---|---|---|---|
| 墨韵 | 水墨风 | 宣纸白 | 墨黑 | 朱砂红 |
| 青瓷 | 雅致 | 米白 | 青墨 | 青绿 |
| 夜航 | 沉稳 | 雾白 | 深蓝黑 | 琥珀 |
| 丹砂 | 热烈 | 纸白 | 暖黑 | 丹红 |
| 琉璃 | 现代玻璃 | 冰白 | 玻璃黑 | 渐变紫蓝 |
| 简约纸感 | 极简 | 象牙白 | 石墨 | 中性灰 |
| 酒馆官方 | SillyTavern 默认 | 象牙米白 | 墨黑 #171717 | 青绿 + 引用橙 |
| 竹青 | 竹林晨光 | 米绿 | 竹墨 | 青绿 |
| 暮紫 | 黄昏暮色 | 淡紫白 | 暮黑 | 紫 + 暖橙 |
| 晨雾 | 雾蓝清冷 | 雾白 | 深蓝灰 | 雾蓝 |
| 樱粉 | 樱色温柔 | 粉白 | 樱黑 | 粉 + 淡紫 |
- 默认浅色(暖纸色底,不用纯白
#FFFFFF),深色“跟随系统”可选 - 消息布局:AI 纯文本流(无气泡,纸面阅读感)+ 用户右侧胶囊(AI 陪伴对话路线,参照 Character.AI);头像 / 名字 / 时间戳左对齐;最后一条 AI 常驻快捷按钮,历史消息长按操作
- 底部导航 + 返回手势 + 下拉刷新 + 长按菜单(复制 / 编辑 / 删除 / 重新生成 / 滑动切回复)
- 设置项中文为主,字号调节、夜间模式自动、免打扰
- 分享 / 导出路径用中文提示(“已导出到…”)
- 未导入卡 / 未取色时:全局默认跟随系统壁纸动态色(Material You)
- 角色卡 seed 优先覆盖:显式配方 seed > 头像取色 / 名字哈希 > 全局预设
- 每张卡的完整配方(seed + 背景 + 形状 + 字体)可导出 / 导入 / 分享
| 用途 | 组件 | 坐标 |
|---|---|---|
| 主题框架 | Material3 基线 1.4.0 稳定版(Expressive 组件在 1.5.0-alpha,等稳定后再启用) | androidx.compose.material3:material3 |
| 种子色 → M3 配色 | MaterialKolor 4.1.x 稳定版(勿用 5.0 alpha) | com.jordond.materialkolor:* |
| 氛围渐变 | 官方 MeshGradient(动画版参考 ComposeMeshGradient) | androidx.compose.ui.graphics.MeshGradient |
| 玻璃 / 模糊 | skydoves/Cloudy 0.7.1 稳定版(GPU + 旧设备 CPU 降级);备选 Haze、miuix-blur | com.github.skydoves:cloudy:0.7.1 |
| 卡图取色 | Palette / landscapist-palette | androidx.palette:palette |
| 图片加载 | Coil 3 | io.coil-kt.coil3:coil-compose |
| 图标 | Phosphor Icons(内置官方路径,见 scripts/gen-phosphor-icons.mjs) | app/.../ui/icons/PhosphorIcons.kt |
| 中文字体(可下载) | 霞鹜文楷 Screen/Lite、霞鹜新晰黑(OFL 开源) | 可下载字体包 / Google Fonts Provider |
| 主题切换动画 | animateColorAsState + Crossfade |
内置 |
| 持久化 | Room + DataStore | androidx |
- 取色必须在 IO 线程跑一次并缓存,禁止 UI 线程执行
- 背景模糊用 1/4 尺寸位图,禁用原图,避免滚动掉帧
- 所有背景上的文字必须叠遮罩(浅色卡图 + 白字 = 灾难)
- 主题数据(seed / 背景 / 形状 / 字体)跟随角色卡导入导出
- 设置页做实时预览(选主题直接看到效果)
- MaterialKolor 已移除 Expressive 支持(4.0+):配色走基线 M3,Expressive 只做组件/动效层,两者不冲突
- 生产依赖 M3 1.4.0 稳定版;Expressive 组件(1.5.0-alpha)仅在尝鲜分支启用,不进入主线
- 中文字体用屏幕版/轻便版(霞鹜文楷 Screen/Lite),完整版体积过大,作可下载项
- 配色系统 = 1 个主色 seed(生成整套 M3 色调,约 20+ 色值,和谐由源头统一);背景氛围 = 取 2–4 个低饱和色(负责丰富与辨识度)——界面克制、背景出彩
- 可选“副 seed”:取卡图第二主色降饱和作 tertiary(第三色),默认关闭,防花哨
- 背景氛围渐变一律低饱和(取色后降饱和 30–40%),光晕克制;禁止高饱和霓虹渐变球(2026 已俗)
- 玻璃效果只用于浮层 / 输入栏 / 顶栏,正文区永远干净;同屏玻璃元素不超过 2–3 处
- 每屏只有一个视觉焦点:角色图或聊天内容,不叠加抢眼
- 动效 200–300ms,spring 只用于交互反馈;常驻动画仅限生成微光
- 深色默认 tinted 灰(Android 16 方向),纯黑仅作可选
- 排版 2–3 档字号、行高 1.5–1.6、对比度达标
- 默认配方保持克制;用户自定义“花哨”是用户自由,但不进默认主题
- 默认系统字体;氛围字体(霞鹜文楷等)作可下载可选
高级感 = 克制(Quiet Luxury,2026 主流方向)
- 奢侈品设计的信号不是装饰,是留白、清晰层级、有限色彩强调、克制对比——安静界面没有地方藏弱层级
- “极简做对”的标准:3 色上限、排版当主角、留白是主动设计(不是空白)
- 每屏一个强调方向(one accent direction at a time),一次只突出一个东西
色彩
- 界面主色 3 色以内:1 个 seed 生成的主色 + 中性底色 + 背景氛围的低饱和色
- 低饱和 = 高级;高饱和只做点缀(按钮/链接/名字色),面积越小越好
- 预设主题对应情绪:墨韵=水墨留白 · 青瓷=雅 · 夜航=沉稳 · 丹砂=热烈但克制 · 琉璃=现代玻璃 · 简约纸感=quiet luxury · 酒馆官方=SillyTavern 1.18 默认(public/style.css :root 核对)· 竹青=清新 · 暮紫=沉静 · 晨雾=清冷 · 樱粉=温柔
中文美学基因(留白/水墨/雅)
- 中国 UI 设计的传统是“计白当黑、以无胜有”:视觉焦点靠留白引导,不靠装饰堆砌
- 水墨的用法:黑白灰墨韵打底 + 少量朱砂级点缀,不堆具象元素
- 聊天页应是大面积留白 + 低饱和氛围光 + 少量角色色强调——这就是“雅”
排版
- 全 App ≤ 2 种字体(默认 1 种系统黑体 + 可选氛围字体);每屏 ≤ 3 种字重/字号组合
- 字号、字重、颜色是建立层级的三个杠杆,优先于一切装饰
- 中文行高 1.5–1.6,正文 16sp,标题 20–24sp,说明 12–13sp
动效与材质
- 柔和动效(soft motion):200–300ms,一次只动一个东西;spring 仅用于交互反馈
- 材质诚实:玻璃只做表面(浮层/输入栏/顶栏),正文区永远干净;阴影/光晕克制
- 生成微光是唯一允许的常驻动画,亮度低、节奏慢
来源:
EmberInn-UI质感提升方案。问题诊断:功能流畅、M3 规范,但"任何一个 M3 App"的既视感。根本原因:处处用 M3 组件默认值(默认圆角/阴影/字体/算法直出配色),规范只保证"正确",不保证"有态度"。本清单是在规范之上加一层专属的视觉偏好。 验收自查:截图盲测——和任意有质感的 App 并排对比阴影软硬/图标粗细/间距节奏/饱和度。
第一批(纯技术、无设计风险,先做)
- 阴影升级新 API:
Modifier.dropShadow()/innerShadow()(color/radius/spread/offset/brush),阴影色用元素自身颜色深色版而非纯黑;开工前确认 API 在锁定 Compose 版本脱离 experimental,未稳定则用社区coloredShadow兜底 - 组件走主题强调色:全局检查
SwitchDefaults.colors()等 M3 组件颜色是否接角色/主题动态色,而非默认 - 触觉反馈铺满关键交互:
LocalHapticFeedback.performHapticFeedback()按语义匹配(确认用Confirm、开关用ToggleOn/Off、删除用Reject、点选用极轻反馈);覆盖发送/切换角色/删除确认/开关 - 骨架屏替换转圈 Loading:自写
shimmerEffect()(rememberInfiniteTransition + 扫光渐变,约 20 行),颜色跟随角色主题色而非灰色默认(现成库灰骨架无法适配动态取色) - 首页角色卡直接用取色结果做底色:取色系统已接(seedColor),卡片底色必须体现"每角色专属氛围",禁止统一灰白底
- 声音反馈:已按用户要求移除(2026-08-11,不再实现)
第二批(需设计判断) 7. 字体真正落地:氛围字体(霞鹜文楷/思源宋体)不只"可下载",角色名/旁白优先接入,正文保持清晰无衬线 8. 形状语言区分角色:每卡圆润 16dp / 方正 4dp / 浑圆 24dp 形状真正在跑,禁止全局统一 M3 默认 12dp 9. 六套预设主题各自独立性格:不只换 seed 色——间距节奏/动效速度/形状语言也随性格变(墨韵留白大动效慢、丹砂利落动效快) 10. 算法取色后加统一滤镜:MaterialKolor 输出后统一降饱和一档 + 背景叠专属冷灰/暖灰 tint,让任何 seed 出来的颜色都带统一气质 11. 空状态设计:替换"暂无数据"默认文案/灰图标,用有语气的文案 + 克制的轻动效,覆盖首页无卡、聊天无记录 12. 设置页重新设计:避免"图标+文字+箭头"机械通栏,按语义分组独立卡片区块、组间留白、分组标题样式化
第三批(排版与一致性)
13. 排版层级大胆:标题/正文字号级差、字重跳跃更鲜明(Bold 直跳 Light),层级对比 = 经过设计
14. 图标一致性:全局排查混用 Icons.Default.xxx(Material 内置)与 Phosphor 的情况,统一 Phosphor
执行原则:每次只集中做一到两项深做,做完验证再推进;MeshGradient 与新阴影 API 有版本 churn 风险,接入前先用最小 spike 验证 API 在锁定版本可用。
- 生产依赖一律使用当前最新稳定版;仅有 alpha/beta 才支持的功能放“尝鲜分支”或功能开关,不进主线
- 2026-08 实测基线:Compose BOM 2026.06.01 · Kotlin 2.4.10 · material3 1.4.0(Expressive 1.5.0-alpha25 仅尝鲜)· MaterialKolor 4.1.x(5.0 为 alpha,不用)· Coil 3.5.0(+coil-gif)· Media3 1.10.0 · DataStore 1.2.1 · activity-compose 1.13.0 · OkHttp 5.4.0 · multiplatform-markdown-renderer 0.43.0 · Palette / Room / Navigation 跟最新稳定版
- 升级流程:Renovate / Dependabot 每周自动 PR → CI 通过自动合 patch/minor → major 人工看 changelog + 全量回归
- 小库失活预案:直接把开源源码搬进项目(vendoring),不守死库
NativeTavern 的问题(源码核实:home_screen.dart):AppBar + 一长串 ListTile 卡片 + 一个 FAB;首页=纯聊天列表,无层级、无氛围、无搜索、角色藏在二级页,默认深色。
EmberInn 首页(余烬美学):
┌──────────────────────────────┐
│ ✦ 余烬酒馆 [导入] │ ← 标题字 + 毛玻璃顶栏
│ 🔍 搜索角色 / 会话 / 世界书 │ ← 全局搜索
│ ┌──────────────────────────┐ │
│ │ ✨ AI 对话(玻璃渐变卡) │ │ ← 置顶:无卡直接聊
│ └──────────────────────────┘ │
│ 最近聊过(横向卡片:头像+名字)│ ← 1 秒续聊
│ ── 我的角色 ── │
│ ┌────┐ ┌────┐ ┌────┐ │
│ │卡图 │ │卡图 │ │卡图 │ │ ← 双列卡片网格:卡图为主角
│ │名字 │ │名字 │ │名字 │ │ 名字 + 最近消息预览
│ └────┘ └────┘ └────┘ │
│ [+ 导入角色卡] │ ← FAB
└──────────────────────────────┘
[角色] [聊天] [设置]
优化点对照:
- 首页=角色书架,不是聊天列表;聊天列表移到底部「聊天」Tab
- 角色卡是视觉主角:卡图大卡片 + 名字 + 最近消息,主题色点缀,每张卡一眼不同
- 搜索置顶且全局(角色/会话/世界书/设置)
- 「AI 对话」玻璃渐变卡置顶,空状态双按钮(导入卡 / 直接聊天)
- 最近聊过横向滑,兼顾续聊效率
- 默认浅色暖纸底 + 氛围渐变 + 毛玻璃顶栏,克制动效
- 卡片交互:点卡片=进聊天(主操作);长按=快捷菜单(置顶/新会话/编辑/导出/删除);右上角「⋯」=同一菜单的显式入口——卡片下面不放按钮排,保持卡面干净
- 开场:欢迎页直接淡入(Compose 动画,约 1.6 秒后显示内容);仅首次,之后不再播放
- 欢迎页:「欢迎来到余烬酒馆」+ 副标题“每个角色都是一炉火,故事在余烬里继续”
- 两个主选项(玻璃卡片,大按钮,低饱和氛围渐变背景):
- 「导入角色卡」→ 直接打开文件选择器(PNG / JSON / CharX)
- 「直接开始聊天」→ 进入「AI 对话」并带一句默认开场(“我是余烬,想聊点什么?”)
- 底部一行小字:数据仅保存在本地(信任信号)
- 允许「跳过」→ 进入角色列表空状态
- 启动无黑屏、无图标动画:直接进入角色列表(按用户要求不搞开头动画)
- 直接进角色列表首页:AI 对话(置顶)→ 最近聊过 → 全部角色
- 设置可选:「启动时直接进入上次聊天」(默认关)
- 角色列表置顶「AI 对话」:点开即新会话
- 聊天 Tab:「+」新建对话(默认 AI 对话,可改选角色)
- 角色内:顶栏菜单「新会话」,每个角色可开多个空白会话
- 空白聊天 = 无历史的新会话;主题沿用当前角色配方或全局主题
角色 Tab(首页)
├─ 搜索:角色 + 会话 + 世界书 + 设置(全局搜)
├─ AI 对话(置顶)
├─ 最近聊过(横向卡片)
├─ 全部角色(长按 = 置顶 / 编辑 / 导出 / 删除)
└─ FAB:导入角色卡
角色详情页(入口:聊天页 ⋮ →「角色详情」,或角色列表长按 →「编辑」)
├─ 基本信息:名字 / 头像 / 标签 / 版本 / 作者
├─ 卡字段(**分字段展示,每字段一行**:标签 + 预览 + 点击展开编辑):
│ 描述 / 性格 / 场景 / 开场白(含备选)/ 示例对话 / 系统提示 / PHI / 创作者备注
├─ 扩展字段:extensions / depth_prompt / assets(图标/背景/语音)/ skip 系列
├─ 世界书(该卡)
├─ 正则 / 变量(该卡)
├─ 模型覆盖(可选,默认收起)
├─ 主题配方
└─ 会话列表 / 新会话 / 导出 / 删除
聊天页
├─ 顶栏:返回 + 角色名 + ⋮
├─ 消息流:长按 = 复制 / 编辑 / 重新生成 / 继续生成 / 删除(AI 消息多“冒充”);左右滑 = 切换回复;点选气泡浮现小操作条
│ ├─ **折中交互(默认)**:最后一条 AI 消息下方常驻小按钮(复制 / 重新生成 / 继续 / 删除)——高频操作集中在最后一条;历史消息保持干净
│ └─ **设置开关**:常驻按钮模式(每条都显示,旧项目习惯)/ 沉浸模式(全隐藏)
├─ 输入区:+(附件 / 语音) [输入框] 🎤 ➤(生成中变 ■)
└─ ⋮ 菜单:人设 / 作者注释 / 预设 / 世界书快捷 / 统计 / 主题背景 / 导出聊天
聊天 Tab
├─ 全部会话(按时间;长按 = 置顶 / 删除 / 导出)
└─ +:新建对话 / 新建群聊(勾选已有角色)
设置 Tab
├─ 外观与主题 / 提供商与模型 / 语音 / 服务 / 数据与隐私 / 关于
└─ 顶部设置搜索
统一规则
├─ 任何功能 ≤ 3 步可达;一个功能只有一个“家”(不重复摆放)
├─ 长按承载高频操作;删除统一二次确认
├─ 空状态给“下一步”按钮;报错说人话
└─ 平板 / 折叠屏:双栏 + Navigation Rail,逻辑不变
主设置(底部导航「设置」Tab)=所有人的公共环境
├─ 外观与主题:浅/深/跟随、全局预设主题、字体、圆角密度、背景模糊、启动行为
├─ 提供商与模型:连接档案(地址/Key)、全局默认模型、默认采样参数、代理
├─ 语音:TTS 朗读、STT 语音输入
├─ 服务:翻译、图像生成、向量库、搜索
├─ 快捷回复:全局预设 + 槽位(官方 Quick Reply 字段,输入区快捷盘执行)
├─ 数据与隐私:存储位置、备份/导出、清缓存
└─ 关于:版本、许可、开源仓库
角色设置(每张卡单独,从角色详情页进)=只管这一个角色
├─ 角色信息:名字/头像/卡字段(描述、性格、场景、示例对话、系统提示、PHI…)
├─ 世界书:内嵌(导入随卡带入)+ 可挂外置
├─ 正则 / 变量:本角色专用
├─ 模型覆盖(可选,默认收起):连接档案、采样、上下文长度
├─ 主题配方:seed、背景、形状、字体、风格档位、浅/深锁定
└─ 会话:聊天列表、新会话、导出
「AI 对话」=无卡角色,同样有自己的角色设置页(名字/头像/系统提示词/世界书/模型覆盖/主题)
重叠项规则:模型、正则、世界书、预设 = 默认“跟随全局”,角色页可“本角色覆盖”;主题 = 默认跟随全局,角色卡自动生成配方覆盖,可一键恢复;卡字段 = 只属于角色,主设置不出现。
官方源码确认的消息级操作:继续生成(mes_continue)、冒充(mes_impersonate)、停止(mes_stop)、重新生成、删除(二次确认)、书签、编辑、滑动切换、复制、TTS 朗读、token 统计;输入区可选快捷「继续 / 冒充」(power-user quick_continue / quick_impersonate)。
| 功能 | 官方出处 | 图标(Phosphor) | 位置 |
|---|---|---|---|
| 复制 | hover 按钮 | Copy |
最后一条常驻 + 长按菜单 |
| 重新生成 | option_regenerate | ArrowsClockwise |
最后一条常驻 + 长按菜单 |
| 继续生成 | mes_continue / quick_continue | CaretDoubleRight |
最后一条常驻 + 长按菜单 + 输入区快捷(可选) |
| 删除 | option_delete_mes(二次确认) | TrashSimple |
最后一条常驻 + 长按菜单 |
| 编辑 | hover 按钮 | PencilSimple |
长按菜单 / 选中操作条 |
| 冒充 | mes_impersonate / quick_impersonate | MaskHappy |
长按菜单(AI 消息)+ 输入区快捷(可选) |
| 滑动切换 | swipe | 手势左右滑(菜单可加 CaretLeft/CaretRight) |
手势为主 |
| 书签 | option_new_bookmark | BookmarkSimple |
长按菜单 |
| TTS 朗读 | hover 按钮 | SpeakerHigh |
长按菜单 |
| token 统计 | option_toggle_logprobs | ChartBar |
长按菜单 |
| 更多 | — | DotsThree |
卡片/气泡右上角(显式入口) |
| 停止 | mes_stop | Square |
输入区(生成中) |
规则:气泡本身无按钮;最后一条 AI 消息常驻 4 键(复制/重生成/继续/删除);完整操作收长按菜单;图标统一 Phosphor Regular、24dp、onSurfaceVariant(激活 primary)。
官方对照:核心 = Showdown(Markdown)+ highlight.js(代码高亮)+ DOMPurify(HTML 消毒);LaTeX / Mermaid 官方靠社区扩展,我们原生覆盖。
- 消息排版主题(可配):引号(blockquote)变色 + 斜体变色——引用块左栏/底色用角色主题色,斜体用柔和 tint;每张卡可带“消息样式”配方(引用色 / 斜体色 / 代码块风格 / 字号 / 行高)
- Markdown 全量:标题、粗体、斜体、引用、行内代码、代码块(Highlights 高亮)、表格、链接、图片(Coil)、列表、任务列表、删除线
- 数学公式:LaTeX(huarangmeng/latex)
- 图表:Mermaid → 局部 WebView 兜底(离线渲染)
- HTML 消息:可选开关(默认关),开启后用本地 WebView + 消毒渲染,对齐官方 power-user HTML 设置
- 流式渲染:增量解析 + 增量排版,不逐 token 全量重渲染;长消息 LazyColumn 虚拟化
- 音视频附件:消息里的 audio/video 用 Media3 ExoPlayer(官方消息 extra.media → 引擎 MediaEngine 判定 → Media3 渲染);图片/GIF 用 Coil3
- 入口:输入区「📚」按钮或快捷工具盘展开
- 面板内容:当前命中 / 注入的世界书条目列表 + 指示灯:
- 🔵 常驻(Constant,永久注入)
- 🟢 关键词命中且已注入
- 🟠 关键词命中但未注入(预算不足 / 优先级被裁)
- ⚪ 未命中不显示(或置灰收起)
- 每行显示:条目名、命中关键词、注入位置、占用的 token
- 引擎要求:
WorldBookScanner必须返回完整 match 结果(命中条目 / 命中键 / 注入状态 / 预算占用),状态面板只是它的视图——设计引擎时就要带上
- 输入框上方拖拽手柄,上拉展开“快捷工具盘”:世界书状态 · 上下文占比胶囊(圆环进度 + token/上限 + 百分比,绿→黄→橙→红分级,点开详细分解)· 快捷回复 · 常用正则开关 · 图像生成 · 附件 · TTS 朗读
- 不放进工具盘:群聊成员(属于群聊页管理,官方在群聊界面内管理成员,与输入上下文无关);提供商/模型/主题等环境设置(留在主设置)
- 竞品对照(NativeTavern):它有上下文占比指示器(输入区可展开菜单)但没有世界书命中亮灯(只有内部 activeWorldInfoIds + 调试日志);默认深色写死。我们的差异点:命中指示灯 + 默认浅色 + 常驻上下文占比
- 也可收成底部弹层(Bottom Sheet),用完即收,不占聊天空间
- 主设置页顶部加“常用”折叠区:主题 · 模型 · 语音 · 备份,高频设置一眼可见
之前文档里的 📚⚡🖼 只是占位示意,不是最终图标。
- 主推:Phosphor Icons(1512 个,Regular 字重)——圆头端点、有机现代,最配“余烬/炉火”的温暖美学,撞车少
- 系统级备选:Material Symbols Rounded(官方 4067 个)——与 M3 原生契合,最稳
- 内容级备选:Lucide(旧项目已用,1.5px 圆头细线)——简洁现代
- 规范:24dp 网格 · 统一字重(全 App 只用一种字重档)· 圆角端点 · 默认
onSurfaceVariant,激活primary,警示error· 状态图标(命中灯)用小圆点自绘,不用图标代替
官方仓库呼声最高的功能(GitHub issue 评论数排序):
- 每条消息都能滑动切换回复(不只最后一条)— #1731
- 聊天历史分块裁剪,加快 prompt 构建 — #1278
- RAG / 知识库完善 — #1671
- 快捷回复脚本全屏编辑器 — #2285
- 一键生成聊天背景 — #937
- 内置网络代理(HTTP/SOCKS,非 AI Agent)— #831
- 无障碍 / 读屏支持 — #2694
- 世界书负深度 — #3344
- 聊天内单独显示角色名 — #4357
- 世界书注入改进 / 激活组 / Freeze to History — #5655 / #3762 / #5852
- EPIC:把 Persona 并入 Character,模型与参数按角色设置 — #3139(验证了我们的“角色为唯一主体 + 每角色模型覆盖”设计)
社区扩展热度排行(2025-2026): 表情精灵(Character Expressions)> 视觉小说模式(Visual Novel Mode)> TTS > 记忆/总结 > 世界书。
市场缺口(我们的机会):
- 世界书命中指示灯——官方与 NativeTavern 均无(只有内部数据/调试日志)
- 移动端真原生 + 中文界面 + 中文美学主题——无一家做全
- 上下文透明度(占比 + 世界书命中状态)——权力用户刚需,竞品不可视
- 角色卡驱动主题(每卡一套观感)——无一家做到位
- 人性化细节(设置搜索 / 空状态引导 / 人话报错 / 可撤销)——开源项目普遍缺失
交互参照命理2(RikkaHub Plus)
SettingProviderPage/ProviderConfigure:卡片列表 → 详情编辑,不是向导。 底层协议与接口仍按酒馆官方 1:1(见“服务商注册表”),UI 层自由。
- 提供商列表:品牌 SVG 头像(
assets/icons,参照命理2 AutoAIIcon;无品牌图标的厂商用首字母圆形兜底)+ 名称 + 一句话说明 + 已配置/未配置状态;顶部搜索,已保存连接可快速切换/删除 - 详情编辑:名称 / API Key(密码遮罩 + 显示切换,粘贴自动去空格)/ 接口地址(未配置时自动预填厂商默认地址,来自 providers.json)/ 区域(硅基流动、Z.AI、MiniMax)/ Workers 账户 ID / Azure API 版本 / 默认模型(底部弹层 + 搜索选择)
- 测试连接:一键验证(复用官方 /status 模型列表逻辑;无模型列表端点的厂商走最小对话探测),成功自动拉取模型列表;拉不到用预填 default_models 兜底
连接档案:可建多个(命名、切换)、全局默认 + 每角色可选覆盖(呼应官方 EPIC #3139);扫码导入导出分享(沿用旧项目概念)
- 供应商 = 数据 + 协议路由:openai-compatible / anthropic / google / mistral / xai / cohere / ai21,加新厂商只改注册表 JSON,不动协议代码
- 可扩展接口:LlmProvider / CardParser / WorldBookScanner / MacroEngine / SlashParser / PromptAssembler / TTS / ImageGen / VectorStore / Translator / ThemeSource——新功能按接口插,不侵入核心
- 上游跟进(我们是重写,不是 git 合并官方):官方发版 → 对照 CHANGELOG + 官方行为回归测试 → 翻译/移植新功能到对应模块 → CI 全量验证;按版本节奏(每月/每大版)例行执行
- 分层纪律:engine 不依赖 UI;data 不依赖 engine;provider 只做协议;新增功能先落接口再落实现
- 单向依赖:
app → engine / data / provider / services / theme;engine 不依赖 UI,data 不依赖 engine,provider 只做协议——依赖只朝一个方向 - 先接口后实现:所有可变点(LlmProvider / CardParser / WorldBookScanner / MacroEngine / SlashParser / PromptAssembler / TTS / ImageGen / VectorStore / Translator / ThemeSource)先定接口再写实现;新增功能 = 新实现 + 注册,不侵入核心
- 数据驱动注册表:供应商、主题预设、默认模型 = JSON 数据表;加新条目不改代码
- 接口/事件通信:模块之间通过接口与事件通信,不互相 import 具体实现类
- 功能开关:新功能一律带 feature flag,可灰度、可回滚
- 依赖版本目录:组件版本全部收进
gradle/libs.versions.toml+ Renovate 自动 PR - 上游跟进:官方发版 → CHANGELOG + 官方行为回归测试 → 翻译/移植到对应模块 → CI 全量验证(重写项目不是 git 合并)
- 回归测试锁行为:每个引擎模块配官方行为对照测试,任何改动不得破坏兼容
| 社区需求(官方 issue) | 优先级 | 落点 |
|---|---|---|
| 每条消息滑动切回复 #1731 | P1 ✅ | 聊天页消息流(滑动 + 计数 + 变体列表弹层) |
| 聊天历史分块裁剪 #1278 | P2 | 引擎:上下文管理 / tokenizer |
| RAG / 知识库 #1671 | P1 ✅ | services:向量库(世界书/聊天历史/文件数据银行已接,2026-08-10) |
| 快捷回复全屏编辑器 #2285 | P3 | 快捷回复管理页 |
| 一键生成聊天背景 #937 | P4 ✅ | 主题配方:AI 生成背景(接图像服务) |
| 内置网络代理 #831(HTTP/SOCKS,不是 AI Agent,用于访问国外 API 或中转) | P5 | services:网络代理 |
| 无障碍 / 读屏 #2694 | P0 贯穿 | 图标均有 contentDescription、按钮为文本标签;复杂滑动手势边界登记 |
| 世界书负深度 #3344 | P2 ✅ | 世界书引擎(负深度不注入 + 扫描深度<0 返回空) |
| 聊天内单独显示角色名 #4357 | P1 | 聊天显示 |
| 世界书注入改进 / 激活组 / Freeze to History #5655 #3762 #5852 | P2 | 世界书引擎 |
| Persona 并入 Character + 每角色模型 #3139 | P0 / P2 ✅ | 人设管理 + 角色级模型覆盖 |
| 表情精灵 | P4 | 主题 / 消息头像 |
| 视觉小说模式 | 远期 | — |
| TTS | P3 | services |
| 记忆 / 总结 | P3 | services |
- 长按菜单:Material3
ModalBottomSheet(底部弹层,手机端操作惯例)+combinedClickable(onLongClick)——现成组件,无需第三方库 - 选中操作条:
AnimatedVisibility包一行IconButton(默认隐藏,选中浮现) - 下拉菜单 / 弹窗 / 浮层:
DropdownMenu/Dialog/Popup(Material3 现成) - 动效(Compose 内置,全现成):
- 出现/消失:
AnimatedVisibility+ fadeIn/Out、slideIn/Out、expand/shrinkVertically - 颜色过渡:
animateColorAsState(角色主题切换) - 背景切换:
Crossfade - 内容过渡:
AnimatedContent;数值/尺寸:animateFloatAsState/animateDpAsState - 弹性动效:
spring(M3 风格)
- 出现/消失:
- 需要自己写的只是“编排逻辑”(何时触发/参数/顺序),动画引擎与组件全部现成
引擎层(1:1 官方):纯 Kotlin,不依赖任何 UI 组件;官方 JS 逻辑全部翻译在 engine(角色卡 / 世界书 / 宏 / 斜杠 / 提示词组装 / 提供商转换器 / 媒体 / 群聊 / 表情)。
App 层(自由选型):Kotlin · Jetpack Compose · Material3(1.4.0 稳定)· Navigation Compose · Room · DataStore 1.2.1 · Coil3 3.5.0 · Media3 1.10.0 · OkHttp 5.4.0 · Koin · kotlinx.serialization
渲染与主题:multiplatform-markdown-renderer 0.43.0 · latex-renderer · Highlights/KodeView · androidx.palette · MaterialKolor · MeshGradient · Cloudy
接线纪律:App 只“调用引擎 + 渲染结果”,逻辑不重写;每个引擎能力对应的官方源码位置和 App 接线点见 docs/HANDOFF.md 4.7。完整组件清单(版本 / 为什么选 / 接入点 / 官方源码位置)见 docs/COMPONENTS.md。
- P0 骨架:工程、主题系统、导航、角色列表/详情、V2/V3/JSON 导入
- P1 聊天:消息流、流式渲染、气泡、滑动/长按交互、聊天存储
- P2 引擎:世界书扫描注入、宏引擎、提示词组装、tokenizer
- P3 功能:斜杠、群聊、预设、人设、作者注释、regex
- P4 主题:角色卡取色驱动、模糊背景、毛玻璃、预设主题完成
- P5 服务:STT、服务商注册表完善(TTS/图像/翻译/向量执行层已接)
- P6 扩展:自有插件 API + 官方行为回归测试体系
- 核心兼容层与官方 1:1,UI 层自由:数据格式、字段名、注入算法、宏展开、斜杠行为、导入导出文件必须与官方互读互通;界面、交互、主题完全自主。兼容层 1:1 是长期可维护的前提——官方发版时只需对照行为测试,不会伤及 UI。
- 每个引擎模块配“官方行为回归测试”:同一输入,官方输出 vs 本项目输出。 1.5. 编排层(PromptPipeline 总装)只做“调用顺序与传参”,业务逻辑必须留在各差分模块;App 只调总装,不在 UI 层重拼提示词。
- 核心引擎不依赖 UI 层。
- 服务商注册表只改数据,不改协议代码。
- 保持小步提交,CI 全量验证后再合入。
AGPL-3.0(参考/翻译 SillyTavern 源码,派生义务;分发必须开源)。
分发渠道:以 GitHub Release APK + F-Droid 为主(App 本身不生成内容,内容由用户自带模型 API 生成;上架 Google Play 前需单独确认 BYOK 角色扮演类客户端政策边界)。