把小说变成短视频/漫画——全流程技术复盘

用 AI 把小说变成短视频/漫画------全流程技术复盘

本文记录了一个从零到跑通的 AI 内容生产平台的技术实现过程。核心能力:输入一段小说文本,自动输出一集短视频或一页漫画。


背景与动机

现在 AI 生成视频和图像的能力已经非常成熟,但"把小说改编成可视化内容"这件事仍然高度依赖人工------你需要自己写分镜、描述每一帧画面、选择风格、保持人物一致性......

这个项目想把这个流程完全自动化:

复制代码
小说文本 → Claude 理解情节 → 生成剧本 → 生成分镜 → AI 逐帧生成图/视频 → 合成输出

支持两种输出模式:短视频 (MP4 合成)和漫画(逐格 PNG)。


技术架构概览

vbnet 复制代码
Next.js 16 (App Router)
├── 前端:React 19 + TailwindCSS v4
├── 后端:Next.js Route Handlers(全部 SSE 流式)
├── 数据库:PostgreSQL + Prisma ORM
├── AI 分析/编剧/分镜:Anthropic Claude
├── 图像生成:Stable Diffusion(本地)/ 豆包 Seedream(云端)
└── 视频生成:Seedance / Runway / Kling / Flow2API

没有独立的后端服务,全部跑在 Next.js 的 Route Handlers 里,长任务全部用 SSE 流式推送进度。


一、数据库设计:层级化内容模型

整个系统围绕一个五层数据模型运转:

css 复制代码
Series(系列)
  └── Project/Part(子项目,每集对应一个)
        ├── Analysis(内容分析结果)
        ├── Episode(集数,含完整剧本 JSON)
        │     ├── Shot[](视频分镜)
        │     └── MangaPanel[](漫画格)
        └── CharacterModel[](角色/场景建模,系列级共享)

几个设计决策值得记录:

scriptContent 用 JSON 字段存全量剧本,而不是拆表。剧本是一次生成、整体消费的数据,不需要单独查询某一行台词,JSON 字段反而更灵活,也避免了过度设计。

CharacterModel 实现版本管理 :每次重新建模会创建新版本,isActive 标记当前激活版本。建模结果系列级共享(seriesId 字段),所有子项目都能用同一套角色参考图,保证跨集视觉一致性。

异步状态追踪Shot.videoStatusMangaPanel.imageStatus 都是 pending / processing / completed / failed 四态状态机。前端通过 SSE 事件实时更新,不需要轮询。

prisma 复制代码
model MangaPanel {
  id             String   @id @default(cuid())
  episodeId      String
  panelNumber    Int
  description    String   @db.Text   // 中文画面描述
  prompt         String   @db.Text   // 英文生图提示词
  dialogue       String?  @db.Text   // 对话气泡
  innerMonologue String?  @db.Text   // 心理独白
  sfx            String?             // 音效拟声词
  expressionType String?             // 表情类型
  panelSize      String   @default("medium")  // big/medium/small
  imageStatus    String   @default("pending")
  imageUrl       String?
}

二、Claude 多阶段调用流水线

整个内容生产流程分四个阶段,每个阶段独立调用 Claude:

阶段 1:内容分析(claude-opus-4-6)

这是整个流程的地基。Prompt 要求 Claude 从小说中提取:

  • 角色:必须包含 8 个维度的外貌描述(脸型、眼型、鼻梁、嘴唇、肤色、身材比例、发型发色、标志性特征),这是后续建模的唯一依据
  • 场景:标志性元素、氛围色调、叙事功能
  • 情节要点:按节拍提取,用于剧本生成

一个关键工程细节:输入文本截断到 60,000 字符,避免超出 context window。输出用 jsonrepair 库自动修复 LLM 可能生成的格式破损 JSON(比如末尾多了逗号、括号不匹配等)。

阶段 2:剧本生成(claude-opus-4-6)

基于分析结果生成短剧结构剧本,要求"钩子→冲突升级→爽点→悬念"的四段式结构。支持多集生成,并对第一集和收尾集有特殊提示词(第一集需要更强的吸引力钩子,收尾集需要留悬念)。

