模組一|為什麼不做全自動(Day 1–5)
先給你三個數字,全部是我自己跑指令量出來的:
上架不到一年,五十集以上。
兩個 repo 加起來 1,513 個 commit。
其中 ci: 開頭的,0 個。
前兩個數字看起來像在炫耀。第三個不是,它是這 30 天的問題。
一條每個月都在出片、累積了一千多個 commit 的內容產線,完全沒有任何自動化在檢查任何事情。那它的規則是靠什麼在執行的?
我做一個中文新聞 podcast。錄音是真人,我自己講;但從選題、腳本、剪輯、封面到發布文案,每一步都有 AI 參與。
具體到什麼程度:新聞先被寫成結構化的條目存進資料庫,選題從那裡撈;口播稿由流程產出、由腳本驗結構、由另一個模型審編輯線;錄完之後 ASR 出逐字稿,剪點由我口頭指示、AI 寫成可重跑的 Python 剪輯腳本,FFmpeg 負責組裝;封面套版是程式畫的,直式影片是腳本渲的,發布文案也是產出的。
我按下的鍵只有兩個:錄音,跟發布。
所以這個系列不是「我用 AI 全自動做出一個 podcast」。如果是那樣,30 天寫不滿,三篇就講完了。
它是另一個故事:我知道哪些地方不能交給 AI,我把它寫下來了,然後我發現「寫下來」跟「做到」是兩件完全不同的事。
在這條產線的流程目錄裡,有一份 27 行的 markdown。它列了五件事,AI 一律不得自行執行:
檔案第一段的措辭很硬,原文大意是:這是強制的,流程只做草稿,絕不得自行跨越這些界線。
它給的理由只有一句話,而我到現在還認為那句話是對的:
這個流程每一輪都要吃進不可信的外部新聞文字,而 prompt injection 尚未解決,所以不可逆的動作必須留在人類後面。
注意這句話沒有在說 AI 品質不夠。品質可以靠驗證、靠換模型審、靠迭代改善;輸入不可信是結構問題,改善不了。這條區分很重要,Day 4 我會整篇拆它。
這五道閘門的分界線畫得也很準:它切的是可逆與不可逆,不是重要與不重要。起草、改稿、重跑驗證全部放行,因為錯了再跑一次就好;上架、發文、覆寫,錯了就在外面了。
我寫下這五條的時候,覺得自己把事情想清楚了。
這個系列開始整理的時候,我做的第一件事是回頭查 git,想看看這半年多來這五道閘門實際擋下過什麼。
我查到的是三件別的事。
第一,那份文件寫過一次之後,零次修改。它跟它旁邊的流程狀態檔是同一個 commit 建立的,此後再也沒被動過。而在那之後,這個 repo 又推了 205 個 commit、產出了 5 集節目,那五集完全沒有再經過這條流程。
第二,AI harness 的權限清單裡,有 Bash(git commit:*) 和 Bash(rm:*)。閘門第一條寫著「never auto-commit」,而底層設定同時授權了它。兩份設定互相矛盾,而沒有任何東西會發現這件事,因為沒有任何東西在讀那份 markdown。
第三,另一個 repo 只有閘門的引用,沒有閘門的定義。它的狀態檔寫著「Human gates(未做,等人工)」,然後列了三條。但我在那個 repo 裡怎麼找都找不到那份文件,它引用的是一個不存在於自己身上的規則。
我要先把話說清楚:這不代表那五集出事了。它們都是我自己按下的發布鍵,稿子是我自己讀過的,錄音是我自己錄的。
問題是另一個:如果不是我按的,也沒有任何東西會攔。
那五道閘門不是一道機制,是一份我寫給自己看、然後就再也沒有打開過的 markdown。
這件事真正有意思的地方,在於對照組就在旁邊。
同一條產線上有一支 64 行的 bash 驗證器。它只驗一個檔案、只做 15 條檢查,我實際跑過 30 個集數目錄:能通過的只有 2 個、失敗 1 個,另外 27 個根本沒有它要驗的那個檔案。覆蓋率 10%。
聽起來很糟。但這支腳本活著,而且它做到了一件閘門文件沒做到的事:它把主觀的編輯守則變成了可以執行的東西。
它會檢查稿子裡有沒有出現信源層級的標籤。它會檢查查核表是不是空的。它甚至會檢查一個編輯立場有沒有缺席,那條檢查的註解寫著「這是節目不可協商的視角」。
還有一支 34 行的 Python,它的檔頭註解是我看過最誠實的一句話:「防再把合併衝突標記 commit 進去。」
「防再」兩個字,把整個故事講完了:衝突標記被 commit 進資料檔 → 瀏覽器載不動 → 解衝突的時候丟掉了 6 筆資料 → 同一個 commit 裡,資料被救回來,順手加了這支驗證器。
寫得最完整、理由最充分、措辭最強硬的那份閘門文件懸空了。兩支加起來不到 100 行、灰頭土臉的腳本活了下來。
差別在哪,是這 30 天要回答的事。
六個模組:
| 模組 | 天數 | 講什麼 |
|---|---|---|
| 一 | Day 1–5 | 產線全貌、五道閘門各自想擋什麼、為什麼全自動不成立、AI 到底省了什麼 |
| 二 | Day 6–11 | 新聞怎麼被寫成可口播的結構化條目、事實查核怎麼被寫成程式判得出來的條件 |
| 三 | Day 12–16 | 那支 64 行的驗證器、它的 15 條檢查各自防哪一次事故、以及它擋不住的七類東西 |
| 四 | Day 17–22 | ASR、剪點、FFmpeg 組裝鏈、多軌時鐘漂移、以及一個被退回的細剪版本 |
| 五 | Day 23–27 | 封面、直式影片、導流、發布文案、還有集數為什麼會撞號 |
| 六 | Day 28–30 | AI 協作產生的垃圾、寫完就沒再用的方案、以及那五道閘門後來怎麼了 |
每一天都會綁一個具體的檔案、參數,或一次真實的事故。我不打算寫「應該要注意 XX」這種東西,那種話寫 30 天也不會有人記得。
Day 30 會回收今天開場那三個數字,特別是第三個。
一、節目不具名。
我不會寫節目名字,不附收聽連結,不寫上架年月,也不寫精確集號。原因跟保密無關,這個節目公開在跑,想找的人找得到。是因為它的題材有明確的政治立場,而這 30 天要講的是工程。我不希望這兩件事互相干擾。
代價我自己承擔:你沒辦法點連結驗證它真的存在。
所以我改用另一種方式舉證。所有的管線參數、音訊實測值、模型名稱與參數、腳本行為、commit 統計,我全部攤開給你。一個寫得出 silenceremove 門檻怎麼從 -38 漂到 -30 又回到 -40、而且每一次變動的理由都還留著的人,大概不是編的。
二、這是一個人的產線。
沒有團隊,沒有 code review,兩個 repo 的貢獻者去重之後都是 1 個人。這件事有一個特權:你可以在腦子裡執行閘門。這也正是為什麼它懸空了那麼久都沒出事。
所以請不要把這 30 天當成團隊最佳實踐。它更像是一份病歷。
三、數字全部可複查,推論會標明是推論。
我踩過口徑的坑:同一個指標用兩種算法會差將近一倍。所以這個系列每個數字都記了產生它的指令,凡是從跡象推斷的,我會在文中明講「這是我的推論」。
寫這個系列最大的代價,是我得先承認一件不太好看的事:我花時間寫的那份規則文件,實際效力是零。
而且它不是寫壞了。它的推理是對的、分界線是準的、措辭是強硬的。它唯一的問題是,它是寫給 AI 看的文件,而 AI 不會因為讀過一段 markdown 就改變行為。真正決定它能做什麼的,是權限設定。
第二個代價是不具名。我放棄了這個系列最直接的可信度來源(「你自己去聽」),也放棄了導流。這是我自己選的,但接下來 29 天我會不斷被它限制——有些話沒有連結就是講得比較弱。
任何寫給自動化流程的規則,如果不能被 exit code 表達,它就只是註解。
你可以現在就檢查一次:你的專案裡那些「絕對不要」「一律必須」,是寫在 README 裡,還是寫在 CI 裡?寫在 CONTRIBUTING 裡,還是寫在 pre-commit hook 裡?寫在 agent 的 prompt 裡,還是寫在它的權限清單裡?
前者是給人看的。人會讀、會記得、會被同事提醒,所以它有效。
後者才是給機器執行的。而我把給機器的規則,寫成了給人看的格式。
明天我把整條產線攤開,讓你看清楚這五道閘門實際上站在哪個位置。