- frontend/: Next.js 16 app (App Router, React 19, Tailwind v4) - skills/: project skills (seedance, automation, trae-agents, etc.) - Docs: PRD, UI-Design-System, DEV-LOG, seedance integration notes - skills-lock.json: skills version lock Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
265 lines
13 KiB
Markdown
265 lines
13 KiB
Markdown
# Air Spark — PRD
|
||
|
||
> v0.4 | 2026-03-04
|
||
|
||
---
|
||
|
||
## 1. 产品定位
|
||
|
||
AI 驱动的动画自动化生产平台。导演通过对话生成剧本,系统自动串联图片生成 → 视频生成 → 拼接,输出完整成片。
|
||
|
||
先供 Air Spark 内部使用,架构支持未来扩展为 SaaS。
|
||
|
||
---
|
||
|
||
## 2. 用户角色
|
||
|
||
| 角色 | 核心需求 |
|
||
|------|---------|
|
||
| **导演** | 对话写剧本 → 一键触发流水线 → 审核成片 |
|
||
| **管理员** | 管理成员、API Key、Skill 配置 |
|
||
|
||
---
|
||
|
||
## 3. 内容层级
|
||
|
||
```
|
||
项目(Project) ← 一部动画 IP,建立时选内容类型 → 自动加载 Skill 包
|
||
├── 资产库(Asset Library) ← 角色/场景图,跨集跨阶段复用
|
||
└── 剧集(Episode) ← EP01, EP02 ...
|
||
├── 剧本(script.md)
|
||
├── 流水线状态
|
||
└── 各阶段输出文件
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Agent + Skill 架构
|
||
|
||
**核心设计原则**:`模型 + Skill = Agent`
|
||
|
||
Skill 是系统提示词(System Prompt),定义 Agent 的行为规则和输出格式。
|
||
扩展内容类型 = 新增 Skill,不需要改代码。
|
||
|
||
```
|
||
screenplay-skill → 生成符合 Seedance 输入格式的剧本(△行即提示词)
|
||
storyboard-skill → 按场景生成 Keyshot 宫格图(空间位置锚点)
|
||
segmentation-skill → 按内容逻辑将剧本切分为 Seedance 片段(内容驱动,非机械按秒切)
|
||
|
||
两条并行线,都以剧本为输入,互不依赖:
|
||
剧本 → storyboard-skill → Keyshot 图(空间参考)
|
||
↘
|
||
剧本 → segmentation-skill → 片段提示词 → Seedance(提示词 + 参考图)
|
||
↗
|
||
剧本 → 参考图生成(Banana Pro)→ 人设图、场景图
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 七阶段流水线
|
||
|
||
```
|
||
Stage 1 剧本对话
|
||
只加载 screenplay-skill
|
||
导演与 Claude 对话,生成符合 Seedance 格式的剧本
|
||
满意后点「确认剧本」→ 保存 script.md
|
||
↓ [手动确认]
|
||
|
||
Stage 2 资产 & 分镜规划(Claude · storyboard-skill)
|
||
读取 script.md → 输出:
|
||
· characters.json 角色列表 + 英文提示词 + 标记性特征
|
||
· scenes.json 场景列表 + 英文提示词 + 每场估算时长
|
||
· keyshots.json 每场景的 Keyshot 规划:
|
||
- 格数(4格/9格,按时长自动选)
|
||
- 每格的空间位置描述(英文)
|
||
- 宫格图生成提示词
|
||
时长估算规则(与 segmentation-skill 共用):
|
||
对白:3-4字/秒;普通动作:2-3秒;复杂动作:4-5秒
|
||
格数规则:
|
||
场景 ≤ 45秒 → 4宫格(2×2,每格~11秒)
|
||
场景 45秒-2分钟 → 9宫格(3×3,每格~8-13秒)
|
||
场景 > 2分钟 → 拆成两个9宫格(在自然剧情节点分割)
|
||
↓ [可选审核]
|
||
|
||
Stage 3 参考图生成(Banana Pro API · text2img)
|
||
每类图片生成规则:
|
||
人设图 × N(每角色两步生成):
|
||
Step 1:生成正面立绘(白色背景)→ character_{id}_front.jpg
|
||
Step 2:以正面立绘 + 固定三视图模板后缀为输入,生成三视图
|
||
→ 输出一张 16:9 图:包含正面胸像(左)+ 正面全身 + 侧面 + 背面
|
||
→ 最终存入资产库:character_{id}.jpg
|
||
小提示词后缀(固定模板,后续由用户提供):
|
||
"生成这个角色的三视图,包括:正面胸像(位于画布最左侧),正面视角、侧面视角、背面视角,浅灰色无缝背景,干净且简约"
|
||
场景图 × M(每场景1张,最佳角度,不含角色)
|
||
道具图 × K(重要道具,按需)
|
||
→ 存入资产库(命名与 characters.json / scenes.json 的 id 一一对应)
|
||
↓ [人工审核:动画前期必须确认人设]
|
||
|
||
Stage 4 Keyshot 宫格生成(Banana Pro API · text2img)
|
||
读取 keyshots.json:每个场景 → 1次 API 调用
|
||
输入:宫格提示词 + 该场景人设图 + 场景图(来自资产库)
|
||
生成尺寸:
|
||
4宫格 → 2560×1440(裁切后每格 1280×720)
|
||
9宫格 → 3840×2160(裁切后每格 1280×720)
|
||
PIL 精确裁切(本地,零成本):
|
||
→ keyshot_{scene_id}_{keyshot_index}_{cell_num}.jpg
|
||
Keyshot 映射:
|
||
每段 Seedance 片段按起始时码查找对应 Keyshot cell
|
||
cell_num = floor((seg_start - scene_start) / cell_duration) + 1
|
||
↓ [可选审核:快速扫一遍,确认空间位置无明显错误]
|
||
|
||
Stage 5 剧本切分(Claude · segmentation-skill)
|
||
读取 script.md → 按内容逻辑切分(非机械按秒):
|
||
依据:场景边界(必切)、镜头切换点、对话节奏、情绪节点
|
||
上限:每段 ≤ 15秒(Seedance 2.0 最大时长)
|
||
输出:segments.json
|
||
每段包含:
|
||
- 时码、时长、场景ID、出场角色ID
|
||
- Seedance 提示词文本(剧本原文,一字不改)
|
||
- 参考图列表(语义声明):
|
||
[{"type":"character","id":"char_001"},
|
||
{"type":"scene","id":"scene_002"},
|
||
{"type":"keyshot","scene_id":"scene_002","keyshot_index":1,"cell_num":3}]
|
||
不使用 prev_frame(上一段尾帧):
|
||
- prev_frame 依赖上一段视频已生成,强制串行,破坏并发
|
||
- Seedance 2.0 参生机制(人设图+场景图+keyshot+提示词)已保障角色一致性
|
||
- keyshot cell 图承担空间位置锚点,替代尾帧的连续性职责
|
||
- 不同场景之间本就是"硬切",不需要尾帧衔接
|
||
↓ [可选审核]
|
||
|
||
Stage 6 视频生成(Seedance 2.0 · 全并发)
|
||
前置条件:Stage 3(参考图)+ Stage 4(Keyshot 格图)+ Stage 5(segments.json)均完成
|
||
所有片段同时提交,无任何顺序依赖
|
||
Seedance API 请求结构(火山引擎 Ark):
|
||
content 数组(按顺序排列):
|
||
1. {type: "text", text: <完整提示词>}
|
||
2. {type: "image_url", image_url: {url: <图1>}, role: "reference_image"}
|
||
3. {type: "image_url", image_url: {url: <图2>}, role: "reference_image"}
|
||
...(最多 12 张,每张 role 均为 "reference_image")
|
||
其他参数:generate_audio: true,duration: 片段时长,ratio: 项目视频比例
|
||
提示词结构(后端自动拼装):
|
||
{script_text(剧本原文,一字不改)}
|
||
|
||
{渲染风格},[图1]是{角色名},[图2]是{场景名},[图3]是{keyshot位置},[图N]是{道具名},
|
||
你是一位专业的动画导演,自行安排分镜设计,切镜充满电影感,画面氛围也有电影感,不要有背景音乐,但要有音效。
|
||
(动作戏追加:动作戏可以有一点荷兰式倾斜镜头,动作戏的镜头具有视觉张力和空间感。)
|
||
注意:[图N] 序号与 content 数组中 image_url 的顺序严格对应,由后端拼装时自动编号
|
||
参考图拼装顺序(固定):角色人设图(按 character_ids 顺序)→ 场景图 → keyshot cell 图 → 道具图
|
||
任务队列(Celery + Redis):
|
||
- FastAPI 接受触发请求 → 推入 Redis 队列
|
||
- Celery Worker 消费队列 → POST 提交所有片段到 Seedance API
|
||
- 统一异步轮询所有 job_id → 下载完成的片段
|
||
- 任务状态持久化在 Redis,服务重启不丢失,支持断点续跑
|
||
错误处理:自动重试3次(指数退避 1s/4s/16s),429 按响应头等待,超限后人工介入
|
||
断点续跑:跳过已 completed 片段,只重跑 failed/pending
|
||
过渡期(API 未开放前):使用 Seedance 1.5 Pro API,仅 model_id 不同,逻辑一致
|
||
↓ [可选审核:单段重跑时可修改提示词]
|
||
|
||
Stage 7 剪辑审核 & 导出(时间轴 UI + FFmpeg)
|
||
可视化时间轴界面(类 Medeo / 剪映简化版):
|
||
· 底部时间轴:每个片段一个缩略图块,标注时长和场景名
|
||
· 拖拽排序:拖动片段调整顺序,自动更新 concat 序列
|
||
· 单片段预览:点击片段 → 中间预览区播放该片段
|
||
· 右键菜单:重新生成 / 编辑提示词后重跑 / 删除片段
|
||
· 「预览全片」:服务端 FFmpeg concat → 返回预览 MP4(数秒内完成)
|
||
· 「导出成片」:最终 FFmpeg concat -c copy → final-epXX.mp4
|
||
FFmpeg 拼接命令:
|
||
ffmpeg -f concat -safe 0 -i concat.txt -c copy final-ep01.mp4
|
||
无损拼接,保留 Seedance 原生音画同步
|
||
```
|
||
|
||
**流水线模式(项目级设置)**:
|
||
- `全自动`:每阶段自动通过(Stage 1、Stage 3 除外,两处必须人工确认)
|
||
- `逐步审核`:每阶段完成后等待导演批准
|
||
- `自定义`:每个 Stage 单独配置是否需要审核
|
||
|
||
---
|
||
|
||
## 6. 审核门
|
||
|
||
每阶段完成后,导演可以:
|
||
- **批准** → 继续下一阶段
|
||
- **重跑(原提示词)** → 重新执行本阶段
|
||
- **编辑提示词后重跑** → 修改后重新生成
|
||
- Stage 3、4、6 支持**单个资产/片段重跑**,不用整阶段重来
|
||
|
||
---
|
||
|
||
## 7. 错误处理与断点续跑
|
||
|
||
每个原子任务(单次 API 调用)有独立状态:`pending / running / completed / failed`
|
||
|
||
- API 超时 / 5xx → 自动重试,最多3次(指数退避 1s / 4s / 16s)
|
||
- 429 限速 → 按响应头等待后重试
|
||
- 重试耗尽 → 标记 `failed`,审核门提示人工处理
|
||
- 断点续跑:查询当前 Stage 所有任务,跳过 `completed`,只重跑 `failed` / `pending`
|
||
- 任务状态持久化在 Redis,服务重启后状态不丢失
|
||
|
||
---
|
||
|
||
## 8. 资产库
|
||
|
||
- 存储:人设图、场景图、道具图、Keyshot 图
|
||
- 命名规范:`{asset_type}_{id}.jpg`,与 JSON 中的 id 字段严格对应
|
||
- 跨集复用:同项目下新剧集自动引用已有资产,可手动替换单张
|
||
- 操作:查看 / 编辑提示词 / 重新生成
|
||
|
||
---
|
||
|
||
## 9. Skill 系统
|
||
|
||
**架构原则**:Skill = 系统提示词,定义 Agent 的行为和输出格式。扩展内容类型只需新增 Skill,不改代码。
|
||
|
||
**现有已验证 Skill(输出格式改造为 JSON,逻辑不变)**:
|
||
- `screenplay-skill`:剧本生成/优化,输出符合 Seedance △行格式的剧本
|
||
- `storyboard-skill`:场景/人设/Keyshot 提取,输出 characters.json / scenes.json / keyshots.json
|
||
- `segmentation-skill`:剧本切分,输出 segments.json(含语义化参考图声明)
|
||
|
||
**Skill 改造重点**:
|
||
- 现有 Skill 输出的是人类可读 Markdown,自动化需要输出程序可解析的 JSON
|
||
- 改造原则:只改输出格式,不改提示词逻辑和规则
|
||
- `@图x` 占位符改为语义声明(type + id),由后端查表解析为实际文件路径
|
||
|
||
**项目类型 → Skill 包**:
|
||
| 内容类型 | 自动加载 |
|
||
|---------|---------|
|
||
| 原创动画 | screenplay + storyboard + segmentation |
|
||
| 自定义 | 手动勾选 |
|
||
|
||
---
|
||
|
||
## 10. 技术选型
|
||
|
||
| 层 | 选型 | 备注 |
|
||
|----|------|------|
|
||
| 前端 | Next.js 14 (App Router) | SSR,TypeScript,生态成熟 |
|
||
| 后端 | Python FastAPI | AI 生态(PIL/异步),Skill 调用 |
|
||
| 任务队列 | Celery + Redis | 管理 Stage 3/4/6 的并发 API 任务,状态持久化,断点续跑 |
|
||
| 数据库 | PostgreSQL | 流水线状态、资产元数据、Skill 配置 |
|
||
| 实时通信 | Server-Sent Events | 流水线进度推送 |
|
||
| AI | Claude API (Opus 4.6) | 可配置 base_url,支持第三方代理 |
|
||
| 图片生成 | Banana Pro 第三方 API | 适配器可替换,TBD 具体服务商 |
|
||
| 视频生成 | Seedance 2.0(火山引擎 Ark)| 参生模型,过渡期用 1.5 Pro,升级只改 model_id |
|
||
| 视频拼接 | FFmpeg concat -c copy | 无损,保留原生音画同步 |
|
||
| 图片裁切 | Python Pillow(PIL)| 本地执行,零成本,精确 |
|
||
| 文件存储 | 本地文件系统 → S3/OSS | 初期本地,后期迁移 |
|
||
|
||
---
|
||
|
||
## 11. 不做的事(MVP 范围外)
|
||
|
||
- 片头片尾 / 主题曲管理(单独规划)
|
||
- 视频转场特效
|
||
- 多租户 / 账号体系(先单团队使用)
|
||
- 计费功能
|
||
- 移动端
|
||
|
||
---
|
||
|
||
## 12. 待确认
|
||
|
||
1. **Banana Pro API**:具体服务商和接口文档(影响 Stage 3/4 实现);各类图片的"小提示词"后缀模板,用户接入 API 后逐个提供
|
||
2. **Claude API 代理**:具体用哪家(设计为可配置,不阻塞开发)
|
||
3. **视频比例**:项目创建时设定(16:9 / 9:16 / 21:9),影响宫格生成尺寸
|
||
4. **Seedance 并发限制**:火山引擎 Ark 的并发配额,影响 Stage 6 Celery Worker 并发数设置
|