iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
AI Engineering

同一把尺,30 天橫評 AI Agent Skill:從單篇實測到一份能查的選用指南系列 第 10 篇

Day 10 | 少了六個問題,換來一組親手驗證的數字

  • 分享至 

  • xImage
  •  

今天測的是 codex——Claude Code 官方市集裡橋接 OpenAI Codex(GPT-5.4)的套件,讓你在 Claude Code 裡直接叫一個完全不同供應商的模型來審查或協助。前九天測的都是同一個生態系裡的工具,這是第一次測「跨廠牌找第二意見」這件事本身值不值得。

會想測這個,是因為「找一個不同的模型當第二意見」聽起來是個很直覺的做法——同一個模型審查自己的東西,總有一種球員兼裁判的疑慮;換一個完全不同公司、不同訓練資料、不同傾向的模型來看一眼,感覺上應該能補上盲點。這個直覺對不對,今天想拿實際案例測一次,不是憑印象下結論。

這個直覺背後其實藏著一個沒有講清楚的假設:「不同模型會看到不同的東西」,跟「不同模型看到同一件事、但表達或驗證的方式不同」,是兩種完全不同的差異,混在一起講的時候,聽起來都叫「第二意見有幫助」,但對使用者的實際意義完全不一樣。前者代表你真的需要多一雙眼睛才能看全;後者代表你原本那雙眼睛已經夠用,差別只在於多一個角度去佐證。今天的測試想拆開這兩種可能,看實際發生的是哪一種。結果不是單純的誰比較強,是兩種審查風格的具體差異,這個差異本身比輸贏更有用。

技能卡|codex(Claude Code 裡的 Codex 橋接套件)

  • 名稱:codex,官方市集出品(openai-codex),底層打的是 OpenAI 的 Codex CLI,模型是 GPT-5.4
  • 前置需求:本機要先裝 Codex CLI 並用 ChatGPT 帳號登入(不是走 API key)
  • 這次測的子指令:/codex:adversarial-review——文件裡明講定位是「挑戰目前的實作做法對不對、設計選擇合不合理、有什麼假設、在真實條件下哪裡會失敗」,不只是抓一般的程式碼缺陷;跟它並列的 /codex:review 才是比較標準的一般程式碼審查
  • 這個套件裡其實還有一個更重的角色,codex-rescue:專門在 Claude 自己卡住、想要第二種實作方式,或需要更深入診斷時,把整個任務轉交給 Codex 處理,不是單純的審查——今天沒有測到這個,只測了審查這一塊
  • 執行方式:針對 git 工作目錄的實際變更(staged/working-tree/跟某個分支比對),呼叫底層腳本把差異送給 Codex,結果原文照搬回來,不做二次詮釋
  • 使用限制:這個指令是唯讀的,文件明講「只審查,不動手改」,看完結果要不要修全部留給使用者決定
  • 輸出格式:結果會標一個明確的 verdict(今天測到的是「needs-attention」),底下列出分級的 findings,每條都附檔案位置跟建議,最後有一段「next steps」——這種先給結論、再給細節、最後給行動的順序,跟這系列 Day 8 測過的 i-have-adhd「開頭給動作」的邏輯其實有點像,只是這裡的「動作」換成了「先看結論再看細節」
  • 這次證據狀態:同一份變更,跑「不用任何工具的基線審查」與「codex adversarial-review」各 1 次

值得多講一句這個橋接是怎麼運作的。Codex CLI 本身是一支獨立安裝、獨立登入的命令列工具,跟 Claude Code 沒有任何關係;這個套件做的事,是在 Claude Code 裡包一層腳本,把使用者下的指令轉譯成呼叫 Codex CLI 的參數,等 Codex 跑完,再把它的原始輸出整段搬回 Claude Code 的對話裡,不經過摘要、不經過二次詮釋。這個「原文照搬、不做二次詮釋」的設計本身值得注意——如果 Claude 把 Codex 的發現先讀過一遍、用自己的話重新講一次,中間就有機會把 Codex 原本的判斷不小心改寫掉、或者夾帶自己的意見進去,讀者會分不清楚這句話到底是誰講的。文件裡特別強調要保留 Codex 標記的「這是推論」「這是不確定」「這是待確認的問題」這些邊界,不能在轉述過程中把語氣拉得更篤定,這是一個認真在意「不要污染另一個意見」的設計選擇。

