ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

五个Skill拆解小说改短剧:AI短剧剧本、分镜与角色一致性流水线

五个Skill拆解小说改短剧:AI短剧剧本、分镜与角色一致性流水线

1. 把“小说改短剧”拆成五个 Skill,成功的概率才上去

最早我把一本 30 万字的小说整段丢给大模型,让它直接输出“短剧剧本 + 分镜”。结果很典型:前两集还算像样,从第三集开始人名开始飘,主角的性格从隐忍变成了莽撞,分镜里出现了小说里根本没有的场景,最后交付的文档看着很厚,但没人敢拿去开工。后来我复盘,问题不在模型能力,而在我把一件本来该分五步做的事,压成了一次对话。这套被称作 shuohao-skills 的技能包,本质上就是把 AI 短剧投产的五个环节固化成可复用的指令模块:小说拆解、角色设定、剧本生成、分镜拆解、投产包组装。它解决的不是“AI 能不能写剧本”,而是“AI 写出来的东西能不能直接进生产线”。适合三类人看:想用 AI 把小说改编成短剧的独立创作者、需要批量产出内容的小团队、以及已经试过一次性生成但被一致性问题和返工成本劝退的人。下面这套流程我在几个模拟项目里反复跑过,哪一步容易出错、哪一步能省时间,我会尽量讲清楚。

1.1 一次性生成为什么会崩:三个绕不过去的硬限制

第一个限制是上下文窗口的物理边界。一本网文动辄 30 万到 100 万字,就算模型能吃下,注意力在中后段也会明显衰减,前面交代的人物设定到第 20 章基本就“忘了”。这不是调参能解决的问题,是信息密度和注意力机制的天然特性。

第二个限制是任务耦合。拆故事骨架需要的是“判断力”,要决定哪些情节留、哪些砍;写角色卡需要的是“收敛力”,把模糊的人物小传压成可复现的视觉锚点;写分镜需要的是“拆解力”,把一个动作拆成 3 个 2 秒镜头。三种能力放在一个提示词里,模型会互相干扰,最后每一项都做到六十分。

第三个限制是不可回溯。一次性生成的结果是一整块文本,出了问题你不知道是哪一环错的。是骨架阶段就把主线搞歪了,还是剧本阶段把配角写崩了?没有中间产物,就只能整段重跑,成本翻倍。

踩过这个坑之后我的结论很直接:AI 做长内容,靠的不是更强的模型,而是更细的交接。每一步都产出结构化的中间文件,下一步只读这个文件,不读原文。

1.2 拆分依据:按交付物切分,不按工作流程切分

很多人拆 Skill 会按“先想、再写、后改”这种流程切,我不推荐。流程切法的毛病是每一环的输入输出都是模糊的,你没法判断这一步到底做完没有。我采用的是按交付物切:每个 Skill 必须产出一个有明确字段、能被下游直接消费的文件。

Skill交付物主要消费者完成判据
Skill 1 拆解故事骨架 JSONSkill 3 剧本每集有冲突点、有钩子
Skill 2 角色角色卡 YAMLSkill 3、Skill 4每个出场人物有视觉锚点
Skill 3 剧本分集分场稿Skill 4 分镜每场有时长估算、有台词
Skill 4 分镜镜头表 CSVSkill 5 组装每镜有秒数、有画面描述
Skill 5 组装投产包目录制作执行方缺口清单为空

这张表是我后来补上的。最开始我没写“完成判据”这一列,结果经常出现“剧本写完了但分场时长加起来是 40 分钟,目标是 20 分钟”这种返工。判据必须是可量化的,不能是“质量达标”这种话。

1.3 五个 Skill 的串联关系:数据流决定顺序

顺序不能随便调。角色卡必须在剧本之前,因为剧本里的台词风格要跟角色卡里的“说话方式”字段对齐;分镜必须在剧本之后,因为镜头表要引用场号;投产包必须在最后,因为它要做一次全局缺口扫描。

我用一段伪配置说明这个串联关系,这也是我在实际项目里给每个 Skill 写的入口声明:

