做AI短剧这半年多,我对“工业化”这个词的理解发生了很大的变化。以前总觉得工业化就是堆人、堆时间、堆设备,后来真正把一个短剧从剧本到成片跑成一条流水线才发现,决定产能的从来不是某一个模型有多强,而是能不能把大模型、Agent、API编排这些环节,组合成一套不依赖个人手感、能稳定复现的生产系统。我们给这套方案内部取了个代号,叫“羽山数智”,名字听着有点玄,实际上思路非常朴素:上游剧本交给画布Agent去拆解,下游视频、配音、字幕、合成全部通过API编排自动串起来。这篇文章就把整套流程从头到尾复盘一遍,包括画布Agent怎么设计、API层怎么封装、参数怎么定、失败怎么兜底,尽量做到可参考、可复现。

这不是一篇学术论文,也不会只讲概念。所有内容都来自我实际跑项目的记录,包括那些踩过的坑、试错后的参数、以及最后沉淀下来的生产链路。如果你正在做AI短剧、AI视频生成,或者只是想了解Agent和API编排到底怎么在生产环境里落地,这篇文章应该能给你一些实在的参考。

1. 项目背景与整体设计思路拆解

1.1 为什么要做“工业化流水线”而不是“一个个手工生成”

短剧这个东西,单条做出来并不难。现在的大模型和视频生成工具,已经强到普通人输入一段描述就能出画面。但“单条能做”和“稳定批量出片”完全是两个世界。

我一开始也是手工流程:先在对话里让大模型写剧本,再把剧本复制到另一个工具里让它写分镜,然后把分镜一段段粘到视频生成界面里,生成完了还要自己找配音、手动加字幕、手动剪辑。头两部片子还能靠热情撑住,做到第三部就开始崩溃。原因很简单:每次交接都是人工复制粘贴,上下文全断;分镜描述在不同工具之间反复改写,风格漂移得厉害;更麻烦的是,一旦中间某一步效果不好,你根本不知道问题是出在剧本提示词、分镜描述还是视频参数上。

工业化流水线要解决的核心问题,就是把“人肉搬运信息”改成“系统传递结构化数据”,把“靠感觉调参数”改成“每步都有记录、有版本、可回溯”。这个思路说起来简单,落地时涉及三个关键转变:第一,所有创作环节都变成可独立调用的节点;第二,节点之间传递的不是大段自然语言文本,而是结构化的JSON数据;第三,每个生成任务都有明确状态,失败后能定位、能重试、能统计。

1.2 羽山数智方案的架构:为什么是“画布Agent + API编排”两层

整套方案从架构上分成两层,一层是画布Agent,另一层是API编排。有人会问,为什么不干脆全塞进一个Agent框架里跑完?最开始我也这么干过,用LangChain把剧本、分镜、提示词、视频调用全串在一个长链里,结果跑起来非常痛苦。长链任务一旦中间某一步返回结果格式不对,后面全乱;而且生成视频是异步任务,动不动就几十秒甚至几分钟,不能让同步的Agent链一直干等。

画布Agent解决的是“创作链路里的智能决策”问题。它负责剧本结构分析、分镜切分、角色卡提取、提示词组装这些需要大模型理解和生成的工作。我用画布而不是纯代码,是因为团队里有编导、美术、后期这些非技术角色,他们也要能看懂流程、调整规则。画布上每个节点输入输出都是可以看到的,哪一步产出不合理,直接在那个节点改提示词就行,不用翻代码。

API编排层解决的是“生成任务的调度和执行”问题。视频生成、配音合成、音频处理这些都是耗时任务,必须走异步队列。我们用一个中心化的API网关把各类上游服务统一封装,上层Agent画布只需要按固定格式提交任务、查询状态,完全不用关心底层调的是哪家模型、走的什么协议。

不过这里要说明一下,画布Agent和API编排不是严格的先后关系,而是交叉协作。画布Agent负责把“创意”转成“参数化任务”,API编排层负责把“参数化任务”转成“实际生成结果”,生成结果再回流到画布节点里做质检和下一轮决策。

2. 画布Agent:从创意到分镜的结构化拆解

2.1 画布Agent解决了什么核心问题

先说“画布”这个词。你可以把它理解成一张可视化流程图,每个节点是一个处理单元,节点和节点之间用连线表示数据流,拖拽就能搭建一条工作流。和纯代码编写Agent相比,画布方式有三个非常实际的好处。

