剪口播
從一條影片到一份人工複核過的刪詞帳本(Cuts + EDL),不碰媒體檔案。七步一線:
0 就緒 引用「檢查更新」的就緒檢查(本 Skill 不帶環境邏輯)
1 建檔 真實影片 → 雲端逐詞轉錄 → 產品建專案 → 起服務 → 讀回狀態
2 修字 詞典把字改對(通用一本 + 用戶一本)→ 出修字表
3 刪詞 讀偏好與規則 → 五輪掃描,每輪只找一類,只記行
4 彙總 刪詞彙總表 + 重複句子表 → 按表自讀校驗
5 審核 全量提交 → 兩張表呈給用戶 → 打開 Studio 親自複核
6 復盤交棒 對比提案與終版 → 歸檔三抽屜 → 報告四件事
不切媒體:帳本改一次是幾十毫秒,切一次是一個不可撤銷的檔案。到本 Skill 結束, 磁碟上沒有任何新影片。Skill 做語義判斷與編排;產品 Runtime 是專案、Cuts 和 Studio 狀態的唯一寫入者。
用戶只在三處說話:同源專案選繼續還是重來(僅剪過時)、Studio 複核、完成確認。 其餘一律單向彙報,不停下等回覆。每步的完成判據是它的產出物:沒出表,不算完成。
先讀取並執行 業務 Skill 的階段合同。 本文步驟與合同階段的對應:1=preflight+Product state readback,5=proposal+Product CAS, 審核=project-level review binding。合同後三個階段(確認、執行、驗收)屬於匯出 Skill。
各條規矩的事故來歷在 事故簿——規矩在正文,故事在那邊。
0. 就緒
先執行 檢查更新 的「就緒檢查」——skills 是否
最新、Runtime 是否配套;插件根也在那裡定位(本文命令裡的 <插件根> 都代入
那個字面路徑)。只有拿到「就緒」才繼續;「需新會話」或「停」都按它的處置執行
(含「禁止自製替代界面」禁令)。
若就緒結果為 runtime.kind=desktop-managed,它與 CLI 安裝共用同一穩定入口和
launchd/windows-task 服務,直接繼續;不要查找 Electron 安裝目錄、另裝 Bun /
FFmpeg,或啟動第二個 Runtime。
1. 建檔:真實輸入 → 轉錄 → 產品建專案
幹什麼:把用戶的本地真實影片和雲端逐詞稿交給產品,原子建檔,起服務,讀回狀態。
# 雲端逐詞轉錄(生成任務目錄內的 transcript 候選)之後:
node "<插件根>/scripts/videocut-cli.cjs" project create "<專案目錄>" --video "<任務目錄內的影片檔案>" --transcript "<任務目錄內的逐詞稿>" --json
node "<插件根>/scripts/ensure-running.cjs" --json # 產品聲明式確保常駐服務(5190)
node "<插件根>/scripts/videocut-cli.cjs" workflow get "<專案目錄>" --json # Product state readback
node "<插件根>/scripts/videocut-cli.cjs" cuts get "<專案目錄>" --json
規矩:
- 只接受用戶給出的真實口播影片或現有真實專案;沒有真實媒體就停止,禁止用範例、 佔位影片頂替
- 轉錄只用當前環境已獲准的雲端 ASR;禁止回退本地 ASR;沒有可用雲端 ASR 時報告
missing_cloud_transcription_adapter,不開 Studio、不偽造 transcript --video/--transcript必須是任務目錄內的真實檔案;畫幅比不要傳——產品會 從影片實際尺寸自動推導(Runtime 0.4.4+)。只有用戶明確要求特殊畫幅時才加--aspect-ratio W:H- 已有規範專案先
inspect確認並複用,不重複建立projectId;同一個影片剪過時 問用戶:繼續上次,還是重來(這是三個說話點之一)。project prepare是冪等 編譯器,只在恢復中斷或明確重新整理時用,中斷了直接重跑即可 project create是唯一入口:不經過素材庫、上傳會話或額外 Skill;Skill 不得先寫project.json- 服務必須由腳本確認
healthy=true、runtimeMode=launchd(macOS)或runtimeMode=windows-task(Windows)、版本相容、URL 為 canonical 5190 後才繼續;失敗透傳結構化錯誤並停止,禁止回退 foreground、換埠、 殺未知行程 - 兩份 readback 必須指向同一個
projectId,儲存 workflow stage 與 Project / Cuts / EditList 三個 revision;缺失或不一致即停止
2. 修字:把字改對,出修字表
幹什麼:在一切刪詞判斷之前用詞典修正轉錄聽錯的字——字不對,後面的判斷必錯; 聽錯的字不是多餘的話,刪詞修不掉它。
node "<插件根>/scripts/videocut-cli.cjs" transcript dictionary "<專案目錄>" --dictionary "<插件根>/references/ai-term-dictionary.md" --json
用你的檔案工具檢查 $HOME/.chengfeng-videocut/dictionary.md 是否存在;存在就再過一遍
(過渡做法:CLI 暫只收單檔案,分兩次跑;它只能補充、不能撤銷上一遍——完整的
用戶優先合併等多詞典 CLI 釋出):
node "<插件根>/scripts/videocut-cli.cjs" transcript dictionary "<專案目錄>" --dictionary "$HOME/.chengfeng-videocut/dictionary.md" --json
產出物:修字表——把兩次呼叫返回的 applied 清單合併成一張小表(原詞 → 改成 →
上下文),報給用戶。改完必須看這份表——詞典不看上下文也會改錯;看到不對就改
詞典,不在別處打補丁。
只有詞典解決不了、且作者手上有稿子時,才追加一次上下文對齊:
node "<插件根>/scripts/videocut-cli.cjs" transcript align "<專案目錄>" --script "<口播稿檔案>" --json # 只報不改
node "<插件根>/scripts/videocut-cli.cjs" transcript correct "<專案目錄>" --file "<修正檔案>" --json
規矩:
- 只改文字,不改時間、詞數、wordId——產品逐詞比對時間戳,動了直接拒絕
- 只換寫法,不換意思——真說錯又重說的屬於殘句改口,歸刪詞管
- 詞典沒有、稿子也確認不了的,不許猜:報告出來留給人補詞典。塞一個編的名字 比留一個聽錯的名字更壞
- 中文口語按原文保留:說「叉」「大模型」就是他說的話
- 詞典是每次轉錄都要過的一道閘(同一段音訊轉兩遍結果都不一樣,見事故簿)
文稿按標點分段:轉錄裡每個詞帶標點,文稿一個逗號一段、一句一行;字幕吃同一份
標點,兩邊斷句一致。2026-07-28 之前的舊專案沒有標點,跑
node "<插件根>/scripts/videocut-cli.cjs" transcript regroup "<專案目錄>" --json 重切段落即可(逐詞校驗 id/時間/文字
不變,對剪過的專案安全);真要標點得重轉——標點在舊轉錄裡根本不存在。
3. 刪詞:五輪掃描,每輪只找一類
幹什麼:讀材料,然後把播放順序完整讀五遍,每遍只帶一個判據。一次帶一個判據去讀, 判斷品質遠高於一次帶六個;每輪產出小、可檢查。
先讀材料:
node "<插件根>/scripts/videocut-cli.cjs" transcript playback "<專案目錄>" --json
再用你的讀檔案工具讀 $HOME/.chengfeng-videocut/cut-preferences.md(用戶偏好,
他說過的算數;檔案不存在就是新用戶,跳過)。
判據在 語義刪除規則(原則 + 判例)。 教材優先級:用戶偏好 > 用戶判例 > 通用判例。
第 1 輪 重複 句間重複、句內重複(最客觀:兩遍相同)
第 2 輪 殘句與改口 說一半斷掉、換個說法重說
第 3 輪 口誤重說 說錯的數字、專名、詞,後面重說對的
第 4 輪 英文卡殼 詞頭 / 字母 / 音節重複
第 5 輪 口頭禪與語氣詞 最主觀,按用戶偏好的密度與容忍度來
每輪動作固定:按本輪類型查判例 → 找到一處記一行(wordIds + 類型 + 風險)→ 不定奪別的類型。後面輪次遇到已標記的詞直接跳過,衝突留到彙總解決。
規矩:
- 判斷只用
transcript playback的播放順序,不許自己從transcript.json拼—— 「說了兩遍」靠播出來相鄰,自己拼會把跳號讀成缺內容而誤否(見事故簿) - 刪除只有「刪除 / 未刪除」兩態;AI 原因不形成「建議刪除」第三態
- 口誤、重複、殘句預設刪前保後;長句、整句、分岔重說必須高風險複核
- 普通停頓不由 Skill 計算:相鄰靜音合併與
natural-pause-v2由產品確定性執行
4. 彙總:兩張表,表出來才動手
幹什麼:五輪的行合併成兩張表——這是本步的產出物,也是給用戶看的東西。
刪詞彙總表(逐條刪詞決定):
| # | 時間 | 類型 | 刪除 | 剩下讀作 | 風險 | 依據 |
|---|-------|--------|------------------|------------------|-----|----------|
| 1 | 00:12 | 重複 | 這個功能呢 | 這個功能它其實 | 低 | 判例 R2 |
| 2 | 02:31 | 改口 | 比如我就讓他跟蹤 | 比如我讓grok跟蹤 | 高 | 判例 R5 |
重複句子表(說了多遍的句子,逐詞表看不出「錄了幾遍、保哪遍」,而這正是用戶 最想核對的):
| 句子(開頭) | 說了幾遍 | 保了哪遍 | 刪了哪幾遍 | 風險 |
|-----------------|--------|---------------|------------|-----------------|
| 因為今天有什麼… | 3 | 第 3 遍 00:08 | 第 1、2 遍 | 低——三遍基本一致 |
| 多數Agent能搜… | 2 | 第 2 遍 04:40 | 第 1 遍 | 高——兩遍說法有出入,重點聽 |
然後自讀:按表把刪後的全文按播放順序通讀一遍,讀不通的行撤銷。 這是複核的定義:AI 自己再看一遍,不是拿去問用戶;拿不準 = 不列(兩態)。
5. 審核:到人工審核時才打開 Studio
幹什麼:全量提交候選,把兩張表呈給用戶,然後打開產品審核頁讓用戶親自複核。
node "<插件根>/scripts/videocut-cli.cjs" cuts get "<專案目錄>" --json # 取 Cuts 自己的 revision
node "<插件根>/scripts/videocut-cli.cjs" cuts set "<專案目錄>" --file "<提案檔案>" --expected-revision "<Cuts當前revision>" --json
候選只引用穩定 wordIds:
{
"schemaVersion": 1,
"cutWordIds": ["word-12", "word-13"],
"reasons": [
{ "wordIds": ["word-12", "word-13"], "kind": "repeat", "risk": "low" }
]
}
提交規矩:
- 候選是本輪判斷的完整結論,不是增量——
cuts set是替換語義,交增量會把上一輪 語義刪詞靜默丟掉(見事故簿);提交候選時禁止讀取或手工合併initialization.baselineCutWordIds(產品自動併入停頓基線) reasons落盤,如實寫;產品會裁掉提到未刪詞的部分- 不直接寫
cut-selection.json、project.json或事件日誌 cuts get.data.revision是 Cuts 的 revision,workflow get.data.revision是專案的, 禁止混用- 提交成功後必看
noLongerCut(本次不再刪的詞數):不為零且非有意撤回 = 交了增量, 回去補全量重交;讀到"unknown"也要看見 - 隨後立即再次
workflow get+cuts get,確認cut_review_ready與三個 revision; 不一致即停,絕不直接寫 JSON 或自動覆蓋 - 提交後把
<提案檔案>留在任務目錄——第 6 步復盤要用(reasons 在用戶編輯後 會被產品裁掉,事後從帳本反查不可靠)
然後先呈表、再開頁:把兩張表發給用戶,讓他拿著表進 Studio 複核。
node "<插件根>/scripts/ensure-running.cjs" --json # 打開前再次冪等 ensure
node "<插件根>/scripts/videocut-cli.cjs" open "<專案目錄>" --json # 取產品返回的專案 URL
node "<插件根>/scripts/ensure-studio.cjs" --url "<產品專案URL>" --view koubo --json # 能力門禁:確認 5190 註冊了 koubo 視圖
規矩:
- 只有門禁返回
ok=true才用 Codex 內建瀏覽器打開studio.url,然後停止自動推進, 等用戶劃詞、恢復、儲存 - 打開前把
productUrl的#project/<projectId>與 readback 的projectId嚴格比對, 並綁定stage=cut_review_ready與三個 revision——門禁ok=true只證明產品面能力, 不能替代專案級綁定;任何不一致重新 readback studio_capability_missing:停止並說明版本不相容,可建議$chengfeng-report-bug; 禁止因 URL 帶?view=koubo就認為新介面存在,禁止回退舊任務面板- 不要把「開啟工作台」當任務第一步;不存取舊
review.html、8898/8899; 不控制 Studio DOM、不直接改媒體元素;不建立獨立音訊軌或佔位字幕軌
6. 復盤交棒:用戶批改的作業不許扔
用戶複核完成後,先讀回:
node "<插件根>/scripts/videocut-cli.cjs" workflow get "<專案目錄>" --json
node "<插件根>/scripts/videocut-cli.cjs" cuts get "<專案目錄>" --json
復盤(過渡做法,產品的 cuts diff 命令釋出後替換):拿第 5 步留存的
<提案檔案> 與讀回的終版 cutWordIds 對比——
- 用戶恢復的(提案裡有、終版沒有)= AI 刪錯了。對照 proposal 裡自己寫的 reason 問:錯在哪一類?
- 用戶補刪的(終版有、提案沒有、也不在
initialization.baselineCutWordIds停頓基線裡)= AI 漏了。問:這屬於哪個類型,為什麼沒識別出來? (基線只在這裡用於剔除停頓詞,仍然禁止把它併進提交)
歸檔三個抽屜:
- 口味差異 →
~/.chengfeng-videocut/cut-preferences.md追加(Agent 維護的 markdown,只追加與改寫自己的節;檔案不存在就建立) - 專名錯誤 →
~/.chengfeng-videocut/dictionary.md追加(兩列表格,追加前查重) - 規則空白 → 偏好檔案「待升級判例」節記一筆;同類第三次出現時向用戶報告, 建議升級進通用判例(人審後才動 skills 倉庫)
- 零差異也要記:偏好檔案專案記錄一行「全盤採納」
報告四件事:刪了多少詞、少了多少秒;當前 stage(應為 cut_review_ready);
專案 / Cuts / EDL 三個 revision;復盤摘要(提案 N 條,採納 X 恢復 Y 補刪 Z,
主要分歧一句話)。然後告訴用戶下一步跑匯出。
不彈確認卡,不執行剪輯——物理剪輯的確認卡屬於匯出 Skill,那張卡凍結的必須是 用戶按下確認那一刻的 revision。
return_cut_review:先再次 node "<插件根>/scripts/ensure-running.cjs" --json,再返回同一 Studio 繼續複核;
不觸發復盤,復盤只在最終交棒做一次。
報告分級:Product 結構化 revision 為 API/readback PASS;真實瀏覽器幀審核才是 visual frame PASS;沒人實際聽音一律 human listening UNVERIFIED,不得用播放、 DOM、截圖或媒體探測替代。
恢復與失敗
revision_conflict:重新讀取狀態,說明用戶剛才的編輯,不自動覆蓋runtime_unhealthy:不迴圈重裝service_identity_mismatch/service_port_conflict:停止,不回退 foreground、 不換埠、不殺未知行程- 頁面關閉但服務仍在:讀取 workflow 後從當前狀態續做,不新建專案
- 任何失敗都不得把「帳本已寫」說成「已經剪好」——到這一段為止沒有任何媒體檔案產生
附註:本 Skill 接受本地真實影片與雲端逐詞稿直接進入產品,這是合同 preflight 的要求;兩者都真實存在是一切判斷的前提。