阶段 3:分镜生成

这里视频和漫画有完全不同的 Prompt 策略:

视频分镜 Prompt 要求

  • 每集 12--24 个镜头,每镜 5 秒,总时长 60--120 秒
  • 每镜必须包含:景别(远/中/近/特写)、运镜方式(推/拉/摇/跟)、光线描述、情绪标签

漫画分镜 Prompt 要求

  • Claude 被要求理解真正的漫画语言:格子大小权重(大格=情绪高潮,小格=快节奏过渡)
  • 区分对话气泡(dialogue)和心理独白云(innerMonologue)
  • 每格有表情类型标签和拟声词音效
  • Prompt 里提供了 3 个完整示例格,显著提升了输出格式的稳定性

阶段 4:Prompt 翻译(claude-haiku-4-5)

角色/场景描述(中文)→ 图像生成提示词(SD 用英文,Seedream 用中文)。用更快的 Haiku 模型做这个翻译任务,节省成本和时间。

SD 有一个特殊处理:强制把 1girl,1boy, 放在 prompt 最前面。SD 对词序很敏感,性别描述词如果被埋在长 prompt 中间,生成的性别经常是错的。


三、SSE 流式架构

所有耗时任务都用 Server-Sent Events,包括:内容分析、剧本生成、分镜生成、批量生图、批量生视频。

基本模式如下:

