- 后端:项目/运行 API、上下文服务与数据模型 - 前端:Studio 列表、编辑页(R1/R2 布局)、运行页与节点图 - 编辑页顶部:CSS Grid 统一标签行与控件行对齐,项目按钮独立第三行 - Docker 开发配置与文档脚本 Co-authored-by: Cursor <cursoragent@cursor.com>
467 lines
12 KiB
Markdown
467 lines
12 KiB
Markdown
# LLM Workflow Engine
|
||
|
||
一个功能强大的 LLM 聊天工作流引擎,兼容 SillyTavern 生态系统。
|
||
|
||
## 📋 目录
|
||
|
||
- [功能特性](#功能特性)
|
||
- [技术栈](#技术栈)
|
||
- [快速开始](#快速开始)
|
||
- [项目结构](#项目结构)
|
||
- [核心功能](#核心功能)
|
||
- [开发指南](#开发指南)
|
||
- [配置说明](#配置说明)
|
||
- [常见问题](#常见问题)
|
||
|
||
---
|
||
|
||
## 功能特性
|
||
|
||
### 🎯 核心功能
|
||
|
||
- **多模型支持** - 兼容 OpenAI、Claude、Gemini 等多种 LLM API
|
||
- **角色卡系统** - 完整的角色创建、导入、导出功能(兼容 SillyTavern 格式)
|
||
- **聊天管理** - 多聊天切换、历史总结、消息编辑
|
||
- **预设系统** - 灵活的提示词组件管理,支持拖拽排序
|
||
- **世界书** - 动态世界知识注入系统
|
||
- **正则替换** - 强大的文本处理规则系统(完全兼容 SillyTavern)
|
||
|
||
### ✨ 高级功能
|
||
|
||
- **酒馆助手(Tavern Helper)**
|
||
- JavaScript 沙盒执行引擎
|
||
- 提示词模板系统(支持 `{{var}}`、`{{roll}}`、`{{random}}` 等语法)
|
||
- 脚本管理(全局/角色/预设三种作用域)
|
||
- 代码块渲染功能
|
||
|
||
- **多主题支持** - 完整的 CSS 变量主题系统
|
||
- **流式输出** - 实时显示 AI 生成内容
|
||
- **消息 Swipes** - 多版本切换和重roll功能
|
||
- **API 配置管理** - 安全的 API Key 存储和加密
|
||
|
||
### 🔒 安全特性
|
||
|
||
- API Key 加密存储(Fernet 对称加密)
|
||
- JavaScript 沙盒隔离执行
|
||
- 危险 API 拦截机制
|
||
- 环境变量安全管理
|
||
|
||
---
|
||
|
||
## 技术栈
|
||
|
||
### 后端
|
||
|
||
- **框架**: FastAPI (Python 3.11+)
|
||
- **数据库**: 文件系统 + JSON(轻量级,易于备份)
|
||
- **WebSocket**: 实时流式通信
|
||
- **加密**: Fernet 对称加密(cryptography 库)
|
||
- **依赖管理**: pip + requirements.txt
|
||
|
||
### 前端
|
||
|
||
- **框架**: React 18 + Vite
|
||
- **状态管理**: Zustand(轻量级 Redux 替代)
|
||
- **样式**: CSS3 + CSS 变量(支持多主题)
|
||
- **Markdown**: react-markdown + remark-gfm
|
||
- **HTTP 客户端**: Fetch API
|
||
|
||
### 部署
|
||
|
||
- **容器化**: Docker + Docker Compose
|
||
- **反向代理**: Nginx
|
||
- **开发服务器**: Vite HMR
|
||
|
||
---
|
||
|
||
## 快速开始
|
||
|
||
### 环境要求
|
||
|
||
- Python 3.11+
|
||
- Node.js 18+
|
||
- Docker & Docker Compose(可选)
|
||
|
||
### 本地开发
|
||
|
||
#### 1. 克隆项目
|
||
|
||
```bash
|
||
git clone https://github.com/your-repo/llm-workflow-engine.git
|
||
cd llm-workflow-engine
|
||
```
|
||
|
||
#### 2. 后端启动
|
||
|
||
```bash
|
||
# 创建虚拟环境
|
||
python -m venv venv
|
||
source venv/bin/activate # Windows: venv\Scripts\activate
|
||
|
||
# 安装依赖
|
||
pip install -r backend/requirements.txt
|
||
|
||
# 启动服务
|
||
cd backend
|
||
python main.py
|
||
```
|
||
|
||
后端服务将在 `http://localhost:23338` 启动。
|
||
|
||
#### 3. 前端启动
|
||
|
||
```bash
|
||
cd frontend
|
||
|
||
# 安装依赖
|
||
npm install
|
||
|
||
# 启动开发服务器
|
||
npm run dev
|
||
```
|
||
|
||
前端将在 `http://localhost:5173` 启动,自动代理 API 请求到后端。
|
||
|
||
### Docker 开发(Windows / Docker Desktop)
|
||
|
||
日常改代码**不需要重启 Docker Desktop**——后端 uvicorn `--reload`、前端 Vite HMR 会自动生效。
|
||
|
||
```powershell
|
||
# 启动(项目根目录)
|
||
.\scripts\docker-up.ps1
|
||
|
||
# 仅重启容器(HMR/reload 异常时)
|
||
.\scripts\docker-restart.ps1 -Service frontend # 或 backend / all
|
||
|
||
# 依赖或 Dockerfile 变更后重建
|
||
.\scripts\docker-rebuild.ps1 -Service backend
|
||
|
||
# 查看日志
|
||
.\scripts\docker-logs.ps1
|
||
```
|
||
|
||
| 服务 | 地址 |
|
||
|------|------|
|
||
| 后端 API | http://localhost:23337 |
|
||
| 前端 | http://localhost:23338 |
|
||
|
||
详细说明(何时 rebuild、何时才需要重启 Docker Desktop、本地开发替代方案)见 **[docs/DOCKER_DEV.md](./docs/DOCKER_DEV.md)**。
|
||
|
||
```powershell
|
||
# 停止服务
|
||
docker compose down
|
||
```
|
||
|
||
---
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
llm-workflow-engine/
|
||
├── backend/ # 后端服务
|
||
│ ├── api/ # API 路由
|
||
│ │ └── routes/ # 路由处理
|
||
│ ├── core/ # 核心配置
|
||
│ ├── models/ # 数据模型
|
||
│ ├── services/ # 业务逻辑
|
||
│ │ ├── chat_service.py # 聊天服务
|
||
│ │ ├── js_sandbox.py # JavaScript 沙盒
|
||
│ │ ├── script_manager.py # 脚本管理器
|
||
│ │ ├── regex_service.py # 正则服务
|
||
│ │ └── ...
|
||
│ ├── utils/ # 工具函数
|
||
│ ├── main.py # 应用入口
|
||
│ └── requirements.txt # Python 依赖
|
||
│
|
||
├── frontend/ # 前端应用
|
||
│ ├── src/
|
||
│ │ ├── components/ # React 组件
|
||
│ │ │ ├── Mid/ # 中间区域(聊天框)
|
||
│ │ │ ├── SideBarLeft/ # 左侧边栏
|
||
│ │ │ │ └── tabs/ # 标签页组件
|
||
│ │ │ │ └── TavernHelper/ # 酒馆助手
|
||
│ │ │ ├── SideBarRight/# 右侧边栏
|
||
│ │ │ └── TopBar/ # 顶部栏
|
||
│ │ ├── Store/ # Zustand 状态管理
|
||
│ │ ├── styles/ # 全局样式
|
||
│ │ ├── types/ # TypeScript 类型定义
|
||
│ │ ├── utils/ # 工具函数
|
||
│ │ ├── App.jsx # 根组件
|
||
│ │ └── main.jsx # 应用入口
|
||
│ ├── package.json # Node.js 依赖
|
||
│ └── vite.config.js # Vite 配置
|
||
│
|
||
├── data/ # 数据目录(运行时生成)
|
||
│ ├── chat/ # 聊天记录
|
||
│ ├── preset/ # 预设文件
|
||
│ ├── worldbooks/ # 世界书
|
||
│ ├── regex/ # 正则规则
|
||
│ └── ...
|
||
│
|
||
├── docker-compose.yml # Docker 编排
|
||
├── .env.example # 环境变量示例
|
||
├── .gitignore # Git 忽略文件
|
||
└── README.md # 项目文档
|
||
```
|
||
|
||
---
|
||
|
||
## 核心功能
|
||
|
||
### 1. 酒馆助手(Tavern Helper)
|
||
|
||
完全兼容 SillyTavern 酒馆助手的提示词模板系统。
|
||
|
||
#### 支持的语法
|
||
|
||
| 语法 | 功能 | 示例 |
|
||
|------|------|------|
|
||
| `{{var}}` 或 `{{getvar::key}}` | 获取变量 | `{{name}}` |
|
||
| `{{setvar::key::value}}` | 设置变量 | `{{setvar::age::25}}` |
|
||
| `{{delvar::key}}` | 删除变量 | `{{delvar::temp}}` |
|
||
| `{{random::a,b,c}}` | 随机选择(逗号) | `{{random::苹果,香蕉,橙子}}` |
|
||
| `{{pick::a\|b\|c}}` | 随机选择(竖线) | `{{pick::剑\|斧\|弓}}` |
|
||
| `{{roll XdY}}` | 掷骰子 | `{{roll 3d6}}` |
|
||
| `{{// 注释}}` | 注释(不输出) | `{{// 这是注释}}` |
|
||
|
||
#### 使用示例
|
||
|
||
```python
|
||
from backend.services.js_sandbox import JSSandboxExecutor
|
||
|
||
sandbox = JSSandboxExecutor()
|
||
|
||
template = """
|
||
{{setvar::character::勇者}}
|
||
{{setvar::weapon::{{random::剑,斧,弓}}}}
|
||
{{character}}手持{{weapon}},掷出了:{{roll 1d20}}
|
||
{{// 这是注释,不会显示}}
|
||
""".strip()
|
||
|
||
result = sandbox.render_template(template)
|
||
print(result)
|
||
# 输出: 勇者手持剑,掷出了:15
|
||
```
|
||
|
||
#### 脚本管理
|
||
|
||
支持三种作用域的脚本:
|
||
|
||
- **GLOBAL** - 全局脚本,对所有聊天可用
|
||
- **CHARACTER** - 角色脚本,绑定到当前角色卡
|
||
- **PRESET** - 预设脚本,绑定到当前预设
|
||
|
||
详细文档:[TAVERN_HELPER_IMPLEMENTATION.md](./TAVERN_HELPER_IMPLEMENTATION.md)
|
||
|
||
### 2. 正则替换系统
|
||
|
||
强大的文本处理规则,完全兼容 SillyTavern 格式。
|
||
|
||
#### 应用位置(placement)
|
||
|
||
- `0` - System Prompt(系统提示词)
|
||
- `1` - User Input(用户输入)
|
||
- `2` - AI Output(AI 输出)
|
||
- `3` - Quick Reply(快捷回复)
|
||
- `4` - World Info(世界书信息)
|
||
- `5` - Reasoning/Thinking(推理/思考内容)
|
||
|
||
#### 规则示例
|
||
|
||
```json
|
||
{
|
||
"id": "hide-thinking-001",
|
||
"scriptName": "隐藏思考标签",
|
||
"findRegex": "<thinking>[\\s\\S]*?<\\/thinking>",
|
||
"replaceString": "",
|
||
"placement": [2],
|
||
"substituteRegex": 0,
|
||
"markdownOnly": false,
|
||
"promptOnly": false,
|
||
"disabled": false
|
||
}
|
||
```
|
||
|
||
### 3. 预设系统
|
||
|
||
灵活的提示词组件管理。
|
||
|
||
#### 特性
|
||
|
||
- 多组件拖拽排序
|
||
- 角色字段支持(system/user/assistant)
|
||
- 注入位置控制(injection_position)
|
||
- 注入深度控制(injection_depth)
|
||
- 触发条件(injection_trigger)
|
||
- 完全兼容 SillyTavern 预设格式
|
||
|
||
### 4. 聊天管理
|
||
|
||
完整的聊天生命周期管理。
|
||
|
||
#### 功能
|
||
|
||
- 多聊天切换
|
||
- 消息编辑和保存
|
||
- 消息 Swipes(多版本)
|
||
- 右键菜单(编辑/复制/重roll/删除)
|
||
- 历史总结
|
||
- 智能滚动
|
||
|
||
---
|
||
|
||
## 开发指南
|
||
|
||
### API 路由
|
||
|
||
所有 API 路由定义在 `backend/api/routes/` 目录下:
|
||
|
||
- `chatWsRoute.py` - WebSocket 聊天(流式输出)
|
||
- `chatsRoute.py` - 聊天管理
|
||
- `charactersRoute.py` - 角色卡管理
|
||
- `presetsRoute.py` - 预设管理
|
||
- `worldbooksRoute.py` - 世界书管理
|
||
- `regexRoute.py` - 正则规则管理
|
||
- `apiConfigRoute.py` - API 配置管理
|
||
|
||
### 状态管理
|
||
|
||
前端使用 Zustand 进行状态管理,store 定义在 `frontend/src/Store/`:
|
||
|
||
```
|
||
Store/
|
||
├── Mid/ # 中间区域状态
|
||
│ ├── ChatBoxSlice.jsx # 聊天框状态
|
||
│ └── ChatBoxUISlice.jsx # 聊天框 UI 状态
|
||
├── SideBarLeft/ # 左侧边栏状态
|
||
├── SideBarRight/ # 右侧边栏状态
|
||
└── TopBar/ # 顶部栏状态
|
||
```
|
||
|
||
### 样式系统
|
||
|
||
使用 CSS 变量实现多主题:
|
||
|
||
```css
|
||
:root {
|
||
--color-bg-primary: #ffffff;
|
||
--color-text-primary: #1a1a1a;
|
||
--color-accent: #667eea;
|
||
/* ... */
|
||
}
|
||
|
||
[data-color-theme='dark'] {
|
||
--color-bg-primary: #1a1a1a;
|
||
--color-text-primary: #ffffff;
|
||
/* ... */
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 配置说明
|
||
|
||
### 环境变量
|
||
|
||
创建 `.env` 文件(从 `.env.example` 复制):
|
||
|
||
```env
|
||
# 后端配置
|
||
HOST=0.0.0.0
|
||
PORT=23338
|
||
DEBUG=True
|
||
|
||
# 前端代理
|
||
VITE_API_URL=http://localhost:23338
|
||
|
||
# API 加密密钥(自动生成,不要手动修改)
|
||
FERNET_KEY=your_generated_key_here
|
||
```
|
||
|
||
### API 配置
|
||
|
||
API Key 通过前端界面配置,自动加密存储到 `data/apiconfig/` 目录。
|
||
|
||
⚠️ **注意**:`data/apiconfig/*.json` 已添加到 `.gitignore`,不会被提交到版本控制。
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### 1. 前端无法连接后端
|
||
|
||
**问题**: 前端请求返回 404 或网络连接错误
|
||
|
||
**解决**:
|
||
```bash
|
||
# 检查后端是否运行
|
||
curl http://localhost:23338/api/health
|
||
|
||
# 检查前端代理配置
|
||
cat frontend/vite.config.js
|
||
```
|
||
|
||
### 2. API Key 不生效
|
||
|
||
**问题**: 配置了 API Key 但仍然无法调用 LLM
|
||
|
||
**解决**:
|
||
1. 检查 API 配置文件是否存在:`data/apiconfig/`
|
||
2. 检查加密密钥是否正确:`.env` 中的 `FERNET_KEY`
|
||
3. 重启后端服务
|
||
|
||
### 3. Docker 部署后无法访问
|
||
|
||
**问题**: `docker-compose up` 后无法访问服务
|
||
|
||
**解决**:
|
||
```bash
|
||
# 查看容器状态
|
||
docker-compose ps
|
||
|
||
# 查看日志
|
||
docker-compose logs -f backend
|
||
docker-compose logs -f frontend
|
||
|
||
# 重新构建
|
||
docker-compose up -d --build
|
||
```
|
||
|
||
### 4. 正则规则不生效
|
||
|
||
**问题**: 配置了正则规则但没有效果
|
||
|
||
**解决**:
|
||
1. 检查规则是否启用(disabled: false)
|
||
2. 检查 placement 是否正确
|
||
3. 检查正则表达式语法
|
||
4. 重启后端服务
|
||
|
||
---
|
||
|
||
## 贡献指南
|
||
|
||
1. Fork 项目
|
||
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
||
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||
5. 开启 Pull Request
|
||
|
||
---
|
||
|
||
## 许可证
|
||
|
||
本项目遵循与 SillyTavern 相同的分发协议。
|
||
|
||
---
|
||
|
||
## 致谢
|
||
|
||
- [SillyTavern](https://github.com/SillyTavern/SillyTavern) - 优秀的开源项目,提供了设计灵感和兼容标准
|
||
- [JS-Slash-Runner](https://github.com/N0VI028/JS-Slash-Runner) - Tavern Helper 扩展,提供了 JavaScript 沙盒实现参考
|
||
|
||
---
|
||
|
||
**最后更新**: 2026-05-05
|
||
**版本**: 1.0.0
|