8.7 KiB
8.7 KiB
SillyTavern Repalice
一个基于 SillyTavern 灵感的 AI 角色扮演聊天应用,具有自定义扩展功能。
🏗️ 技术栈
- 前端: Vue 3 + Vite + TypeScript + Pinia
- 后端: NestJS + TypeScript
- 共享层: Zod schemas + TypeScript types
- LLM: Vercel AI SDK v4
- 持久化: 本地文件系统(无数据库)
- 部署: Docker Compose
📁 项目结构
sillytavern-repalice/
├── shared/ # 前后端共享模块
│ ├── types/ # TypeScript 类型定义
│ │ ├── sillytavern.types.ts # SillyTavern 兼容格式
│ │ ├── internal.types.ts # 项目内部扩展格式
│ │ └── converters.ts # 数据转换器
│ ├── schemas/ # Zod 运行时验证 schemas
│ │ ├── sillytavern.schemas.ts
│ │ └── internal.schemas.ts
│ └── index.ts # 统一导出
│
├── server/ # 后端 NestJS 应用
│ ├── src/
│ │ ├── modules/ # 业务模块
│ │ │ ├── chat/ # 聊天管理
│ │ │ ├── character/ # 角色卡管理
│ │ │ ├── llm/ # LLM 集成
│ │ │ ├── import-export/ # 导入导出
│ │ │ └── workflow/ # 工作流引擎
│ │ ├── persistence/ # 持久化层
│ │ │ ├── interfaces/ # 仓储接口
│ │ │ ├── implementations/ # 具体实现
│ │ │ └── file-system/ # 文件系统实现
│ │ ├── controllers/ # 路由控制器
│ │ ├── services/ # 业务逻辑服务
│ │ ├── core/ # 核心基础设施
│ │ │ ├── config/ # 配置管理
│ │ │ ├── filters/ # 异常过滤器
│ │ │ ├── interceptors/ # 拦截器
│ │ │ ├── guards/ # 守卫
│ │ │ └── di/ # 依赖注入 tokens
│ │ ├── tools/ # 工具层
│ │ │ ├── context-chunker.ts # 上下文分块
│ │ │ ├── prompt-assembler.ts # 提示词组装
│ │ │ └── token-counter.ts # Token 计数
│ │ ├── dto/ # 数据传输对象
│ │ └── interfaces/ # 接口定义
│ └── test/ # 测试文件
│ ├── unit/ # 单元测试
│ ├── integration/ # 集成测试
│ └── e2e/ # 端到端测试
│
├── client/ # 前端 Vue3 应用
│ ├── src/
│ │ ├── components/ # 组件
│ │ │ ├── TopBar/ # 顶部栏
│ │ │ ├── LeftPanel/ # 左侧面板(角色列表、聊天历史)
│ │ │ ├── CenterPanel/ # 中央面板(聊天界面)
│ │ │ ├── RightPanel/ # 右侧面板(角色详情、工作流编辑器)
│ │ │ └── common/ # 通用组件
│ │ ├── layouts/ # 布局组件
│ │ ├── stores/ # Pinia 状态管理
│ │ ├── router/ # 路由配置
│ │ ├── composables/ # 组合式函数
│ │ ├── api/ # API 客户端
│ │ ├── utils/ # 工具函数
│ │ ├── constants/ # 常量定义
│ │ ├── styles/ # 全局样式
│ │ ├── App.vue # 根组件
│ │ └── main.ts # 入口文件
│ └── public/ # 静态资源
│
├── data/ # 持久化数据目录(运行时生成)
│ ├── characters/ # 角色卡数据
│ ├── chats/ # 聊天记录
│ ├── worldinfo/ # 世界书数据
│ ├── presets/ # 预设配置
│ └── workflows/ # 工作流定义
│
├── docker/ # Docker 配置
│ ├── backend.Dockerfile
│ ├── frontend.Dockerfile
│ └── nginx/
│ └── default.conf
│
├── docker-compose.yml # Docker Compose 配置
├── package.json # 根 package.json (monorepo)
└── .env.example # 环境变量示例
🚀 快速开始
前置要求
- Node.js >= 20.x
- npm >= 10.x
- Docker & Docker Compose (可选,用于容器化部署)
本地开发
- 克隆仓库
git clone <repository-url>
cd sillytavern-repalice
- 安装依赖
npm install
- 配置环境变量
cp .env.example .env
# 编辑 .env 文件,填入你的 LLM API 密钥
- 启动开发服务器
# 同时启动前后端
npm run dev
# 或者分别启动
npm run dev:server # 后端 http://localhost:3000
npm run dev:client # 前端 http://localhost:5173
# Docker 部署后访问
# 后端: http://localhost:3000
# 前端: http://localhost:23337
Docker 部署
中国大陆用户特别说明
由于网络原因,在中国大陆构建 Docker 镜像可能会遇到依赖下载缓慢或卡死的问题。项目已针对此情况进行了优化:
-
自动使用国内镜像源:通过
.npmrc文件配置https://registry.npmmirror.com作为 npm 镜像源 -
简化构建流程:移除 BuildKit cache mount,使用更稳定的方式
-
提供一键构建脚本:
# Windows 用户(PowerShell) .\build-docker.ps1 # Windows 用户(CMD) build-docker.bat # Linux/Mac 用户 chmod +x build-docker.sh ./build-docker.sh -
详细的故障排除指南:如果构建仍然失败,请参考 TROUBLESHOOTING.md
标准部署流程
# 构建镜像
npm run docker:build
# 启动服务
npm run docker:up
# 查看日志
npm run docker:logs
# 停止服务
npm run docker:down
📊 数据架构
双格式设计
本项目采用双数据格式设计:
-
SillyTavern 兼容格式 (
shared/types/sillytavern.types.ts)- 严格遵循 SillyTavern 官方规范
- 用于导入导出,确保兼容性
- 包含:角色卡 V2/V3、世界书、聊天记录 JSONL
-
项目内部格式 (
shared/types/internal.types.ts)- 继承 SillyTavern 格式并扩展
- 添加自定义字段和功能
- 支持:激活方式枚举、RAG 配置、逻辑表达式、工作流等
-
数据转换器 (
shared/types/converters.ts)- 在两种格式之间无缝转换
- 保证导入导出的完整性
核心数据类型
- WorldInfo (世界书): 支持 4 种激活方式(永久、关键词、RAG、逻辑表达式)
- CharacterCard (角色卡): 扩展了分类标签、输出 schema、头像管理等
- ChatLog (聊天记录): 结构化存储,支持表头数据和消息 swipe
- Workflow (工作流): 可视化编排,支持并行执行和动态拼接
- GenerationPreset (预设): LLM 采样参数配置
🏛️ 架构设计原则
MVC 分层架构
-
Model (模型层):
- Services (
server/src/services/) - Persistence (
server/src/persistence/)
- Services (
-
View (视图层):
- Components (
client/src/components/) - Layouts (
client/src/layouts/)
- Components (
-
Controller (控制层):
- Controllers (
server/src/controllers/) - Router (
client/src/router/)
- Controllers (
依赖注入
- 后端使用 NestJS 内置 DI 容器
- 通过
@Inject()装饰器和 Injection Tokens 实现松耦合 - 便于单元测试和模块替换
工具层分离
- Tools Layer (
server/src/tools/):- Context Chunker: 上下文分块管理
- Prompt Assembler: 提示词动态组装
- Token Counter: Token 计数和优化
🔧 开发指南
添加新功能模块
- 在
shared/types/中定义类型 - 在
shared/schemas/中添加 Zod schema - 创建后端模块:
server/src/modules/<feature>/ - 创建前端组件:
client/src/components/<Feature>/ - 实现数据转换器(如需要)
测试
# 运行所有测试
npm test
# 单元测试
cd server && npm run test
# E2E 测试
cd server && npm run test:e2e
📝 待办事项
当前项目已完成基础架构搭建,后续需要实现:
- 完整的角色卡 CRUD 操作
- 聊天界面的实时交互
- 世界书的可视化管理
- Vercel AI SDK 集成
- 工作流编辑器
- RAG 库管理
- 导入导出功能
- 数据迁移工具
📄 许可证
MIT
🙏 致谢
- SillyTavern - 灵感来源
- Vercel AI SDK - LLM 抽象层
- NestJS - 后端框架
- Vue 3 - 前端框架