ARTICLE · INTELLIGENCE

战地情报 · 详情页

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

OpenMontage 与 Remotion:用 AI Agent 编排程序化视频流水线

OpenMontage 与 Remotion:用 AI Agent 编排程序化视频流水线

1. 从 OpenMontage 这个名字说起:它到底想解决什么问题

第一次看到 OpenMontage 这个词,我脑子里蹦出来的第一反应是"开放蒙太奇"。蒙太奇是剪辑语言的核心——把不同镜头拼在一起产生新的含义。把这个词用在 AI 编程助手上,其实非常精准:它想做的事情,就是把散落在不同工具、不同模型、不同素材里的"镜头",用一套 agentic 的流程自动拼成一条完整的片子。

我接触过不少做视频自动化的团队,大家的痛点高度一致:写脚本、找素材、配音、剪辑、导出,每一步都能用工具做,但每一步之间是断的。你写完文案要手动丢进配音工具,配完音要手动对齐时间轴,对齐完还要手动套模板渲染。OpenMontage 这类项目瞄准的就是这条断链——它把 Remotion 这种"用代码写视频"的框架,和 AI coding assistant 这种"用自然语言驱动代码"的能力接在一起,让一个 agent 从头到尾把片子跑出来。

关键词里出现的 Remotion 和 Veo 很说明问题。Remotion 是 React 生态里做程序化视频的框架,你用组件描述画面,用 props 控制内容,最后渲染成 mp4。Veo 则是生成式视频模型的代表,负责产出真实感镜头。OpenMontage 的定位,大概率是站在 Remotion 这一侧做"编排层",把 Veo 这类生成模型当作素材来源之一,再通过 agentic 的决策把整条流水线串起来。

这篇文章适合谁看?如果你是会写前端、想用代码批量做视频的人,或者你在做 AI 内容生产工具、想理解 agentic 编排怎么落地到视频场景,再或者你只是好奇"AI coding assistant 除了写 CRUD 还能干嘛",那这篇值得往下读。我会把 OpenMontage 这类项目的核心机制、Remotion 的实操细节、agent 编排的设计取舍,以及我自己踩过的坑,尽量讲透。

需要先说明一点:OpenMontage 本身公开的细节有限,下面涉及具体实现的部分,我会基于 Remotion 生态和 agentic 工具的通用实践做合理补全,并明确标注哪些是推断、哪些是成熟做法。这样你拿去复现时心里有数。

2. Remotion 为什么成了程序化视频的事实标准

2.1 用 React 写视频,本质是把时间轴变成函数

传统剪辑软件里,时间轴是可视化的轨道,你拖拽片段、调关键帧。Remotion 换了个思路:视频就是"给定帧号,返回这一帧长什么样"的函数。你写一个 React 组件,Remotion 在渲染时逐帧调用它,把每一帧画到 canvas 或截图上,最后用 FFmpeg 合成。

这个模型的好处是,视频内容变成了纯数据驱动的。比如你要做一个"每天自动生成昨日数据播报"的视频,只需要把数据当 props 传进组件,Remotion 就能渲染出对应的画面。没有手动剪辑,没有重复劳动。这也是为什么它特别适合和 AI agent 结合——agent 最擅长的就是生成结构化数据,而 Remotion 最擅长的就是把结构化数据变成画面。

我实测下来,Remotion 的学习曲线对前端来说几乎为零。你会写 React,就会写 Remotion。真正的门槛在渲染性能和音视频同步这些工程细节上,后面会细讲。

2.2 Composition、Sequence、useCurrentFrame 三件套

Remotion 的核心 API 其实就三个概念,理解了它们,80% 的活儿都能干。

Composition是视频的入口,你在这里注册一个"片子",指定它的宽高、帧率、总时长,以及用哪个组件渲染。一个项目里可以注册多个 Composition,比如一个横版主片、一个竖版短视频。

Sequence是时间轴上的片段,你可以指定它从第几帧开始、持续多少帧。它解决的是"什么时候出现什么"的问题。多个 Sequence 叠加,就形成了蒙太奇。

