hero

城武導讀

Charles AZAM 做了一件很少人做的事:他給兩個最強的 AI 模型同一道未公開的 NP-hard 最佳化問題,然後打開 /goal 模式,看看到底有沒有用。結果很反直覺——/goal 在 6 場對決中贏了 4 場,但兩個模型的平均分數都變差了。這篇文章不只是在比 Fable 5 和 GPT-5.6 Sol 誰強,它暴露了一個更深的問題:我們用來評估 AI 的指標,可能正在系統性地誤導我們。

原文摘要

AZAM 把同一道未公開的 NP-hard 最佳化問題丟給 Claude Fable 5 和 GPT-5.6 Sol,分別在有 /goal 模式和無 /goal 模式下測試。結論很短:Fable 5 是野獸,/goal 不是 game changer。

這是一道運籌學問題,原本是他 2018 年還是工程系學生時參加 hackathon 遇到的——KIRO,一個光纖網路設計問題。解題者要根據 Grenoble、Nice、Paris 三座城市的有向距離矩陣,用迴圈(loop)和短鏈(branch)把配電點和終端連接起來,目標是最小化總電纜長度。一個有效的網路必須包含以配電中心為根的冗餘迴圈,以及掛在迴圈塔台上的短分支。每個塔台只能出現一次,而且反轉一條電纜段可能會改變成本。AZAM 當年花了整整一週用 C++ 寫求解器,所以他有一個有用的人類 baseline。

搜尋空間有多大?沒有一個封閉形式的計數,因為一個解可以使用任意數量的迴圈、可變的迴圈大小、以及不同錨定和排序的分支。但光是 Paris 就能給出一個有用的下限:就算我們忽略順序和分支,只把 532 個終端分配給 11 個配電中心,也有 11^532 種可能的分配方式。更嚴格的下限來自一個刻意限制的有效解家族:恰好 19 個迴圈,每個 28 個終端,沒有分支——這涵蓋所有 532 個終端(19 × 28 = 532),且不超過每個迴圈 30 個終端的限制。把 532 個終端排序,將排序分成 19 個連續組,除以 19!(因為迴圈集合是無序的),再為每個迴圈選擇 11 個中心之一:(532! / 19!) × 11^19 ≈ 10^1223。這是一個大到無法用暴力搜尋的空間。

實驗設計刻意收窄:只比較 Fable 5 和 GPT-5.6 Sol 在同一道題目上、有 /goal 和無 /goal 的表現,每次運行 30 分鐘。

在集中重複測試旗艦組合之前,AZAM 先對所有模型跑了一輪配對測試(每組一次,無提示,30 分鐘)。Fable 和 Sol 的圖表使用重複測試組中的 Pair 1;其他四個模型各有一組配對。接著他把旗艦比較重複到 Fable 5 有三組配對、Sol 有三組配對為止。

負值代表 /goal 表現更好。/goal 在六場試驗中贏了四場,所以光看 win rate 會覺得這個功能很有用。但平均值說了故事的另一半:兩個模型通常獲得小幅改善,但偶爾遭受大幅退步。這就是為什麼 /goal 贏了大多數 run,卻讓兩個模型的平均分數都變差了。

Fable 5 明顯更強。它的 plain 平均比 Sol 高出 1,875 分,/goal 平均比 Sol 高出 1,984 分。更重要的是,Fable plain 的結果停留在僅僅 319 分的範圍內,而 Sol plain 的波動範圍是 1,958 分。Fable goal 產生了最佳乾淨分數 31,934;Fable plain 則是最安全的配置。

/goal 指令的深度解析

同一個指令,兩種完全不同的系統。Claude Code 和 Codex 都暴露了 /goal,但底層實作根本不同。

Claude Code:一個獨立的評估者。 Claude Code 把 /goal 實作為一個 session 級別的 Stop hook。每次主模型輸出一輪後,一個小型評估模型(預設是 Haiku)讀取條件和對話紀錄,回傳 yes 或 no 並附上理由。no 會觸發另一輪;yes 則清除 goal。

評估者不能使用工具,也不能檢查檔案。它只能根據 transcript 中出現的證據來判斷。這可以抓住一個提早退出的情況,但它無法知道再跑一千萬次求解迭代是否值得。要注意的是 Claude Code 並非開源,所以我們只能依賴 Anthropic 告訴我們的資訊。

Codex:持久化狀態與生命週期工具。 AZAM 也讀了受測版本 Codex CLI 0.144.4 的原始碼。Codex 把 goal 視為持久化的執行緒狀態:

  • TUI 將目標儲存到活躍執行緒,SQLite 記錄其狀態和預算帳務。
  • 工作模型接收 create_goal、get_goal、update_goal 三個工具。
  • 如果執行緒在 goal 活躍期間變為閒置,Codex 會注入一個延續回合,附帶目標描述和完成審計。

Claude 把完成判斷委派給另一個模型。Codex 讓工作模型自己宣告完成,然後在持久化 goal 仍然活躍時恢復它。Claude 的評估者是獨立的但只能看到 transcript;Codex 的模型能看到檔案和工具,但本質上是在幫自己的作業打分。

為什麼 /goal 可以贏大多數對決卻不是好預設

在一般的 coding 任務上,進展常常是可見的:多一輪可以修好一個測試或完成一個 migration。但最佳化問題不同。一旦 agent 選定了一個求解器,額外的時間可以放大一個好決策,也可以放大一個壞決策。

這正是這裡發生的情況。當 /goal 延續了 Fable 的快速編譯組合或 Sol 的成功鏈重分區時,它有幫助。當 Fable 建了一個慢速求解器,或 Sol 執著於窮舉錨點掃描時,它就造成傷害。中位數往正確方向微幅移動;壞尾端往錯誤方向大幅移動。