pipeline: short-drama-production skills: - id: novel-skeleton input: raw_text/*.txt, project_meta.yaml output: 01_skeleton/story.json - id: character-card input: 01_skeleton/story.json output: 02_characters/*.yaml - id: script-forge input: 01_skeleton/story.json, 02_characters/*.yaml output: 03_script/SxxExx.md - id: storyboard input: 03_script/SxxExx.md, 02_characters/*.yaml output: 04_board/SxxExx.csv - id: production-pack input: 01_* ~ 04_* output: 05_pack/

注意每个 Skill 的 input 里都只出现了上一环的产物,没有一个 Skill 直接读原始小说。这是整套流程最关键的设计。原文只在 Skill 1 被读一次,之后全部靠结构化中间件传递,这样每一环的成本是可预测的,也能单独重跑。

一个容易被忽略的细节:02_characters同时被 Skill 3 和 Skill 4 消费。写剧本时用它约束台词语气,拆分镜时用它约束外貌描述。同一个文件被两处引用,才能保证“台词里的她是她,镜头里的她也是她”。


2. Skill 1 小说拆解:把长篇压缩成能判断的结构化骨架

这个 Skill 最容易被人低估,觉得无非是“总结一下”。但总结和拆解是两回事。总结产出的是给人看的摘要,拆解产出的是给下游消费的结构。差别的核心在于:摘要可以含糊,结构不能含糊。

2.1 输入要按章节切片,并做滚动摘要回填

直接把整本小说喂进去,前 20% 和中间 20% 的质量差得很明显。我用的办法是滑动窗口加滚动摘要:每 10 章为一个批次,批次结束时让模型输出一段 300 字以内的“已读摘要”,这个摘要会带着全部人物和未解决的悬念,拼到下一批的上下文里。

# 简化示意:分批处理并累积摘要,避免上下文无限膨胀 state = {"summary": "", "characters": [], "open_threads": []} for batch in chunks(chapters, size=10): prompt = build_prompt( batch=batch, carry_over=state, # 上一批沉淀的摘要与人物名册 task="提取本批次的情节事件、人物变化、悬念钩子" ) result = call_model(prompt) state["summary"] = merge_summary(state["summary"], result["batch_summary"], max_len=300) state["characters"] = merge_unique(state["characters"], result["characters"]) state["open_threads"] = update_threads(state["open_threads"], result["threads"])

滚动摘要的长度必须设上限,我一般卡 300 到 400 字。不设上限的话,跑到第 50 章时“摘要”本身就有一万多字了,等于没压缩。合并时要显式告诉模型“旧的摘要优先保留主线,新内容优先补充变化”,否则它会把早期的重要设定挤掉。

2.2 输出字段:决定能不能开工的就这七项

骨架 JSON 我固定输出七个字段。少一个,后面某一环就会卡住。

字段作用缺失后果
logline一句话卖点剧本没有统一调性
三幕主线整体节奏分集时集与集之间没有递进
爽点、钩子列表每集结尾的抓手剧情平,留不住人
人物名册谁在什么时候出现人物无限增加
场景清单需要多少实景或素材制作成本失控
时间线顺序、回忆、插叙分镜逻辑乱
可影视化评分改编难度评估做了一半发现拍不出来

其中“可影视化评分”是我自己加的,值得单独说。我按四个维度各打 1 到 5 分:场景复用度(同一场景出现的频率高不高)、特效依赖度(有没有大量玄幻、灾难场面)、对话占比(对白驱动的戏更好改)、群演规模(动辄几十人同框的戏成本高)。四项加起来低于 10 分的,我会重新评估要不要做,或者先做前几集试水。

2.3 取舍原则:砍情节的三个明确标准

拆解阶段最难的是砍。我的三条标准是:不推动主线的支线全砍、不改变人物关系的过场全砍、不产生新信息的对话全砍。判断“是否产生新信息”有个笨办法,把这段戏删掉,看后面的剧情还讲不讲得通,讲得通就删。

但有一条必须保留:人物性格的转折点。哪怕这场戏很短、很“水”,只要它解释了主角为什么从隐忍变成反击,就得留。短剧的观众对情节容错率比长视频低,但对“人设崩了”的容忍度更低。我一般会在骨架里单独标一个turning_points数组,剧本阶段强制要求这些点每集不超过一个,且必须落在集尾。


3. Skill 2 角色设定:确保 AI 生成的脸在二十个镜头里是同一个人

角色卡是整套流程里最容易被敷衍、又最容易出问题的一环。很多人写的角色卡是“女主,25 岁,美丽大方,性格坚强”,这种卡下游完全没法用:图像生成不知道长什么样,剧本不知道该怎么说话,分镜不知道该给什么景别。

3.1 字段设计:每个字段都要有“可复现”属性

我的角色卡固定包含九项,其中前三项是硬约束,缺了下游直接报错。

code: C01 name: 主角代号 identity: 身份与处境(一句话) visual_anchors: # 视觉锚点,必须可量化 hair: 齐耳短发,栗棕色,发尾微外翘 face: 偏圆脸,单眼皮,眉尾上挑 body: 身高约 165,偏瘦,肩线窄 outfit_main: 卡其色工装外套,内搭白色圆领,深色直筒裤 prop: 左手腕常年戴一只旧皮表 speech_style: # 说话方式,直接约束台词 sentence_len: 短句为主,单句不超过 20 字 tone: 少用形容词,喜欢反问 catchphrase: “行吧。” motivation: 表层欲望与深层需求 arc: 从 A 到 B 的三段式变化 relations: 与其他人物的关系及称呼 lock: # 一致性锁 ref_image_id: C01_v2 negative: 避免浓妆、避免长卷发、避免高跟鞋

关键在于visual_anchors里没有出现任何一个“漂亮”“气质好”这类无法转成视觉描述的形容词。所有描述必须是摄影师听了能摆机位、画师看了能下笔的粒度。发色写“栗棕”不写“棕色”,因为纯棕在暖光下容易偏红;发尾写“微外翘”不写“自然”,因为“自然”这个词等于没说。

3.2 从人物小传到视觉锚点:三步压缩法

从小说里抠出来的往往是“她有一双会说话的眼睛”这种句子。转成视觉锚点要走三步:

  1. 删修饰,只留物理特征:会说话的眼睛 → 眼睛偏大,双眼皮,眼尾略下垂。
  2. 加可辨识细节:给每个主角配一个“记忆点”,比如一块旧皮表、一道浅疤、一个固定的发绳。这个细节要在分镜里反复出现,观众才记得住。
  3. 写负面约束:明确写出“不要什么”,比写“要什么”更有效。比如配角 C03 是个中年男性,负面里要写“不要胡须、不要眼镜”,否则每次生成都可能多一副眼镜。

我实测下来,负面约束能减少大约三到四成的角色漂移。这一步很多人省了,结果就是同一个角色在不同镜头里像两个人。

3.3 一致性如何向下游传递:一个文件、两处引用

角色卡不是写完就放着,它要在两个地方被强制引用。剧本阶段,每段台词生成前,把该场出场角色的speech_style拼进提示词;分镜阶段,每个镜头生成前,把visual_anchors和lock拼进提示词。

我用的做法是给每个角色卡算一个短哈希,剧本和分镜的每一行都带上这个哈希。返工时如果发现某个镜头的角色不对,直接查哈希就知道当时用的是哪一版角色卡。这个技巧在改了三次主角发型之后救了我一次,因为我能精确知道哪些镜头需要重跑,而不是全片返工。

提醒一句:角色卡一旦定稿,就不要在剧本阶段“顺手改一下”。改了就必须回填版本号,并且标记受影响的下游文件。我吃过这个亏,改完忘了标记,结果分镜里一半用旧版一半用新版,人物在两个镜头之间换了发型。


4. Skill 3 剧本生成:从大纲到分场,再到能念出口的台词

到了这一步,很多人会急着一口气把整集台词写出来。我的经验是必须分成三稿,而且三稿由三次独立的模型调用生成,不要合并。

4.1 三稿制:每稿只解决一个问题

第一稿是大纲稿,只输出每集的 logline、三到五个情节点、集尾钩子。这一稿不写台词,纯粹解决“这一集讲什么”。写完必须人工过一遍,因为这是全流程里性价比最高的人工介入点,改一句话的成本,比改到分镜阶段低两个数量级。

第二稿是分场稿,把情节点拆成场。每场标明场号、时间(日/夜)、地点、出场人物、本场事件、预估时长。分场稿的核心产出是时长表,把所有场的秒数加起来,跟目标时长对一下。对不上就现场调,别拖到分镜阶段。

第三稿是台词稿,只在这时才写台词。写的时候把角色卡的speech_style拼进去,逐场生成。

4.2 时长换算:一个能救命的对照表

短剧的时长控制非常严格,多 20 秒可能就影响投放。我用的换算基准是:中文对白每分钟约 220 到 260 字,加上动作描述和留白,剧本正文每分钟对应约 300 到 350 字。

单集目标时长对白字数场次数镜头数(估)
60 秒220-2602-312-18
90 秒330-3903-418-25
120 秒440-5204-525-35
180 秒660-7805-735-50

这张表我贴在项目文档最上面。每次分场稿写完先算一遍,超了就砍场,不要想着“到时候节奏快一点就行”,节奏一快观众跟不上,数据更差。

4.3 台词自检:六条能直接对照的清单

台词稿生成完之后,我会跑一遍自检。这六条是踩坑踩出来的,不是理论:

  • 单句超过 25 字就拆。短剧观众是碎片时间在看,长句听不完。
  • 一场戏里超过两句连续的书面语就改口语。“因此”“然而”“使得”这类词在短剧台词里基本不该出现。
  • 每三句至少有一个信息增量或情绪变化,否则就是废话。
  • 避免大段独白。真有内心戏,用旁白加空镜,别让演员站着说话。
  • 称呼要统一。主角叫“周姐”就不能中途变“周女士”,除非剧情需要。
  • 每场结尾留一个未完成动作或未回答问题,这是留人的最小单位。

我在实际项目里发现最容易被忽略的是第五条。模型很爱在不同场景换称谓,尤其是有第三人在场时会自动“变正式”。解决办法是在角色卡的relations字段里写死称呼规则,比如“对上级永远称职务,对同级永远称名字,不使用敬语”。


5. Skill 4 分镜拆解:把剧本变成能直接开工的镜头表

剧本是给演员看的,分镜是给拍摄或生成环节看的。这两者之间的转换,信息损失最大。我见过太多项目,剧本写得挺好,分镜一拆就散架,因为分镜里缺了“这个动作到底怎么拍”的具体描述。

5.1 镜头表字段:少一个字段就多一次沟通成本

我的镜头表固定用 CSV,字段如下。用 CSV 而不是 Markdown 表格,是因为它能直接被表格软件打开排序,也能被脚本处理。

字段含义示例
shot_id镜号S01E01_SH03
scene_id场号S01E01_SC02
dur时长(秒)3
shot_size景别中近景
angle机位角度平视略仰
move运镜固定
visual画面内容她站在门口,手停在门把上
action角色动作缓慢转头看向走廊
line台词、旁白“行吧。”
audio音效、音乐走廊回声,低频铺底
gen_prompt生成提示词见下方映射规则
char_lock角色锁哈希a3f2

dur这一列是硬约束。我要求单镜头时长在 2 到 6 秒之间,超过 6 秒必须拆,低于 2 秒要考虑合并。原因很实在:太长的镜头在生成端容易画面漂移,太短的镜头观众看不清。

5.2 提示词映射:从镜头表字段拼出生成描述

gen_prompt不是手写的,是拼出来的。拼装顺序固定:景别 + 机位 + 角色视觉锚点 + 动作 + 环境 + 光线 + 风格锚点 + 负面约束。这个顺序有讲究,主体信息放前面权重更高。

def build_gen_prompt(shot, char_cards, style_anchor): c = char_cards[shot["char_code"]] parts = [ shot["shot_size"], shot["angle"], shot["move"], f'{c["visual_anchors"]["hair"]},{c["visual_anchors"]["face"]}', f'身穿{c["visual_anchors"]["outfit_main"]}', shot["action"], shot["visual"], style_anchor["lighting"], style_anchor["film_look"], "负面:" + ",".join(c["lock"]["negative"]), ] return ",".join(p for p in parts if p)

style_anchor是一个全片共享的配置文件,里面固定写光线基调、色调、镜头质感。这个文件的存在是为了解决“五个 Skill 各说各话”的问题,我后面会专门讲。

5.3 节奏约束:每 15 秒必须有一个视觉变化

短剧的节奏比长视频紧得多。我给分镜定了个土规矩:每 15 秒必须出现一次视觉变化,可以是景别切换、机位变化、光线变化、或者人物位置变化。做法很简单,按时间轴累加dur,每满 15 秒检查一次上一个镜头的景别,如果连续三个镜头是同一个景别,强制插入一个特写或全景。

另一个规矩是对话场景用正反打。两个人说话,不要一个镜头拍完,拆成 A 说话、B 反应、A 再说。这样镜头数上去了,节奏也活了。但要注意别过度,我一般控制在每组对话三到五个镜头,太多了剪辑会碎。


6. Skill 5 投产包组装:交付的是一套能开工的文件夹

前面四个 Skill 产出的都是散件,最后这一步是把散件打包,并且做一次全局体检。这一步看起来最没技术含量,实际上最能体现专业度。下游拿到的东西能不能直接用,全看这一步。

6.1 目录结构与命名:让陌生人也能看懂

05_pack/ ├── 00_README.md # 一页纸说明:怎么用这个包 ├── 01_skeleton/ │ └── story.json ├── 02_characters/ │ ├── C01.yaml │ └── ref/ # 角色参考图或参考图编号 ├── 03_script/ │ ├── S01E01.md │ └── S01E02.md ├── 04_board/ │ ├── S01E01.csv │ └── S01E02.csv ├── 05_assets/ │ ├── scene_list.csv # 场景清单与复用统计 │ └── gap_report.md # 缺口报告 └── 06_style/ └── style_anchor.yaml # 全片风格锚点

命名规则我固定成SxxExx加类型后缀,版本号用_v1_v2。不要用日期做版本,因为同一天可能改三版。00_README.md一定要写,而且要写得像个说明书而不是目录,把“先看哪个、哪些字段是必须对齐的、改动了要通知谁”写清楚。我见过太多交付包,打开一看全是文件,没有人知道从哪下手。

6.2 缺口检查:用脚本扫一遍比人眼靠谱

缺口检查我写成一个简单的扫描逻辑,跑一遍就能列出问题。

issues = [] for ep in episodes: script = load(f"03_script/{ep}.md") board = load_csv(f"04_board/{ep}.csv") # 1. 剧本里的每一场,分镜里都要有镜头 for sc in extract_scenes(script): if sc not in set(board["scene_id"]): issues.append(f"{ep} 场 {sc} 在分镜表中缺失") # 2. 分镜里出现的角色,角色卡里都要有 for code in set(board["char_code"]): if not exists(f"02_characters/{code}.yaml"): issues.append(f"{ep} 引用了未定义角色 {code}") # 3. 时长要对得上 total = sum(float(x) for x in board["dur"]) target = project_meta["episode_seconds"][ep] if abs(total - target) / target > 0.1: issues.append(f"{ep} 时长偏差 {(total-target)/target:.0%}") write("05_assets/gap_report.md", issues)

三条检查覆盖了八成的返工原因。时长偏差我卡 10%,超过就说明分场阶段算错了,回去改剧本比分镜阶段凑更省事。

6.3 版本回溯:改一处要知道影响哪几处

投产包做完不是终点,客户改需求是常态。我的做法是每个产物文件头写三行元信息:版本号、依赖文件的版本、生成时间。这样一旦上游改了,能顺着依赖链往下找。

举个例子,主角发型从短发改成长发,角色卡从 v2 升到 v3。要做的不是全片重跑,而是:查04_board里所有char_lock是旧哈希的镜头行,重拼gen_prompt,标红等重生成;查03_script里有没有提到发型的台词,有就改。这样一次改动的影响面是可枚举的,不会变成“全部推倒重来”。


7. 整条流水线跑下来,最容易在三种情况下出问题

前面讲的是怎么做,这一段讲我实际踩过的坑。这部分内容在文档里基本看不到,但恰恰是最影响效率的。

7.1 上下文衰减:跑到第七集,模型忘了第一集

长篇改编最典型的问题。前五集还挺连贯,到第七集突然给主角加了个小说里没有的弟弟。根因是骨架文件太长,剧本 Skill 每次只读了一部分。

我的修法是骨架分层:story.json里再拆出series_bible.json,只放“不可变事实”,包括人物名册、称呼规则、世界设定、核心悬念。写每一集时,series_bible无条件全量注入,分集骨架才按需读取。

# series_bible.json 的核心结构 characters_locked: - code: C01 name: 主角代号 aliases: [“小周”, “周姐”] # 所有允许出现的称呼 forbidden: [“周女士”, “老周”] world_rules: - 故事发生在当代城市,无超自然元素 - 时间跨度为七天 open_threads: - 旧皮表的来历(第 3 集提出,第 8 集揭晓)

forbidden这个字段特别有用。模型爱自由发挥称呼,把禁用的称呼列出来,能挡掉大部分。

7.2 风格漂移:五个 Skill 各写各的

第二个坑更隐蔽。剧本阶段的台词偏文艺,分镜阶段的画面描述偏写实,最后拼起来像两个项目。根因是每个 Skill 的提示词是独立写的,没有共享的“调性锚”。

解决办法是建一个style_anchor.yaml,所有 Skill 都注入。

tone: 冷峻、克制、少煽情 dialogue: 短句,口语,不用成语 visual: 低饱和,冷色调,自然光为主 pacing: 每 15 秒一次视觉变化 forbidden: [慢镜头抒情, 大段旁白, 华丽形容词]

这个文件不长,但它把五个 Skill 的产出统一到一个基准上。我的经验是,风格统一靠文件,不靠提示词里反复强调。你在五个提示词里各写一遍“保持冷峻”,不如让它们读同一个文件。

7.3 返工定位:从分镜倒推剧本的三步法

出了问题要快速定位是哪一环的锅。我的三步法:

第一步,看分镜和剧本是否一致。拿分镜表对照剧本,看场号、台词、动作是否对得上。对不上就是 Skill 4 的问题,局部重跑那几镜。

第二步,看剧本和骨架是否一致。看这一集的情节点有没有偏离大纲,人物动机有没有变。偏离了就是 Skill 3 的问题,重跑这一集的第二稿和第三稿。

第三步,看骨架和原著是否一致。这一步最少出问题,但一旦出问题最麻烦,因为要重跑整条链。所以我在 Skill 1 完成后一定要人工确认一次,宁可多花半小时。

这三步的顺序是有讲究的,从下游往上游查。因为下游的产物文件小、结构清楚,查起来快;上游的产物体量大,一上来就查上游容易陷进去。


8. 关于成本和效率,几个我实测出来的数字

不写具体金额,因为不同模型和服务差异太大,写死了反而误导。但量级可以说。

一本 30 万字左右的小说,跑完整条链路,调用次数大约在80 到 120 次:拆解阶段占四成,因为要分批处理;角色卡占一成;剧本阶段按集数算,每集三稿三次调用;分镜阶段每集一次;组装基本不消耗调用。可以看到,成本大头在拆解和剧本,这两个环节优化收益最高。

时间上,纯机器跑一轮,一本 20 集的项目大概在一到两小时内能出初稿,但人工介入是跑不掉的:Skill 1 的结果要人工过一遍,Skill 3 的大纲稿要人工过一遍,Skill 5 的缺口报告要人工确认。三处人工加起来,我的经验是三到五小时。这个比例很合理,机器负责产出,人负责判断,不要指望全自动。

最后分享一个我一直在用的小技巧:给每个 Skill 的提示词末尾加一句“如果输入信息不足以完成这一步,直接输出 MISSING: 具体缺什么,不要自行编造”。这句话能挡掉大量的“模型自己脑补设定”,尤其在角色卡和骨架阶段特别有效。前期多拦住一次,后期少返工一轮,这个投入产出比在所有优化里是最高的。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进