useCurrentFrame是获取当前帧号的 hook。你在组件里调用它,就能根据帧号算出动画进度。比如淡入效果,就是opacity = interpolate(frame, [0, 30], [0, 1])。

import { Composition, Sequence, useCurrentFrame, interpolate } from 'remotion'; const Title = () => { const frame = useCurrentFrame(); const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: 'clamp' }); return <h1 style={{ opacity }}>OpenMontage 演示</h1>; }; export const Root = () => ( <Composition id="Demo" component={Title} durationInFrames={150} fps={30} width={1920} height={1080} /> );

这段代码就是最小可运行的 Remotion 片子:一个 5 秒、30fps 的 1080p 视频,标题在 1 秒内淡入。你会发现,视频逻辑和普通 React 逻辑没有本质区别,只是多了"帧"这个维度。

2.3 为什么 agent 偏爱 Remotion 而不是传统剪辑工具

这里有个关键判断:AI agent 要操作一个工具,前提是这个工具能被"文本化"地描述和调用。传统剪辑软件的操作是鼠标拖拽,agent 很难精确控制。而 Remotion 的项目本身就是代码,agent 可以直接生成、修改代码,然后触发渲染。

换句话说,Remotion 把"剪辑"这件事从图形操作变成了代码操作,而代码恰恰是 AI coding assistant 最擅长的领域。这就是 OpenMontage 这类项目选择 Remotion 作为底层渲染引擎的根本原因。Veo 负责生成"真实镜头"这种 Remotion 不擅长的部分,两者互补,agent 负责调度。

3. Agentic 编排:让 AI 自己决定"下一步做什么"

3.1 从"单次生成"到"多步决策"的跨越

普通的 AI 视频工具,流程是线性的:你输入一句话,它生成一段视频。这叫单次生成。Agentic 的区别在于,它把任务拆成多步,每一步根据上一步的结果决定下一步。比如:

  1. 读取脚本,判断需要几个镜头
  2. 对每个镜头,决定是用 Remotion 画动画,还是调 Veo 生成实拍感素材
  3. 生成对应代码或调用对应 API
  4. 检查产出是否符合预期,不符合就重试
  5. 把所有片段按时间轴拼起来,加转场和配乐
  6. 渲染导出

这个循环里,第 4 步"检查并重试"是 agentic 的灵魂。没有它,就只是批处理脚本;有了它,才叫 agent。

3.2 工具调用协议:agent 怎么"看见"Remotion 和 Veo

Agent 要操作外部能力,靠的是工具调用(tool calling)。在 OpenMontage 这类项目里,通常会定义几类工具:

工具类型作用典型实现
代码生成工具生成/修改 Remotion 组件让 coding assistant 输出 JSX
渲染工具触发 Remotion 渲染调用npx remotion render
素材生成工具调 Veo 等模型产出视频片段HTTP API 调用
检查工具校验产出(时长、分辨率、内容)FFprobe + 规则判断
文件工具读写项目文件标准文件操作

关键在于,这些工具的输入输出都要是 agent 能理解的文本或结构化数据。比如渲染工具返回的不只是"成功/失败",还要返回视频时长、帧数、文件路径,agent 才能据此决定下一步。

3.3 状态管理:多步任务最容易翻车的地方

我踩过最大的坑就在这。Agent 做多步任务时,如果没有清晰的状态记录,很容易"忘记"自己做到哪了,或者重复生成同一个片段。常见做法是维护一个任务状态对象,类似:

{ "script": "...", "scenes": [ { "id": 1, "type": "animation", "status": "done", "file": "scene1.mp4" }, { "id": 2, "type": "generated", "status": "pending" } ], "currentStep": "generate_scene_2" }

每完成一步就更新这个对象,agent 每次决策前先读它。这样即使中间某步失败重试,也不会把已完成的活儿重做。这个设计看起来朴素,但实测能省掉大量重复调用成本——尤其是 Veo 这种按次计费的模型,重复调用就是烧钱。

提示:状态对象一定要持久化到磁盘,不要只放在内存里。Agent 任务动辄跑几分钟到几十分钟,进程重启是常事,内存状态一丢,整个任务就得重来。