第一个是规则可视化。剧本拆成几幕、每幕包含哪些场次、分镜表需要哪些字段,这些规则直接展现在画布上。编导提需求说“把节奏加快”,我只需要调整某个节点的提示词,不用去翻几千行代码。第二个是产出可检查。每个节点的输出都有预览,剧本生成后可以马上检查人物关系有没有矛盾,分镜表出来后可以马上检查镜头衔接是不是顺。第三个是出错可定位。流水线跑挂了,直接看是哪个节点报错,是输入格式问题还是模型返回超时,界面上一目了然。

我们不追求把所有逻辑都塞进画布,而是只把需要“智能判断”的步骤放进去。比如“分析这段剧本的情绪曲线”适合放Agent节点,“把这段视频从MP4转成MOV”这种纯算力的操作放编排层做就行。这样画布既保持了灵活性,又不会因为节点太多导致维护成本爆炸。

2.2 画布节点的设计与数据流规范

节点的设计原则是“单一职责”,一个节点只做一件事,并且输入输出格式严格定义。我们实际在画布上跑的节点大概有6类,每一步都有对应产物:

  • 剧本结构分析节点:输入故事梗概或原始剧本,输出场次表、人物表、故事冲突曲线
  • 分镜提取节点:输入场次表,输出分镜表,包含镜头号、景别、时长、画面描述、台词、情绪、音效
  • 角色一致性节点:从剧本里提取每个角色的相貌特征、服装、年龄、气质,生成角色卡
  • 提示词组装节点:把分镜和角色卡组装成各个生成模型能理解的提示词,分正向和负向
  • 风格控制节点:锁定整体视觉风格,比如“写实电影感”“古风国漫”“都市悬疑”,输出风格关键词
  • 质检规则节点:输出每个镜头必须满足的硬性标准,比如人脸清晰、无多余文字、无穿帮

节点之间传递的数据格式从一开始就固定成JSON,这是整个方案里最重要的一条规则。一个分镜的数据结构大概长这样:

{
  "scene_id": "S01_03",
  "shot_id": 5,
  "duration": 6.5,
  "shot_type": "medium_close_up",
  "camera": "slow_push_in",
  "setting": "废弃工厂内部,暖黄色灯光,灰尘颗粒可见",
  "character_actions": "男主转身,手拿旧照片,表情从怀疑到震惊",
  "character_ref": "male_lead_v3.png",
  "style": "cinematic_realism",
  "dialogue": "这地方……我小时候好像来过。",
  "emotion": "shock",
  "sfx": "低频轰鸣声,风穿过铁窗",
  "negative": "blurry_face, bad_hands, extra_fingers, watermark, wrong_text"
}

这个JSON是画布和API编排层之间的“通用语言”。不管底层大模型返回的格式有多不规范,画布节点都会把它清洗、校正成标准结构后再传给下一层。这样做的好处是:换模型不换结构。今天用这个视频模型,明天换那个,API编排层接收的参数格式基本不变。

2.3 画布编排中容易踩的三个坑

第一个坑是上下文无限制膨胀。画布Agent在处理一个3分钟短剧时,剧本、人物小传、分镜表加起来文本量非常大。刚开始我们没有做窗口管理,直接把全部内容塞给大模型重新生成,结果频繁触发上下文超限报错。日志里最常见的提示就是上下文长度超了模型上限。后来我们每完成一个节点,就做一次“摘要压缩”,把关键信息保留、详细过程丢弃,只把结构化字段往下传。分镜提取节点只需要当前场次的内容,不需要把整个30集剧本都带着。

第二个坑是节点粒度过细或过粗。细到“给每个镜头单独生成一个提示词”会让整张画布密密麻麻,维护成本极高;粗到“一个节点从剧本直接输出成片脚本”又会失控,你没法在中间插入人工检查。我们反复调整后才定下来:以“场景”为粒度设计分镜节点,一次处理一个场景里的几场戏,既保证上下文完整,又便于中途干预。

第三个坑是画布“什么都能做”的诱惑。我见过很多团队把Agent框架越搭越复杂,最后成了一个谁都不敢动的巨型系统。我的建议是,画布里只保留需要模型智能判断的节点,所有确定性逻辑全部下沉到代码和编排层。比如“判断视频人物是否出现鬼影”这种可以通过视觉模型打分来实现,在编排层做效果更好,就不要硬塞进Agent认知节点。

3. API编排层:打通“文本-图-视频-配音”的完整链路

3.1 API编排层的模块划分

画布Agent跑完之后,产出的是标准化的JSON任务清单。接下来的问题是:谁来把这些任务提交给视频生成服务、配音服务、剪辑服务?谁来管失败重试?谁来统计产能?

