简介面向零基础AI内容创作者的漫剧制作教程聚焦Kimi K2.5、Flux、Seedance 2.0三款免费工具协同解决不会写剧本、不会画分镜、不会做动效的三大痛点直接套用示例设定校园甜宠题材、日系二次元风、9:16竖屏即可产出1分钟短视频适合抖音、快手自媒体新人及学生快速上手。资源为单个docx文档压缩包仅11KB文字精炼但步骤完整。已有267人学习。教程按“Kimi生成分镜脚本→Flux生成日系漫画分镜图→Seedance生成动态视频→剪映拼接导出”的主线展开前期先确定人设、风格与规格以避免返工中期给出可直接复制的提示词模板、Flux参数设置9:16、1080×1920、风格强度80%及Seedance动效生成方法后期补充脚本简化要点、避坑指南和批量生产进阶技巧。内容还附带6镜头示例脚本与各步骤耗时估算按步骤复制粘贴即可复现成果。1. 做AI漫剧最难的从来不是工具本身而是把Kimi、Flux、Seedance串成一条不卡壳的生产线AI漫剧制作眼下最热闹的玩法是拿Kimi写对白、Flux出日系二次元分镜图、Seedance把静态图变成动态镜头。这三样工具单拎出来都不难但真正做成一集短剧的人都会卡在同一个地方剧本格式没法直接喂给画图模型画出来的角色换个镜头就变脸视频生成完又跟对白对不上时间轴。这套资源的价值是给出了一个从文本到图像再到视频的中间层设计——用一套固定的角色设定、分镜编号、画面描述规范把三个模型串成一条可以批量跑的生产线。适合零基础想搭第一条漫剧流水线的人也适合已经用单点工具翻过车、想把成品率提上来的从业者。下面按模块拆开讲。2. Kimi剧本模块把小说式对白改造成可切分的结构化分镜2.1 为什么漫剧剧本必须用Kimi这类长上下文模型来写漫剧和普通短视频不一样它每一集都有明确的角色关系、场景切换和镜头节奏。用通用大模型写剧本经常出现对白写得漂亮、但没有画面信息的情况——镜头怎么走、角色什么状态、背景是什么全部缺失。Kimi K2.5在长上下文保持上比较稳能在一个上下文窗口里同时维护角色表、场景表和几十个分镜条目这是漫剧剧本生产最需要的。你不用纠结用Kimi网页版、客户端还是API模型本身输出结构是一样的。但整套自动化流程里必须有API入口后面会调用它做批量生成。网页版适合前期调promptAPI适合进生产流程这是两种用途不冲突。2.2 提示词模板强制输出可解析的JSON分镜结构漫剧剧本要进自动化流程第一件事是让Kimi输出结构化数据。我一般会在prompt里给出明确的JSON schema要求让每个分镜都包含场景、镜头号、角色、对白、画面描述等字段。下面是我常用的一套模板{ role: 漫剧编剧, task: 生成日系二次元漫剧分镜脚本, constraints: [ 只输出JSON不要markdown代码块包裹, 角色表角色数量不超过5个, 每个分镜的shot_desc必须包含画面主体、景别、镜头运动、表情, 对白使用日系轻小说口吻每句不超过30个汉字 ], output_schema: { title: 剧集标题, roles: [ { role_id: R1, name: 角色名, appearance: 外貌特征描述, personality: 性格关键词 } ], scenes: [ { scene_id: S1, location: 场景地点, time: 时间段 } ], shots: [ { shot_id: SH001, scene_id: S1, roles_in_shot: [R1, R2], dialogue: 角色对白, shot_desc: 画面描述包含景别、镜头运动、角色动作、表情, duration: 预估秒数 } ] } }这段模板的逻辑是把漫剧剧本拆成三个层次角色层、场景层、分镜层。角色层负责定义“这个人长什么样”场景层负责定义“在哪里拍”分镜层负责定义“这一刻镜头里发生了什么”。三个层次之间用role_id和scene_id关联后面Flux出图和Seedance出视频都要靠这两个ID做数据对齐。参数说明里有几个值得注意的地方。角色数量限制5个是为了控制后续出图和视频生成的规模角色越多Flux保持角色一致性的难度越高。对白字数限制是为了让字幕和视频节奏匹配纯漫剧对白太长画面根本来不及展示。shot_desc里强制写景别和镜头运动是因为Flux只看静态画面描述而Seedance需要镜头运动信息才能生成动态效果。2.3 批量生成与清洗调用Kimi API并处理返回结果prompt调好以后可以写一个批量生成脚本把整集的文本描述发给Kimi拿到返回结果后做数据清洗。这里有个常见的坑Kimi偶尔会在JSON外面套markdown代码块标注或者在某条对白里多打一个引号导致JSON解析失败。所以我一般会做两轮处理先剥离代码块标记再尝试解析。import re import json import time from openai import OpenAI client OpenAI( api_keyyour-kimi-api-key, base_urlhttps://api.moonshot.cn/v1 # Kimi兼容OpenAI协议 ) def generate_script(topic: str, prompt_template: dict) - dict: prompt json.dumps(prompt_template, ensure_asciiFalse) \n\n主题 topic resp client.chat.completions.create( modelkimi-k2.5, messages[ {role: system, content: 你是一个漫剧编剧输出严格JSON。}, {role: user, content: prompt} ], temperature0.4, max_tokens4000 ) raw resp.choices[0].message.content # 第一轮清洗剥离可能的markdown代码块 raw re.sub(rjson|, , raw).strip() # 第二轮清洗截取第一个大括号到最后一个大括号 start raw.find({) end raw.rfind(}) if start -1 or end -1: raise ValueError(返回内容中没有JSON结构) raw_json raw[start:end 1] try: return json.loads(raw_json) except json.JSONDecodeError: # 兜底把单引号替换成双引号再试一次 fixed raw_json.replace(, \) return json.loads(fixed) # 批量生成三集剧本 topics [放学后的屋顶告白, 深夜食堂的猫耳店员, 夏日祭烟花下的约定] episodes [] for idx, topic in enumerate(topics): time.sleep(2) # 手动限速避免触发限流 episodes.append(generate_script(topic, template)) # 保存结果 with open(episodes.json, w, encodingutf-8) as f: json.dump(episodes, f, ensure_asciiFalse, indent2)这段脚本的逻辑是先把整集主题拼进prompt然后调用Kimi的对话补全接口。temperature设成0.4是刻意的——漫剧剧本需要创意性但更需要结构稳定温度太高会出现分镜数量忽多忽少、角色名拼写不一致的情况。max_tokens设4000基本够一集短剧的剧本体量如果分镜超过30个需要调大这个值。提示Kimi的API兼容OpenAI的调用格式base_url指向moonshot的地址即可不需要额外装SDK。time.sleep(2)是给API调用加的手动限速。漫剧剧本一次性批量生成很容易触发限流与其等报错再处理不如先粗暴地控制请求频率。实际生产里可以用指数退避重试替代后面第5章会展开讲。3. Flux图像生成用固定seed和角色卡把“角色一致性”从玄学变工程3.1 Flux模型出图特性与漫剧适配选型Flux模型在日系二次元风格上的表现确实能打线条干净、色彩饱和、光影层次好。不过它真正的优势是对长提示词的遵循度高——普通模型画面描述超过30个字就开始丢信息Flux在80到100字的复杂场景描述下还能保持构图完整。这对漫剧分镜出图非常关键因为同一张图里往往要同时描述角色、动作、表情、场景、镜头角度五个维度。选择Flux而不是其他模型还有个实际原因社区生态成熟Lora资源多。如果你觉得默认画风不够日系可以挂一个二次元风格的Lora后面第6章会提到怎么用Lora统一风格。3.2 角色卡与prompt拼接规则每个分镜都要拼入同一段角色特征漫剧出图最容易翻车的点是同一个角色在不同分镜里长得不一样。这个问题的根源在于Flux模型对“角色名”没有记忆能力它只认视觉描述。所以做法是把Kimi生成的roles表转成角色卡每个角色的外貌特征浓缩成一段固定文本拼进每一个涉及该角色的分镜prompt里。from diffusers import FluxPipeline import torch # 加载Flux模型半精度节省显存 pipe FluxPipeline.from_pretrained( black-forest-labs/FLUX.1-dev, torch_dtypetorch.bfloat16 ) pipe.enable_model_cpu_offload() # 角色卡从Kimi生成的roles表转换而来 role_cards { R1: 银色双马尾少女琥珀色眼睛白色水手服表情冷淡, R2: 黑发猫耳少年绿色瞳孔黑色夹克嘴角带笑 } # 场景基础描述全局共享 scene_base { S1: 放学后的学校屋顶傍晚金色阳光微风, S2: 深夜的小餐馆暖黄色灯光木质吧台, S3: 夏日祭的夜晚烟花在天空绽放人群拥挤 } def build_flux_prompt(shot: dict, role_cards: dict, scene_base: dict) - str: scene_desc scene_base[shot[scene_id]] role_desc [] for role_id in shot.get(roles_in_shot, []): role_desc.append(role_cards[role_id]) # 拼接顺序场景 角色 镜头指令 风格后缀 prompt , .join([ scene_desc, .join(role_desc), shot[shot_desc], 日系二次元风格高细节精美插画赛璐璐上色 ]) return prompt # 分镜列表从Kimi输出中取前5个演示 shots episodes[0][shots][:5] prompts [build_flux_prompt(s, role_cards, scene_base) for s in shots] # 固定seed保证同角色图像风格统一 seed 14321 generator torch.Generator(cuda).manual_seed(seed) for shot, prompt in zip(shots, prompts): image pipe( prompt, width1024, height576, num_inference_steps28, guidance_scale3.5, generatorgenerator ).images[0] # 按shot_id命名供Seedance阶段回填 image.save(fframes/{shot[shot_id]}_seed.png)这段脚本的核心是build_flux_prompt函数。它的拼接顺序是有讲究的场景描述放最前面让模型先确定空间环境角色描述紧随其后用高度一致的措辞锁定外观最后放镜头动作信息和风格后缀。这个顺序不是玄学Flux对prompt的注意力分配是从前往后的前面内容权重更高。参数说明是重点。width和height设成1024×576这是漫剧竖屏转横屏常用的2K比例太宽或太高都会增加生成时间和显存占用。num_inference_steps设28Flux在20到30步之间画面质量趋于稳定步数太少会出现细节粗糙太多只是浪费时间。guidance_scale设3.5这个值和文字符合度相关太高画面会过饱和太低又容易跑偏提示词。seed固定为14321这一步非常重要——虽然每个分镜画面不同但同一集里保持seed稳定能让色彩倾向和笔触风格更统一。注意生成结果按shot_id加seed后缀命名这是为了后面Seedance阶段能反查每个镜头对应的首帧图不要省掉这一步。3.3 批量出图的并发控制与文件命名规则分镜出图是整条流水线里最耗时的一环一集短剧20个镜头单线程跑可能得五六分钟。常见的做法是用线程池做并发但并发数要控制好否则显存会被打爆。FXLUX.1-dev在1024×576分辨率下单张图约需12到16G显存如果显卡显存不够并发数就得降到1。from concurrent.futures import ThreadPoolExecutor, as_completed import os def generate_and_save(shot: dict, out_dir: str frames): 单镜头出图任务 prompt build_flux_prompt(shot, role_cards, scene_base) image pipe( prompt, width1024, height576, num_inference_steps28, guidance_scale3.5, generatortorch.Generator(cuda).manual_seed(seed) ).images[0] # 文件名分镜ID_场景ID_角色ID.png三步对齐便捷 fname f{shot[shot_id]}_{shot[scene_id]}_{_.join(shot[roles_in_shot])}.png image.save(os.path.join(out_dir, fname)) return fname # 用线程池控制并发避免显存溢出 all_shots episodes[0][shots] os.makedirs(frames, exist_okTrue) with ThreadPoolExecutor(max_workers2) as executor: futs [executor.submit(generate_and_save, s) for s in all_shots] for fut in as_completed(futs): fname fut.result() print(f完成: {fname}) print(f共生成 {len(all_shots)} 张分镜图)文件名规则看起来简单实际是整条流水线的数据契约。Shot ID对应Kimi剧本里的镜头编号Scene ID对应场景描述角色ID列表对应角色卡。这三个信息全在文件名里Seedance阶段读文件的时候不需要再回查数据库就能知道这个镜头属于哪个场景、哪个角色出场。max_workers设2是相对稳妥的起步值。如果有24G显存可以尝试3或4但并发任务同时读取模型权重会增加显存碎片实际提速并不线性。更合理的做法是通过队列控制显存占用避免多个torch.Generator同时持有CUDA上下文。4. Seedance视频生成把静态分镜图变成可拼接的镜头4.1 Seedance 2.0的镜头控制逻辑与导演台概念Flux出好图之后下一步是把静态图变成动态镜头。Seedance 2.0在这类任务上的表现比较突出特别是对首帧图的理解——它能读取图片内容并生成合理的后续运动而不是简单做缩放平移。Seedance 2.0还有一个值得关注的“导演台”机制它的开源版本允许通过分镜参数控制镜头运动方式、景别变化、主体运动轨迹。这正好匹配漫剧生产场景我们可以把Kimi写的shot_desc里的“镜头运动”字段映射到Seedance的镜头控制参数上。这个映射关系要做到足够细才能保证生成出来的视频符合预期而不是让模型自由发挥。4.2 用脚本把分镜参数转换为Seedance请求体Seedance的服务端API通常需要一个frame_list来描述首帧图的获取位置以及motion参数来控制镜头运动。在实际项目中我会把所有分镜的镜头参数整理成一个请求体直接发给Seedance服务端。import requests import json # 分镜数据从episodes.json读取第一集并与出图结果合并 with open(episodes.json, r, encodingutf-8) as f: episodes json.load(f) def split_video_requests(shot: dict, frame_path: str) - dict: 构造Seedance请求体把文字分镜翻译成镜头参数 motion_map { 推进: {type: zoom_in, speed: 0.8, duration: 3}, 拉远: {type: zoom_out, speed: 0.8, duration: 3}, 左摇: {type: pan_left, speed: 0.4, duration: 3}, 右摇: {type: pan_right, speed: 0.4, duration: 3}, 固定: {type: static, speed: 0, duration: 2} } # 深度解析场景文本识别出镜头指令 desc shot[shot_desc] shot_keys [推进, 拉远, 左摇, 右摇, 固定] matched_motion 固定 for key in shot_keys: if key in desc: matched_motion key break # 按镜号的规则生成请求体 return { frame_path: frame_path, motion: motion_map[matched_motion], start_frame: auto, end_frame: auto, # 让模型自动预测尾部画面 resolution: 1024x576, fps: 24, total_frames: int(motion_map[matched_motion][duration] * 24) } # 构造请求列表 requests_list [] for shot in episodes[0][shots]: # 读取上面Flux生成的frame路径 frame_path fframes/{shot[shot_id]}_{shot[scene_id]}_{_.join(shot[roles_in_shot])}.png requests_list.append({ shot_id: shot[shot_id], video_request: split_video_requests(shot, frame_path) }) # 发送到Seedance服务端 for item in requests_list[:3]: # 先测试前3个镜头 resp requests.post( https://api-seedance.example.com/v1/video/generate, jsonitem[video_request], headers{Authorization: Bearer your-seedance-api-key} ) print(item[shot_id], resp.status_code)这段请求体的构造逻辑是把Kimi的文本描述翻译成Seedance能理解的镜头参数。motion_map里定义了五种基础镜头运动每个对应一个模型层的type值、速度和时长。为什么要这么做因为Flux生成的描述文字是给画图模型看的其中“推进”“拉远”这些词汇对Flux毫无意义——画面本身是静态的——但对Seedance至关重要它决定视频里镜头的运动方向。参数方面total_frames用duration乘以fps。我设定3秒镜头24帧也就是72帧视频生成时间会显著增加而漫剧的节奏本身需要短镜头快切——3到4秒的镜头在第5章会有解释。fps设24是为了和国内短视频平台常用的帧率一致这样后期拼接时对不同片段的帧率要复查一次避免出现跳帧。注意这里的请求逻辑中end_frame用了auto方式。实际生产环境中首尾帧方式会更稳——首帧交给Flux出图尾帧可以用Kimi的续写逻辑生成或者干脆再用一张Flux图指定尾帧画面。auto适合测试阶段生产建议切到“first_last_frame”模式。4.3 生成结果的下载与对白时间轴拼接Seedance服务端生成视频后一般是异步返回任务ID然后轮询任务状态。拿到结果后要下载视频并按镜头编号存储再和Kimi里的对白时间对齐。下面是一个简单的轮询下载逻辑import time import os def poll_generate_result(task_id: str, timeout: int 300): 轮询任务状态直到完成或超时 start time.time() while time.time() - start timeout: resp requests.get( fhttps://api-seedance.example.com/v1/task/{task_id}, headers{Authorization: Bearer your-seedance-api-key} ) data resp.json() if data[status] succeeded: return data[video_url] elif data[status] failed: raise RuntimeError(f任务失败: {data[error]}) time.sleep(10) raise TimeoutError(f任务超时: {task_id}) # 存储下载路径 os.makedirs(clips, exist_okTrue) for task in submitted_tasks: video_url poll_generate_result(task[task_id]) clip_path fclips/{task[shot_id]}.mp4 # 实际的下载逻辑就是标准文件下载这里用一个示意 with open(clip_path, wb) as f: f.write(requests.get(video_url).content)视频下载之后对白时间轴拼接通常用剪辑软件或ffmpeg完成。Seedance生成的单个镜头时长是3到4秒一集20个镜头大约80秒的成片这种体量用剪映或Premiere Pro手动拖放是可行的。如果要做全自动拼接需要用ffmpeg的concat协议把每个片段按分镜顺序拼成一个完整视频文件。这一步对算力要求不高但对编码参数有一定要求后面第5章展开讲避坑点时再细说。5. 编排层与常见问题排查把剧本到成片的中间层做稳5.1 中间层配置一个JSON串起三个模块现在三个核心模块已经清楚了Kimi负责剧本结构化Flux负责出首帧图Seedance负责生成动态镜头。但如果你直接按顺序手动跑会发现到处都需要手工搬运数据——把Kimi输出复制给Flux脚本再把图片一张张上传。所以还需要一个编排层用一个全局配置文件把三个模块的数据接口统一起来。{ project: 日系二次元漫剧测试季, episode: 1, kimi: { model: kimi-k2.5, temperature: 0.4, max_tokens: 4000 }, flux: { model: black-forest-labs/FLUX.1-dev, seed: 14321, width: 1024, height: 576, steps: 28, guidance: 3.5 }, seedance: { resolution: 1024x576, fps: 24, shot_duration: 3, motion_map: { 推进: {type: zoom_in, speed: 0.8}, 拉远: {type: zoom_out, speed: 0.8}, 左摇: {type: pan_left, speed: 0.4}, 右摇: {type: pan_right, speed: 0.4}, 固定: {type: static, speed: 0} } }, output: { frames_dir: frames, clips_dir: clips, final_video: output/result.mp4 } }这个配置文件把三个模块的超参数都集中放在一处它的真正价值在于版本管理——当你调整剧本或者更换模型版本只需要改配置不用在每个脚本里搜索参数。特别是seed和shot_duration这两个值改了其中一个其他模块的行为就会相关联配置统一就能减少很多不一致的问题。5.2 编排脚本的批次处理思路有了配置后需要写一个主控脚本按顺序执行“剧本生成→分镜出图→镜头生成→视频拼接”。这里有一个坑生成视频的耗时会远超想象所以批次处理必须支持断点续跑。# 主控脚本示意 import subprocess import json def run_pipeline(config_path: str): 执行整条AI漫剧流水线 # 阶段1: 剧本生成 subprocess.run([python, scripts/step1_script.py, config_path], checkTrue) # 阶段2: 分镜出图幂等支持resume subprocess.run([python, scripts/step2_flux.py, config_path], checkTrue) # 阶段3: 视频生成耗时最长可校验结果后重跑 subprocess.run([python, scripts/step3_seedance.py, config_path], checkTrue) # 阶段4: 视频拼接 subprocess.run([python, scripts/step4_concat.py, config_path], checkTrue) if __name__ __main__: run_pipeline(config/episode1.json)这套编排逻辑的关键思路是每个脚本都保持幂等——重复执行不会产生副作用。Step2的Flux脚本在保存图片之前会检查文件是否已存在如果存在且文件大小合理就直接跳过。Step3的Seedance脚本会在本地记录已经提交成功的task_id重跑时只提交缺失的镜头。这样即使某一步在凌晨三点崩了第二天改完参数重新跑不会从头再来。5.3 常见问题排查到了这个阶段前面那套流程里最容易翻车的几个点基本都出来了。下面按“现象→原因→解决”的格式整理都是实测踩过的坑。第一Flux出图同一角色前后不相似。现象是Kimi剧本里同一个角色在第一个分镜里是银发少女第二个分镜里变成了棕色头发。原因是角色的外观描述在Kimi生成时前后措辞不一致同一句话在不同分镜里出现了微调Flux把变化当成不同角色处理。解决方法是角色卡必须人工核对并统一措辞而且角色卡要固定放在prompt的场景描述之后、镜头指令之前让模型把稳定特征放在高注意力权重区。第二Seedance生成视频时首帧画面突然拉伸变形。现象是输入Flux生成的横版图像Seedance输出的视频首帧对不上画面被裁切。原因是Flux输出的是1024×576而Seedance内部有自己的安全分辨率如果输入不匹配某些规格它会自动居中裁剪。解决方法是统一尺寸——在Flux生成时严格设成1024×576不要用“接近”的分辨率然后再做一次降采样确保精确匹配。第三Kimi输出的镜头数量总是上下浮动一集20个镜头第1次生成18个第2次生成23个。原因是temperature调太高导致生成不稳定性而且prompt里没有写死“必须生成恰好20个分镜”。解决方法是把temperature降到0.4以下并且在约束里明确加一条“本集必须有且仅有20个分镜”如果数量不符就重新生成。第四Seedance请求报错或者超时。现象是第10个镜头开始API响应变得很慢甚至返回429限流错误。原因是请求太密漫剧镜头数量多且体积大。解决方法是把time.sleep(10)的轮询间隔放宽并且在线程池里限制并发提交数量一次最多提交3个任务。第五最终拼接视频画面流畅但没有声音。现象是剪辑软件里的成片视频正常但音轨对不上。原因是漫剧对白不是后期配的而是Kimi生成的文本需要在剪辑软件里用TTS生成配音。常见的做法是在拼接完之后统一做一步配音对齐根据每个镜头的对白长度分配配音段落。如果跳过配音直接发布观众会觉得这是一个哑剧。6. 验证方法三表对账和一套我每次必做的检查清单流程跑通以后先别急着发布。我每次交付一集漫剧前都会做一遍三表对账角色表、场景表、分镜表三张数据表和实际生成的文件做交叉比对。角色表要和分镜文件里的角色ID一致场景表要和Flux生成图中出现的背景一致分镜表要和Seedance生成的视频片段数量一致。任何一张对不上说明中间某一步数据被篡改或丢失。这份检查清单我固定下来每次跑完流水线都会执行。第一核对角色卡数量——剧本里出场5个角色Flux输出目录里对应的文件名里就应该出现5个不同的角色ID一个不多一个不少第二核对分镜文件数量——剧本定义了20个分镜frames目录里就该有20张图clips目录里就该有20个视频少了任何一个都说明有任务没有成功返回第三核对分辨率和帧率——抽查3个视频文件用ffprobe确认宽高都是1024×576fps是24这两项不一致会导致拼接时出现黑边或跳帧。进阶技巧是训练一个统一风格的Lora。Flux社区可以训练自定义Lora用同一部漫剧的前几集成片做数据集训练一个角色风格Lora挂载到Flux推理流程里——具体方法是在加载模型时使用lora权重文件让模型在生成时倾向特定角色风格而不是依赖prompt里反复描述外貌。这样做能大幅减轻角色一致性压力。从那以后我每次搭建新项目的流水线不管工具换成什么模型都会强制把三表对账走一遍数据对不齐绝不进入下一步。这套流程看着多一道工序实际省掉的是后期数十个小时的返工时间。希望帮到你。本文还有配套的精品资源点击获取