案例設計:功能全對,但有一個設計層級的隱患

寫了一個報表快取服務:查詢過的報表存進記憶體字典,同樣的請求第二次直接從快取拿,不用重算。程式邏輯完全正確,兩個單元測試都會過。真正的問題藏在一個地方:這個快取沒有任何上限、沒有淘汰機制——只要進來的資料集內容有一點點不同(哪怕多一個空白),就會被當成新的鍵永久留在記憶體裡,不會自動清掉。這種問題不會讓測試變紅,只會讓正式環境跑久了、跑到夠多不同的請求之後,慢慢把記憶體吃光——這正是「功能正確」跟「設計沒問題」之間的落差,也是 adversarial-review 這種強調「挑戰設計選擇」的審查角度該抓到的東西。

具體想像一下這個問題會怎麼發生:如果這支服務每天處理幾千個不同使用者、每個人查詢的資料集內容都不完全一樣,快取字典裡的鍵就會每天新增幾千筆,而且沒有任何一筆會被清掉。跑一天可能感覺不出差異,跑一個禮拜、一個月,記憶體用量會持續往上爬,跟流量、跟有沒有 bug 都沒有關係,純粹是時間的函數。這種問題最麻煩的地方,是它不會在開發環境、也不會在測試階段暴露——測試通常只會送幾次固定的請求,資料量小到不可能撐爆記憶體;只有真的上線、跑過一段夠長的時間,才會在某個深夜悄悄把服務榨乾。這也是為什麼這類問題特別考驗審查者的功力:不是眼前的程式碼有沒有錯,是要在腦中模擬「這支程式跑三個月會變成什麼樣子」。

選這種問題當案例是刻意的。前面幾天測過的資安類漏洞(SQL injection、路徑穿越),本質上都是「這行程式碼寫錯了」,靜態分析工具靠比對已知的危險模式就能抓到;今天這個問題不是「寫錯」,程式碼每一行單獨看都合理、都正確,問題出在「這個設計選擇長期跑下去會怎樣」,這種問題沒有一個固定的語法模式可以比對,得靠真的理解這段程式碼想解決什麼問題、部署在什麼環境下、會被呼叫多少次,才看得出來——這正是「審查設計」跟「掃描漏洞」的本質差異,也是今天想測 adversarial-review 而不是普通 review 的原因。

codex 的結果:只講一件事,但親自做了實驗

adversarial-review 跑完,結論是「暫不建議上線」,理由直接寫「程序共用快取無容量限制,會永久保留每份不同的輸入資料,存在記憶體耗盡風險」。抓到的問題跟我設計的一致。

真正讓我意外的是它怎麼證明這件事——它沒有只憑讀程式碼就下結論,是自己寫了一段程式,真的送了 1,000 次不同的請求進去,量出快取確實留住了 1,000 筆記錄、總共超過一千萬個字元的資料留在記憶體裡,才把這個數字寫進報告。這不是空口說「可能會有記憶體問題」,是有一組可以重複驗證的實測數字撐著。它的完整發現只有這一條,標成「高風險」,附上具體建議(要嘛加一個有總位元組預算的淘汰機制,要嘛對超大資料集跳過快取),然後在「下一步」直接寫「補上快取容量與淘汰測試後再審查」,沒有節外生枝去講別的。

這個「不只講理論、還真的跑一次」的習慣,其實在它一開始的執行紀錄裡就看得出來——它做的第一件事是跑 git diff 看真實的變更內容,第二件事是直接執行程式碼、印出檔案內容跟行號,確認自己看到的程式碼跟實際狀態一致,才開始下判斷。這種「先核對現場、再下結論」的順序,跟這系列從 Day 1 開始一直強調的方法論剛好對上——不是因為它讀過這系列的文章才這樣做,是巧合地示範了同一套紀律。

基線的結果:抓到同一個核心問題,外加六個 codex 沒提的地方

