
这次想试一件事:让大模型分工拍一部短片。
需求就一句话:
生成一个关于奥德修斯的故事的短片,风格使用手绘蜡笔水彩风格,先由你确定创意构思,再使用 sonnet 完成落地。
分工很明确:
- Claude Opus 5.5(主代理):导演 + 美术指导。负责创意、写设计规格、拆任务、审稿、给修改意见。它自己一行业务代码都不写。
- Claude Sonnet 5.5(子代理) :执行团队。拿着规格写代码、出图、跑测试,遇到规格外的审美问题不许自己拍板,只能在报告里提出来。
最后的成片:2 分 40 秒、16 个镜头、1080p,所有画面都是 JavaScript 程序画出来的,旁白、配乐也是代码合成的。
先看成品(每个镜头抽一帧):

一、任务:一个关于"回家"的故事
Opus 拿到需求后,先定了创意,而不是马上动手:
- 主题不是打怪,是回家。 十年战争、十年漂泊,独眼巨人、塞壬、斯库拉都只是回家路上的阻碍。情绪落点放在老狗认主和橄榄树床相认。
- 贯穿符号:一条红围巾。 佩涅洛佩在织布机上织的红线,就是奥德修斯脖子上的红围巾。全片只有这条围巾是高饱和的红色,大海再大,那一点红就是"家"的牵挂。结尾围巾挂在自家窗台上随风飘------回到了。
- 首尾呼应。 从织布机开始,到织布机窗口结束。
- 16 个镜头:片头 → 织机 → 木马 → 独眼巨人 → 波塞冬 → 风袋 → 喀耳刻 → 塞壬 → 斯库拉与卡律布狄斯 → 孤舟夜海 → 卡吕普索 → 老狗阿尔戈斯 → 拉弓穿斧 → 橄榄树床 → 黎明 → 片尾。
这些全部写进了两份文件:brief.md(创意说明)和 shots.json(每个镜头的旁白、画面描述、运镜参数)。后面所有 Sonnet 都以这两份文件为唯一依据。
二、画面路线:用 JS 把它们画出来
这次的画面全部用 JavaScript(Node + @napi-rs/canvas)程序化绘制。
难度不低:程序画"蜡笔水彩",质感全靠算法;人物、怪物、船、海全要用代码构造。但这也恰好是验证"Opus 设计 + Sonnet 执行"这套分工最好的场景------设计含量极高,执行量也极大。
三、分工方式:Opus 写规格,Sonnet 照规格干活
Opus 先写了一份约 400 行的绘制规格 js_art_spec.md,这是整个项目的核心产物。它不是"画一个好看的海"这种模糊描述,而是可以直接执行的设计:
| 规格章节 | 写清楚了什么 |
|---|---|
| 色板 | 30 个颜色的 hex 与用途;scarfRed 只允许红围巾使用 |
| 纸 | 纸齿、斑驳两张噪声场怎么生成,最终怎么乘到画面上 |
| 水彩 | 叠层变形算法的每一步参数:递归深度、方差衰减、层数、alpha、边缘加深、颗粒沉积 |
| 蜡笔 | 线条怎么重采样、抖动、压力、两端收尖、每个采样点戳几个小矩形 |
| 分层合成 | 每个"平面"= 遮盖层 + 水彩层(multiply) + 蜡笔层(纸齿蒙版),从后往前合成 |
| 人物骨架 | 以身高 h 为单位的比例(头半径 0.09h......),关节角约定,14 种姿态的动作含义 |
| 分镜构图 | 15 个场景每个元素的坐标(2560×1440 基准),并保证关键人物在运镜起止窗口内 |
| 审查流程 | 先出半尺寸预览 → 自查技术问题 → 全尺寸出图;审美问题只报告,不自改 |
然后按依赖关系拆成 4 个阶段,能并行的都并行:
markdown
阶段 1 笔刷核心库(1 个 Sonnet)
│ Opus 审测试页 → 调参意见 → 通过
阶段 2 人物骨架与角色(1 个 Sonnet) ∥ 环境道具库(1 个 Sonnet) ∥ 渲染管线改造(1 个 Sonnet)
│ Opus 审角色页/道具页 → 各 1 轮修改 → 通过
阶段 3 场景 S00--S04 ∥ S05--S09 ∥ S10--S14(3 个 Sonnet 并行)
│ Opus 逐张审 15 个场景 → 8 个场景返修 1 轮 → 通过
阶段 4 最终渲染与验证(1 个 Sonnet)
几个让并行不打架的约定:
- 文件所有权 :每个 Sonnet 只能写自己名下的文件,场景代理禁止修改
lib/,私有辅助函数放各自的_helpers_A/B/C.js。 - 接口先行:阶段 1 结束时让 Sonnet 在报告里写清 API 签名,阶段 2/3 的任务说明直接引用。
- 遇到规格没覆盖的情况停下来问,而不是自己发挥。
四、笔刷:程序怎么画出"蜡笔 + 水彩"

