





















OpenMontage 自称"全球首个开源的 Agentic 视频制作系统",由 Cales Thio AI Labs 开发。它将 AI 编程助手(Claude Code、Cursor、Copilot、Windsurf、Codex)转化为一个完整的视频制作工作室——用户只需用自然语言描述需求,Agent 即可自动完成从主题研究、脚本撰写、素材生成、剪辑到最终渲染的全流程。与市面上仅能做"文字生成视频片段"的 AI 工具不同,OpenMontage 强调的是"从创意到成片"的完整流水线 [1]。
| 项目 | 详情 |
|---|---|
| 项目名称 | OpenMontage |
| 项目地址 | https://github.com/calesthio/OpenMontage |
| 项目官网 | 暂无独立官网;官方 YouTube 频道 @OpenMontage;X 账号 @calesthioailabs |
| 作者 | calesthio(Cales Thio AI Labs) |
| Stars | 7,000+(截至 2026 年 6 月) |
| 当前版本 | v0.1.0 |
| 开源协议 | AGPL-3.0 |
| 主要语言 | Python(核心工具链)、TypeScript/React(Remotion 合成引擎)、HTML/CSS/GSAP(HyperFrames 合成引擎)、YAML/JSON(流水线定义) |
| 首次发布 | 2026 年 3 月 29 日 |
| 提交数 | 103 次 Commits |
README 中展示了 6 个成品视频示例,充分体现系统能力 [2]:
| 示例视频 | 类型 | 技术栈 | 成本 |
|---|---|---|---|
| "SIGNAL FROM TOMORROW" | 科幻电影预告片 | Veo 视频生成 + Remotion 合成 | — |
| "THE LAST BANANA" | 60 秒皮克斯风格动画 | 多工具链 | $1.33 |
| "VOID — Neural Interface" | 产品广告 | 仅 OpenAI API Key | $0.69 |
| "Afternoon in Candyland" | 吉卜力风格动画 | 12 张 FLUX 图片 + Remotion 动画 | $0.15 |
| "Mori no Seishin" | 吉卜力风格森林精灵 | 12 张 FLUX 图片 | $0.15 |
| "Into the Abyss" | 深海探索动画 | 零视频生成 API | $0.15 |
项目根目录提供 diagram.png 架构示意图。
AI Agent 是整个系统的"大脑",Python 仅作为工具和持久化层。所有编排、创意决策、审查、阶段转换逻辑都存在于 YAML 流水线清单和 Markdown 技能文件中,而非硬编码在 Python 代码中 [3]。架构模式为:
Agent 读取流水线清单(YAML) → 读取阶段导演技能(MD) → 使用工具(Python BaseTool) → 自我审查(meta skill) → 检查点(Python) → 提交人工审批
| 层级 | 位置 | 职责 |
|---|---|---|
| Layer 1 | tools/tool_registry.py |
工具注册中心,回答"有哪些工具、能做什么" |
| Layer 2 | skills/ |
项目级使用约定,回答"OpenMontage 如何使用这些工具" |
| Layer 3 | .agents/skills/ |
通用 API 知识(47 个已安装技能),回答"技术本身如何工作" |
涵盖动画讲解、纪录片蒙太奇、电影预告片、屏幕演示、播客重制、角色动画、虚拟形象、本地化配音等多种场景,每条流水线包含 8 个标准阶段(研究→脚本→视觉规划→素材生成→剪辑→音效→合成→渲染)。
自动在 Remotion(React 声明式渲染)和 HyperFrames(HTML/CSS/GSAP 动画渲染)之间选择,根据视频类型智能匹配最佳渲染引擎。
| 免费资源 | 说明 |
|---|---|
| Piper TTS | 免费离线语音合成 |
| Archive.org / NASA / Wikimedia Commons | 免费素材源 |
| Pexels / Pixabay / Unsplash | 免费图片/视频素材 |
| Remotion / HyperFrames | 开源合成引擎 |
无需任何付费 API 即可产出完整视频,最低成本 $0.00。
每次工具选择(Provider Selection)在 7 个维度上打分(质量、速度、成本、稳定性、适配度、许可合规、可用性),生成可审计的决策日志。
| 对比维度 | OpenMontage | 传统 AI 视频工具(Runway, Pika) |
|---|---|---|
| 工作范围 | 完整流水线(研究→脚本→素材→剪辑→合成) | 单一环节(文生视频片段) |
| 操作方式 | 自然语言对话式,Agent 自主执行 | 手动操作或单个 Prompt |
| 开源 | 完全开源(AGPL-3.0) | 闭源商业服务 |
| 成本 | 最低 $0.00 | 按量付费或订阅 |
| 素材来源 | 真实视频素材 + AI 生成 + 免费素材库 | 仅 AI 生成 |
| 可扩展性 | 可自定义流水线、工具、技能 | 封闭 |
| 级别 | 要求 |
|---|---|
| 最低(免费路径) | CPU 即可,无需 GPU |
| 推荐 | 4 核 CPU,8GB RAM |
| GPU 加速(本地视频生成) | NVIDIA GPU,推荐 VRAM >= 8GB,支持模型:WAN 2.1-1.3B / 14B、Hunyuan 1.5、LTX-2、CogVideo 5B |
| 平台 | 支持状态 | 备注 |
|---|---|---|
| macOS | 完整支持 | brew install ffmpeg |
| Linux | 完整支持 | sudo apt install ffmpeg |
| Windows | 部分兼容 | npm install 可能需 npx --yes npm install,HyperFrames 运行时可能有兼容问题 |
| 依赖项 | 版本要求 | 说明 |
|---|---|---|
| Python | 3.10+ | 核心运行时 |
| FFmpeg | 最新稳定版 | 视频编码、混音、字幕烧录 |
| Node.js | 18+ | Remotion 和 HyperFrames 合成引擎 |
| AI 编程助手 | Claude Code / Cursor / Copilot / Windsurf / Codex | 作为 Agent 驱动整个系统 |
Python 核心依赖(requirements.txt):PyYAML >= 6.0、Pydantic >= 2.0、jsonschema >= 4.20、python-dotenv >= 1.0、Pillow >= 10.0、requests >= 2.31。
GPU 额外依赖(requirements-gpu.txt):diffusers、transformers、accelerate。
# 1. 克隆仓库
git clone https://github.com/calesthio/OpenMontage.git
cd OpenMontage
# 2. 一键安装(推荐)
make setup
# 3. 无 make 时手动安装
pip install -r requirements.txt
cd remotion-composer && npm install && cd ..
pip install piper-tts
cp .env.example .env
# 4. 可选:GPU 加速
make install-gpu
# 在 .env 中添加 VIDEO_GEN_LOCAL_ENABLED=true 和 VIDEO_GEN_LOCAL_MODEL=wan2.1-1.3b
# 5. 可选:配置 API Key(按需编辑 .env 文件)
OpenMontage/
├── README.md # 项目说明
├── AGENT_GUIDE.md # Agent 操作指南(核心合同)
├── PROJECT_CONTEXT.md # 项目架构与约定
├── config.yaml # 全局配置
├── setup.py # Python 包入口(v0.1.0)
├── Makefile # 构建与安装脚本
├── diagram.png # 架构示意图
├── .env.example # 环境变量模板
├── requirements.txt # 核心依赖
├── requirements-gpu.txt # GPU 依赖
│
├── tools/ # Layer 1:工具层(Python 实现)
│ ├── base_tool.py # 工具基类(ToolContract)
│ ├── tool_registry.py # 工具注册中心(自动发现)
│ ├── cost_tracker.py # 成本追踪与预算管控
│ ├── video/ # 视频相关工具
│ │ ├── video_compose.py # 合成引擎路由(Remotion/HyperFrames/FFmpeg)
│ │ ├── video_stitch.py # 多片段拼接
│ │ └── hyperframes_compose.py # HyperFrames 运行时
│ ├── audio/ # 音频工具(TTS、混音)
│ ├── image/ # 图像生成工具
│ ├── avatar/ # 虚拟形象工具
│ ├── character/ # 角色动画工具
│ ├── subtitle/ # 字幕工具
│ ├── analysis/ # 分析工具(视频分析、转写)
│ ├── enhancement/ # 增强工具
│ └── graphics/ # 图形工具
│
├── pipeline_defs/ # 流水线定义(YAML 清单)
│ ├── animated-explainer.yaml # 动画讲解
│ ├── animation.yaml # 动画
│ ├── cinematic.yaml # 电影预告片
│ ├── documentary-montage.yaml # 纪录片蒙太奇
│ ├── hybrid.yaml # 混合
│ ├── clip-factory.yaml # 片段工厂
│ ├── podcast-repurpose.yaml # 播客重制
│ ├── screen-demo.yaml # 屏幕演示
│ ├── talking-head.yaml # 对话头像
│ ├── avatar-spokesperson.yaml # 虚拟形象
│ ├── character-animation.yaml # 角色动画
│ ├── localization-dub.yaml # 本地化配音
│ └── framework-smoke.yaml # 测试流水线
│
├── skills/ # Layer 2:技能层(Markdown 指令)
│ ├── INDEX.md # 技能索引
│ ├── core/ # 核心技能(FFmpeg、Remotion、HyperFrames 等)
│ ├── creative/ # 创意技能(视频编辑、数据可视化、音效等)
│ ├── meta/ # 元技能(审查器、检查点协议、技能创建器等)
│ └── pipelines/ # 流水线阶段导演技能
│ ├── explainer/ # 讲解流水线(9 个阶段技能)
│ ├── talking-head/ # 对话头像流水线
│ ├── screen-demo/ # 屏幕演示流水线
│ ├── clip-factory/ # 片段工厂流水线
│ ├── podcast-repurpose/ # 播客重制流水线
│ └── character-animation/ # 角色动画流水线
│
├── .agents/skills/ # Layer 3:通用 API 知识(47 个技能)
│
├── lib/ # 核心库
│ ├── checkpoint.py # 检查点读写与验证
│ ├── pipeline_loader.py # 流水线清单加载器
│ ├── config_model.py # 运行时配置(Pydantic)
│ ├── media_profiles.py # 平台渲染配置
│ ├── hyperframes_style_bridge.py # 样式桥接
│ └── scoring.py # 决策评分引擎
│
├── schemas/ # JSON Schema 定义
│ ├── artifacts/ # 产出物 Schema
│ ├── pipelines/ # 流水线清单 Schema
│ ├── checkpoints/ # 检查点 Schema
│ ├── styles/ # 样式 Playbook Schema
│ └── tools/ # 工具 I/O Schema
│
├── styles/ # 样式 Playbook(YAML)
│ └── playbook_loader.py # Playbook 加载器与验证器
│
├── remotion-composer/ # Remotion 合成引擎(React/TypeScript)
│ └── src/components/ # 8 个 Remotion 组件(TextCard, StatCard 等)
│
├── docs/ # 文档
│ ├── PROVIDERS.md # 供应商指南(详细定价与配置)
│ └── ARCHITECTURE.md # 架构深度解析
│
├── tests/ # 测试
│ ├── contracts/ # 合约测试
│ └── qa/ # 质量验证脚本
│
├── projects/ # 项目工作区(gitignored,运行时生成)
│ └── <project-name>/
│ ├── artifacts/ # 各阶段产出物(JSON)
│ ├── assets/ # 素材(图片、视频、音频、字幕)
│ └── renders/ # 最终渲染视频
│
└── music_library/ # 用户音乐库(gitignored)
tools/tool_registry.py)自动发现并注册所有 tools/ 目录下的 BaseTool 子类,提供 discover()、support_envelope()、provider_menu()、provider_menu_summary() 等查询方法。支持按能力(capability)、供应商(provider)、状态(status)、稳定性(stability)筛选工具,自动加载 .env 环境变量。
核心特性:
pkgutil.walk_packages 递归扫描 tools/ 下所有子包,自动导入并注册provider_menu_summary() 生成面向 Agent 的能力菜单,包含"已配置/未配置"比例、合成引擎可用性、一键修复建议tools/base_tool.py)定义 BaseTool 抽象基类,所有工具必须继承。声明完整的工具合约:名称、版本、能力、供应商、依赖、资源需求、重试策略、成本估算。定义 ToolResult 返回结构(success, data, artifacts, cost_usd, duration_seconds),自动检测依赖状态(ToolStatus.AVAILABLE / UNAVAILABLE / DEGRADED),支持 cmd:、env:、python: 三种依赖检测方式。
lib/pipeline_loader.py)从 pipeline_defs/ 加载 YAML 流水线清单,使用 JSON Schema 验证清单结构,提供阶段顺序提取、工具需求收集、扩展权限检查等功能。每条流水线定义 8 个标准阶段和对应的技能引用。
lib/checkpoint.py)每个流水线阶段完成后写入检查点(JSON),支持断点续传(get_next_stage() 自动找到下一步),关联决策日志(decision_log.json),确保所有决策可审计,Schema 验证检查点结构。
tools/cost_tracker.py)预算管控模块,实现 estimate → reserve → reconcile 三段式成本管理,支持 warn / cap 两种模式,单次操作审批阈值默认 $0.50。
tools/video/video_compose.py)根据视频类型自动选择合成引擎:
# tools/base_tool.py
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from enum import Enum
from typing import Any
class ToolTier(Enum):
CORE = "core"
EXTENDED = "extended"
COMMUNITY = "community"
class ToolStability(Enum):
STABLE = "stable"
BETA = "beta"
EXPERIMENTAL = "experimental"
class ToolStatus(Enum):
AVAILABLE = "available"
UNAVAILABLE = "unavailable"
DEGRADED = "degraded"
@dataclass
class ResourceProfile:
estimated_duration_seconds: int = 30
max_concurrent: int = 1
recommended_interval_seconds: float = 0.5
@dataclass
class ToolResult:
success: bool
data: dict[str, Any] = field(default_factory=dict)
artifacts: list[str] = field(default_factory=list)
cost_usd: float = 0.0
duration_seconds: float = 0.0
error: str | None = None
class BaseTool(ABC):
"""所有 OpenMontage 工具的抽象基类"""
name: str = ""
version: str = "0.1.0"
tier: ToolTier = ToolTier.CORE
stability: ToolStability = ToolStability.EXPERIMENTAL
capability: str = "generic"
provider: str = "openmontage"
dependencies: list[str] = [] # 如 ["env:FAL_KEY", "cmd:ffmpeg"]
install_instructions: str = ""
best_for: list[str] = []
not_good_for: list[str] = []
agent_skills: list[str] = [] # Layer 3 技能引用
resource_profile: ResourceProfile = ResourceProfile()
fallback_tools: list[str] = []
def get_status(self) -> ToolStatus:
try:
self.check_dependencies()
return ToolStatus.AVAILABLE
except DependencyError:
return ToolStatus.UNAVAILABLE
@abstractmethod
def execute(self, inputs: dict[str, Any]) -> ToolResult:
...
def get_info(self) -> dict[str, Any]:
"""返回完整工具合约,供注册中心发现"""
return {
"name": self.name,
"version": self.version,
"tier": self.tier.value,
"capability": self.capability,
"provider": self.provider,
"stability": self.stability.value,
"status": self.get_status().value,
"dependencies": self.dependencies,
"install_instructions": self.install_instructions,
"best_for": self.best_for,
"not_good_for": self.not_good_for,
"agent_skills": self.agent_skills,
"resource_profile": {
"estimated_duration_seconds": self.resource_profile.estimated_duration_seconds,
"max_concurrent": self.resource_profile.max_concurrent,
},
"fallback_tools": self.fallback_tools,
}
这是整个工具系统的基石。每个工具通过声明式属性定义合约,ToolRegistry.discover() 自动扫描注册,无需手动维护。
# tools/tool_registry.py
import importlib
import pkgutil
from pathlib import Path
class ToolRegistry:
def __init__(self):
self._tools: dict[str, BaseTool] = {}
def discover(self, package_name: str = "tools") -> list[str]:
"""递归导入包树并注册所有具体工具"""
self._load_dotenv()
package = importlib.import_module(package_name)
discovered: list[str] = []
package_paths = [str(Path(package.__file__).parent)]
for module_info in pkgutil.walk_packages(
package_paths, f"{package.__name__}."
):
if module_info.name.endswith(".base_tool"):
continue
module = importlib.import_module(module_info.name)
discovered.extend(self.register_module(module))
return discovered
def register_module(self, module) -> list[str]:
"""注册模块中所有 BaseTool 子类"""
registered = []
for attr_name in dir(module):
attr = getattr(module, attr_name)
if (isinstance(attr, type) and
issubclass(attr, BaseTool) and
attr is not BaseTool):
instance = attr()
self._tools[instance.name] = instance
registered.append(instance.name)
return registered
def provider_menu_summary(self) -> dict[str, Any]:
"""生成面向 Agent 的紧凑能力菜单"""
menu = self.provider_menu()
capabilities = []
for cap, bucket in menu.items():
available = bucket.get("available", [])
unavailable = bucket.get("unavailable", [])
capabilities.append({
"capability": cap,
"configured": len(available),
"total": len(available) + len(unavailable),
"providers": [e.get("provider") for e in available],
})
return {"capabilities": capabilities}
discover() 使用 pkgutil.walk_packages 递归扫描,自动导入并注册工具,无需手动维护工具列表。provider_menu_summary() 生成面向 Agent 的能力菜单,在预检阶段直接读取向用户展示。
# lib/checkpoint.py
import json
from datetime import datetime, timezone
from pathlib import Path
def write_checkpoint(
pipeline_dir: Path,
project_id: str,
stage: str,
status: str,
artifacts: dict,
pipeline_type: str = None,
) -> Path:
"""写入阶段检查点,支持断点续传"""
checkpoint = {
"version": "1.0",
"project_id": project_id,
"pipeline_type": pipeline_type,
"stage": stage,
"status": status,
"timestamp": datetime.now(timezone.utc).isoformat(),
"artifacts": artifacts,
}
# 合并决策日志
if "decision_log" in artifacts:
_merge_decision_log(pipeline_dir, project_id, artifacts["decision_log"])
validate_checkpoint(checkpoint)
path = _checkpoint_path(pipeline_dir, project_id, stage)
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w") as f:
json.dump(checkpoint, f, indent=2)
return path
def get_next_stage(
pipeline_dir: Path,
project_id: str,
pipeline_type: str = None,
) -> str | None:
"""通过比对已完成阶段和流水线阶段顺序,确定下一个待执行阶段"""
stages = get_pipeline_stages(pipeline_type)
completed = set(get_completed_stages(pipeline_dir, project_id, pipeline_type))
for stage in stages:
if stage not in completed:
return stage
return None
def _merge_decision_log(pipeline_dir: Path, project_id: str, new_entries: list):
"""累积合并决策日志,确保全流程可审计"""
log_path = pipeline_dir / project_id / "decision_log.json"
existing = []
if log_path.exists():
existing = json.loads(log_path.read_text())
existing.extend(new_entries)
log_path.parent.mkdir(parents=True, exist_ok=True)
log_path.write_text(json.dumps(existing, indent=2))
检查点系统是流水线状态持久化的核心。每个阶段完成后写入 JSON 检查点,get_next_stage() 自动确定下一个待执行阶段,决策日志通过 _merge_decision_log() 累积合并,实现全流程可审计。
# tools/cost_tracker.py
from dataclasses import dataclass, field
from enum import Enum
class BudgetMode(Enum):
WARN = "warn" # 超预算时警告但继续
CAP = "cap" # 超预算时停止
@dataclass
class CostTracker:
budget_usd: float = 5.0
mode: BudgetMode = BudgetMode.WARN
approval_threshold_usd: float = 0.50 # 单次操作审批阈值
_reserved: float = 0.0
_spent: float = 0.0
_log: list[dict] = field(default_factory=list)
def estimate(self, operation: str, estimated_cost: float) -> bool:
"""预估操作成本,检查是否在预算内"""
if estimated_cost > self.approval_threshold_usd:
# 需要人工审批
return False
if self._spent + self._reserved + estimated_cost > self.budget_usd:
if self.mode == BudgetMode.CAP:
raise BudgetExceededError(
f"预算 {self.budget_usd} 已超,操作 {operation} 需要 {estimated_cost}"
)
return True
def reserve(self, operation: str, amount: float):
self._reserved += amount
def reconcile(self, operation: str, actual_cost: float):
self._reserved -= actual_cost
self._spent += actual_cost
self._log.append({"operation": operation, "cost": actual_cost})
成本追踪器实现三段式成本管理(estimate → reserve → reconcile),支持 warn/cap 两种模式,单次操作超过 $0.50 需人工审批。
| 场景 | 对应流水线 | 典型用途 |
|---|---|---|
| 教育内容 | animated-explainer |
科普讲解、在线课程、知识短视频 |
| 社交媒体 | animation、clip-factory |
TikTok/Reels/Shorts 短视频批量生产 |
| 品牌营销 | cinematic、avatar-spokesperson |
品牌宣传片、产品发布预告、虚拟代言人 |
| 纪录片/散文 | documentary-montage |
视频散文、怀旧蒙太奇、城市意象 |
| 软件演示 | screen-demo |
产品演示、代码教程、软件操作指南 |
| 内容重制 | podcast-repurpose、clip-factory |
播客转视频、长内容拆解为短视频 |
| 多语言分发 | localization-dub |
字幕翻译、配音、本地化 |
| 角色动画 | character-animation |
卡通角色动画、故事短片 |
| 混合创作 | hybrid |
实拍素材 + AI 生成视觉增强 |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。