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、時間花在哪 |