# 04 · 核心业务流程与 AI 流水线

## 1. 端到端业务流程

```
[用户注册/登录]
    ↓
[创建项目] ─ 上传剧本 + 选择纵横比/分辨率/风格
    ↓
[剧本解析] ─ 文本抽取 → 角色提取 → 关系推理 → 智能分集
    ↓
[风格确认] ─ 选择艺术风格手册(2D日漫/国风/3D/水墨...)
    ↓
[大纲生成] ─ 三幕结构 + 付费卡点 + 篇章划分
    ↓
[资产建设] ─ 角色四视图 / 场景图 / 道具图(可并行)
    ↓
[分镜生成] ─ 按集拆分 → 每集 N 个 shot(首尾帧描述 + 对白 + 相机指令)
    ↓
[首尾帧生成] ─ 注入角色参考图 + 风格约束 + 色板约束
    ↓
[视频生成] ─ 首尾帧插值或参考图模式(通义万相/可插拔)
    ↓
[TTS 配音] ─ 按角色音色生成对白音频
    ↓
[口型同步] ─ 可选(Pro 功能)
    ↓
[视频合成] ─ FFmpeg 拼接 + 字幕烧录 + BGM 混音 + 转场
    ↓
[导出/发布] ─ MP4 下载 / 水印处理 / 团队审核
```

## 2. AI 流水线分层

### Stage 1 · 剧本解析流水线

| 步骤 | 输入 | 模型 | 输出 | 存储 |
|------|------|------|------|------|
| 1.1 文本抽取 | 上传文件 | Apache POI / PDFBox | 纯文本 | `projects.script_text` |
| 1.2 事件提取 | 纯文本 | Qwen-Max | 章节 + 事件表 | `novel_events` |
| 1.3 角色提取 | 纯文本 + 事件 | Qwen-Max | 角色卡列表(含去重) | `characters` |
| 1.4 关系推理 | 角色 + 剧本 | Qwen-Max | 关系图 | `character_relations` |
| 1.5 智能分集 | 事件 + 目标集数 | Qwen-Max | 分集方案(三幕 + 卡点) | `episodes` |

**提示词来源**: 借鉴 AIComicBuilder 的 `import_character_extract` + Toonflow 的 `script_execution_skeleton.md`。

### Stage 2 · 资产生成流水线

| 步骤 | 输入 | 模型 | 输出 | 特殊约束 |
|------|------|------|------|---------|
| 2.1 角色四视图 | 角色描述 + 风格手册 | 通义万相 | 4 张参考图(正/3/4侧/侧/背) | 单次生成 16:9 画布 |
| 2.2 衍生资产 | 剧本分析 | Qwen-Max | 服装变体/状态变体列表 | 仅状态变化才衍生 |
| 2.3 衍生资产图 | 父资产图 + 变体提示 | 通义万相 | 变体图 | 参考父资产 |
| 2.4 场景图 | 场景描述 + 色板 | 通义万相 | 场景底图 | 支持室内/室外 |
| 2.5 道具图 | 道具描述 | 通义万相 | 道具素材 | 可选 |

**并发**: 10 张/批,RabbitMQ `image.generate` 队列。

### Stage 3 · 分镜生成流水线

| 步骤 | 输入 | 模型 | 输出 |
|------|------|------|------|
| 3.1 导演规划 | 剧本 + 角色 + 关系图 + 风格 | Qwen-Max | 拍摄计划(景别/机位/运动) |
| 3.2 场景分组 | 剧本 + 导演计划 | Qwen-Max | 场景分组 + 每场镜头数 |
| 3.3 镜头拆分 | 场景 + 时长目标 | Qwen-Max | shot 列表(见下) |
| 3.4 监督审核 | shot 列表 | Qwen-Max | 审核报告 + 修订建议 |

**Shot 字段** (借鉴 AIComicBuilder shot-split):

```json
{
  "sequence": 1,
  "prompt": "张三从树后走出,警惕扫视",
  "startFrame": "张三正面从树后探身,左手扶剑柄,夕阳斜照",
  "endFrame": "张三走到空地中心,目光锁定前方",
  "motionScript": "0-2s: 右肩先露出... 2-4s: 身体侧转...",
  "videoScript": "精炼 40-70 字散文提示词",
  "duration": 8,
  "cameraDirection": "slow zoom in",
  "compositionGuide": "rule_of_thirds",
  "focalPoint": "张三面部",
  "depthOfField": "shallow",
  "dialogues": [{"character": "张三", "text": "谁在那里?"}],
  "characters": ["张三"],
  "transitionIn": "cut",
  "transitionOut": "dissolve",
  "soundDesign": "夜风、远处蝉鸣",
  "musicCue": "紧张低弦乐"
}
```

### Stage 4 · 视觉生成流水线

