README.md 6.6 KB

Video Production Build Agents

项目有两条职责分离、分别持久化的正式 LangGraph:

Global Data 0.3
preprocess
→ plan_global_data
→ prepare_next_task
→ execute_task
→ validate_task
   ├─ PASS → prepare_next_task
   └─ FAIL → replan_global_data → prepare_next_task
→ validate_global_data_stage
   ├─ PASS → finalize_global_data
   └─ FAIL → replan_global_data → prepare_next_task
→ finalize_global_data
→ COMPLETED

Production 0.6
prepare_inputs
→ Production Planner
→ materialize_production_plan
→ prepare_next_segment
→ Segment Executor
→ Segment Validator
   ├─ PASS → prepare_next_segment
   └─ FAIL → Production Replan → Production Planner
→ Assembly → Readiness → Production Validator
   ├─ PASS → Final ProductionDelivery
   └─ FAIL → Production Replan → Production Planner

Planner 自由决定 Global Data DAG 的任务数量和内容;运行时按 priority → task_id 串行选择 ready Task。通用 Executor 按 skill_id 加载唯一 Skill 和工具白名单,独立 Validator 按执行能力和交付类型选择验证 Skill。只有 Validator PASS 的 Task 才会解锁依赖。全部 Task PASS 后,独立的 Stage Validator 还会检查 Requirement 满足情况、Planner 漏项、Artifact 可用性和 跨 Task 冲突;任一层 FAIL 时 Planner 输出完整下一版 DAG,最多 Replan 5 次。

Global Data 协议为 0.3。身份链固定为 SourceAsset → ArtifactExpectation → ArtifactExpectationBinding → RequirementEvaluation: 只有 PASS Delivery 中显式落盘的 Artifact Binding 才能满足 Expectation,未绑定的 Artifact 只作为辅助产物。协议决策见 docs/adr/0001-source-asset-expectation-binding.md

完整 Plan 历史、TaskPackage、ExecutorDelivery、ValidationReport、工具调用 账本和阶段 Delivery 均按 Run 落盘。LangGraph State 只保存调度状态和业务文件路径, 不保存完整制作表、完整媒体或 Agent 消息历史。Agent 自身的恢复消息单独保存在 内层 checkpoint,不会传给下一个 Task。

Production 使用独立 0.6 协议。真实 Production Planner 只读 ProductionBrief、GlobalDataStageDelivery 和无损 ProductionInputCatalog,输出 Segment 数据 DAG;代码负责 DAG 合法性、READY、EXECUTE/REUSE、验收 verdict 和 返工授权范围,LangGraph 只推进节点、恢复和预算。Production 源码只实现当前 0.6 合同;旧协议或混合协议 Run 会在任何新写入前 fail closed,不会自动迁移或 继续执行。

正式 Artifact 必须是当前 Run 可复验的本地文件,并保存 content_sha256size_bytes;工具返回的远程 URL 只作为 Candidate 输入和 source_uri 来源记录, 不能直接成为正式 Artifact.uri。共享业务 Capability 定义位于 production_build_agents/capabilities.py,不归属于某个 Agent 角色。

环境要求

  • Python 3.12
  • uv
  • ffmpegffprobe:视频裁剪、拼接、贴音频和抽帧需要

安装 Python 依赖:

uv sync

.env.example 复制为 .env,配置 Planner、Executor、Validator 和需要 使用的远程工具。 工具目录、使用边界和 Skill 授权关系见 production_build_agents/tools/README.md

运行

Global Data:

uv run python run_global_data.py \
  "容易内耗的人其实需要停止悲伤者叙事#自我(690788)_production_final.json" \
  --output-dir demo_output \
  --thread-id global-data-live

Production 0.6:

uv run python run_production.py \
  demo_output/global-data-live/global_data_stage_delivery.json \
  --output-dir demo_output \
  --thread-id production-live \
  --shared-visual-anchor /absolute/path/to/sealed-anchor.png \
  --max-replans 2

共享视觉锚点是 Production 外部已经封印的输入;本阶段不在 Global Data 内新增锚点 制作逻辑。Planner 没有任何媒体工具权限。每个 Ready Segment 的 Directive 按需落盘, PASS 后立即封印 AcceptedSegmentRef;整片 FAIL 只能按结构化失败范围解封相关 Segment,其他 PASS Segment 强制复用。

每个 thread-id 使用独立 Run 目录、外层 checkpoints.sqlite、内层 agent_checkpoints.sqlite 和文件锁。未完成 Run 用同一命令启动时既能从业务 节点恢复,也能从 Planner / Executor / Validator 尚未结束的模型—工具循环恢复; 已经成功或失败的 Run 不会重新执行。 同一版本业务文件采用 write-once:内容相同直接复用,内容不同立即报版本冲突。 仓库级 .run_registry 把 thread、输入路径与内容 hash、Run 目录稳定绑定,防止 同一个 thread 在另一输出目录被误用;它不是 checkpoint 或业务真相源。

有副作用的远程生成和本地媒体处理使用稳定调用账本。已成功调用会回放;请求 发出但结果未知时进入 TOOL_OUTCOME_UNKNOWN,不会自动重发。

成功终态为 COMPLETED,同时生成:

global_data_stage_delivery.json
run_summary.json
run_metrics.json

run_metrics.json 是可变的运行观测投影,记录各节点耗时、Agent 模型名称与 token、 工具调用/回放、Replan 原因,以及服务明确返回的费用。若服务不返回费用则 cost_status=unavailable,Runtime 不按猜测价格计算。它不是业务合同或终态真相源。

失败终态不会进入人工节点。Production 中只有正式 SegmentValidationReport FAIL 或 ProductionValidationReport FAIL 可以进入 Replan;OUTCOME_UNKNOWN、Readiness 技术失败、合同错误、篡改和身份漂移全部 fail closed。

v18 脱敏协议回放不调用模型或媒体服务:

uv run python -m unittest tests.test_v18_replay -v

8 个 Global Data 0.3 离线 Eval(含远程 URL 内容替换对抗案例):

uv run python evals/global_data/run.py

LangSmith Studio(开发调试)

根目录的 langgraph.json 让 LangGraph Agent Server / LangSmith Studio 加载 production_build_agents/app.py:graphexamples/studio_input.json 是对应的调试输入示例。该入口只用于观察节点、状态和提示词,不包含正式 Run 的 registry、输入身份绑定、文件锁与终态业务文件重验。

Global Data 的正式 Run 使用 run_global_data.py;Production 的正式 Run 使用 run_production.py。两者当前都保持串行:Global Data 按 priority → task_id 选择 ready Task,Production 按依赖和 priority → Plan 顺序 选择 ready Segment;Plan 可以表达 DAG,但本版本不并行执行。