Files
gen2d/README.md
T
Gmarker689 ecb74a2aed feat: 异步生成管线 + 前端轮询 + 图片编辑 + JWT 中间件
后端:
- 异步生成: POST /api/v1/generate 立即返回 taskId,后台执行管线
- 任务轮询: GET /api/v1/tasks/:id + GET /api/v1/tasks/:id/assets
- 图片保存: 生成图片写入 ../generation/{projectId}/{taskId}/,静态服务
- 图片编辑: POST /api/v1/images/edit (multipart/form-data)
- JWT 中间件: mildware/auth.go 保护生成/编辑端点
- config.yml 清空敏感默认值,交由 .env 控制
- ImageGenConfig 新增 Quality 字段

前端:
- api/generate.ts: 对接真实 API (submitGenerate + poll getTask/getAssets)
- api/types.ts: 新增 GenerateResponse, AssetsResponse, Task 类型
- stores/generation.ts: 异步提交→轮询进度→获取素材→完成
- stores/task.ts: 默认分辨率 256→1024
- GenerateForm: 分辨率范围 1024-1536
- GeneratePage: 显示状态文本,完成后可查看结果/继续生成
- ResultPage: 从 store 读取,下载功能实现
2026-05-25 14:08:08 +08:00

212 lines
7.1 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# gen2d
AI 驱动的 2D 游戏素材生成工具。通过文本提示词或可视化参数,快速生成风格一致、管线友好的 Sprite、背景、UI 元素与动画帧。支持 Unity / Godot 一键集成。
[![Go](https://img.shields.io/badge/Go-00ADD8?logo=go&logoColor=white)](https://go.dev/)
[![Gin](https://img.shields.io/badge/Gin-008ECF?logo=gin&logoColor=white)](https://gin-gonic.com/)
[![React](https://img.shields.io/badge/React-61DAFB?logo=react&logoColor=black)](https://react.dev/)
[![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
[![Vite](https://img.shields.io/badge/Vite-646CFF?logo=vite&logoColor=white)](https://vite.dev/)
### **[在线体验 http://47.121.181.112:10000](http://47.121.181.112:10000)**
架构采用多智能体协作管线(PromptOptimizer → AssetGenerator → QualitySupervisor → FormatAdapter),详见 [docs/backend.md](docs/backend.md)。
## 提示词优化链路
前端用户输入标签和原始描述后,后端通过 Eino 驱动的 PromptAgent 调用 LLM 进行提示词优化,最终生成规范的三段式提示词(【主题】【风格】【技术】)。
### 优化管线
```
用户输入 (标签 + 原始Prompt + 素材类型)
│
▼
formatMetaPrompt (Lambda)
│ 构建元提示词:角色设定 + 输出格式要求 + 用户输入
▼
llmRefine (Lambda → ChatModel API)
│ 调用 OpenAI 兼容的 Chat Completions API
│ 支持流式 (SSE) 与非流式响应
│ 无 API key 时自动回退到模板生成
▼
三段式规范提示词(【主题】【风格】【技术】)
│
▼
PromptOptimizer → AssetGenerator → QualitySupervisor → FormatAdapter(生成管线)
```
### 特性
- **Eino Chain 编排**:`START → formatMetaPrompt → llmRefine → END`
- **OpenAI 兼容 API**:支持任意兼容 OpenAI 接口的 LLM 服务(OpenAI / DeepSeek / 本地模型等)
- **SSE 流式解析**:自动识别 `text/event-stream` 响应并拼接完整内容
- **优雅降级**:API 调用失败或未配置 key 时回退到模板生成,不阻塞管线
详见下方 [提示词优化 API](#提示词优化-api)。
## 快速开始
### 后端
```bash
cd backend
go mod tidy
go run cmd/main.go
```
服务默认运行在 `http://localhost:8080`。
### 前端
```bash
cd frontend
npm install
npm run dev
```
开发服务器默认运行在 `http://localhost:5173`,通过 Vite proxy 转发 API 请求到后端。
## 配置
配置通过 Viper 读取,分为三个优先级(高→低):
| 优先级 | 来源 | 说明 |
|--------|------|------|
| 1 | 环境变量 | 适合 Docker / CI,敏感字段推荐使用 |
| 2 | `config.yml` | 文件位于 `backend/internal/config/config.yml`,存放非敏感默认值 |
| 3 | 默认值 | 代码内置,无需任何配置文件即可启动 |
**环境变量会覆盖 YAML 文件中的同名配置。**
### 大语言模型配置
| 环境变量 | YAML 路径 | 默认值 | 说明 |
|----------|-----------|--------|------|
| `GEN2D_LLM_BASE_URL` | `llm.base_url` | `https://api.openai.com/v1` | LLM API 地址(兼容 OpenAI 接口) |
| `GEN2D_LLM_API_KEY` | `llm.api_key` | (空) | API 密钥,**请通过环境变量设置** |
| `GEN2D_LLM_MODEL` | `llm.model` | `gpt-4o` | 模型名称 |
| `GEN2D_LLM_TEMPERATURE` | `llm.temperature` | `0.7` | 生成温度 (0–2) |
| `GEN2D_LLM_MAX_TOKENS` | `llm.max_tokens` | `2048` | 最大输出 token 数 |
### 文生图配置
| 环境变量 | YAML 路径 | 默认值 | 说明 |
|----------|-----------|--------|------|
| `GEN2D_IMAGE_BASE_URL` | `image_gen.base_url` | `https://api.stability.ai/v1` | 文生图 API 地址 |
| `GEN2D_IMAGE_API_KEY` | `image_gen.api_key` | (空) | API 密钥,**请通过环境变量设置** |
| `GEN2D_IMAGE_MODEL` | `image_gen.model` | `stable-diffusion-xl` | 模型名称 |
| `GEN2D_IMAGE_WIDTH` | `image_gen.width` | `1024` | 生成图片宽度 |
| `GEN2D_IMAGE_HEIGHT` | `image_gen.height` | `1024` | 生成图片高度 |
| `GEN2D_IMAGE_NUM_IMAGES` | `image_gen.num_images` | `1` | 每次生成图片数量 |
| `GEN2D_IMAGE_STEPS` | `image_gen.steps` | `30` | 扩散步数 |
| `GEN2D_IMAGE_CFG_SCALE` | `image_gen.cfg_scale` | `7.0` | CFG 引导强度 |
### 服务基础配置
| 环境变量 | YAML 路径 | 默认值 | 说明 |
|----------|-----------|--------|------|
| `GEN2D_PORT` | `server.port` | `8080` | HTTP 监听端口 |
| `GEN2D_MODE` | `server.mode` | `debug` | Gin 运行模式 (`debug` / `release`) |
| `GEN2D_DSN` | `database.dsn` | `data/gen2d.db` | SQLite 数据库路径 |
| `GEN2D_JWT_SECRET` | `jwt.secret` | `gen2d-dev-secret` | JWT 签名密钥 |
| `GEN2D_JWT_EXPIRE` | `jwt.expire` | `7200` | JWT 过期时间(秒) |
### 快速配置示例
**方式一:直接使用环境变量**
```bash
export GEN2D_LLM_API_KEY=sk-your-openai-key
export GEN2D_IMAGE_API_KEY=sk-your-stability-key
go run cmd/main.go
```
**方式二:使用 `.env` 文件**
```bash
# backend/.env
GEN2D_LLM_API_KEY=sk-your-openai-key
GEN2D_IMAGE_API_KEY=sk-your-stability-key
```
**方式三:修改 `config.yml`(仅非敏感字段)**
```yaml
# backend/internal/config/config.yml
llm:
base_url: "https://api.openai.com/v1"
model: "gpt-4o"
image_gen:
width: 512
height: 512
```
## 提示词优化 API
### POST /api/v1/prompt/optimize
接收用户标签和原始描述,调用 LLM 生成规范化的三段式提示词。
**请求体:**
```json
{
"tags": ["像素", "战士"],
"assetType": "sprite",
"prompt": "我要一个拿着大剑的战士角色",
"userNote": "需要发光特效"
}
```
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `tags` | string[] | 是 | 用户选择的风格标签,至少 1 个 |
| `assetType` | string | 是 | 素材类型:`sprite` / `background` / `ui` / `animation` |
| `prompt` | string | 否 | 用户输入的原始提示词描述 |
| `userNote` | string | 否 | 额外补充说明 |
**响应:**
```json
{
"code": 0,
"message": "ok",
"data": {
"prompt": "【主题】一个融合像素、战士元素的游戏角色精灵图...\n【风格】色彩鲜明;像素风格...\n【技术】输出格式: spritesheet;分辨率: 64x64...",
"rawText": "【主题】一个融合像素...\n【风格】色彩鲜明..."
}
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.prompt` | string | 优化后的三段式提示词,可直接传入生成管线 |
| `data.rawText` | string | LLM 原始返回文本 |
接入真实 LLM 后(配置 `GEN2D_LLM_API_KEY`),LLM 会根据标签+原始描述+素材类型生成高质量、可执行的提示词。未配置 API key 时自动回退到模板生成。
## 项目结构
```
gen2d/
├── backend/ # Go + Gin API 服务
├── frontend/ # Vite + React 前端
└── docs/ # 项目文档
├── architecture.md # 架构设计
└── api.md # API 文档
```
详细架构说明见 [docs/architecture.md](docs/architecture.md)。
## API
接口统一前缀 `/api/v1/`,详见 [docs/api.md](docs/api.md)。
## 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request