三個 reviewer 都答對了——「判斷分歧」是提問製造的
先看一張很普通的表。資料管線專案的一輪修復,同一條驗證項,三份審查結論擺在一起:
- Gemini 3.1 Pro:⚠️——「diff 中無環境斷言程式碼」
- qwen:
met - Claude:
met
看起來就是三位 reviewer 意見不合,一個說有問題、兩個說沒問題。而這一張表後來教會我的事,比任何一張全綠的表都多。
這篇文章的三個案例來自兩個專案——一個資料管線、一個 Android TV app——但協作形狀完全一樣:規劃與調查由 planner 跑,實作交給 Claude,審查分散給 qwen、Gemini 3.1 Pro、Opus;我的位置在兩端,出題,以及決定收不收。
三個案例指向同一句話:reviewer 的 verdict 回答的是你送出的問題,不是你以為你在問的問題。 verdict 相反時,差別常常不在模型的能力或誠實,而在幾份 prompt 的措辭——分歧是提問製造的。而裁決這種分歧,靠的不是投票、不是權威,是把爭議那一層的機制親自讀一遍。三個案例各佔一角:一個看分歧怎麼被製造出來,一個看兩個鏡頭連「什麼算對」都不同,一個看有的地雷只住在一個鏡頭裡。
下面從最短的案例開始。
一、兩個鏡頭看同一份 diff,連「什麼算對」都不同
資料管線專案,某一輪實作完,Claude 自己招認了一件事:manifest 檔頭升級的時候,動了既有檔案的第一行。而計畫裡白紙黑字寫著 D5:「append-only,不得重寫既有列」。表面上這就是違規,該 FAIL。
兩位審查者看的是同一份 diff。
Gemini 3.1 Pro 從程式碼本身看:這是灰色地帶,但手法妥當——升級是冪等的、遇到非預期的檔頭會 sys.exit、寫入是 atomic 的。判:不 FAIL。
Claude 帶著專案脈絡看,多推了一步:如果檔頭不升級,新列有 7 欄,舊檔頭只有 6 欄,pandas.read_csv 會直接報錯——真缺口重算和日後一切依賴 manifest 的分析,會在第一個新列出現的那天死掉。照這個推法,升級檔頭非但不是違規,反而是把下游的閘門保存了下來。
Claude 沒有停在推論。它自己跑了 awk -F, 'NR>1{print NF}',實測出 5,728 列是 6 欄、1,496 列是 7 欄——資料列 byte 級未動,15 列 402(限流錯誤碼)證據全在 6 欄那一側。它沒有只信實作報告。
同一份 diff,一邊看手法、一邊看後果,連「什麼算對」的定義都換了。而最後把事情定下來的,是那一次 awk——後果是用量測推出來的,不是用立場的氣勢吵出來的。
二、三個都答對了——分歧是提問製造的
回到開頭那張表。那條被三份結論夾在中間的驗證項叫 Test 0,母計畫對它的描述是「版本不符須以環境錯誤訊息失敗」,條目標題是「必須跑在所有數值比對之前」。
收到三份結論後,planner 最初把它記成「三位判斷分歧、我判 Gemini 3.1 Pro 對」——它記下的「我」是它自己。這個框架是錯的——我當場指出。 於是 planner 回頭去查實際送出的三份 prompt,逐字:
- 給 Gemini 3.1 Pro:「實際 diff 有沒有滿足?…請只評估「機制是否正確實作」」
- 給 Claude:「規範 6 一律用
./.venv/bin/python3」——規範 6 是這個專案的鐵則「所有量測一律走專案 venv 直譯器」;對被審的一方,這是一句實踐陳述,根本不是問題 - 給 qwen:通用審查提示詞,對照實際磁碟狀態驗收
三份 prompt,三個不同的問題。planner 事後在筆記裡寫下的一句話,成了這整篇的題目:「三個都正確回答了我問的問題。分歧是我製造的。」句子裡的兩個「我」都是 planner——問題是它出的,分歧是它造的。Gemini 3.1 Pro 被問「機制在不在 diff 裡」,它答不在——對。qwen 被問「驗收項對照磁碟狀態成不成立」,它答成立——對。Claude 收到的是一句陳述,它答符合——也對。三個零分的問題,三個滿分的答案。
根因再往上一層,在計畫本身:Test 0 描述了失敗「長什麼樣」,卻從沒說這個斷言住在哪裡、也沒說它要是持久的。實作者讀成「我在數值比對前先確認環境」——對照條目標題,這是站得住的讀法。
而信號當時就擺在那裡。planner 的規矩是驗證項引用的每個指令都要真的跑一次,那一輪其他驗證項都跑了,唯獨 Test 0 沒有任何指令可跑。事後回看,「沒有指令可跑」本身就是它還不是機制的證據——一個真的住在程式裡的斷言,不可能生不出一行可以執行的檢查。
這個風險不是理論的。planner 實測:用系統直譯器(pandas 2.2.3,專案是 2.2.0)跑這支工具——完全正常、零警告、exit 0——環境斷言不存在時,什麼都不會發生,這正是「版本不符須以環境錯誤訊息失敗」想擋的失效模式。修正之後,錯誤的直譯器 exit 3,印出實際值與期望值。
三、有的地雷,只住在一個鏡頭裡
Android TV app 的重寫,一個 cycle 走了四輪。第二輪的結論分佈是:隨 dispatch 的第一道審查 qwen 判 PASS;後面兩位分開指派立場的覆審——Opus 讀 code、另一個 Claude 帶專案脈絡——雙 FAIL,共 13 項:dialog 焦點接線三連違、DCA 鍵穿透、AC-D9 不開 dialog、isDolby 缺守衛、視覺 scope creep 等等。
13 項裡 3 個 Critical 兩位覆審都抓到了;互補的部分分得很乾淨——Opus 抓純邏輯(rating ?: 0、report 未申報 deviation),Claude 抓慣例地雷(R4 的 runCatching、硬編「觀看」、OSD 兩行、reason=dca 恆不觸發、label_ok 改值)。
最銳的一條是 dialog 焦點接線(.focusable() 缺失)。這顆地雷,專案的 memory 裡早有預言,原話:
static review+in-dispatch+code-facing 全沒抓到、只有 project-context lens 抓得到
這一輪再度應驗:in-dispatch 的 qwen 兩輪都沒抓;Opus 在 prompt 明示了那兩條規則之後才抓到;帶專案脈絡的 Claude 獨立抓到全部三條。 同一顆地雷,在不同鏡頭下的可見度是不同的——有的要別人先指給你看才看得見,有的自己就看見。
第三輪又出了一件事:in-dispatch review 在 qwen 階段被砍掉了。處置是「缺席不等於 PASS」——把後面那位覆審升為主要審查,補審。就是這一輪補審,抓出了僅剩的兩個缺陷(誤刪 EPG_DIALOG action=open、底線圖被 constraints 壓制)。整個 cycle 的收斂軌跡:6 → 13 → 2 → 0。
verdict 的格式,假裝它們在回答同一個問題
三個案例底層是同一件事,拆開來是三步。
第一步,verdict 的格式會說謊。 PASS/FAIL/⚠️/met 長得像在回答同一個問題。三個不同問題的正確答案並排時,外觀就是「判斷分歧」。案例二的三份結論沒有一份是錯的,錯的是把它們並排的那個框架。
第二步,流程講究了「誰來審」,沒講究「問了什麼」。 多模型、分立場、覆審升級——「誰」的配置一直在進化。但把案例二裡三道關卡實際拿到的輸入攤開:qwen 拿到的是通用提示詞與磁碟狀態;Gemini 3.1 Pro 拿到的是 diff 和一句「只評估機制」;Claude 拿到的是一句實踐陳述。三個輸入對應三個不同的題目,而三份 verdict 回來的格式裡,沒有任何一個欄位記著題目。並排的動作把三個不同的題目熔接成一個想像中的共同題目——「分歧」就誕生在那一格。而整條流程裡,沒有任何一道關卡要求把「送出的問題本身」當成嫌疑犯。
第三步,裁決的預設動作是「相信其中一個」。 而真正的裁決材料——prompt 的措辭、那一層的原始碼、一次量測——都要回頭才拿得到。回頭這個動作沒有人要求,它只在有人當場喊停的時候發生。案例二裡那個錯的框架,就是在被喊停之後才拆開的。
上一篇已經站在這裡
《不可能變紅的檢查,通過時資訊量是零》的結尾講過「互補來自立場,不來自廠牌」:讀 code 那側指定的模型當場失能,換同一家的模型頂上,兩位覆審變成同一家,互補照樣成立。同一篇裡 verdict 相反(Opus PASS、Claude FAIL)的那次,最後是 planner 親讀原始碼推出的時序論證裁決的。
那一篇講的是「指定互補立場」這個動作。這一篇往上爬一格:立場不在編制裡,在問題裡——「驗機制還是驗磁碟」「驗形狀還是驗方向」「驗手法還是驗後果」,問題的措辭就是立場。不改措辭的「互補」,只是把同一個問題問兩遍。
五個動作
把這篇收進可執行的清單,五條,每一條都有案例背書:
- 讀 verdict 之前,先重讀自己送出的 prompt。 「分歧」先查問題定義,再查答案——案例二的三個答案各自都對,錯的是並排它們的框架。
- 立場寫進問題裡。 要驗什麼,明說:機制還是磁碟狀態、形狀還是方向、手法還是後果。措辭就是立場,漏掉措辭的立場指定是不生效的。
- verdict 相反時,不投票。 把爭議那一層親自讀一遍、跑一次量測——
awk數欄數、時序論證、逐條讀路徑,都是同一個動作。裁決的材料是實測,不是氣勢。 - 缺的鏡頭可以事後補。 審查缺席不等於 PASS;案例三第三輪的補審,抓出的正是僅剩的兩個缺陷。
- 兩種鏡頭都要在場。 有的地雷天生只住在一個鏡頭裡(案例三,兩次應驗)——讀 code 的與帶專案脈絡的並不是保險的雙份,是兩塊不同的覆蓋。
這條診斷線也已經改了流程本身:後來的覆審指派,從不指定立場改成 A/B 各持一種立場分開審——那個改動,就是從「verdict 是問題的函數」這句話來的。
下一次再收到一張看似分歧的表,第一個動作不是問哪個模型對,是回頭看自己送出了什麼問題。答案通常就寫在題目裡。