八种交付承诺:哪两种不许退回静图
做视频最难受的失败不是做砸了,是做出来的东西悄悄换了品类。你要的是一条有运动、有镜头的片子,最后拿到手的是一串加了缓动的静图,配上旁白,长度刚好对得上。它不报错,它甚至能过,它只是不是你要的那个东西。
OpenMontage 把这件事当成一个需要在代码里挡住的失败模式,挡它的地方叫交付承诺(delivery promise),实现在 lib/delivery_promise.py。
模块开头那段话就是设计意图
这个文件的 docstring 写得很直白,照抄原文:
Delivery promise classifier.
Before provider selection, classify what the production is actually promising
to deliver. This prevents the most damaging failure mode: silently downgrading
from motion-led to still-led without the user knowing.
The delivery promise is set at the proposal stage and locked. If the compose
stage can't honor it, the system must stop and ask — not silently substitute.
三句话,信息量都在时序上。
第一句是位置:分类发生在 provider 选择之前。也就是说,系统不是先挑好工具再看能做出什么,而是先把「这条片子到底承诺交付什么」定下来,再拿这个约束去选工具。
第二句是它要防的东西:它自称要防的最具破坏性的失败模式,就是在用户不知情的情况下,从「动效主导」悄悄降级成「静图主导」。
第三句是执行方式:承诺在提案阶段设定并锁定;到了 compose 阶段如果兑现不了,系统必须停下来问,而不是悄悄替换。
八个取值
PromiseType 枚举实读是八个:
MOTION_LED = "motion_led"
SOURCE_LED = "source_led"
DATA_EXPLAINER = "data_explainer"
TEACHER_EXPLAINER = "teacher_explainer"
SCREEN_DEMO = "screen_demo"
AVATAR_PRESENTER = "avatar_presenter"
HYBRID = "hybrid"
LOCALIZATION = "localization"
这八个名字不是按题材分的,是按这条片子的质量靠什么支撑分的。动效主导、用户素材主导、数据讲解、教学讲解、录屏演示、数字人出镜、混合、本地化配音——你会发现「宣传片」「短视频」这种我们平时说的分类一个都没有。
这个分类角度是有代价的:它不能告诉你片子长什么样,只能告诉你这条片子塌在哪里就算废了。一条产品宣传片可以是 motion_led,也可以是 source_led,还可以是 screen_demo,取决于你打算靠什么把它撑起来。所以第一步不是挑模板,是回答一个更别扭的问题:这条片子里,哪一部分是不能被替换的。
PROMISE_RULES 全表
每个承诺类型对应一条规则,实读逐格照抄:
| promise_type | still_fallback_allowed | requires_video_generation | min_motion_ratio | description(原文) |
|---|---|---|---|---|
motion_led | False | True | 0.7 | Video’s quality depends on real motion — generated video clips, footage, or animation. |
source_led | True | False | 0.3 | User-provided footage is the primary medium. Generated assets fill gaps only. |
data_explainer | True | False | 0.0 | Data visualization and explanation. Motion graphics preferred but images acceptable. |
teacher_explainer | True | False | 0.0 | Educational content. Clarity and comprehension over spectacle. |
screen_demo | True | False | 0.0 | Screen recording or product demo. Legibility over cinematic dressing. |
avatar_presenter | False | True | 0.3 | AI avatar or talking head presentation. Requires video generation for presenter. |
hybrid | True | False | 0.2 | Mix of source footage, generated content, and graphics. |
localization | True | False | 0.0 | Translation/dubbing of existing video. Preserving source timing and clarity. |
三列的含义按字段名读:允不允许静图回退、是否要求具备视频生成能力、动效比例下限。
从这张表能直接读出来的四件事
第一,不许退回静图的只有两种:motion_led 和 avatar_presenter。 其余六种 still_fallback_allowed 全是 True。这两种也正好是唯二把 requires_video_generation 标成 True 的——不允许退成静图和必须有视频生成能力,在这张表里是同一件事的两面。逻辑上讲得通:如果连回退路径都不给,那生成能力就得是硬前置。
第二,min_motion_ratio 全表只有五档取值:0.7(motion_led)、0.3(source_led 和 avatar_presenter)、0.2(hybrid)、0.0(data_explainer、teacher_explainer、screen_demo、localization)。没有 0.5,没有 0.9,就这几个数。
第三,四种承诺的动效比例下限是 0.0。 讲解片、教学片、录屏演示、本地化配音,在规则层面完全允许零动效。这一条值得单独记住:很多人默认「这套系统会逼我加动画」,但表里写得清清楚楚,有一半的承诺类型在这一项上根本不设下限。你要做的是产品录屏,规则本身就不要求你堆运镜。
第四,avatar_presenter 的 0.3 和 motion_led 的 0.7 不是一回事。 数字人这一类要求有视频生成,但动效比例下限只有 0.3——它要的是「出镜的人得是视频」,不是「整条片子七成在动」。motion_led 那行的 0.7 旁边有一句源码内联注释,写的是 # At least 70% of cuts must be real motion (video/animation, not Remotion slides),把「真实动效」和「Remotion 幻灯片」明确对立了起来。注释只交代了意图,一个镜头到底怎么被判成「真实动效」,那段判定代码我们没有读过,所以这里不展开——能确认的只有两件事:这条注释是源码里的原文,0.7 是全表唯一一处。
三条 description 里藏着价值取向
这张表的最后一列是原文描述,其中三条不是在描述形态,是在给优先级排序:
- 教学类:Clarity and comprehension over spectacle.(清晰与理解高于奇观)
- 录屏类:Legibility over cinematic dressing.(可读性高于电影感包装)
- 本地化:Preserving source timing and clarity.(保住源片时序与清晰度)
写规则表的时候顺手把「不要为了好看牺牲什么」写进 description,这在配置文件里不常见:同一处结构里,左边三列是可以被代码直接比较的硬约束(布尔值和阈值),右边这一列是给人看的取舍方向。这两类信息被放在了一起。至于这些描述文本在运行时会被谁读到、有没有进入哪一段提示词,PROMISE_RULES 之外的调用代码我们没有读过,不做推断。
承诺对象本身有哪些字段
DeliveryPromise 数据类实读是这样:
promise_type: PromiseType
motion_required: bool
source_required: bool
tone_mode: str # "cinematic", "educational", "corporate", "playful", "raw"
quality_floor: str # "draft", "presentable", "broadcast"
approved_fallback: str | None = None # "animatic", "still_led", or None
from_dict() 里的反序列化默认值:motion_required 默认 False、source_required 默认 False、tone_mode 默认 "corporate"、quality_floor 默认 "presentable"、approved_fallback 默认 None。
三个值得留意的点。
tone_mode 有 5 个取值,默认是 corporate。 不是 cinematic。你什么都不说的时候,这套系统按企业宣传的调性走,不按电影调性走。
quality_floor 有 3 档,默认 presentable,落在中间。 上面是 broadcast,下面是 draft。这个字段叫 floor(下限)而不是 target,语义上是「不得低于」。
approved_fallback 只有两个具名取值加一个 None:"animatic"(动态分镜)和 "still_led"(静图主导)。这一行其实是前面那句「不许悄悄替换」的落地方式——降级不是被禁止的,是必须被显式批准的。没有走过批准的时候,这个字段就是 None;一旦是 None,就没有任何一条合法的降级路径可走。这比「一律不许降级」更实用:你确实可能接受先出一版动态分镜,但那得是你点头的结果,不是系统替你决定的。
这份承诺在什么时候被拿出来用
README 的 Production Governance 一节里,Pre-compose validation(合成前校验)这道闸列了三种阻断情形,第一种给的例子就是违反交付承诺——原文举的例子是「动效主导」的视频里 80% 是静图。同一节还写了渲染后自审会去核验交付承诺是否被兑现。也就是说这个字段至少出现在两处闸口上:渲染之前拦一次,渲染之后再对一次。
承诺被设定的那个阶段也有对应的结构化产物:schemas/artifacts/ 下有一份 proposal_packet.schema.json。我们没有读过这个 schema 的任何字段,只能说存在这样一份提案包的契约文件,它和「承诺在提案阶段锁定」这句话在目录层面对得上。
DeliveryPromise 上另有两个方法:get_rules() 取该承诺类型的强制规则,validate_cuts(cuts) 拿一组剪辑点对着承诺做校验,其 docstring 说返回一个含 'valid'、'violations'、'motion_ratio' 三个键的 dict。这个方法内部怎么算 motion_ratio、怎么判定一个 cut 算不算「真实动效」,我们没有读完那段代码,所以不描述——只能说签名和返回结构长这样。
落到使用上
对着这张表,开工前值得先问自己一句:我要的这条片子,质量到底靠什么支撑?
答案是「靠画面在动」,那就是 motion_led,随之而来的是必须具备视频生成能力、没有静图回退、动效比例下限 0.7 这一整套约束——这条路径上,缺 provider 就是真的走不下去,而不是自动降一档凑合出片。答案是「靠我手里那批素材」,那是 source_led,下限 0.3,允许静图补空。答案是「把一件事讲明白」,那多半落在 teacher_explainer 或 data_explainer,下限 0.0,规则明写清晰高于奇观。
选错承诺类型的代价是双向的:选高了,卡在闸口出不来;选低了,系统不会拦你,因为规则层面它没有被违反。这套机制能保证的是「不悄悄降级」,不是「替你判断你想要什么」。
需要说明的边界:以上全部是 lib/delivery_promise.py 与 README 的文本口径,我们没有安装或运行过这套系统,也没有跑过任何一次校验,实际行为以你本地跑出来的为准。
本文依据 OpenMontage 官方仓库(github.com/calesthio/OpenMontage)的 README、
AGENT_GUIDE.md、config.yaml、pipeline_defs/ 与 lib/ 下的治理模块整理,核对日 2026-08-09。
本文内容为仓库源码与文档口径,我们没有安装或运行过该系统,也没有调用过其中任何一个 provider API,
文中出现的成本数字均为项目方在 README 中自行标注的金额,非我们的实测结果。
该项目以 AGPL-3.0 发布,部分流水线在 manifest 中自标 stability: beta,请以仓库最新内容为准。