水彩用的是 Tyler Hobbs 的叠层变形法:一个多边形反复做"边中点沿法线随机偏移",派生出几十个略有不同的形状,每层只填 4.5% 的不透明度,叠起来就有了水彩那种不规则边缘和内部浓淡:
js
// 每条边取中点,沿法线偏移 gauss(0, variance*v*边长);递归 depth 次
function deform(verts, depth, variance, rng) {
let cur = verts;
for (let d = 0; d < depth; d++) {
const out = [];
for (let i = 0; i < cur.length; i++) {
const a = cur[i], b = cur[(i + 1) % cur.length];
out.push(a);
const dx = b.x - a.x, dy = b.y - a.y, len = Math.hypot(dx, dy);
const vv = (a.v + b.v) * 0.5;
const off = rng.gauss(0, variance * vv * len);
out.push({ x: (a.x + b.x) / 2 - dy / len * off, y: (a.y + b.y) / 2 + dx / len * off, v: vv });
}
for (const q of out) q.v *= 0.65; // 越细的层级偏移越小
cur = out;
}
return cur;
}
蜡笔是在路径的每个采样点上"戳"一把 1~2.4px 的小矩形,位置在法线方向三角分布(中间密两边稀),再叠加低频抖动、压力变化、两端收尖。
真正让它"像蜡笔"的是纸齿蒙版 :蜡笔层合成前逐像素乘上 smoothstep(0.22, 0.62, tooth),蜡只挂在纸的凸起上,笔触自然断续、有颗粒:
js
// 纸齿蒙版:a *= smoothstep(0.22,0.62,tooth)(蜡笔只挂在纸的凸起上)
for (let i = 0, p = 3, N = Wp * Hp; i < N; i++, p += 4) {
const a = d[p];
if (a) d[p] = (a * mask[i] + 127) / 255;
}
第一版测试页 Opus 并不满意,给 Sonnet 的意见是这样的(节选):
wash 默认值:spread 0.9→0.55(边缘要像湿水彩边,不是撕纸);granulate 0.35→0.15;tone 0.45→0.22,且浓淡噪声尺度至少是形状尺寸的 2 倍(色块内部是宽缓的明暗过渡,不是云团斑块);edge 0.6→1.1(边缘有可见的深色水线,这是水彩最重要的特征)。
gradientWash 重写(横带不能再被看出来):......
意见里是具体的参数和判断标准,不是"再好看一点"。 这是 Sonnet 能一次改到位的关键。
五、人物与道具
人物是一个简单的 2D 骨架:以身高 h 为单位定比例(绘本式大头,头半径 0.09h),关节角驱动四肢,服装、头发、胡子、红围巾都是参数化部件。14 种姿态覆盖了所有镜头的动作:拉弓、被绑在桅杆上、背影坐在石头上、单膝跪地伸手、相拥......

道具库包括希腊船(高翘船头、船眼、方帆、一排桨,船身拆成前后两部分,好让水手"站在船里")、双刃斧、木马、城墙、织布机、羊、猪、老狗、橄榄树......