4. 把 Remotion 接进 agent 流水线的实操细节

4.1 项目脚手架怎么搭才不容易乱

Remotion 官方提供了create-video脚手架,但直接用它做 agent 项目会有点乱,因为 agent 生成的代码需要有个稳定的落点。我的做法是固定一套目录结构:

project/ src/ compositions/ # 每个片子一个 Composition scenes/ # 可复用的场景组件 assets/ # 图片、音频、字体 generated/ # agent 生成的代码放这里 remotion.config.ts package.json

把 agent 生成的东西统一放generated/,好处是出问题时你能一眼看出哪些是 AI 写的、哪些是手写的,排查起来快很多。而且可以给generated/加 lint 和类型检查,agent 生成的代码先过一遍检查再渲染,能挡掉不少低级错误。

4.2 渲染命令的参数怎么配

Remotion 渲染的核心命令是npx remotion render,但参数配置直接决定成败。几个关键参数:

  • --concurrency:并发渲染的帧数。默认是 CPU 核数的一半。我实测在 8 核机器上设 4 比较稳,设太高反而因为内存争抢变慢。
  • --codec:编码格式。h264 通用性最好,h265 体积小但兼容性差,prores 适合后期再加工。
  • --crf:画质参数,18 到 28 之间,数字越小画质越好体积越大。做网络分发一般 23 够用。
  • --props:传入动态数据,这是 agent 驱动内容的关键入口。
npx remotion render src/index.ts Demo out/demo.mp4 \ --concurrency=4 \ --codec=h264 \ --crf=23 \ --props='{"title":"今日播报","items":["A","B","C"]}'

--props这个参数值得单独说。它让同一个 Composition 能渲染出不同内容,agent 只需要生成 props 的 JSON,不用改代码。这大大降低了 agent 出错的概率——生成 JSON 比生成 JSX 简单多了。

4.3 音视频同步:最容易被忽视的坑

Remotion 里音频和视频是分开处理的。如果你用<Audio>组件加背景音乐,用<Sequence>控制画面,很容易出现"画面和声音对不上"的情况。原因是音频的采样和视频的帧率不是一一对应的。

我的经验是:所有时间相关的计算,统一用帧号做单位,不要用秒。音频的startFrom和endAt也都换算成帧。这样能保证音画在帧级别对齐。另外,如果要做精确的卡点,建议先把音频的节拍点分析出来,转成帧号,再让 agent 根据这些帧号安排画面切换。

注意:Remotion 渲染时如果音频文件格式不被 FFmpeg 支持,会静默失败——视频能出来,但没声音。建议统一用 wav 或 mp3,渲染前先用 FFprobe 检查一遍。

5. Veo 这类生成模型在流水线里的正确打开方式

5.1 生成素材和程序化素材的边界在哪

不是所有镜头都适合用生成模型。我的判断标准是:

  • 需要真实感、复杂光影、人物动作:用 Veo 这类生成模型
  • 需要精确文字、数据图表、品牌元素:用 Remotion 程序化生成
  • 需要精确时长和节奏控制:用 Remotion
  • 需要创意性、不可预测的画面:用生成模型

原因很简单:生成模型对"精确"这件事天然不擅长。你让它生成一个"显示 2024 年 Q3 营收 1234 万"的图表,它大概率给你一堆乱码数字。但 Remotion 可以精确渲染任何你给的数据。反过来,你让 Remotion 画一个"人在雨中奔跑"的镜头,那得写死你。所以两者是互补关系,agent 的价值就在于判断每个镜头该用哪种。

5.2 生成结果的验收:agent 怎么判断"这条能不能用"

生成模型有个特点:同样的 prompt,出来的东西质量参差不齐。Agent 必须有能力判断生成结果是否可用。常见做法是:

  1. 技术校验:用 FFprobe 检查时长、分辨率、帧率是否符合预期
  2. 内容校验:抽帧,用视觉模型判断画面是否包含预期元素
  3. 一致性校验:如果多个镜头需要风格统一,比较它们的色调、构图