我们搭的API编排层分四个模块。

第一个是统一API网关。所有外部服务都以API方式接入,网关统一管理密钥、鉴权、限流和计费。不同服务商返回的异常格式不一样,网关会把它们标准化成统一的错误码:超时、限流、审核不通过、参数错误、余额不足。这样做的好处是,上层代码永远只处理一套异常体系,不用为每个服务商单独写异常处理逻辑。

第二个是任务队列。一个3分钟短剧通常有20到40个分镜,每个分镜都要生成视频片段,这些任务绝对不能同步执行。我们把任务提交到队列里,消费者按配置的并行度去拉取任务、调度外部API。刚开始并行度不敢开太高,后来实测下来,4路并行是稳定性和速度的平衡点。再高容易触发上游服务限流,反而增加重试成本。

第三个是任务状态机。每个任务都有明确状态流转:待处理、处理中、成功、失败、重试中。状态机不只是给机器看的,也给管理后台看。我打开一个仪表盘,能看到今天总共提交了多少任务、成功率多少、平均耗时多少、失败原因分布是什么。没有这套数据,所谓工业化就是一句空话。

第四个是回调与轮询兜底。视频生成是异步任务,提交后要等服务端回调。但回调不是100%可靠,所以我们设计了兜底机制:任务提交后开启定时轮询,超过一定时间没收到回调就主动查状态;回调丢失超过3次就标记为异常任务,人工介入。

3.2 关键参数的实测经验

API编排不只是“调接口”,参数怎么定往往决定成品质量。我贴几个实测下来的参数,供参考。

大模型文本生成参数:剧本和分镜这类创作任务,温度设在0.7到0.85之间比较合适,太低会重复,太高会散乱。分镜这种结构化任务,温度降到0.3,保证输出稳定。Top-p固定在0.9,max_tokens要留足,分镜表经常一份就一两千字,给太少会被截断。

视频生成参数:分辨率按平台支持力度来,但我们内部统一以横屏16:9为主,码率放到平台支持的最高档。时长方面,每个分镜默认6.5秒,这个长度既不显得拖沓,也给后期留了剪辑空间。步数不是越高越好,我们用50到60步,画质和耗时的平衡最好,再高肉眼几乎看不出区别,成本却成倍增加。seed固定很关键,同一段提示词配合固定seed,很多平台能保持差不多的构图,这对后期统一色调非常有帮助。

配音参数:TTS现在基本都支持情绪标签,我们会在分镜JSON里带上emotion字段,直接转成配音参数。语速按短剧快节奏定在每分钟240到260字左右,比日常语速略快;停顿标签要人工埋点,一句话说完了加个静音段,比让模型瞎生成停顿自然得多。

3.3 异步任务与重试策略

视频生成任务经常挂在网络、服务端负载、审核策略这些环节。最初我们设计的是“失败就重试”,后来发现不行,因为失败原因不同,处理方式也不同。

二维码、底边字幕这类属于内容审核不通过,重试也会被拦,必须改提示词或者换表达方式。这类失败我们直接进人工队列,不自动重试。限流失败则相反,属于上游服务保护策略,我们采用指数退避重试,第一次等10秒,第二次等30秒,第三次等90秒,最多重试3次。超时失败比较复杂,有的是请求发出去但服务端没回,有的是服务端在处理但我们没等到回调。统一处理方式是先查询任务状态,确认到底存不存在,再决定重试还是标记失败。另外还有一个容易忽略的点:API token有效期。长流水线经常跨小时运行,token如果过期,整个队列会在某个时间点集体报错。后来我们在网关层统一做token自动续期,这个问题才算根治。

4. 实操过程与核心环节实现:一条3分钟短剧的完整跑通

4.1 从剧本到分镜:Agent怎么拆

写个具体例子。我们做一部悬疑题材的3分钟短剧,故事梗概是“男主回到废弃老宅找童年记忆,发现宅子和自己记忆中完全不一样,最后意识到记忆是被篡改的”。这个梗概丢进画布Agent后,第一个节点先做结构分析,把故事拆成“起、承、转、合”四个阶段,并标出关键转折点。这段分析结果是一段自然语言,但紧接着的节点就会把它转成场次表JSON。

场次表生成之后,分镜提取节点开始干活。它按场景和情绪曲线把每个场次进一步切分成具体镜头。以“男主走进老宅大门”这个场景为例,Agent会按“远景交代环境—中景人物进入—近景面部特写”的逻辑切3个镜头,每个镜头时长、景别、画面描述、台词都能补全。