不用任何工具的審查也抓到了同一個核心問題(無上限快取),但接下來的內容明顯更廣,而且依嚴重度分成「必須擋下」跟「該修但不用擋」兩層,講得很有條理。原文是這樣寫這條核心問題的:

「Cache 沒有上限、沒有 TTL、沒有 eviction——這是正式環境的 OOM 風險。ReportCache._cache 是一個永遠只增不減的 dict……這是典型會在生產環境半夜把 process 撐爆的 memory leak。」

除了記憶體風險,它還挑出一件我覺得最犀利的事:那支測試 test_same_request_uses_cache 其實不管有沒有真的做快取都會通過——因為 _render_report 本身是決定性函式,同樣輸入本來就會得到同樣輸出,這支測試沒有真正證明「快取生效、沒有重算」這件事,是一個套套邏輯式的假保障。原文的講法是:

「_render_report 是純函式、deterministic,就算完全不做 cache,r1 == r2 一樣會成立……這支測試在『拔掉整個 cache 機制、直接每次都重算』的情況下依然會通過——換句話說它沒有真正鎖住這支程式要保證的行為。」

另外還提到 dataset_json 這個參數名跟文件字串都暗示會解析 JSON,但實作只是把字串用逗號切開,完全沒有 json.loads——如果之後真的丟進符合 JSON 格式的字串(陣列、物件屬性、字串值裡面本來就常常帶逗號),會產生一個「看起來有跑、但結果完全錯」的結果,比直接報錯更危險;測試直接戳私有屬性、共用全域單例造成的測試間依賴風險;多執行緒下兩個請求同時 miss 同一個鍵時可能重複計算的競爭條件;多行程部署下每個 process 各自維護一份快取、快取形同虛設;以及完全沒有清除快取的對外介面。七個問題,一次性列完。

這七個問題裡,「參數名不符實」跟「套套邏輯測試」這兩條特別值得多講一句,因為它們都不是「這段程式碼會不會壞掉」層次的問題,是「這段程式碼會不會誤導下一個接手的人」層次的問題——一個叫 dataset_json 的參數卻沒有真的處理 JSON,一個叫 test_same_request_uses_cache 的測試卻沒有真的測到快取有沒有生效,兩者的共通點是「名字承諾的事,實作沒有兌現」。這種問題不會讓系統當機,但會讓維護這段程式碼的人建立錯誤的心智模型,之後在這個錯誤的假設上疊加更多程式碼,錯誤會越滾越大——這正是那種只讀程式碼、願意花時間細看每一行意圖跟實作有沒有對齊的審查方式,比較容易抓到的類型。

兩邊不是誰贏,是審查的形狀不一樣

把兩份報告並排看,不是一邊比較準、一邊比較不準——是兩種完全不同的審查風格。codex 這次做的事,範圍窄,但那一條發現有真正的實驗數據撐著,不是憑印象推測;基線做的事,範圍廣,涵蓋了設計、測試品質、部署環境好幾個層面,但每一條都停在「讀程式碼推論出來的判斷」,沒有一條像 codex 那樣附一組實測數字。

這個差異值得記住,因為它推翻了我原本設計這篇時的預設——我以為找一個跨廠牌的「第二意見」,賣點會是「補上另一邊沒看到的東西」,範圍上互補。今天測出來的比較像是兩種審查方法論的差異,不是誰看得比較全面:一個選擇窄而深、拿證據說話;一個選擇廣而快、靠經驗判斷。這兩種都有真實的價值,但適合的情境不一樣,不能簡單說裝了 codex 就等於多一雙眼睛幫你看得更廣。

換個角度想這件事:如果今天的任務是「說服一個懷疑論者這個設計真的有問題」,codex 那份帶著實測數字的報告會更有說服力——你可以直接把那組「1,000 筆、一千萬字元」的數字拿去開會,沒有人能反駁「這只是你的猜測」。如果今天的任務是「盡量不要漏掉任何一個值得討論的地方」,基線那份廣而完整的清單會更有用,代價是每一條都還需要自己再花時間確認是不是真的成立。兩種需求在真實工作裡都會出現,只是很少同時出現在同一個當下——這也是為什麼「兩邊都跑一次、拿兩份報告互相對照」本身是一個合理的工作方式,不是浪費,是刻意讓兩種審查風格互補彼此的弱點。