技术校验是必须的,内容校验看成本。我一般会设一个重试上限,比如同一个镜头最多生成 3 次,3 次都不满意就用备选方案(比如降级成 Remotion 动画)。这个上限很重要,不然 agent 可能陷入无限重试。

5.3 成本控制:别让 agent 把预算烧光

生成模型按次计费,agent 如果没约束,很容易反复调用。我的做法是给 agent 设一个"预算"概念:

  • 每个镜头最多 N 次生成尝试
  • 整个任务最多 M 次生成调用
  • 超过预算就降级到程序化方案

这个预算要写进 agent 的系统提示里,并且在工具调用层做硬性拦截。光靠提示词约束不够,模型有时候会"忘记",必须在代码层面卡死。

6. 我在实际搭建这类流水线时踩过的坑

6.1 Agent 生成的 Remotion 代码跑不起来

这是最高频的问题。Agent 生成的 JSX 经常犯的错包括:用了不存在的组件、props 类型不对、忘了 import、用了浏览器 API 但 Remotion 渲染环境里没有。

解决办法是给 agent 一个"代码模板"作为参考,并且在生成后强制跑一遍类型检查和 lint。我一般会在系统提示里塞几个正确的示例组件,让 agent 照着改。实测这样能把首次通过率从三成提到七成以上。

另外,Remotion 的渲染环境是 Node 环境,不是浏览器。window、document这些在渲染时会报错。Agent 不知道这个边界,很容易踩。建议在提示里明确写清楚"渲染环境没有 DOM"。

6.2 渲染时间比预期长得多

Remotion 渲染是逐帧的,一个 1080p、30fps、60 秒的视频就是 1800 帧。如果每帧渲染要 100ms,那就是 3 分钟。加上并发,可能压到 1 分钟。但如果你的组件里有复杂计算或大量图片,每帧可能要 500ms,那就变成 15 分钟。

优化思路有几个:把复杂计算提前算好,用useMemo缓存;图片预加载;降低不必要的分辨率。还有一个技巧是用 Remotion 的--scale参数先渲染低分辨率预览,确认没问题再渲染全分辨率。

6.3 Agent 的"幻觉"在视频场景里特别致命

文本场景里,agent 幻觉顶多写错一句话。视频场景里,agent 幻觉可能导致:引用了不存在的素材文件、生成了逻辑矛盾的镜头序列、时长算错导致音画错位。

我的应对是"关键节点人工确认"。不是每一步都确认,而是在几个关键点设卡:脚本定稿后确认一次、素材生成后确认一次、最终渲染前确认一次。这样既保留了自动化的效率,又避免了灾难性错误。

6.4 状态丢失导致重复烧钱

前面提过状态持久化,这里再强调一次。我有一次跑一个 20 镜头的任务,跑到第 15 个时进程崩了,因为状态只在内存里,重启后从第 1 个重新生成,白白多花了十几次生成调用。从那以后,我所有 agent 任务的状态都是每步落盘,用 JSON 文件存,简单可靠。

7. 这套方案适合谁,以及怎么开始上手

如果你只是想做个简单的自动视频,其实不需要 agentic 这么重。Remotion 加一个脚本就够了。Agentic 的价值在于"决策"——当你的视频生产需要根据内容动态选择方案、需要多轮迭代、需要处理不确定性时,它才划算。

想上手的话,我的建议路径是:先用 Remotion 手写一个能跑的片子,理解 Composition 和 Sequence;然后写一个脚本,用--props驱动内容变化;最后再引入 agent,让它生成 props 和选择方案。不要一上来就搞全自动,那样出问题你都不知道是哪一层的问题。

关于 OpenMontage 这类项目的未来,我个人比较看好的是"编排层"这个定位。底层渲染有 Remotion,素材生成有 Veo 这类模型,中间怎么把它们聪明地串起来,才是真正有壁垒的地方。而这个"串"的能力,恰恰是 agentic 最擅长的。我最近在试的一个方向是让 agent 自己维护一套"镜头库",把生成过的好素材存下来复用,这样越用越省。这个思路还在打磨,等跑顺了再单独写一篇。

RELATED READING

延伸阅读

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