一個連結放進內容產線,最後交出一篇文章。畫在流程圖上,好像只需要一條箭頭。
可是只要中間任何一步出錯,「AI 已經做完」這句話幾乎沒有幫助。我還是得回頭問:它讀了哪一份資料?留下了什麼?下一步接到的是原始內容、模型回答,還是一個不知道從哪裡來的檔案?
Day 7 講的是控制流,Day 8 決定一筆輸入能不能開始。今天接著往後走,只回答一個問題:開始之後,下一站憑什麼接手?
我先更正上一篇的預告。Day 8 最後寫到,今天會拆「擷取、Whisper、結構化與靜態網站交付」。重新核對案例後,我確實找到 VTT 字幕,卻找不到它由 Whisper 產生的同版本紀錄。Whisper 可以拿來解釋語音轉文字的一種機制,不能被我寫成這次案例實際使用的工具。
這個缺口剛好就是今天的核心:有一份輸出,不代表知道它怎麼來;一個工具做得到,也不代表這次案例用過。
所以這篇不把工具排成一條漂亮的技術棧。我會把影片導讀流程拆成五個狀態、四次交接。每次交接都要留下下一站能辨認、能檢查、能追查,也能拒收的產物。
這次核對的是一筆去識別的既有影片導讀案例。
較早的工作產物裡,有一筆影片中繼資料與一份 VTT 字幕。後來另一輪處理相同來源時,外層紀錄顯示它用同一個來源識別碼命中快取。相同內容版本裡,還能看到來源整理、帶時間碼的紀錄、文章架構、正文、圖片規劃、頁面中繼資料、HTML 與圖片。
後半段另有一段可以對上的外層紀錄:字幕快取命中、必要產物檢查、建置完成,再到部署工具回應。
這些證據可以證明三件事:擷取產物存在、同一內容版本留下多份可對照產物、後半段曾經連續執行。
但它們不能證明「一個連結進來後,從第一次擷取一路無人介入地跑到交付」。最初擷取與後來的快取命中分屬不同輪次;內容中間幾站也沒有逐站執行紀錄。第 8 天提出的 Input Contract,則是一份設計,這筆案例沒有同版本的入口判定紀錄可以和後面鎖在一起。
換句話說,今天的起點「已接受來源」是條件式起點,不是我已經觀察到的一次放行事件。
如果為了讓案例好看,把這些不同日期、不同版本的線索接成同一次執行,文章會很順,流程卻是假的。我寧可保留斷點,再看每一段目前能說到哪裡。
我把整條流程整理成五個狀態:
| 狀態 | 下一站真正需要拿到什麼 |
|---|---|
| 已接受來源 | 可以辨認來源身分的定位與必要資訊 |
| 擷取產物 | 保存下來的中繼資料、字幕或影音資料 |
| 文字候選 | 帶來源識別與回查線索的文字,不先當成事實 |
| 結構化內容 | 來源整理、時間碼、文章架構、正文與圖片規劃等明確檔案 |
| 交付候選 | 可建置的頁面、圖片與交付回應,但尚未等同正式發布或人工批准 |
五個狀態之間,剛好有四次交接:
這不是四個工具。擷取可以換工具,語音辨識可以換模型,網站也可以換平台。真正不能省略的是交接責任:上一站到底留下什麼,下一站又根據什麼接手。
W3C PROV-DM 把資料實體、轉換活動、使用、產生與衍生拆開描述。這對內容產線很有用,因為「某份輸入曾被使用」不必然等於「後面的成品就是由它衍生」。我沒有直接搬用整套 PROV 規格,而是借它提醒自己:資料、動作、責任與證據不要混成一顆「完成」燈。
Handoff Record v1:下一站接的不是一句「完成了」為了讓四次交接能用同一把尺檢查,我先整理一份 Handoff Record v1。這是本文提出的工作底稿,不是現行流程已共用的格式,也不是產業標準。
每一站要填六件事:
| 欄位 | 白話問題 |
|---|---|
| 收到的產物 | 下一站實際讀的是哪一份資料? |
| 轉換責任 | 確定性程式、AI 和人各自做什麼? |
| 輸出的產物 | 這一站結束後留下哪個檔案或狀態? |
| 放行條件 | 哪些條件成立,下一站才能開始? |
| 交接證據 | 程式碼、產物或單次紀錄能證明到哪裡? |
| 未知與人工責任 | 哪些事查不到,必須停下來找人? |
如果要把它做成機器可讀的紀錄,可以先從這個最小提案開始:
handoff_id: <stable-handoff-id>
input_artifact:
artifact_id: <input-id>
source_id: <source-id>
transform_responsibility: <program-ai-or-human>
output_artifact:
artifact_id: <output-id>
release_condition:
result: pass | fail | unknown
evidence_relation: trace-matched | artifact-linked | unknown
unknown_or_human: <what-still-needs-a-person>
這份紀錄刻意允許 unknown。因為沒有證據時,最危險的不是流程暫停,而是 AI 為了把欄位填滿,替我補出一段不存在的執行歷史。
第一站收到來源定位與來源識別,工作是把後面真的需要的資料保存下來。
選定案例裡,能直接觀察到的是影片中繼資料與 VTT 字幕。後續另一輪又用相同來源識別碼找到快取。這代表產物不只是暫存在模型上下文裡,它曾被保存,後來也能再次找到。
但這裡有兩個邊界。
第一,後來找到同一份快取,只能說兩輪之間可以靠來源識別碼連起來,不能說它們是同一次未中斷執行。第二,目前沒有同版本紀錄能回答最初由什麼事件觸發、來源版本怎麼鎖定、內容是否做過雜湊、首次中斷後又由誰重新開始。
外部工具可以提供一個相鄰做法。例如 yt-dlp 能把影片中繼資料寫成 .info.json,也能分開保存字幕。它的文件還提醒,中繼資料可能含有個人資訊,公開前要篩選。
這些能力說明「來源身分、媒體資訊和字幕應該分開保存」可以怎麼實作,不代表這次案例就是用 yt-dlp,也不能把案例的中繼資料直接說成 .info.json。
第一交接真正該交出的,不是「影片抓到了」,而是一組有來源身分、可再次定位、也知道保存邊界的擷取產物。
第二站把影音或字幕資料整理成可以被後續內容階段讀取的文字。
如果來源沒有字幕,語音辨識模型可以負責這一段。OpenAI Whisper 的官方轉錄程式 可以輸出 TXT、VTT、SRT、TSV、JSON 與 JSONL 等格式。其中 VTT、SRT、TSV 與結構化 JSON 輸出能保留片段資訊,TXT 則只留純文字。
但我要再說一次:這是 Whisper 的官方能力,不是選定案例使用 Whisper 的執行證據。
案例裡有 VTT,卻沒有同版本紀錄指出它由哪一個轉錄器、哪個版本、哪些參數產生。實際工具目前是 unknown。我如果因為檔名剛好是 VTT,就把 Whisper 填進流程圖,等於拿一個合理猜測補掉證據缺口。
就算真的使用 Whisper,輸出仍然只能叫作「文字候選」。Whisper 模型卡 明確提到,模型可能產生音訊裡沒有的文字,也可能重複內容;不同語言、口音與方言的表現也不一致。
所以第二交接的完成條件,不該寫成「已得到正確逐字稿」。它最多只能保證:下一站收到一份帶來源身分與可回查線索的文字產物。這份文字是否聽對、時間碼是否準確,留到 Day 10 再往回核對。
文字候選還不是文章。
同一內容版本裡,可以觀察到 VTT、來源整理、帶時間碼的紀錄、文章架構、正文與圖片規劃。這組產物彼此可以對照,至少知道內容不是只留在某一輪模型對話裡。
Day 6 已經拆過這些檔案各自負責什麼,今天不再重講來源台帳與文章架構。Day 9 在意的是另一件事:下一站應該取得明確產物,不該依賴上一個模型回合裡一段看不見的上下文。
GitHub Actions 的工作產物 提供了一個很直白的相鄰例子:一個工作完成後,可以保存檔案,再讓同一工作流程裡的其他工作下載使用。這只能證明檔案能被保存和傳遞,不會替檔案內容背書。
結構檢查也是一樣。JSON Schema Draft 2020-12 可以描述資料形狀,required 可以要求指定欄位存在。真的要擋住「下一站根本讀不懂」的產物,還得讓驗證器執行這份規格,並把失敗接進停止條件。即使結構通過,它仍然不知道摘要是否忠於來源,也不知道 summary 裡是不是只有一句空泛模板。
這一站因此有兩種不能混在一起的檢查:
案例能支持的是多份結構化內容產物存在。至於它們由一個模型回合一次寫出、由多個階段依序產生,還是有人在中間補齊,目前沒有逐階段紀錄可以判定。這一段只能標成「產物可連,執行方式未知」。
最後一站把正文、頁面中繼資料與圖片組成可讀頁面。
選定案例裡,內容版本包含 HTML 與圖片,建置程式會先檢查必要檔案。後半段的同輪外層紀錄,則能連起字幕快取命中、產物檢查、建置完成與部署工具回應。
這是四次交接裡,證據最接近連續執行的一段。但它仍然只能把狀態推到「交付候選」。
原因是下面幾件事回答的問題完全不同:
| 狀態 | 它真的證明什麼 |
|---|---|
| 必要檔案檢查通過 | 建置程式找得到預期輸入 |
| build 成功 | 建置命令以成功狀態結束 |
| 部署工具回應 | 工具接到並處理這次交付要求 |
| 預覽網址可開 | 某個候選頁面可以被讀取 |
HTTP 200 OK |
該次 HTTP 請求成功 |
| 人工批准 | 作者願意認領這一版內容 |
Cloudflare Pages 的建置文件 說明,它以建置命令的結束碼判斷成功或失敗;結束碼是 0,就會把輸出目錄的檔案上傳,即使標準錯誤輸出仍有訊息。這個機制很適合提醒我:build 成功是一個程式狀態,不是文章品質結論。
預覽部署 也有自己的網址與存取設定,代表候選頁面和正式交付本來就可以分開。RFC 9110 定義 200 OK 為該次請求成功,並沒有替回傳內容檢查來源、版本或作者意見。
目前沒有證據能讓我寫「頁面現在仍然可見」「內容已通過人工審閱」或「這就是正式發布版本」。因此第四交接停在交付候選,不再多走那一步。
前面逐站拆完後,整條案例可以收成這張 Handoff Record v1:
| 交接 | 收到的產物 | 轉換責任 | 輸出的產物 | 放行條件 | 交接證據 | 未知/人工責任 |
|---|---|---|---|---|---|---|
| 1. 來源 → 擷取 | 來源定位與識別 | 取得並保存中繼資料與字幕;實際觸發方式未知 | 中繼資料、VTT | 同版本入口與擷取條件未找到 | 產物已觀察;後續快取跨輪可連 | 來源版本、雜湊、使用權、首次中斷與重啟方式 |
| 2. 擷取 → 文字 | 影音或字幕資料 | 語音辨識或字幕整理;案例實際工具未知 | 文字候選 | 私有流程的放行條件未找到 | VTT 已觀察;未找到轉錄器執行紀錄 | 工具、版本、參數與抽查方式 |
| 3. 文字 → 結構 | VTT 與來源識別 | 整理時間碼、來源紀錄與文章結構 | 來源整理、時間碼、架構、正文、圖片規劃 | 同版本的結構與內容 gate 未找到 | 產物已觀察;部分內部分工只有文件自述 | 產生順序、模型版本、內容查核與人工接受 |
| 4. 結構 → 交付 | 結構化內容、中繼資料與圖片 | 檢查必要檔案、建置頁面並交給部署工具 | HTML、圖片、工具回應 | 後半段產物檢查與 build 通過;不含內容批准 | 後半段同輪紀錄可對 | 最初擷取如何銜接、目前可見性、正式發布與人工批准 |
這張表看起來沒有一條全綠的線,反而更接近真實的自動化工作。
舊案例留下的產物,不能用後來新增的工具替它補執行歷史;目前文件描述的流程,也不能倒推成七月就是同一版。不同版本各自回答自己的問題,不互相借證據。
走完四站後,我想留下的不是一份「影片轉文章工具清單」。
yt-dlp、Whisper、JSON Schema、GitHub Actions 或靜態網站平台都可以替換。真正會決定這條線能不能長期運作的,是每次交接有沒有固定責任:
unknown?我不需要每一站都交給 AI,也不需要每一站都全自動。人可以選來源、批准觀點,程式可以檢查檔案與狀態,AI 負責把模糊內容轉成候選產物。重點是責任被寫出來,交接不再藏在人的記憶裡。
一個連結不會自己變成文章。中間至少有四次交接,每一次都可能讓來源身分、時間線、內容邊界或人工責任掉在地上。
Day 9 先走到交付候選。第二站留下的文字看起來已經很完整,仍可能誤聽、漏字、重複,甚至出現音訊裡沒有的內容。
Day 10 要繼續追問:逐字稿裡的這一句,怎麼回到原始影音的那個時間點?