還有一個角度值得補充:codex 選擇「只講一件事」,也可能不是它能力上限,是它對「adversarial review」這個任務類型的自我定位——文件裡講得很明白,這個指令的核心任務是挑戰「做法對不對」,不是條列所有大小毛病。如果它把七個問題不分輕重全部列出來,反而可能稀釋掉最關鍵的那一個。今天看到的「窄而深」,某種程度上是它刻意收斂範圍、把火力集中在它判斷最致命的那一點,這是一種設計選擇,不是廣度不夠的缺陷——只是身為使用者,如果你沒有意識到這個設計選擇存在,很容易誤以為「它只找到一個問題」等於「它只看得到一個問題」,這兩件事其實不一樣。

這對你有什麼用

  • 不要預期跨廠牌的第二意見會「覆蓋」另一邊漏掉的範圍。 今天的核心問題兩邊都抓到了,代表真正重要的事,不太需要靠換一個供應商才找得到;換供應商比較可能改變的是「怎麼證明」,不是「看不看得到」。這跟很多人對「多找一個意見」的直覺期待不太一樣——大部分人找第二意見,是希望對方看到自己看不到的東西,今天的結果比較接近「對方看到同一件事,但講的方式不一樣」,這個期待落差值得先調整過來,才不會覺得白花了一輪時間。
  • adversarial-review 這類定位成「挑戰設計」的審查,適合拿來驗證一個你已經有懷疑、但需要證據才敢下決定的地方,不適合當成一次性的全面體檢。 今天它只挑了一件事出來講清楚,這是它的設計傾向,不是它的能力上限——如果你要的是全面掃過一輪,這不是它的強項。
  • 看到一份審查報告附了實際測出來的數字,那條發現的可信度會比純粹靠推論的高。 這不代表沒附數字的發現就不值得理會,是提醒你:同一份報告裡,有實測支撐的那幾條,優先度可以排高一點。
  • 測試「是不是真的鎖住了要保證的行為」,比測試「輸出有沒有變」更值得多想一層。 今天基線抓到的套套邏輯測試是一個好例子——寫一個問題自己:如果把這個機制整個拔掉,這支測試還會不會過?會的話,這支測試沒有真正保護到你以為它在保護的東西。
  • 拿到一份審查報告,先看它有沒有真的執行過什麼,還是全部停在讀程式碼推論。 這不是要你不信任沒有實測的發現,是提醒你分辨「這件事被驗證過」跟「這件事講得很有道理」是兩個不同的可信等級,混在一起看容易高估報告的確定性。
  • 如果你要導入跨廠牌的第二意見當固定流程,先想清楚要它解決哪一種需求。 要證據力,選會做實測的審查方式;要覆蓋面,選會廣泛列舉的審查方式;兩者都要,就得接受要花兩份時間,沒有一次到位的捷徑。
  • 看到一份審查只提一個問題,先確認那是工具的能力邊界,還是工具刻意收斂的設計選擇,兩者的因應方式不一樣。 前者代表你可能需要換個工具補齊;後者代表這個工具本來就設計成專注在最關鍵的那一點,你該做的是另外找一輪覆蓋面更廣的審查來補足,而不是覺得這個工具不夠力。
  • 名字跟實作對不上的地方,值得特別留意。 一個變數、一支函式、一支測試的名字,是寫程式的人當初想表達的意圖;如果實作沒有兌現那個名字承諾的事,代表這裡很可能有認知落差,不一定是 bug,但常常是未來 bug 的溫床。

