OpenMontage Backlot 活故事板实战指南:用python -m backlot open一条命令打开流水线实时制片面板
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
Backlot 是 OpenMontage 中面向 Agent 流水线的只读式"活故事板"(living storyboard):它以本地 Web 服务器观察projects/目录,把流水线阶段、剧本、场景计划与已生成的资产实时渲染成浏览器面板。读完本文,你将掌握python -m backlot open <project-id>的完整用法与幂等设计,理解看板如何从磁盘文件推导全部状态(观察而非上报),并能用模拟运行脚本在无真实制片的情况下体验 Live 更新。
Backlot 是什么:给 12 条生产流水线配的"观察窗口"
在 OpenMontage 中,一条制片流水线由 12 个生产管线(pipeline_defs/*.yaml)驱动,Agent 依次执行 research → script → assets → compose → publish 等阶段。Backlot 的定位不是"汇报工具",而是一面只读的镜子——正如 backlot/init.py 开宗明义:
A read-only, disk-derived production board for OpenMontage. A small local web server watches
projects/and renders each production's pipeline stages, script, scene plan, generated assets, decisions, cost, and activity — live.
它的设计契约只有三条:
- 观察,而非上报(Observation, not reporting):面板的所有状态都派生自流水线本来就会写入的磁盘文件,Agent 绝不直接更新 UI;
- 永不阻塞、永不崩溃(Never block, never break):状态缺失或损坏时优雅降级;
- Agent 的唯一职责:流水线初始化时执行一次
python -m backlot open <project>。
这意味着 Backlot 可以复用于任意管线类型:只要项目目录里存在project.json、checkpoint_*.json、artifacts/*.json、events.jsonl等标准产物,面板就能自动渲染;尚未落盘的阶段则退化为"watcher 看到什么就展示什么"的视图(媒体、快照、渲染输出)。
命令详解:python -m backlot open的三种形态
Agent 提示(.codex/prompts/backlot.md)规定的用法,也是 backlot/main.py 的实现:
# 打开指定项目的看板(server 未启动则先启动,再在浏览器打开) python -m backlot open <project-id> # 不带项目 id → 打开库视图(列出所有项目) python -m backlot open # 前台运行服务器(默认端口 4750) python -m backlot serve --port 4750幂等启动:健康检查 → 后台拉起 → 打开浏览器
cmd_open的执行路径(backlot/main.py):
- 读取端口:优先取环境变量
BACKLOT_PORT,否则使用默认值DEFAULT_PORT = 4750(定义于 backlot/init.py); - 探测
http://127.0.0.1:<port>/api/health,超时 1.5 秒,返回 200 视为存活; - 若未存活,以分离的后台进程方式拉起
python -m backlot serve --port <port>(stdin/stdout/stderr 全部重定向到 DEVNULL,POSIX 下start_new_session=True,Windows 下使用CREATE_NEW_PROCESS_GROUP); - 最多轮询 15 秒等待 server 就绪;
- 打开浏览器:有项目 id 访问
http://127.0.0.1:<port>/p/<project-id>,否则访问根路径(库视图)。
两次调用不会拉起两个服务器:第二次执行时健康检查命中,直接复用已有进程打开浏览器——这就是提示中强调的Idempotent(幂等)。serve子命令则通过 uvicorn 前台运行backlot.server:app。
失败契约:看板是观察者,绝不是阻塞器
open在两种情况下会打印提示并以状态码 1 返回,但不会抛出异常打断流水线:
- 服务器拉起失败:
backlot: could not start server (...) — continuing without the board; - 15 秒内未就绪:
backlot: server did not come up in time — continuing without the board。
正如提示原文所写:"If it fails, report and continue — the board is an observer, never a blocker." 这一"尽力而为"的语义与 backlot/init.py 中的模块 docstring 完全一致,是 Agent 集成时最需要记住的边界。
架构与数据流:watchfiles + SSE,浏览器自动刷新
Backlot 的实时性不依赖任何 Agent 参与。backlot/server.py 中_watch_projects后台任务用watchfiles的awatch递归监听PROJECTS_DIR,每 400ms 汇总一次变更;变更路径经_project_of_change映射到项目 id(纯字符串前缀匹配,避免渲染高峰期成千上万路径的逐文件系统调用),随后:
- 失效该项目的摘要缓存(
_invalidate_summary); - 通过
ChangeHub向该项目的 SSE 订阅者发布通知。
浏览器端(backlot/ui/board.js)订阅/api/project/{id}/events的 SSE 流,收到change事件后重新拉取/api/project/{id}/state并重绘。SSE 每 15 秒发送一次心跳(SSE_HEARTBEAT_SECONDS = 15)保持连接;ChangeHub的队列按项目过滤,一个项目的事件突发不会冲垮另一个项目的订阅队列。
看板元素与磁盘数据源的对应关系
backlot/README.md 给出了完整的映射表,这也是理解 BoardState 结构的核心:
| 看板元素 | 磁盘数据源 |
|---|---|
| 项目身份 / 阶段顺序 | project.json+pipeline_defs/<type>.yaml |
| 阶段状态、关卡、版本 | checkpoint_<stage>.json+history/ |
| 剧本卡片 / 弹窗 | artifacts/script.json |
| 胶片条卡片 | scene_plan × script × asset_manifest三表 join |
| 生成中微光、活动日志 | events.jsonl(由BaseTool埋点写入) |
| 花费仪表 | checkpointcost_snapshot |
| 渲染输出 | renders/*.mp4(含项目根目录 mp4 启发式扫描) |
PROJECTS_DIR的定义在 lib/paths.py:默认为仓库根下的projects/,可通过环境变量OPENMONTAGE_PROJECTS_DIR覆盖(供 staging、截图与测试使用)——检查点写入、事件归属、Backlot 监听全都跟随这同一个根,保证"单一事实来源"。
只读与安全边界
服务器对项目目录从不写入。涉及文件的接口均做了路径逃逸校验:_safe_project_dir拒绝包含/、\、:的 project id(防止 Windows 盘符相对路径坍缩),并校验目录存在;/media/{project_id}/{path}与/thumb/{project_id}/{path}在解析后通过relative_to断言目标不越出项目目录,越界返回 403。
缩略图走_thumbnail_for(backlot/server.py):图片用 PIL 降采样,视频用ffmpeg -ss 1.5 -frames:v 1抽取首帧,统一输出为宽 320/640/960 三档的 JPEG,缓存于仓库根.backlot/thumbs/(缓存键含 mtime_ns 与 size,文件变更自动失效)。视频缩略图失败时不退回裸视频字节给<img>消费者,而是返回 404,避免浏览器解码整个 mp4。
BoardState:项目目录如何被推导为可渲染状态
backlot/state.py 的load_board_state(project_dir)是看板的"编译"入口,全程只读且防御式编程:任何 JSON 解析失败、产物缺失、半写检查点都只会降级,绝不让面板崩溃。
项目标记与管线元数据
project.json(marker)提供pipeline_type、title、style_playbook、created_at;缺失时回退读meta.json,再回退到检查点里携带的pipeline_type,最终回退到目录名;_load_pipeline_meta调用 lib/pipeline_loader.py 的load_pipeline读取pipeline_defs/<type>.yaml,提取每个阶段的名称、gated(由human_approval_default推导)与produces产物清单,并按lru_cache(maxsize=32)缓存;- 若清单不可知,回退到内置
FALLBACK_STAGES(research → proposal → idea → script → scene_plan → assets → edit → compose → publish)。
阶段轨道与关卡审计
每个阶段的当前状态来自checkpoint_<stage>.json(status/review/cost_snapshot/error/human_approved等字段),历史版本来自history/checkpoint_<stage>_N.json。_build_stage_rail还会做关卡审计(gate audit):一个gated: true的阶段若以completed收尾,却从未在历史或当前状态中出现过awaiting_human,也没有human_approved,就会被标记为gate_skipped: true——这是对 Agent"跳过审批"行为的可视化告警。清单未声明的阶段(遗留运行、管线不匹配)也会按其在FALLBACK_STAGES中的规范位置插入轨道,而不是悬挂在末尾。
故事板三表 join
_build_storyboard把scene_plan.json的场景列表 ×script.json的段落 ×asset_manifest.json的资产清单做 join:
- 场景与剧本段落按
script_section_id精确匹配,缺失时按start_seconds/end_seconds时间窗重叠度回退匹配,从而给每个场景卡补充 narration 文本; - 资产按
scene_id分组,分为 visual(image/video/diagram/animation)与 audio(audio/narration/music/sfx);只有真正存在且可缩略的栅格图/视频才算renderable(可展示的 take),.tsx类 bespoke 动画资产(atelier 合成)虽在磁盘上但不可缩略,会回退到snapshots/<scene_id>.png场景快照或保持占位; - "正在生成(generating)"状态由
events.jsonl顶层(depth=0)事件推导:最近的start未配对finish/error即视为生成中,并显示对应工具名。
资产路径解析支持三种实测形态:项目相对路径(assets/images/x.png)、仓库相对路径(projects/<id>/assets/images/x.png)、绝对路径;解析结果必须落在项目目录内才算可服务。
Live / Stalled 判定
live:距最近一次状态文件活动(checkpoint_*.json、events.jsonl、artifacts/*.json的最大 mtime)在LIVE_WINDOW_SECONDS = 5 * 60秒内;stalled:存在in_progress阶段且超过STALL_WINDOW_SECONDS = 10 * 60秒无任何文件系统活动——这是设计点 F-05:"卡死的 Agent 必须可见,而不是沉默",心跳检查点与工具事件都会重置计时。
花费仪表
cost优先取最新检查点的cost_snapshot,否则回退到asset_manifest.json的total_cost_usd,再否则为None(前端显示 0)。库视图的summarize_project则以轻量摘要(标题、活跃阶段、是否 awaiting_human、完成阶段数、渲染数、场景数、poster)供/api/projects批量返回,并按"live 优先、再按最近活动时间倒序"排序。
浏览器端界面:库视图与项目板
UI 是纯静态资源(backlot/ui/board.html 与 backlot/ui/index.html),通过 backlot/ui/board.js 与 backlot/ui/library.js 渲染,无任何后端模板耦合。
项目板顶部的状态徽章有四态,对应board.js的判定逻辑:
LIVE(绿点):s.live为真或有阶段in_progress;◈ AWAITING YOU:存在awaiting_human阶段——需要人工审批,这也是脚本关卡图的来源;⚠ STALLED?(红点):存在stalled阶段;IDLE · X MIN AGO:其余情况,附最近活动时间。
此外还包含:深色/浅色主题切换(存于localStorage的backlot.theme)、阶段轨道抽屉(点击阶段展开检查点详情)、决策与活动侧栏、以及REPLAY RUN——已完成运行的端到端回放,由检查点历史与事件时间戳重建。
服务器对/、/ui/*、/p/*统一注入Cache-Control: no-cache,保证长驻 SPA 每次刷新都能用 ETag 条件校验拿到最新 UI;媒体与缩略图则保持常规缓存策略,避免渲染产物反复回源。
无真实制片也能体验:模拟运行脚本
仓库提供了 scripts/backlot_simulate_run.py,用真实契约(init_project、in_progress检查点、awaiting_human关卡、工具事件、渐进写入的 artifacts)在磁盘上驱动一条假制片,让看板实时"活"起来:
python scripts/backlot_simulate_run.py # 完整演示(约 1 分钟) python scripts/backlot_simulate_run.py --fast # 等待压缩到 ~0.3s,供自动化验证 python scripts/backlot_simulate_run.py --cleanup # 结束清理项目目录 python -m backlot open backlot-demo-run脚本默认演示《The Last Lighthouse》四场景制片(sc1 灯塔黄昏 → sc4 守灯人爬上楼梯),逐阶段写检查点并在awaiting_human处停顿,期间可观察胶片条逐场景点亮、活动日志与费用不断刷新——这是理解"观察而非上报"的最佳实践入口。运行时请确认脚本依赖(watchfiles缺失时看板退化为手动刷新,ffmpeg缺失时视频缩略图返回 404,均不影响面板核心功能)。
质量保障:测试如何守住"永不阻塞"的底线
backlot/init.py 提到的设计文档(internal/design/LIVING_STORYBOARD.md,仓库内以设计注释形式存在于模块 docstring)由 tests/backlot/ 下的测试落实:
- tests/backlot/test_state.py:校验 BoardState 推导与优雅降级(坏 JSON、缺失产物、gate audit);
- tests/backlot/test_server.py:FastAPI 接口、路径逃逸拒绝(403)、媒体/缩略图路由;
- tests/backlot/test_gate_scenarios.py:关卡通过/跳过的多场景审计;
- tests/backlot/test_watch_captures.py 与 tests/backlot/test_visual_eval.py:watcher 捕获与视觉评估;
- tests/backlot/test_ui_bug_bash.py:前端 bug bash 回归。
与 Checkpoint Protocol 的协同:诚实的检查点喂养诚实的看板
Backlot 展示的阶段状态全部来自checkpoint_*.json,而检查点的写法由 skills/meta/checkpoint-protocol.md 规定:阶段完成并过审后,依据清单中checkpoint_required与human_approval_default的组合决定"写检查点并请求人工批准 / 写检查点并自动继续 / 跳过"。因此看板的真实性完全取决于检查点是否诚实——这正是 Agent 提示中"Keep checkpoints and artifacts honest"(保持检查点与产物诚实)的落点:不要让 UI 说谎,让每个awaiting_human、每个completed、每个gate_skipped都如实反映磁盘上发生过什么。
小结:Agent 集成 Backlot 的四个要点
- 初始化时调用一次
python -m backlot open <project-id>,幂等、失败仅报告不阻塞; - 绝不手动更新 UI:所有状态派生自
projects/<id>/磁盘文件,把注意力放在写对检查点、产物与事件上; - 合理利用实时语义:LIVE / AWAITING YOU / STALLED? 徽章对应 5 分钟活跃窗口与 10 分钟停滞窗口,可据此感知流水线健康度;
- 用
--fast模拟脚本做回归演示,无需真实制片即可验证看板的端到端实时链路。
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考