工作能外包給 AI,決策不能
先前在〈一個模型不夠〉寫過「多視角找」:拉幾個不同視角的模型來審程式碼改動,收到不少「這招我也在用」的回饋。那篇其實埋過一次本篇的縮影:我問它「你這整段解釋是推論吧,還是有證據?」它認錯,回頭翻對話紀錄取證,把自己編的一段機制解釋推翻掉。但後來我想通一件事:多視角只解決「找不找得到問題」,沒解決「找到之後你信不信」。而且更常見的場景是反過來的:AI 端出一份 spec 或一個結論,你點頭、動手,如果從頭到尾沒發生過「我打斷它、逼它撤回一次」,其實你已經在照單全收了。
三段真的發生過的對話
以下三段都出自同一個 session,討論的是超商取貨標記殘留的 spec,三段對應三種反問方式。
盤問(逼它換一種講法重講):我跟它說「這題我看不懂,講白話一點」。它換成一個叫小明的客人重講整個故事:小明昨天選了超商取貨、沒結完帳就把瀏覽器關了;今天回來用同一個結帳連結,把地址改成宅配、這次真的下單。結果後台看到的訂單,地址欄是宅配、內部的取貨方式標記卻還寫著超商。講完故事它自己補了一句:「說實話我也不確定這是當下清掉標記、還是跨 session 的 case,兩個都可能。」沒被問,這句它八成不會主動講。
發明選項:同一個標記問題要修,我不接受它給的方案,自己想了第四個——等 long-polling(掛著等伺服器回應的那種查詢)第一次回應後再決定要不要補跑校正,這樣行不行。結果逼它認真論證,列出五個問題:race(前端和伺服器資料誰先到的競態)沒真的解決只是往後挪、沒資料的情況會死等到逾時、某個資料查詢 hook 的介面得跟著改、要 bind 一個沒有文件化的伺服器訊號、useEffect 的依賴會變脆弱。繞一圈,結論是還是回到原本「接受 race」的方案。
逼證據:討論到它力推的另一個方案時,我問「~50-100ms 是根據什麼條件算出來的」。它老實認了:是估的,沒實測,憑空丟數字違反了自己被交代的「宣稱要對齊證據」原則。順帶也承認那個方案還有沒解決的問題:某個 checkout 元件要拆成外層、內層兩層,外層負責等 hydration(前端程式接手、頁面真正能互動之前的那段初始化);等待一直逾時的話整塊就看不到;Shopify checkout extension 的生命週期撐不撐得住這種拆法,它根本沒驗證過。我追問下去:那這個延遲是純 JS,不含 API 嗎?這次它去查了 Shopify 的型別定義文件,發現儲存的底層其實是 localStorage,延遲跟著翻案:量級只有約 6-25ms(它當場從文件推出來的量級、不是實測),不打網路,先前的 50-100ms 估太高。但同一份文件也寫著「data persistence isn’t guaranteed」,資料保存根本沒被保證,這件事讓原本兩個方案的比較前提整套垮掉:它力推的那個方案多防的場景其實很窄,於是改回推先前那個。
三段的結果其實不一樣:第一段只是把不確定性逼出來、第二段繞一圈回到原方案、第三段才真的翻案。反問的目的不是逼它讓步,是逼它把理由攤開:結果可能是撤回,也可能像第二段一樣,原案反而站得更穩。共同點是,沒有人追,這些全部不會發生:不確定性不會自己招、我的方案不會被認真算帳、估錯的數字就一路錯下去。
為什麼要追到它認錯
老實說,我用下來的觀察是:LLM 傾向迎合,也不太會承認自己不知道或沒做到什麼,幻覺很大一部分就是這麼來的,這種傾向也讓回答看起來總是充滿肯定跟自信。我自己在 threads 評過 deepseek「不愛反問人類」這個毛病,反過來也一樣,AI 該反問人、人也該反問 AI,兩邊都是認知對齊的問題。
追問說到底不是在懷疑某一次的答案:模型結構性有這毛病,人就得把踩煞車當成固定動作,跟哪一個案例對不對沒關係。
固定三問是怎麼盤出來的
除了臨場反問,我還固化了三個固定問題。上面三種是臨場想到才問的;這三問不一樣,寫死在自審流程裡、每次都要過。它們不是憑空想的。我原本以為自己不會踩到這種雷,直到發現引入 superpowers 做 spec-driven development 一陣子後,自己也越來越懶得看 spec。r/ClaudeAI 上有人吐槽過這種毛病,原來自己也中了🤣。整份懶得看,就想乾脆讓模型自己挑重點講給我聽,但「叫模型自己挑重點」太隨機,於是換成固定三個面向,寫成模型的第一人稱、讓它對自己發問(下面的「我」是模型自己):
「我做了哪 3 個你可能不同意的決策?各附我選它的理由跟反方理由。」 「我對關鍵變數、範圍、依賴假設了什麼?哪些沒跟你確認過?」 「這份 spec 哪裡偷工、含糊帶過、留了沒解的問題?」
真正的靶心不是那些 brainstorm 時已經講到爛的點,那些問了也沒意義。要抓的是兩類:一類是我覺得不用特別講的常識,模型因為我沒說就自己腦補了一版;另一類是超出我認知外、被它偷偷補進去的東西。模型不會主動講「這裡你沒講、我猜的」,固定問題就是逼它招供的鉗子。
後來我把這件事寫進規則裡
反問不只是我做的一個動作,判準也被我寫進了規則,讓模型自己知道會被抓什麼。全域規則裡有一條「宣稱與證據層級對位」的硬規則,講明白:說「完成、全部、掃過」這種話,同一句就要附上證據;講採用頻率,也不能只拿 memory 或文件裡的字當數字。前面逼證據那段的「我憑空丟數字違反宣稱要對齊證據原則」,引的就是這條(模型記的是短版名字)。這條規則後來還長成一套自動監工,回合結束時盯有沒有空口宣稱完成;哪些部分寫得成死規則、哪些寫不成,〈AI 說做完不算數:拿證據來〉整篇在講它。
review-spec 這個我自己寫的本地指令也是同一套邏輯:從淺到深分四層,最淺的第一層不派額外模型、直接在原本對話裡逼它唱反調自審,越往上派進來的外部模型越多、看的範圍越大。我另外在流程上掛了一個提醒腳本(hook),原本設計是自動把第一層的自審指令餵進去,後來改成只跳提醒、讓我自己主動選要跑哪層,理由寫在腳本註解裡:自動餵會讓流程幾乎永遠停在最淺的那層,不會往下追。這個設計轉折跟反問是同一個邏輯:與其讓預設值替人做決定,不如把「人來拍板」這個動作本身做進流程裡。
review-spec 後來還陸續釘進幾條不分層都要遵守的守則。批評的那個模型只能看到東西本身和需求,不能先看到我自己的結論。跟我原本想法對不對齊這種事,留在當下對話討論就好,牽到架構或整個 repo 才外派給別的模型看。它講出來的發現,最後還要拿我腦子裡的實際情況驗一遍:要是 spec 根本沒把我真正想的寫進去,那些發現再漂亮也是白抓。
同期還有一個小鏡像:我在 debug 用的 skill 裡固化了「先列幾個假設、能驗的先驗、帶驗證結果來討論」這條,反過來把「先驗再談」內化成模型自己的流程,不用等我開口追。
這招不限 spec review
同樣的反問在別的場景也一再生效。準備那套空口宣稱監工的 benchmark 時(〈雲端太遠,hook 等不了〉裡的本地判官同屬這套系統),我問它第一階段是不是真的全部做完、過程的結論經驗有沒有記下來,它老實答不是,自己抓自己的清單,抓出五項沒記錄的東西,包括錯誤率其實是 19.5%:原本講的 5% 是拿 60 筆校準樣本算出來的,真實資料一跑差了將近四倍。另一次整理個人研究記憶時我問「你確定 memory 有紀錄某個 distill 系統嗎,搞不好在講別的」,逼它逐條 verify:它原本宣稱 memory、wiki、git 紀錄三種來源都有,驗完發現七個命中裡只有三個 git commit 是真的,memory 和 wiki 那幾條講的全是別種東西,「三處都有」被修正成「只有 git 紀錄有」。
翻過 Claude Code(CC)的對話語料,三十萬行裡「怎麼算的」「有證據嗎」「你確定」這類質疑句粗撈就命中超過 80 條,分佈在工作 repo、個人研究、記憶盤點各種場合。這不是 spec review 限定的招,是一個工作習慣。
工具擁有不等於工具在用
誠實講一句。我手上另一個 code review 用的指令 /pr-review,把整套多視角審查包起來、打一下就全部跑完,到 2026-07-02 為止的統計累計被叫了 74 次;同一份統計裡,review-spec 這邊要我自己記得手動選更高層的,只有 3 次。這 3 次很乾淨、就是純手動,沒有任何自動預設值的雜訊。兩個數字對照出來的是:接了自動化的層會被用爆,靠自律的層就躺著。工具擺在那裡,不代表真的在用它的深度。
連寫這篇的當下也被抓包
先前準備一場內部分享、請模型統計我自己工具用量的時候,它第一輪告訴我 review-spec 只用過 7 次。我反問「不可能吧,還是你沒發現自己常常在自審?」,它回頭重算,把沒派出去、直接在對話裡做的自審也算進來,數字變成 13 次。七變十三這件事本身,就是這個命題在被自己 dogfood。
寫這篇文章的過程,同一件事又發生一次:我本來想拿「13 比 3」當對照數字,講「連我自己都幾乎停在最淺層」。後來我反問模型,這 13 次是不是都算數:那個選層的提醒選單超時沒人理,會自動走預設值,等於有一部分「停在最淺層」根本不是人選的。查證下來確實混進了這種自動放行的雜訊:13 這個計數本身沒錯(那些自審真的發生了),但拿它當「人主動怎麼選」的對照就不乾淨,只好作廢,改用前面那組乾淨的 74 比 3。連寫這篇講反問的文章,自己都被反問了一次。
三問也好,四層 Tier 也好,其實都不重要,重要的是模型出、人反問、模型撤回或翻案、人拍板,這個迴圈有沒有跑起來。下次 AI 給你答案的時候,你有沒有反問——這才是真正的差別。