🎨 添加文档 && 新增正则脚本模块

Signed-off-by: Echo <1711788888@qq.com>
This commit is contained in:
2026-02-28 15:11:12 +08:00
parent a6234e7bb0
commit 3bfa59cf3e
17 changed files with 26980 additions and 1 deletions

356
docs/优化方案.md Normal file
View File

@@ -0,0 +1,356 @@
## SillyTavern 完全兼容优化方案Go + Gin + Postgres + React
> 目标:基于现有 Go + React 系统,构建一个与 SillyTavern下称 ST高度兼容的角色卡 / 世界书 / 正则 / 预设 / 对话平台。
---
### 1. 总体目标与设计原则
- **技术栈统一**所有核心功能角色卡、世界书、正则、预设、聊天、AI 集成)全部收敛到:
- **后端**`server/` 下的 Go + Gin + PostgreSQL
- **前端**`projects/web-app` 下的 React + TypeScript + Tailwind
- **SillyTavern 完全兼容**
- 支持 ST 角色卡 V2/V3chara_card_v2 / v3导入导出
- 支持 ST 世界书字段及触发逻辑keys/secondary_keys/regex/depth/sticky/cooldown/probability/position 等);
- 支持 ST Regex Scripts 配置placement/runOnEdit/markdownOnly/promptOnly/substituteRegex/min/max depth
- 支持 ST 风格预设与 prompt 注入顺序prompt_order / injection depth/position
- **单一真相来源SSOT**
- **数据库即真相**Postgres 负责持久化所有 ST 相关实体;
- **前端只是 UI**React 只做编辑/展示,请求都经过 API不再有“前端内存版预设/世界书”。
- **可扩展性**
- 提前为插件系统预留 HookonUserInput/onWorldInfoScan/beforePromptBuild/onAssistantDone 等);
- 方便接入未来的 WebSocket/SSE 流式聊天、统计系统、市场/分享功能。
---
### 2. 当前 Go + React 系统现状(基于现有文档与代码)
#### 2.1 后端server/
根据 `projects/docs/development-progress.md`
-**用户系统** 已完成2024-02-26
- 模型:`AppUser`, `AppUserSession`
- API`/app/auth/register`, `/app/auth/login`, `/app/auth/refresh`, `/app/auth/logout`, `/app/auth/userinfo`
- JWT、会话、用户资料、密码修改均已实现
-**角色卡管理AICharacter** 已完成:
- 模型:`AICharacter`(完全兼容 ST V2 格式),使用 JSONB 存储 `tags/alternateGreetings/characterBook/extensions` 等复杂结构
- API
- `POST /app/character`
- `GET /app/character`(分页、搜索、标签筛选)
- `GET /app/character/:id`
- `PUT /app/character/:id`
- `DELETE /app/character/:id`
- `POST /app/character/upload`PNG/JSON 角色卡)
- `GET /app/character/:id/export`(导出 JSON
- 工具:`utils/character_card.go`PNG tEXt chunk / ST V2 工具)
- 🚧 **预设管理**
- 前端页面 `/presets` 已完成(导入 JSON、复制、导出、编辑参数
- 后端预设 API 尚未实现(`development-progress.md` 已给出规划端点)。
- 📋 **对话系统 & AI 集成**
- 前端基础 UI 已完成(`/chat` + 侧边栏 + 输入框)。
- 后端对话 API、AI 流式集成、世界书/正则逻辑尚在规划阶段。
#### 2.2 前端(`projects/web-app`
- **用户系统前端**`LoginPage/RegisterPage/ForgotPasswordPage/ProfilePage` 已完成,`api/client.ts + api/auth.ts` 已完成 token 注入与刷新。
- **角色卡管理前端**`CharacterManagePage` + `api/character.ts`
- 功能:
- 上传 PNG/JSON 角色卡(调用 `/app/character/upload`
- 编辑角色卡核心字段、内嵌 `characterBook`(世界书)字段
- 导出 JSON调用 `/app/character/:id/export`
- 搜索、分页、删除
- **预设管理前端**`PresetManagePage`
- 当前为 **前端内存里的假数据** + 文件导入/导出;尚未接入真实后端 `/app/preset`
- **聊天前端**`ChatPage + Sidebar + ChatArea + CharacterPanel + SettingsPanel`
- 已实现基础布局、会话切换、角色选择、背景图/主题色设置等 UI。
- 消息发送、历史加载、预设切换、世界书/正则开关还需后端配合。
- **AI 配置前端**`api/aiConfig.ts`(对应 `/app/ai-config` 系列)。
> 结论:**角色卡链路基本打通**,用户系统成熟;预设/对话/AI/世界书/正则目前主要停留在前端 UI 或规划层面,正好适合作为“集中下沉到 Go 后端”的突破口。
---
### 3. 目标架构SillyTavern 兼容实现)
#### 3.1 核心领域模型(后端)
建议在现有 `model/app` 中引入或规范以下模型(部分已存在,可扩展):
- `AICharacter`(已存在)
- ST 角色卡 V2/V3 的标准化版本 + 原始 JSON 存档。
- `Worldbook` & `WorldbookEntry`
- 支持角色内世界书与全局世界书。
- `RegexScript`
- 支持 scope`global | character | preset`
- `Preset` & `PresetPrompt` & `PresetRegexBinding`
- 表达 ST preset 的参数、prompt 列表和 regex 绑定。
- `Conversation` & `Message`
- 对话与消息记录,支持与 `AICharacter``Preset` 和 AI 配置关联。
#### 3.2 运行时 Pipeline
所有客户端(现阶段只有 React Web将来可增加其他统一通过 Go 后端完成以下流程:
1. **输入正则脚本处理**global/character/preset
2. **世界书扫描**keys/secondary_keys/regex/depth/sticky/cooldown 等)
3. **Prompt 构建**(角色 system + world info + preset prompts + 历史消息)
4. **AI 调用**OpenAI/Anthropic/custom via `/app/ai-config`
5. **输出正则脚本处理**
6. **持久化消息与统计**
React 前端只负责:
- 提供管理与编辑界面;
- 将用户选择的 preset/worldbook/regex 传给后端;
- 使用 SSE/WebSocket 将 AI 流输出展示给用户。
---
### 4. 后端详细优化方案Go + Gin + Postgres
#### 4.1 模型与数据库设计(概念级)
> 不强制你立刻改现有表名与字段;这部分作为“目标状态”,可通过迁移脚本或视图逐步对齐。
- **AICharacter**(已有)
- 新增/规范字段:
- `raw_card_json JSONB`:存原始 ST 角色卡,用于无损导出。
- `bound_worldbook_ids UUID[]`:角色绑定世界书 ID 列表(可选)。
- `bound_regex_ids UUID[]`:角色绑定正则脚本 ID 列表(可选)。
- **Worldbook / WorldbookEntry**
- Worldbook`id, name, owner_char_id (nullable), meta JSONB, created_at, updated_at`
- WorldbookEntry包含 ST 全字段:
- `uid, keys, secondary_keys, comment, content, constant, disabled, use_regex, case_sensitive, match_whole_words, selective, selective_logic, position, depth, order, probability, sticky, cooldown, delay, group, extra JSONB`
- **RegexScript**
- `id, name, find_regex, replace_with, trim_string`
- `placement INT[]`
- `disabled, markdown_only, run_on_edit, prompt_only`
- `substitute_regex, min_depth, max_depth`
- `scope, owner_char_id, owner_preset_id, raw_json`
- **Preset / PresetPrompt / PresetRegexBinding**
- 基本采样参数 + prompt 列表 + regex 绑定。
- **Conversation / Message**
- Conversation`id, user_id, character_id, preset_id, ai_config_id, title, settings JSONB, created_at, updated_at`
- Message`id, conversation_id, role, content, token_count, created_at`
#### 4.2 角色卡导入/导出(巩固现有实现)
> 从 `development-progress.md` 看,`/app/character` 模块已经“完全兼容 ST V2”这里更多是规范与扩展。
- **导入 `/app/character/upload` 已具备**
- PNG使用 `utils/character_card.go` 提取 `chara` tEXt chunk → JSON。
- JSON直接解析填充 `AICharacter`
- 优化点:
- 当角色卡中包含 `character_book` 时:
- 自动在 `worldbooks/worldbook_entries` 中创建对应记录;
- 将 worldbook.id 写入 `AICharacter.bound_worldbook_ids`(或冗余到 `characterBook` 字段中)。
- 当包含 `extensions.regex_scripts` 时:
- 自动创建 `RegexScript`scope=character, owner_char_id=该角色)。
- 将脚本 id 写入 `AICharacter.bound_regex_ids``extensions` 中。
- **导出 `/app/character/:id/export`**
-`raw_card_json` 存在,优先以它为基础;将 DB 中新增的信息 patch 回去(例如补上最新的 worldbook/regex 变更)。
- 若不存在,则按 ST V2 规范组装 JSON兼容 V1/V3 的 data 字段)。
#### 4.3 世界书World Info引擎
1. **世界书激活来源**
- 全局启用列表per-user 或全局 settings 中的 `active_worldbook_ids`)。
- 角色绑定:`AICharacter.bound_worldbook_ids`
- 会话特定选项:`conversation.settings.activeWorldbookIds`(从前端设置面板传入)。
2. **触发与过滤算法**
- 遍历所有激活 worldbook 的 entries
- 忽略 `disabled` 的 entry。
-`constant=true`:无视关键词匹配,直接进入候选(仍受 sticky/cooldown/delay/probability 控制)。
- keys 匹配:
- `use_regex=true`:将每个 key 作为正则(考虑 `caseSensitive``matchWholeWords` 标志)。
- 否则:普通字符串包含匹配(可选大小写敏感)。
-`selective=true`:根据 `selectiveLogic` 结合 secondary_keys
- `0=AND`secondary_keys 至少一个命中;
- `1=OR`:主 keys 或 secondary_keys 任一命中;
- `2=NOT`:主 keys 命中,但 secondary_keys 不命中。
- depth仅在最近 `entry.depth` 条消息(或 tokens中搜索关键字。
- sticky/cooldown/delay基于会话级状态比如 Redis/内存/DB存储 entry 上次触发时间或 sticky 状态。
- probability按百分比随机决定最终是否注入。
3. **注入到 prompt 中**
- 简化版:将所有命中 entry.content 拼接为 `[World Info]` 段,附加在 system prompt 后;
- 高级版:按 ST 行为,依据 position/depth/order放到不同位置角色描述前/后、历史中等)。
#### 4.4 正则脚本Regex Scripts引擎
1. **脚本来源**
- Global`scope='global'``disabled=false`
- Character`scope='character' AND owner_char_id=当前角色`
- Preset`preset_regex_bindings` 中绑定到当前 preset 的脚本。
2. **执行阶段placement**
- 输入阶段placement=1用户消息入库前
- 输出阶段placement=2模型输出生成后、入库/返回前;
- 世界书阶段placement=3扫描 / 注入 world info 内容前;
- 推理阶段placement=4如有单独 reasoning prompt可在构建 reasoning 时处理。
3. **实现细节Go**
- 解析 JS 风格正则 `/pattern/flags`,支持 `i/m/s`
- 替换宏:
- `substitute_regex=1` → 用当前用户名称替换 `{{user}}`
- `=2` → 用当前角色名替换 `{{char}}`
- `trim_string`:按行定义需要从文本中删掉的子串。
- minDepth/maxDepth结合消息历史深度决定是否执行脚本。
- runOnEdit在“消息编辑接口”中也调用该脚本集。
- markdownOnly/promptOnly通过标志决定作用在 UI 文本 or prompt 文本。
#### 4.5 Prompt Pipeline 与对话 API
将现有/规划中的对话 API 统一收敛到一个 pipeline例如 `/app/conversation/:id/message`(或 `/conversations/:id/messages`,按统一风格即可):
1. **接收请求**
```json
{
"content": "用户输入文本",
"options": {
"presetId": "uuid-xxx",
"overrideModel": "gpt-4",
"stream": true
}
}
```
2. **管线步骤**
1. 根据 conversationId 加载:
- Conversation、AICharacter、Preset、AI 配置、世界书/正则等上下文;
- 合并 settings会话内 + 用户全局)。
2. 输入文本经过 regex 引擎placement=1
3. 写入一条 user message 到 DB。
4. 从最近 N 条消息构造 world info 触发文本,调用世界书引擎得到 entries。
5. 构建 prompt
- system角色 system + scenario + authorsNote + preset.systemPrompt + world info
- history最近若干 user/assistant 消息;
- preset.prompts按 depth/position 注入额外 messages。
6. 调用 AI 服务(依据 `/app/ai-config` 中 baseUrl/apiKey/model
- 支持流式:通过 SSE/WebSocket 对前端推送 tokens。
7. 将完整 assistant 输出经过 regex 引擎placement=2
8. 写入一条 assistant message 到 DB。
9. 返回响应给前端(同步返回最终内容 + 可选流式过程)。
---
### 5. 前端详细优化方案React `projects/web-app`
#### 5.1 角色卡管理CharacterManagePage
目标:完全对齐 ST 角色卡 V2/V3 字段,并为世界书/正则后端拆分打好基础。
优化点:
- **字段映射明确化**
- 确保 `Character` 接口与后端模型一致,并在注释中标明 ST 对应字段:
- `firstMes``first_mes`
- `mesExample``mes_example`
- `systemPrompt``system_prompt`
- `postHistoryInstructions``post_history_instructions`
- `characterBook``character_book`
- `extensions``extensions`
- **世界书编辑 UI 扩展**
- 目前 `WorldBookEntry` 较简化keys/content/enabled/insertion_order/position
- 建议增加更多高级属性编辑项(可以先折叠到“高级设置”中):
- `secondary_keys` / `constant` / `use_regex` / `case_sensitive` / `match_whole_words`
- `selective` / `selective_logic`
- `depth` / `order` / `probability` / `sticky` / `cooldown` / `delay` / `group`
- 保存时将这些字段一并放入 `characterBook.entries`,后端负责拆分入 DB。
- **导入/导出保持 ST 兼容**
- 当前上传/导出流程基本正确;随着后端增强,无需大改,只要保证前端不破坏 JSON 结构即可。
#### 5.2 预设管理PresetManagePage
目标:把当前的“前端内存预设”完全改造成**后端驱动的 ST 预设系统**。
实施步骤:
1. 后端按 `development-progress.md` 规划实现 `/app/preset` API
```text
POST /app/preset
GET /app/preset
GET /app/preset/:id
PUT /app/preset/:id
DELETE /app/preset/:id
POST /app/preset/import
GET /app/preset/:id/export
```
2. 前端新建 `src/api/preset.ts` 对应这些端点。
3.`PresetManagePage` 中的 `useState` 初始数据删除,改为:
- `const { data } = await presetApi.getPresetList()`
- 导入、导出、编辑、删除全部通过后端。
4. 预设 JSON 的读写字段与 ST 对齐:
- `temperature/top_p/top_k/frequency_penalty/presence_penalty/system_prompt/stop_sequences/...`
#### 5.3 聊天与设置面板ChatPage / SettingsPanel / CharacterPanel
目标:把“选 preset / 选世界书 / 选正则”的入口统一放到设置面板,并通过 `conversation.settings` 与后端 pipeline 串联。
建议:
-`SettingsPanel` 中增加:
- 当前会话使用的 preset 选择器(下拉 list来自 `/app/preset`)。
- 可选的世界书列表(来自未来的 `/app/worldbook`,初期可只展示角色内 worldbook
- 可选的全局正则脚本列表(来自未来的 `/app/regex`)。
- 保存时调用 `/app/conversation/:id/settings`(或 `PUT /app/conversation/:id`
```ts
settings: {
backgroundImage: string
themeColor: string
presetId?: string
activeWorldbookIds?: string[]
activeRegexIds?: string[]
}
```
- 发送消息时,前端不再参与世界书/正则逻辑,只负责传 `content`,后端从 conversation/preset/character 中解析所有配置。
---
### 6. 分阶段落地路线图(仅 Go + React
#### 阶段 1打通所有核心 CRUD 与数据流(短期)
- 后端:
- 巩固 `/app/character` 模块(确保 ST V2/V3 完全兼容)。
- 实现 `/app/preset` 模块CRUD + 导入/导出)。
- 设计并实现 `worldbooks/worldbook_entries``regex_scripts` 的数据结构与基础 API。
- 前端:
- 改造 `PresetManagePage` 接入真实 API。
-`CharacterManagePage` 中补全世界书 entry 字段,保持 ST 兼容。
#### 阶段 2实现 Prompt Pipeline 与对话 API中期
- 后端:
- 聚合世界书与正则逻辑,形成独立的 `chatPipeline` service。
-`/app/conversation/:id/message`(或 `/conversations/:id/messages`)中调用 pipeline完成一次“完整的 ST 风格对话请求”。
- 引入流式输出SSE 或 WebSocket
- 前端:
-`ChatPage/SettingsPanel` 中增加 preset/worldbook/regex 的选择与设置保存。
- 调整 ChatArea 接收流式输出并实时渲染。
#### 阶段 3高级特性与插件系统长期
- 后端:
- 引入插件概念(`plugins` 表 + manifest + hooks
- 实现插件执行沙箱WASM 或 goja并在 pipeline 中注入插件 hooks。
- 增加统计、日志与审计功能。
- 前端:
- 增加插件管理页面与可视化配置。
- 对接统计与调试视图(例如:查看某次回复中哪些 world info/regex/插件生效)。
---
### 7. 总结
- 你当前的 Go + React 系统已经完成:
- **用户系统**(认证/资料);
- **角色卡管理**(完整 ST V2 兼容导入/导出);
- **预设管理与对话 UI 的前端骨架**。
- 接下来最重要的三件事是:
- **在后端固化 ST 兼容的领域模型与 Prompt Pipeline**
- **让 `/app/conversation` 成为唯一的“对话真相源”React 只是 UI 壳**。