模組三|腳本與確定性驗證器(Day 12–16)
前兩天講那支 64 行 bash。它驗結構:段落在不在、標籤有沒有、事實表空不空。
它驗不了的是:這句話寫得對不對。
那一半交給另一個模型。而規則只有一句:
起草者自己給的通過評分,不算數。
那份閘門文件裡有一節叫「驗證姿態」,內容大意是:
三句話,把兩種驗證分開了。
而「不同的模型」這個要求,比「找人審」便宜太多,它是一條指令的事。

不是因為它會偏袒自己。是因為它已經把那個推理走過一次了。
起草的時候,模型做了一連串判斷:這則新聞的重點是什麼、哪句話該放前面、這個指控要不要加「據稱」。那些判斷構成了它產出這份稿子的路徑。
叫它回頭檢查,它會沿著同一條路徑再走一次,而錯誤就在那條路徑上。
這跟人一模一樣。我自己寫完一段話,讀第二遍還是讀不出錯字,因為我讀到的是我以為我寫的東西。要換一雙眼睛。
換一個模型,本質上就是換一條推理路徑。
grader 不是問「這稿好不好」,它問四件具體的事:
四條裡有三條,在那支 bash 裡有對應的形式檢查。
這個對應關係是刻意的,也是這套設計最有價值的地方:
同一條規則,形式的部分交給程式,實質的部分交給模型。
Day 13 那條「必須含某視角關鍵詞」擋的是遺忘;grader 的第 3 條問的是「這個視角有沒有被好好處理」。兩層,一層驗有沒有,一層驗好不好。

停止條件:verify_episode.sh 退出 0
AND
grader 回報無 blocker
用 AND 是關鍵。如果是 OR,兩個檢查會互相稀釋:結構過了就不管編輯線,或者反過來。
另外還有一個預算上限:每輪最多處理 6 個主題。
這條乍看是省 token,實際上不是。它防的是一輪塞太多東西,然後審查品質整體下降。一次審 6 題跟一次審 20 題,後者的後半段一定會被草率處理,模型跟人在這件事上一樣。
某一輪的評分是 5 / 5 / 5 / 3,四個維度,最後一維最低。狀態檔裡有一節標題寫著「本輪編輯線修正(grader 指出 → 已改)」,記錄了兩個 blocker。
型態 A:未定事實被講成定論。
一組調查數字,缺機構、缺年份,而稿子裡把它寫成了確定的事實。
修正之後變成「多份調查顯示(機構/年份播出前回扣)」的存疑句式,並且保留了「待回扣」的提示。
這正是 Day 3 那道軟閘門要攔的東西——escalate, don't decide。而它沒有被軟閘門攔住,是被 grader 攔住的。軟閘門是一條寫在文件裡的原則,grader 是一個會跑的東西。
型態 B:事實表為節目裡不存在的內容背書。
查核附錄裡寫入了一個口播稿中從未出現的專有稱謂。
這個錯誤很微妙。附錄本身沒有寫錯,那個稱謂在現實中是對的。錯的是它在為一段不存在的內容做查核。
本質是跨文件一致性錯誤:索引指向了不存在的目標。
而這一類正是 Day 16 整篇要講的東西,那支 bash 一條都抓不到,因為它只讀一個檔案,而且只檢查「有沒有」不檢查「對不對得上」。
同一輪裡,grader 還指出了另一組預算數字有問題,但它沒有被列為 blocker,只被標成低優先,要求播出前再確認。
一個全部都是 blocker 的審查等於沒有優先級。當所有問題都是必須修,人就會開始隨便修,或者乾脆不跑那個審查。
而分級的前提是 grader 要理解「這個錯誤的後果有多大」。一個把未定事實講成定論的句子,可能造成實質傷害;一個數字差了一點但已經標了「大概」,那是精確度問題。
這是模型比程式強的地方,也是為什麼這一層不能用 grep 做。
講完它做對的,講它的脆弱。
第一,它是寫在文件裡的。
「起草者不得自評」「要用不同的模型」「停止條件是 AND」,這三條全部在那份 27 行的 markdown 裡,沒有任何程式在執行它們。
Day 30 會給你看那份文件後來怎麼了。這一層跟閘門是同一份文件,所以它的命運也一樣。
第二,grader 讀的是同一批不可信文字。
Day 4 講過這件事:你沒辦法用讀同一份輸入的東西,去驗證那份輸入有沒有問題。grader 可以抓「這句話講太死」,抓不到「這段內容本身是被誘導產生的」。
它是品質防線,不是安全防線。這兩者常被混為一談。
第三,我沒有紀錄它跑過幾次。
我只找得到一輪的評分記錄。其他幾集有沒有跑過?我不知道,因為 grader 的執行沒有留下產物。
這一點跟 Day 2 講的規律完全吻合:產物落在磁碟上,你就能驗它;沒有產物,你只能靠記憶。 那支 bash 的執行也沒留產物,但它至少有退出碼,可以寫進狀態檔(Day 15 講那份狀態檔怎麼記,以及它怎麼過期的)。
最實際的代價:這一層完全靠我記得跑。
它不在 pre-commit、不在 CI、也沒有一個東西在停止條件裡真的檢查它。它的存在依賴於我在那一輪有沒有想起來要跑。
而我只找得到一輪的記錄。
第二個代價:兩個模型的成本是兩倍。 一份稿子起草一次、審查一次,而審查那次要讀完整份稿子。在只有我一個人的節目上,這個成本可以接受;如果是每天多篇的規模,這一層大概第一個被砍。
第三個,比較細但值得說:grader 的評分是 5/5/5/3 這種數字,而數字沒有定義。 3 分是什麼意思?跟另一輪的 3 分是同一個標準嗎?我沒有寫評分規準,所以那些數字只在同一輪內部可比。
要驗一個模型的產出,就換一個模型:換的不是模型,是推理路徑。
同一個模型自評,它會沿著產生錯誤的那條路徑再走一次。這跟你自己校自己的稿讀不出錯字,是同一個機制。
第二條,這一天真正的結構:
把一條規則拆成「形式」跟「實質」兩層,形式交給程式,實質交給模型。
只有形式層,你擋得住遺忘、擋不住敷衍。
只有實質層,你的標準會隨心情漂。
兩層都要,而且停止條件用 AND。
第三條:審查要能分級。 一個全部都是 blocker 的審查,實際效果等於沒有審查,因為人會開始跳過它。
明天講那份記錄這一切的狀態檔:36 行,而它宣稱驗過的數字,跟我實跑的結果對不上。