把 X2.0 接进内容生产流程时,判断某个环节能不能“边看边改”,不看模型响应快不快,而是看两件事:这个环节的产出物是否要等下游消费,改动会不会让已经生成的素材失效。同一类环节里,改参数的往往能实时回写,改结构的通常只能重跑。因此先列环节清单、再定可变性,比先接接口更重要;本文给出的分类需要结合你自己的流程图调整,不能直接照搬。
先按分镜、画面、文案、剪辑四类把现有流程拆开,标注每类的人工操作与产出物;再用“是否需要连续反馈、改动是否影响上下游”两个维度判定可实时改还是只能重跑。可实时改的环节用 session_id + shot_id + base_rev 做局部回写,失败时保留上一版产出、只给下游打失效标记,不自动重生成。判断是否成立,跑一次完整流程看日志里实际回写的环节与分类表是否一致。
把现有流程拆成分镜、画面、文案、剪辑四类环节
拆环节的目的不是画流程图好看,而是让每个环节都有明确的产出物,后面才谈得上判断“改这个产出物要不要整体重来”。建议按四类拆,并在每一类后面写上当前由谁完成——同一个环节换人做,可变性判断可能就变了。
- 分镜:人工把脚本拆成镜头列表,标注景别、时长、顺序、画面描述。产出物是分镜表(结构化字段或表格)。当前一般由编导或策划完成。
- 画面:按分镜生成或挑选素材,产出单个镜头的视频片段或关键帧序列。当前一般由剪辑或生成工具执行。
- 文案:口播稿、字幕文本、标题、封面文案,产出物是文本字段。当前一般由文案或运营完成。
- 剪辑:拼接、配乐、字幕对齐、转场,产出物是成片时间线与渲染结果。当前一般由剪辑完成。
拆完先做一件事:在每个环节旁边写一句“这个产出物被谁消费”。分镜被画面消费,画面和文案被剪辑消费,剪辑只被发布消费。这句话决定了后面改动的影响半径。
给每个环节标注“可实时改”还是“只能重跑”
判定用两个问题:这一环节人是否需要连续反馈(改一版立刻看到效果再改下一版),以及这次改动是否波及已生成的下游产出物。需要连续反馈且不动下游的,归为可实时改;改的是结构、数量、风格、素材来源的,归为只能重跑。两个问题冲突时,以影响下游为准——宁可重跑,不要把一个失效的片段留在时间线里。
| 环节 | 典型改动 | 需连续反馈 | 影响下游 | 判定 |
|---|---|---|---|---|
| 分镜 | 单镜头时长、顺序微调 | 是 | 否(局部) | 可实时改 |
| 分镜 | 增删镜头、改变叙事结构 | 是 | 是 | 只能重跑 |
| 画面 | 单镜头重生成、换一帧 | 是 | 否(同 shot_id 内) | 可实时改 |
| 画面 | 换风格、改分辨率、换素材来源 | 否 | 是 | 只能重跑 |
| 文案 | 口播、字幕、标题改写 | 是 | 否(仅字幕重新对齐) | 可实时改 |
| 剪辑 | 入出点、音量、字幕时间微调 | 是 | 否 | 可实时改 |
| 剪辑 | 片段顺序调整、整体替换素材 | 否 | 是 | 只能重跑 |
这张表是接入前必须和实际操作的人对一遍的。常见分歧在于“画面换风格”算不算实时改:如果你们的画面环节是一镜一镜生成的,换风格会让所有镜头全部失效,那就是重跑;如果只是套一层统一滤镜,可以另开一个后处理节点,那才有实时改的空间。
在可实时改的环节定义输入与回写字段
字段约定先于接口实现。输入侧至少要能定位到“哪一次会话、哪个环节、哪个镜头、基于哪一版”,回写侧要能告诉调用方“这次改动生效了没有、哪些下游被标脏”。字段名可以先占位,接入时按你们的实际命名替换。
{
"input_fields": [
"session_id",
"stage",
"shot_id",
"patch_type",
"base_rev",
"payload",
"idempotency_key"
],
"writeback_fields": [
"rev",
"applied",
"rejected_reason",
"downstream_invalidated",
"artifact_ref",
"updated_at"
],
"on_failure": "keep_prev_artifact"
}
- base_rev 是并发保护:调用方带的是它看到的版本,服务端版本对不上就拒绝,不要静默覆盖。
- downstream_invalidated 只做标记、不触发重生成,让下游环节自己决定何时重跑,避免一次微调引起连锁生成。
- 失败保留策略:回写失败或校验不过时,artifact_ref 仍指向上一版可用产出,前端继续展示旧版本并给出提示;不要清空,否则流程会停在一个没有产出的状态。
写一段最小接入骨架把实时环节串起来
骨架只做一件事:把实时环节的改动送进去,把判定结果带回来。地址用占位,替换成你们的服务端即可。
POST {{X2_BASE_URL}}/v2/pipeline/patch
Content-Type: application/json
{
"session_id": "sess_demo_001",
"stage": "copy",
"shot_id": "sh_003",
"patch_type": "text_replace",
"base_rev": 12,
"payload": { "field": "voiceover", "value": "替换后的口播文本" },
"idempotency_key": "sess_demo_001-sh_003-12"
}
-- 期望回写
{
"rev": 13,
"applied": true,
"rejected_reason": null,
"downstream_invalidated": ["subtitle:sh_003"],
"artifact_ref": "ref://demo/sess_demo_001/sh_003/r13"
}
串起来之后必须验一次,验证方式不是看页面好不好看,而是看日志:跑一条完整流程,从分镜到成片,中途对每个“可实时改”的环节各发一次补丁,对每个“只能重跑”的环节也故意发一次。然后检查日志里 stage、applied、rejected_reason 三个字段——可实时改的环节应出现 applied=true,只能重跑的环节应出现拒绝或直接没有对应接口被调用。
grep -E 'stage=|applied=|rejected_reason=' pipeline.log | sort
如果日志显示的边界和分类表对不上,通常是三种情况:某环节被标成实时改,但实际会清掉下游产出;某环节被标成重跑,其实只改了一个不影响下游的字段;或者 base_rev 一直对不上,说明前端拿的是缓存版本。前两种回表调整分类,第三种先修版本传递,再谈接入。这条流程建议在隔离环境先跑通,再接到真实生产内容上。