这里有一个实操技巧:分镜的“画面描述”不要写“男主走进大门”这种笼统的句子,而要写成能直接拍出来的描述,最好是“男主穿着深色夹克,推开锈迹斑斑的铁门,铁门发出刺耳声响,门框上方半块牌匾摇摇欲坠,镜头缓缓推向他眼睛”。细节越具体,视频生成模型出来的画面越可控。我们甚至要求Agent把光线方向、镜头运动、人物表情全部写进描述里,这比加一堆风格后缀词管用得多。

4.2 画面与视频生成:角色一致性方案

AI短剧工业化最头疼的就是角色一致性。同一个角色,第一集是这个脸,第二集变成另一个人,观众根本看不下去。我们用了三招组合方案。

第一招是“角色卡前置”。在画布Agent阶段就生成角色卡,把外貌特征、服装、气质、典型动作都固定下来,存成图片参考和文字描述双份。第二招是“参考图锁定”。视频生成时提交角色参考图,配合固定seed,让模型在推理时参考参考图。第三招是“首帧锁人”。用图生视频的方式,先用文生图生成一张完全符合角色设定的首帧图,再以这张图为起点生成动态视频。首帧图走的是静态图像生成流程,很多细节比视频生成模型直接出画面稳定得多。跑出来的镜头,角色脸部一致性比直接文生视频好了不止一个档次。

场景一致性也用过类似思路。每部剧的主要场景,比如“废弃老宅客厅”“地下室走廊”“屋顶天台”,先各生成一张场景基准图。分镜需要这个场景时,就以场景基准图作为背景约束,让画面始终保持统一空间感。这个细节很多人忽略,实际修起来比角色一致性还费劲。

4.3 配音、字幕与合成:流水线最后一段

视频画面生成完之后,流水线还有三段要走:配音、字幕、合成。

配音是TTS接口直接调用,但在把文本发给TTS之前,我会先做一次文本清洗。短剧对白经常有口语化表达、语气词、情绪停顿,这些都要转成TTS能理解的表现方式。比如“男主说:不可能……这不可能!”清洗后会变成“不可能(停顿,低声)这不可能(声调渐高)”。我们用一套自定义的标注语法,Agent节点负责把台词加上表现力标记,TTS服务直接识别这个语法。

字幕生成有一个坑:直接从台词文件生成字幕没问题,但合成时经常出现“字幕已经显示出来,配音还没说到那句话”的错位。解决办法是合成时不以视频画面为基准,而是以音频对齐。先把配音音频按句切分,拿到每句话的起止时间,再按这个时间轴生成字幕和画面衔接点。画面剪辑节奏反过来适配音频节奏,短剧的听觉体验和视觉体验就统一了。

合成阶段用的是传统视频处理工具,FFmpeg一把梭:把所有分镜视频片段按镜头顺序拼接,每个片段长度严格对齐音频切分点;字幕以ASS格式烧录,字体大小统一,描边加阴影保证在亮色背景上也能看清;BGM音量在配音段落自动压低,情绪高潮处再抬起来。这些规则全部脚本化,一键执行。

4.4 全链路调度脚本示例

画布Agent和API编排层之间的调度,我们用一个主控制脚本来驱动。这个脚本负责读取分镜JSON、分批提交任务、轮询状态、收集产物、组装成片。下面是一个非常精简的可参考版本:

import json
import time
from pathlib import Path
from your_api_wrapper import submit_video_task, query_video_status, submit_tts_task, query_tts_status

def run_pipeline(script_json_path: str, output_dir: Path):
    scenes = json.loads(Path(script_json_path).read_text(encoding="utf-8"))
    video_tasks = {}
    tts_tasks = {}

    for scene in scenes:
        for shot in scene["shots"]:
            vid_resp = submit_video_task(shot)
            video_tasks[vid_resp["task_id"]] = shot["shot_id"]
            tts_resp = submit_tts_task(shot["dialogue"], shot["emotion"])
            tts_tasks[tts_resp["task_id"]] = shot["shot_id"]

    # 轮询等待全部完成,携带重试逻辑
    for _ in range(180):
        done = True
        for task_id, shot_id in list(video_tasks.items()):
            status = query_video_status(task_id)
            if status["state"] == "succeeded":
                # 下载视频片段到本地
                video_tasks.pop(task_id)
            elif status["state"] == "failed":
                # 归档失败原因,进入人工处理队列
                log_failure(task_id, shot_id, status["error"])
                video_tasks.pop(task_id)
            else:
                done = False
        if not video_tasks and not tts_tasks:
            break
        if done:
            break
        time.sleep(10)

    assemble_final_video(output_dir, scenes)