typescript 复制代码
export async function POST(request: NextRequest) {
  const encoder = new TextEncoder();
  const stream = new ReadableStream({
    async start(controller) {
      const enqueue = (data: Record<string, unknown>) =>
        controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`));

      // 长任务逻辑
      enqueue({ type: "start", total });
      for (const item of items) {
        await processItem(item);
        enqueue({ type: "done", id: item.id, result });
      }
      enqueue({ type: "complete" });
      controller.close();
    },
  });

  return new Response(stream, {
    headers: {
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      Connection: "keep-alive",
    },
  });
}

每个 SSE 事件都有 type 字段,前端根据 type 更新对应的 UI 状态。比如漫画批量生图会推送 { type: "done", panelId, panelNumber, imageUrl },前端收到后直接把对应格子的图片替换掉。

export const maxDuration = 300 把 Vercel 的超时上限拉到 5 分钟,对于批量生成任务基本够用。


四、图像生成:SD 本地 vs Seedream 云端

两套图像生成后端,通过 imageProvider 参数切换(值为 "sd" 或具体的 Seedream 模型 ID)。

Stable Diffusion(本地)

风格一致性是最大挑战。解决方案:锁死所有生成参数。

typescript 复制代码
const MANGA_STYLE_PREFIX =
  "masterpiece, best quality, anime style, manga illustration, cel shading, clean linework, flat color, 2d illustration,";
const MANGA_STEPS = 30;
const MANGA_CFG = 9.0;
const MANGA_SEED = 42;  // 固定 seed 是关键

同时用 stripStylePrefix() 函数把 Claude 生成的 prompt 中的风格词(anime stylemasterpiece 等)先剥离,再统一拼接上我们锁定的前缀。否则两套风格词叠加会互相干扰。

Seedream(云端)

豆包的 Seedream API 支持文生图和图生图,接口在 https://ark.cn-beijing.volces.com/api/v3/images/generations

关键设计:通过是否传入 referenceImageUrl 自动判断用文生图还是图生图,不需要调用方显式指定模式。建模时,如果该角色已有激活版本,就用图生图(denoise=0.55)在原图基础上生成新版本,保持角色一致性。

typescript 复制代码
export async function seedreamGenerate(
  prompt: string,
  opts: { referenceImageUrl?: string; size?: string; model?: string } = {}
): Promise<{ url: string }> {
  const body: Record<string, unknown> = {
    model: opts.model ?? DEFAULT_SEEDREAM_MODEL,
    prompt,
    size: opts.size ?? "1024x1024",
  };
  if (opts.referenceImageUrl) {
    body.image = opts.referenceImageUrl;  // 有参考图 → 图生图
  }
  // ...
}

Prompt 语言也分开处理:SD 用英文(对英文词更敏感),Seedream 用中文(豆包模型对中文理解更好)。


五、视频生成:多 Provider 适配层

视频生成支持 4 个服务商:Seedance、Runway、Kling、Flow2API。用工厂模式做统一适配:

typescript 复制代码
function getProvider(name: string): VideoProvider {
  switch (name) {
    case "runway": return new RunwayProvider();
    case "kling": return new KlingProvider();
    case "flow2api": return new Flow2APIProvider();
    default: return new SeedanceProvider();
  }
}

每个 Provider 实现同一套接口:generate(prompt, options) → 返回任务 ID → poll(taskId) → 返回视频 URL。

批量生成时用 Promise.all() 并发推所有镜头,每个镜头完成后立即通过 SSE 推送结果,前端可以看到镜头一个个出现,而不是等全部完成才刷新。


六、前端:四步工作流

整个工作页面是一个四步状态机:

vbnet 复制代码
Step 1: 上传文件(PDF/EPUB/TXT 解析)
Step 2: 内容分析 + 角色/场景建模
Step 3: 生成剧本
Step 4: 生成分镜 + 生成图/视频(视频/漫画模式分叉)

几个值得记录的细节:

  • 乐观更新:SSE 事件到达时,直接更新本地 state,不重新请求 API,避免闪烁
  • 客户端 JSON 修复 :流式 JSON 解析时也做了简单的格式修复 replace(/,(\s*[}\]])/g, "$1"),处理 Claude 偶尔生成的末尾多余逗号
  • 漫画格布局panelSize === "big" 的格子会占两列(col-span-2),还原漫画的版式感
  • Prisma + Turbopack 缓存坑 :每次修改 schema.prisma 后,必须 rm -rf .next 再重启,否则 Turbopack 会缓存旧版 Prisma Client 导致运行时报 Unknown argument 错误

总结

几个核心决策回顾:

决策 理由
全 SSE,不用 WebSocket Route Handler 里更简单,单向推送足够
视频/漫画共用前三步 降低维护成本,差异只在 Step 4 分叉
用模型 ID 作为 imageProvider 值 无需额外映射,新增模型只改一处
固定 seed/steps/cfg 风格一致性比随机性更重要
CharacterModel 系列级共享 建模是高成本操作,跨集复用是必须的
jsonrepair 修复 LLM 输出 LLM 输出 JSON 不稳定是常态,与其加重试不如加修复

整个项目大约两周从零跑通,主要时间花在 Prompt 调优上------特别是漫画分镜的 Prompt,经过多轮迭代才让 Claude 输出真正符合漫画语言规范的分镜结构。

代码开源在:github.com/hong-peng/t...

相关推荐
飞Link2 小时前
【AI大模型实战】万字长文肝透大语言模型(LLM):从底层原理解析到企业级Python项目落地
开发语言·人工智能·python·语言模型·自然语言处理
TechMasterPlus2 小时前
OpenClaw 源码深度解析:下一代 AI Agent 框架的架构设计与实现原理
人工智能
不完备智能2 小时前
🦌 DeerFlow 2.0 深度解析:字节跳动开源的"超级 Agent harness"架构揭秘
人工智能
阿木木AEcru2 小时前
DeepSeek 崩了 13 小时,不是故障,是 V4 在换引擎
人工智能
小小工匠2 小时前
Superpowers - 09 从构思到落地:如何用「计划编写与任务粒度」驾驭 AI 时代的软件开发
人工智能·skills·superpowers
阿聪谈架构2 小时前
第07章(下):LangGraph 工作流进阶 —— 检查点、人工介入与多 Agent 协作
人工智能·后端
小小工匠2 小时前
Superpowers - 08 在 AI 时代重写「需求评审会」:深入解读 Superpowers 的头脑风暴与设计规范机制
人工智能·skills·superpowers
橘子编程2 小时前
Hermes Agent 完整使用指南
人工智能
yuhulkjv3352 小时前
AI导出的Excel公式失效
人工智能·ai·chatgpt·excel·豆包·deepseek·ai导出鸭