这一轮 Opus 的意见同样很具体,比如:
斧头改成古希腊双刃斧(labrys),不能再像雨伞或镐头;皮袋改成软皮囊,不能再像陶罐;红围巾现在像一串锁链,改成连续的布带:先整条铺 scarfRed 水彩,再叠垂直于布带方向的密排线,两侧用同色相更深的红描边......
六、场景:15 张画,三个 Sonnet 并行
场景阶段三个 Sonnet 同时开工,每人 5 个场景。每个代理都会用脚本把运镜的起止窗口框画到预览图上,确认主角全程在镜头里。
独眼巨人是返修最多的一张。第一版鼻子画成了猪鼻子、四肢像散落的香肠、洞壁像蜂巢。Opus 的返修意见把每个部位的形状、朝向、连接关系都写了出来,第二版就对了:

塞壬:奥德修斯被绑在桅杆上,围巾飘向歌声;水手耳朵里塞着蜡:

老狗阿尔戈斯:二十年后,只有它认出了扮成乞丐的主人。第一版里红围巾掉在地上像一条红腿、狗又小又和草堆一个颜色,返修后变成了现在这样:

橄榄树床:床是围着一棵活着的橄榄树做的,这是只有他们两人知道的秘密:

七、让画"动"起来:线条抖动
每个镜头用不同的蜡笔随机种子渲染 3 个变体,只有蜡笔线条不同,水彩与构图完全一致(这要求代码里构图随机数和线条随机数严格分成两条流,混用就是 bug)。视频里每 3 帧切换一次变体,就得到了手绘动画那种"线条在呼吸"的效果:

再配合缓慢的推拉摇(Ken Burns,亚像素插值避免抖动)、1 秒叠化、纸纹和暗角,整片就有了绘本翻页的感觉。
声音部分:旁白用 edge-tts(zh-CN-YunxiNeural),配乐是 numpy 合成的 Karplus-Strong 拨弦里拉琴(D 多利亚调式)+ 海浪噪声,旁白出现时音乐自动压低,最终响度归一到 -16 LUFS。字幕用 PIL 逐帧绘制(本机 ffmpeg 没有 drawtext)。

八、数据
| 项 | 数值 |
|---|---|
| 成片 | 2 分 40 秒,1920×1080,24fps,16 个镜头 |
| 绘图核心库(笔刷/骨架/道具/环境) | 约 3700 行 JS |
| 15 个场景 | 约 3450 行 JS |
| 音频与合成管线 | 约 650 行 Python |
| 插画 | 15 个场景 × 3 个抖动变体 = 45 张 2560×1440 |
| Sonnet 子代理 | 10 个任务(最多 3 个同时跑) |
| Opus 审查 | 笔刷 1 轮、角色 1 轮、道具 1 轮、场景 8 张返修 1 轮 |
| 最终渲染 | 约 4 分钟 |
九、几点体会
1. 规格写到"可执行",Sonnet 的产出就很稳。 坐标、比例、参数、验收标准都写死之后,Sonnet 几乎不需要猜,返工基本只来自"规格本身没想到"的地方。
2. 审美决策必须收回到 Opus。 明确要求 Sonnet"审美问题只报告不自改"之后,它的报告里会列出"需要主代理判断的点"(比如"S12 求婚者被斧子挡得比较碎,是否接受"),由 Opus 统一拍板,风格才不会在 15 个场景里各自漂移。
3. 审查意见要像规格一样具体。 "猪鼻子改成蒜头鼻:圆润的水滴形,比脸略深的肤色,鼻尖有阴影,鼻孔只是底边两道短弧"这样的意见,Sonnet 一轮就能改对;"再好看一点"只会换来随机的变化。
4. 并行靠边界清晰。 文件所有权、接口先行、随机数分流、"不许改 lib"------这些工程约定比模型能力更决定并行能不能顺利进行。
5. 自查要可验证,而不是"我看过了"。 每个任务都写明了用脚本自证的方法:把运镜起止窗口框画到预览图上、用 numpy 对比三个抖动变体只有蜡笔区域不同、把四条边各裁 60px 拼起来检查有没有漏出纸白。Sonnet 交上来的是证据,Opus 的审查就能集中在审美上。
如果你也在用多模型协作,不妨试试这种"强模型定方向和标准、快模型大量执行"的分工:贵的模型花在判断上,便宜的模型花在体力上。