English · 繁體中文 · 简体中文

# 架构 ReelMimic 由三层组成:**网站**(React)、**服务器**(Node,负责流程与派工)、**agent 工作区**(repo 根目录,Claude Code 或 Codex 在这里读 skill、写档、渲染)。 三层之间只通过**文件**沟通:agent 照 `CONTRACT.md` 写档,服务器用「该写的文件有没有更新」判断每一步是否完成,网站直接读这些文件画画面。 所以换 agent、加引擎、改前端都不需要动到其他层。 ``` 浏览器(app/web,React + Vite) │ REST + Server-Sent Events ▼ 服务器(app/server) ├─ index.ts HTTP API、上传、SSE、提供项目文件(/files/:id/*) ├─ env.ts 启动时加载 ~/.reelmimic/secrets.json ├─ jobs.ts 流程状态机 + 生产线调度(谁先谁后、平行几个、何时暂停) ├─ prompts.ts 每个步骤给 agent 的指令(改档后下一轮就生效,不用重启) └─ agents/index.ts agent 转接层:Claude Code / Codex → 统一事件 │ spawn(stdin 给指令,stdout 串流事件) ▼ agent 工作区(repo 根目录) ├─ .claude/skills/video-clone/ 内核 skill(流程、合约、风格表、工具) ├─ .claude/skills// 制作引擎 skill └─ projects// 这支视频的所有文件 ``` ## 1. 流程(一支视频的一生) ``` new → analyzing → styling → planning → plan_review ⇄ replanning │ 核准(required_inputs 都已提供或略过) ▼ producing ──→ needs_input(只有用户能给的东西 / 审查多轮未过) │ ▼ critiquing ⇄ revising → done ⇄(用户回馈)revising ``` | 阶段 | 谁做 | 必须写出的文件 | |---|---|---| | analyzing | `scripts/analyze.py`(不是 agent) | `analysis/report.json`、`sheet_1fps.jpg`、`sheet_scenes.jpg` | | styling | 导演 agent | `analysis/STYLE.md`、`analysis/route.json`(风格 → 制作引擎) | | planning | 导演写企划内核 → 每个角色一个 agent、素材一个 agent 同时做 → 导演集成并画定调画面 | `plan.json`、`STORYBOARD.md`(逐镜对照参考片、素材与授权、定调画面、required_inputs)、角色定义档草稿 | | replanning | 导演 agent | `plan.json`(依用户意见修改) | | producing | 生产线(见下节) | `build/production.json` … `out/video.mp4` | | critiquing | 独立评审(全新对话) | `out/check/critique.json` | | revising | 导演 agent | `out/video.mp4`、`out/check/fixes.json`(每项附修改前后截屏) | **完成的判准是文件**:`turn()` 记下必须文件的修改时间,agent 回合结束后检查它们有没有被更新;没有就停在 `error`,可以「重试这一步」。 服务器重启时,还标在工作中的项目会被标成「已中断」(`recoverOrphans`),重试会从目前的文件接着做。 ## 2. 生产线(核准之后) ``` setup(导演):共用素材、每个角色一个定义档、角色设置图、分段(build/production.json) │ ├──────────────── 角色关(与做镜头同时进行)────────────────┐ │ 每个角色:审查员(全新对话)⇄ 修正 agent,最多 3 轮 │ │ 要改共用骨架的项目 → 导演统一改 → 相关角色重审 │ │ 全部通过 → 并排检查(比例、交互) │ │ │ ├── 分段制作:最多 BUILDERS 个制作 agent 平行,每段 1–4 镜 │ │ 每做完一镜就写 .done.json → 立刻派一个镜头审查员(全新对话)│ │ 审查等角色关通过才开始 ←──────────────────────────────┘ │ → 没过的镜头交回同一个制作 agent 修正 → 只重审没过的镜头,最多 3 轮 │ → 需要改共用档:导演当场改(一次一个,只做加法),制作 agent 同一轮套用 ▼ assemble(导演):组装、混音、全片输出 ▼ 最后评审(全新对话):只看跨段的接缝、连戏、节奏、字幕一致;先核对之前每一个「已修正」 ⇄ 导演修改(最多 2 轮) ``` 设计重点: - **缺陷在哪产生就在哪拦**:角色在做镜头前审、每段做完立刻审,不堆到最后。 - **审查员永远是全新对话**:没有参与制作,不会替自己的作品辩护;制作 agent 则保留自己的对话,修正时记得细节。 - **两级问题**:`blocker`(正常观看就看得出来)才会退回;`polish`(要放大才看得到)记下来交给后面顺手处理。 - **修正要有证据**:每个「已修正」都附同一秒、同一位置的前后截屏,下一轮审查先核对。 - **needs_user**:歌词、自家角色设计图这类只有用户能给的东西不算缺陷,系统暂停请用户提供或略过,不会一直重修。 - **调度**:全域 agent 名额(`MAX_AGENTS`);审查与修正优先于新的制作,缺陷趁制作 agent 还记得细节时修掉。 - **引擎快照**:核准时把制作引擎 skill 拷贝到 `build/engine//`,之后改 skill 不会影响进行中的项目。 ## 3. 文件合约 完整格式在 `.claude/skills/video-clone/CONTRACT.md`,重点: ``` projects// job.json 服务器管理:阶段、session id、对话、事件纪录(最近 600 笔)、生产线状态 logs/events.jsonl 完整事件纪录(不截断) brief.md / inputs/ 用户的需求原文与上传的素材 analysis/ report.json、STYLE.md、route.json、lyrics/subs.lrc|json plan.json 前制企划(网站的主要画面) build/ 引擎项目:production.json、角色定义、每镜一个档、engine 快照 out/check/ cast/(设置图、审查、修正)、shots/(每段 done/review/fixes/shared、每镜截屏)、critique.json、fixes.json out/video.mp4 成片 ``` ## 4. Agent 转接层 `agents/index.ts` 把两种 CLI 统一成同一组事件:`session`、`text`、`thinking`、`tool`、`error`、`done`。 | | Claude Code | Codex | |---|---|---| | 指令 | `claude -p --output-format stream-json --verbose --permission-mode acceptEdits --allowedTools …` | `codex exec --json -c sandbox_mode=danger-full-access -c approval_policy=never (CODEX_SANDBOX) …` | | 接续对话 | `--resume ` | `exec resume ` | | 指令传递 | stdin | stdin | 服务器记下每个角色的 session:导演一条(整支片共用,讨论有上下文)、每个制作 agent 各一条(跨修正轮保留)、审查员每次都是新的。 ## 5. 网站 - `App.tsx`:首页(输入卡片、项目列表)、路由、语言菜单。 - `Project.tsx`:项目页,分页为成品/生产线/企划/参考片拆解;暂停卡、错误卡、必要素材与歌词对时、视频时间点留言。 - `Chat.tsx`:对话与「思考」:把 `job.chat` 与事件纪录合并,工作中的 agent 显示成即时卡片(白话步骤、计时、看过的影格缩略图),完成的回复收成「思考了 N 秒 · M 个步骤」;另有原始纪录分页。 - `i18n.ts`:界面语言(繁體中文为原文、English 对照表、简体中文由 OpenCC 转换)。 - 即时更新:`GET /api/projects/:id/events`(SSE)。 ## 6. HTTP API | 方法 | 路径 | 用途 | |---|---|---| | GET | `/api/agents` | 侦测已安装的 agent CLI | | GET/POST | `/api/projects` | 列表/创建(multipart:reference 或 url、brief、agent、lang、inputs) | | GET | `/api/projects/:id` | 项目快照(网站需要的所有数据) | | POST | `/api/projects/:id/message` | 对导演说话(企划讨论、成片修改、暂停时的指示;附件放 `meta.attachments`) | | POST | `/api/projects/:id/approve` | 核准企划(有未提供的必要素材会回 409) | | POST | `/api/projects/:id/lyrics` | 贴歌词文本 → 自动对时 | | POST | `/api/projects/:id/inputs` · `/waive` | 补上传素材(`?to=attachments` 为对话附件)· 略过某项必要素材 | | POST | `/api/projects/:id/resume` · `/accept` · `/retry` · `/cancel` | 暂停后继续 · 接受目前结果 · 重试失败步骤 · 停止 | | GET | `/api/projects/:id/events` | SSE 事件流 | | GET | `/files/:id/*` | 项目内的文件(视频、截屏) | ## 7. 工具(`.claude/skills/video-clone/scripts/`) | 工具 | 用途 | |---|---| | `analyze.py` | 下载(yt-dlp)与量测参考片:镜头、节奏、BPM、配色、每秒一格总览 | | `compare.py` | 成片与参考片逐镜并排比较 | | `hf_frames.py` | HyperFrames 项目截屏:一次调用多个时间点、PIL 裁切、依内容缓存、全机并行上限 | | `fetch_assets.py` | 授权安全素材搜索与下载(Openverse、Pixabay、Freesound),自动写 ASSETS.md | | `align_lyrics.py` | 用户提供的歌词文本 × 音档 → 每句时间(faster-whisper 只当量尺) | | `yating_tts.py` | 雅婷台湾华语语音 | | `timeline.py` | 分析一支片的生产时间:每个阶段、每个 agent、时间花在哪 |