誠實交代這次測試的限制

  • 兩邊都只跑了 1 次,樣本數很小,不能直接推論成「codex 一定窄而深、基線一定廣而淺」這種通用結論,今天測到的是這一次、這一題的表現。
  • codex 這次選擇的審查範圍(只挑一件事講清楚),有可能是這個案例剛好只有一個夠明顯的核心問題,也有可能是它的傾向本來就是這樣——今天沒有測到它在「案例裡藏了兩三個同等重要問題」的情境下會怎麼分配篇幅。
  • 基線抓到的六個額外問題,我核對過其中兩個(套套邏輯測試、dataset_json 沒真的解析 JSON)確實成立,其餘幾個(執行緒安全、多行程部署風險)屬於合理的工程判斷,沒有像今天核心問題那樣另外找方法驗證過。
  • 只測了 adversarial-review 這一個子指令,codex 套件裡還有標準版的 /codex:review、以及專門處理棘手任務的 codex-rescue,今天都沒有測到。
  • 這次的案例是我自己設計、刻意埋了一個已知問題的合成程式碼,不是真實世界裡自然出現的 PR,兩邊審查者都沒有額外的專案脈絡可以參考,這點跟真實情境不完全一樣。
  • codex 那次執行花的時間明顯比基線長(背景跑了好幾分鐘,中間真的執行了程式碼去量測),基線是單輪對話直接給答案;今天沒有把兩邊的時間成本、token 成本量化並排比較,只呈現了內容上的差異,如果你在意的是「多花的這幾分鐘划不划算」,這個問題今天沒有答案。
  • 兩份報告的呈現風格本來就不一樣(codex 走 verdict/findings/next steps 的結構化格式,基線走自然語言的分類條列),這個格式差異多少會影響閱讀時「感覺誰比較有條理」的主觀印象,今天盡量只比對內容本身有沒有成立,但格式帶來的觀感落差沒有完全排除。
  • 「codex 選擇窄而深是刻意的設計、不是能力上限」這個判斷,是我讀過它的指令文件後做出的推論,不是今天實測直接證明的——要真正驗證這件事,得測一個藏了多個問題的案例,看它是不是還是只挑一個講,這個驗證留給以後有機會再補。

跟前面幾天放在一起看

昨天測 CodeQL 的時候發現,案例規模不夠大,沒能真正逼出「進階工具才做得到」的優勢;今天延續類似的主題,但角度不一樣——不是規模的問題,是審查方法本身有沒有拿出證據的問題。同一個問題,一邊用讀程式碼推論出來,一邊用真的跑一次實驗量出來,兩者說的是同一件事,但可信的重量不一樣。這系列走到第十天,反覆出現的其實是同一個提醒的不同面貌:講得篤定、講得全面,都不能取代「這件事有沒有真的被驗證過」——不管是工具的宣稱、審查的發現,還是今天這種「找誰來審查比較好」的選擇本身,都適用同一個問法。

十天測下來,累積的評分尺沒有變過:有沒有實跑、有沒有對照、有沒有留下可以重新檢查的證據。今天多驗證的一件事是,這把尺不只能拿來量 Skill 本身做得準不準,也能拿來量一份「審查報告」寫得可不可信——同一套標準,量的對象換了,方法完全沒變。

寫到第十天,回頭看這系列一開始立下的規矩——固定任務、有無對照、留下證據、只寫已驗證的結果——今天算是把這套規矩用在一個新的地方:不是拿去測一個 Skill 有沒有做到它宣稱的事,是拿去比較兩份審查報告誰講得比較站得住腳。方法沒變,用途卻自然而然地延伸出去了,這大概也是「同一把尺」這個系列名稱真正想講的事——尺本身很單純,值錢的是拿它去量過的次數夠不夠多、夠不夠老實。

今天也順帶留一個沒答完的問題:如果案例裡藏的不是一個問題、而是三四個同等重要的問題,codex 這種「挑一件事講清楚」的風格,會不會漏掉其中幾個?今天的案例只埋了一個核心問題,沒辦法回答這個問題。這也是下次如果要更嚴謹驗證這個工具時,該補的一塊。

明天想換一個方向測,這系列接下來還是每篇一個獨立的技能卡,累積起來變成一份你自己就能查的 skill 選用清單。


上一篇
Day 9 | 我設計了一個只有進階工具才追得到的漏洞,結果人工也追到了
下一篇
Day 11 | 官方說省 65% token,我量出來是 39%
系列文
同一把尺,30 天橫評 AI Agent Skill:從單篇實測到一份能查的選用指南 共 11 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言