```
for shot in episode.shots:
  first_frame_prompt = build_first_frame(shot, characters, style)
  first_frame = call_image_model(
    prompt=first_frame_prompt,
    reference_images=[char.turnaround_image for char in shot.characters],
    size=project.resolution,
    ratio=project.aspect_ratio
  )
  save_asset(shot_id, type='first_frame', url=first_frame, version=v+1)

  last_frame_prompt = build_last_frame(shot, first_frame)
  last_frame = call_image_model(
    prompt=last_frame_prompt,
    reference_images=[first_frame] + [char.turnaround]
  )
  save_asset(shot_id, type='last_frame', ...)
```

**模型选择**(可插拔):

| 模型 | 输入模式 | 质量 | 速度 | 成本 |
|------|---------|------|------|------|
| 通义万相 wanx2.1 | text + ref | ⭐⭐⭐ | 快 | 低 |
| Seedance 2.0 | text + ref + audio | ⭐⭐⭐⭐ | 中 | 中 |
| Veo 3.1 | text + 3 ref | ⭐⭐⭐⭐⭐ | 慢 | 高 |
| Kling v3 | text + ref | ⭐⭐⭐ | 中 | 中 |

### Stage 5 · 视频生成流水线

```
for shot in episode.shots:
  video_task = submit_video_task(
    model=project.video_model,
    first_frame=shot.first_frame_url,
    last_frame=shot.last_frame_url,
    prompt=shot.videoScript,
    duration=shot.duration,
    resolution=project.resolution
  )
  # 异步轮询 5s x 120 次
  video_url = poll_until_done(video_task.external_id)
  save_asset(shot_id, type='keyframe_video', ...)
```

### Stage 6 · 音频流水线

```
for voice_line in episode.dialogues:
  audio = qwen_tts(
    text=voice_line.text,
    voice=character.voice_id,
    emotion=voice_line.emotion,
    rate=voice_line.speed
  )
  save_asset(voice_line_id, type='audio', ...)
```

### Stage 7 · 合成流水线 (FFmpeg)

```
1. 按 shot.sequence 排序所有 keyframe_video
2. xfade 转场拼接(cut/dissolve/fade,默认 0.5s)
3. 生成 SRT 字幕(基于 dialogues 时间比例)
4. 字幕硬编码烧录
5. 混入对白音频(按时间戳)
6. 混入 BGM(volume=0.3)
7. 添加片头标题卡(3s) + 片尾(2s)
8. 输出 /projects/{id}/episodes/{eid}/final.mp4
```

## 3. 三层 Agent 协作(借鉴 Toonflow)

### 3.1 ScriptAgent(剧本 Agent)

```
用户输入 / 剧本上传
    ↓
[决策层 DecisionAgent]
    解析意图 → 拆解任务 → 调度执行/监督
    ↓
[执行层] 串行调用:
    SkeletonExecutor (故事骨架)
        ↓ 输出到工作区
    [监督层 SupervisionAgent] 审核 → 通过/驳回/重做
        ↓
    AdaptationExecutor (改编策略)
        ↓
    [监督层] 审核
        ↓
    ScriptExecutor (剧本编写)
        ↓
    [监督层] 审核
    ↓
[决策层] 汇总 → 返回用户
```

### 3.2 ProductionAgent(制作 Agent)

```
[决策层]
    ↓
DeriveAssetsExecutor (衍生资产分析)
    ↓
GenerateAssetsExecutor (资产图生成, 异步)
    ↓
DirectorPlanExecutor (导演规划)
    ↓ [监督]
StoryboardTableExecutor (分镜表)
    ↓ [监督]
StoryboardPanelExecutor (分镜面板写入)
    ↓
StoryboardImageExecutor (首尾帧生成, 异步并发)
    ↓
VideoExecutor (视频生成, 异步并发 + 轮询)
    ↓
AssemblyExecutor (FFmpeg 合成)
```

### 3.3 实现要点

- 决策层用 Spring AI Alibaba `ChatClient` + `@Tool` 定义子 Agent 为可调用工具
- 执行层每个 Executor 是独立 `@Service`,提示词从 `skills/` 加载
- 监督层可选开启(Free 套餐关闭以省成本)
- 跨 Agent 上下文通过 Redis Stack 向量检索(RediSearch)+ 短期摘要

## 4. 并发与异步策略

| 队列 | 并发 | 超时 | 重试 |
|------|------|------|------|
| `text.generate` | 50 | 60s | 3 次 |
| `image.generate` | 20 | 120s | 3 次 |
| `video.generate` | 10 | 900s | 2 次(昂贵) |
| `voice.tts` | 30 | 30s | 3 次 |
| `video.assemble` | 5 | 1800s | 1 次 |
| `lipsync` | 5 | 600s | 2 次 |

所有任务**必须**通过 RabbitMQ,**禁止**直接在 HTTP 线程里调 AI(借鉴 waoowaoo 代码卫士)。

## 5. 进度推送

**Server-Sent Events (SSE)** 主推送:

```
GET /api/projects/{id}/events   (text/event-stream)

event: task.progress
data: {"taskId":"...","type":"video","progress":45,"currentShot":12,"totalShots":50}

event: task.completed
data: {"taskId":"...","resultUrl":"..."}

event: task.failed
data: {"taskId":"...","error":"..."}
```

WebSocket 留给后续实时协作(多人同时编辑分镜)。