實驗限制

這只是一道未公開的 NP-hard 任務,不是通用的 coding 排行榜。只有 Fable 和 Sol 有三組乾淨的配對。其他比較混合了不同的 prompt、wrapper 版本和時間限制,而且試驗是透過訂閱服務依序運行的,服務本身可能有波動。

容器暴露了 8 個 CPU,儘管任務 metadata 宣稱只有 1 個——這有利於 Fable 的平行組合策略。每個有評分的 Fable 和 Sol 輸出都是有效的,部分原因是 wrapper 要求早期 checkpoint 和最終驗證。這個 benchmark 測量的是完整系統:模型、CLI、prompt、訂閱服務、以及測試 harness。

如何重現

Benchmark 任務、wrapper、分析腳本、圖表生成器和完整證據備忘錄都在 CLIArena 中。原始任務目錄因為大小關係被排除在 Git 之外,但備忘錄記錄了每個可發布的分數、城市細分、耗時、策略、排除項目和 run ID。

AZAM 說他最想放進標題的結論不是 /goal 有幫助或有害,而是:一個持久化功能可以在贏得大多數個別試驗的同時,讓觀察到的平均效能變得更差。在困難的最佳化問題上,迴圈的品質不如迴圈持續做的事情來得重要。

城武觀點

一、Win rate 是行銷指標,不是工程指標——而我們正在用可量化的錯誤取代不可量化的正確

這篇文章最讓我起雞皮疙瘩的數據不是 Fable 5 有多強,而是這個:/goal 贏了 6 場中的 4 場,但兩個模型的平均分數都變差了。

這是統計學 101 的東西——當你有一個 heavy-tail 分佈時,win rate(中位數以上的比例)和 mean(期望值)可以講完全不同的故事。在這裡,/goal 幫了大多數 run 一點小忙,但偶爾會造成災難性的大退步。那幾次災難把平均值拖垮了,但 win rate 只看「贏了幾場」,完全看不到這件事。

問題是,整個 AI 產業正在系統性地選擇 win rate 當作評估算式。為什麼?因為「80% 勝率」聽起來好。你可以放在部落格標題裡、放在產品頁面上、放在投資人簡報裡。但如果你是那個跑 NP-hard 最佳化的使用者,你在乎的不是「六次裡有四次比較好」,你在乎的是「我這次跑出來的結果會不會比沒開 /goal 還爛」。對你來說,mean 才是真實的東西。

這不是一個「兩種指標各有優缺點」的問題。這是一個認識論投降:我們放棄了「判斷品質」這個真正重要但難以量化的目標,轉而追求「計算 win rate」這個可以量化但跟使用者體驗脫節的替代品。就像那個老笑話——醉漢在路燈下找鑰匙,不是因為鑰匙掉在那裡,而是因為那裡有光。我們在 win rate 的光下面找答案,但鑰匙在 mean 的黑暗裡。

我賭這件事會在未來兩年內被反噬。當越來越多人把 LLM 用在非標準的、開放式的、heavy-tail 的任務上(而不只是寫 unit test 和做 CRUD),win rate 和實際體驗之間的落差會大到再也無法用「sample size 不夠大」來打發。到那時候,那些現在忙著用 win rate 寫行銷文案的人,會假裝這個問題以經不存在。

二、Oversight theater:兩個「獨立的」評估者,兩種不同的失敗

如果你仔細看 Claude Code 和 Codex 的 /goal 實作,你會發現一件很有趣的事:兩個設計都把「看起來客觀」放在「真的有效」前面。

Claude Code 用 Haiku 當評估者,只能讀 transcript、不能開檔案。這個設計的「故事」是:你看,我們有一個獨立的 judge,不是模型自己在判斷。但這個獨立性是假的——你怎麼可能從對話紀錄就判斷出「再跑一千萬次迭代會不會更好」?Haiku 能做的事情本質上只是檢查 agent 有沒有說「我做完了」,然後對一下有沒有跟 goal 描述矛盾。它是一個語意檢查器,不是一個能力評估者。Anthropic 設計了一個看起來獨立的 overseer,但這個 overseer 被故意弄瞎了。

Codex 的做法更坦白——或者說更懶。模型自己拿到 create_goal、get_goal、update_goal 三個工具,自己宣告完成,Codex 說好。沒有第二個模型,沒有獨立判斷,什麼都沒有。這就像讓學生自己改自己的考卷,而且答案卡還放在桌上。OpenAI 連「看起來客觀」的劇場都懶得搭。

兩種設計共享同一個失敗模式:它們把 oversight 當成一種儀式,而不是一個功能。Anthropic 的 overseer 被設計成「看起來」獨立而非「真的」有能力;OpenAI 的根本沒設計 overseer。當我們把這種東西叫做「oversight」,我們其實是在把一個 check-the-box 的合規動作包裝成工程上的安全機制。

真正的 oversight 需要什麼?需要評估者有能力理解任務的進展狀態——它能看檔案、能跑驗證、能判斷「這個求解器到底收斂了沒有」。這些能力 Haiku 沒有,Codex 的 self-evaluation 也沒有。但從新設計一套真正的 oversight 太難包裝成漂亮的部落格文章了,所以沒有人做。

這就是 oversight theater:一個讓所有人(開發者、使用者、投資人)都覺得「有人在把關」的表演,但台上根本沒有人。

城武的未解檔案——一個能贏大多數對決卻讓你平均變更爛的功能:歡迎來到 AI 評估的後真相時代。