这段脚本只是示意,实际项目里比这复杂得多,但核心思路就是这样:统一提交、统一轮询、失败归档、最终合成。工业化流水线的关键并不在于某个环节多炫技,而在于所有环节之间有标准接口、有状态反馈、有异常出口。

5. 常见问题与排查技巧实录

5.1 高频报错与解决速查表

流水线跑得越久,踩过的坑就越有代表性。我把遇到最多的问题整理成一张速查表,基本都是可以直接照着处理的:

现象 核心原因 解决思路
长剧本处理时提示上下文超限 节点直接拼接了完整上下文,超过模型窗口 分场景分场次处理,每节点只保留关键摘要
视频生成后角色严重穿模 未使用角色参考图,或参考图和首帧不一致 角色卡+参考图+首帧锁人,三招组合使用
视频和配音节奏对不上 以画面为基准切分音频 改为先切音频,再按音频时间轴合成画面
同一段任务高频失败 触发了上游限流,但重试太紧急 指数退避重试,并降低并行度
生成画面有异常文字/水印 内容审核未通过或模型风格干扰 在负向提示词中强规则过滤,并走人工审核队列
API key突然失效 长任务跨时段运行,token过期 网关层统一管理密钥,定时自动刷新
分镜提示词参差不齐 大模型输出不稳定 加一层提示词清洗节点,强制字段补全

5.2 排查思路:先看状态机,再看数据流

我排了这么多坑,总结出一条经验:流水线出问题时,先不要急着改提示词或者换模型。第一件事是打开状态机看失败任务集中在哪个环节。如果所有失败都集中在“视频生成”这一步,那基本是上游平台问题或者参数问题;如果失败分散在各环节,那才可能是流程设计的问题。

第二件事是看数据流。拿一个失败的分镜任务,从源头开始追:剧本节点输出的JSON规不规范?分镜节点有没有把字段弄丢?提示词组装节点有没有正确读取角色卡?很多所谓“模型问题”,最后追下去都是前一步数据格式出问题。特别是字段命名不统一这类问题,在画布和API两层之间经常出现,所以从一开始就要把JSON结构当成接口协议来管理,任何字段变更都要走版本控制。

第三件事才是看模型。模型方面的失败往往表现为“任务成功了但效果不对”,比如角色长得不像、场景偏差大、情绪表达不到位。这一步调优是最花时间的,但也是最值得沉淀经验的。我们内部积累了一个提示词模板库,每个模板都标注了测试环境、目标模型和最佳参数,新项目直接套模板,比每次都从零调提示词快得多。

5.3 维护流水线的日常习惯

流水线搭完不是终点,维护才是长期工作。我养成了几个固定习惯,分享出来也许对你有用。

每次上线新模型或者改参数之前,先跑一遍“冒烟测试”。我准备了3个经典分镜,覆盖室内、室外、人物特写三种常见场景,任何改动先在这3个分镜上验证,过了才允许全量跑。每周做一次失败任务复盘,把本周所有失败原因分类统计,看哪些是偶发网络问题,哪些是模型升级带来的指标变化。问题反复出现的,就改进流水线;问题只出现一次的,记录到日志里就行,不用过度反应。

另外,流水线日志一定要保留原始请求和响应。视频生成平台偶尔会调整策略,同一组参数昨天还能出片,今天就不行了。没有原始日志,你根本不知道参数变化是因为自己改错地方还是平台调整了行为。我们所有任务请求和响应都会落盘保存,保留至少30天,这个习惯帮我们排查过很多次疑难杂症。

最后再说一个关于API编排的心得:不要把编排逻辑跟某个具体的服务商绑死。我们接视频生成服务时,在网关层做了一层适配,同一套任务格式可以切到不同的上游平台。刚开始确实多花了一些开发时间,但后来平台做模型升级、调整价格、临时限流的时候,我们都能快速切换到备用通道,整体产能几乎没有受到影响。做工业化流水线,稳定性和可替代性永远比单点性能更重要。

Logo

火山引擎视频云技术社区,是面向 AI 音视频开发者的技术交流平台。这里汇聚源自抖音、豆包等亿级 DAU 产品的 RTC、直播、点播、AI 媒体处理、音视频互动技术,提供接入指南、最佳实践、性能调优、场景案例、Demo 代码、开源项目、白皮书和 API 文档。社区汇聚官方工程师与一线开发者,为 AI 视频通话、数字人、AI 视频处理等应用的开发与落地提供技术支持。

更多推荐