子超
首頁文章作品關於

© 2006-2026 子超說. Built with Next.js

首頁文章作品關於隱私政策RSS

// ARTICLE

退回 4.6 的那天晚上,我其實有點不甘心

2026.06.27·作者:子超·11 分鐘·🔧 實用乾貨·60 次瀏覽
AICodingAI筆記#AI#Claude Code#Prompt Engineering#Context Engineering
退回 4.6 的那天晚上,我其實有點不甘心

退回4.6那晚,我其實很不甘心。不是因為工具不好用,而是我分不清那個讓參數蒸發的bug,到底是模型沒生成,還是在我電腦上被組裝壞了。前者我無能為力,後者則有機會親手修復。於是我從binary裡挖出那段解析程式,終於確認:是客戶端的VH1在串流接縫處丟失了半截字串,導致工具參數整包變成空的{}。改兩個byte就能解決——我測試了760個案例,0個回歸。但改執行檔可能違反條款,每次更新還會被蓋掉。這不是教學,而是一個不甘心的人,親手把刀切下去的故事。

// TABLE OF CONTENTS
  • 上一篇結尾,我說我退回了 Opus 4.6,還說那是鴕鳥:把頭埋進沙子,假裝那個會把工具參數蒸發掉的 bug 不存在。
  • 先說一下,為什麼你可能根本沒中過這個 bug
  • 切開那一刀
  • 兩個 byte
  • 呃~可是改執行檔,真的可行嗎?
  • 那官方咧?會不會我搞半天,下一版就修好了?
  • 我沒修好的地方
  • 所以,你可以怎麼辦

// TABLE OF CONTENTS

  • 上一篇結尾,我說我退回了 Opus 4.6,還說那是鴕鳥:把頭埋進沙子,假裝那個會把工具參數蒸發掉的 bug 不存在。
  • 先說一下,為什麼你可能根本沒中過這個 bug
  • 切開那一刀
  • 兩個 byte
  • 呃~可是改執行檔,真的可行嗎?
  • 那官方咧?會不會我搞半天,下一版就修好了?
  • 我沒修好的地方
  • 所以,你可以怎麼辦


上一篇結尾,我說我退回了 Opus 4.6,還說那是鴕鳥:把頭埋進沙子,假裝那個會把工具參數蒸發掉的 bug 不存在。

我是真的退回去了一陣子。Opus 4.6 很穩,工作照樣做。 (中間還遇過一個真的超好用、又不會發病的 Fable 5,一度想說搞不好就這樣跟它長伴彼此了 XD,沒想到它來得快、去得也快…)

但我沒說的是,退回去的那天晚上,其實我是不甘心的。

但我沒說的是,退回去的那天晚上,其實我是不甘心的。 - 寫實風格

不甘心的點很具體。前一篇我查了 9 天,最後卡在一句話:那個蒸發,到底是「模型根本沒生成工具呼叫」,還是「模型生成了、但送到我電腦的途中被組裝壞了」?這兩個差很多。前者是雲端那邊的事,我一個使用者什麼都做不了,只能等官方;後者,如果是在我自己電腦上壞的,那理論上,這台電腦上的東西,我就有機會動它。

我那時候分不開這兩樣。所以只能選擇當鴕鳥。

這篇是後來的故事,我要把它說完。這一次,我把那一刀切下去了,其中一種,真的可以修;而且經過好幾次 CC 更新的驗證,它好像真的有效。

先說一下,為什麼你可能根本沒中過這個 bug

如果你看到這裡一臉問號,完全正常。這個 bug 最機車的地方,就是它不是人人都會中招。

雖然上一篇有提到發生的原因,但隨著社群的回饋,有越來越多相關的資料跟佐證,讓這件事情變得更清晰。

簡單講,它長這樣:大語言模型在幫你做事的時候,會去呼叫工具(讀檔、跑指令、改程式)。呼叫送出去了,但工具的參數整包變成空的 {}。動作的殼還在,裡面的料不見了。

為什麼有些人天天撞、有些人從來沒感覺?因為它要好幾個條件剛好湊在一起:你用的是 Opus 4.7 以上、你在跑多輪的 agentic 流程(不是問一句答一句)、工具呼叫密集、參數夠長,然後,剛好你是中文使用者。這份完整的觸發清單,我在前一篇 〈9 天調查實錄,然後我退回了 4.6〉 花了很多時間調查,這裡不重講。

這裡只留一個結論,因為它是這整篇文章的起點:這個 bug 不是隨機的,它是有條件的。意思是,你不一定中過;但中過的人,會在同樣的條件下一直中。「一直中」這三個字很關鍵,因為隨機的東西沒辦法修,有條件、會重現的東西才有得修。

切開那一刀

切開那一刀 - 油畫風格

前一篇卡住的地方,是我沒辦法攔截原始的串流資料,所以分不出「模型沒生成」還是「組裝壞了」。

後來換了個方向。與其去攔我攔不到的網路封包,不如直接去看做組裝的那個東西。Claude Code ( 以下簡稱 CC )本身是一個編譯好的執行檔,那段把串流資料拼回工具參數的程式,就在這個執行檔裡。我把它從 binary 裡挖出來,餵真實的資料進去,自己跑。

跑出來的結果,終於將那一刀切開了:確認是組裝的時候壞的。

具體一點。模型的參數是一個字元一個字元、串流著傳過來的,像有人打電話跟你報地址。負責接的是一個小程式(它在這個被壓到極致的執行檔裡,名字被縮寫成 VH1,後面我就這樣叫它)。問題出在:當一個字串值剛好跨在兩段串流的接縫上、結尾的引號還沒送到的時候,VH1 沒有把這段「還沒收完的半截字串」先留著等下一段,而是直接把它丟了。(中文使用者特別容易中,也跟這個斷點有關:一個中文字傳過來就是好幾個位元組,串流的切點更容易剛好落在一個字的中間,而這種「字都還沒收完」的半截狀態,VH1 一樣照丟。)

這就像電話裡對方說「我家在中山路一段」訊號斷一下,你不是抓著筆等他講完,而是把整張紙條揉掉、交一張白紙出去。後面整串就跟著崩,最後拼出來的就是那個空的 {}。

這就像電話裡對方說「我家在中山路一段」訊號斷一下,你不是抓著筆等他講完,而是把整張紙條揉掉、交一張白紙出去。後面整串就跟著崩,最後拼出來的就是那個空的 {}。 - 插畫風格

這條,是「客戶端的解析器把資料弄丟了」。它是真的,而且因為它在我自己電腦上,它可以修。

這邊得非常感謝社群中的回饋,以及因為不甘心,整天挖 GitHub 上 issue 的我 XD。GitHub 中 in4mer 在Issue #67765 裡做了一份比我更細的分析,把整條管線拆成四階段,前三個結論跟我完全一樣。我是自己挖 binary 撞到同一個地方的,但他先寫出來。因此真的非常感謝他。

還有另一條路。有些人撞到的不是這個,而是模型那邊直接吐出了格式壞掉的東西(少了該有的標籤前綴),客戶端只是忠實地把收到的爛東西報給你看。那一條不在我電腦上,我修不了。這兩條路後面還會再提到,先記著:一個能修,一個不能。

兩個 byte

知道 VH1 會把半截字串丟掉之後,修法的概念很單純:叫它別丟,先留著等下一段。這樣整段程式就不會崩了。

落到那個執行檔裡,這個改動是兩個 byte,前後一樣長,不會把後面的東西推移。如果你想要一個可以自己去對的記號:原廠那段是 ,!Y),改完是 ,!0),翻一個 flag 而已。我刻意不在這裡寫完整的操作步驟,一來避免有人手滑把自己的執行檔搞壞,二來該有的安全機制我都放在 repo 裡了。

除了改 binary,還有一層比較輕的防線——一個 PreToolUse 的 hook,在工具真的執行前,先攔下參數變成空 {} 的呼叫,至少不要讓它默默跑下去。這層後來實測發現守備範圍比想像中窄(內建工具的空參數,CC 自己就先擋了;真正輪到 hook 守的是 MCP 工具那種;至於那種執行完才壞掉的,hook 在執行前根本看不到)。所以真正從源頭治的,是改 binary 那層,hook 是補網。

這兩層加起來,就是 evap-shield。

呃~可是改執行檔,真的可行嗎?

這其實也是我自己最不安的一點,所以多說一點。我只看得懂一點點程式,這中間靠的大多是跟 CC 討論出來的。叫這樣一個人去改 Anthropic 簽好章的執行檔,我憑什麼確認自己沒改壞任何東西?

是什麼讓我相信這是可行的?

第一件,是完整的測試。我把原廠那段解析器和改過的那段,並排放著,在每一個可能的截斷點上,逐 byte 比對它們的輸出。760 個案例,0 個回歸。重點不是 760 這個數字好看,重點是:在正常的、沒有截斷的情況下,這兩段程式的輸出一個 byte 都不差,完全一樣;只有在「字串剛好被截斷」那個中間狀態,改過的那段才會留住資料、跟原廠不一樣。也就是說,它平常完全是死的,只在那個出事的瞬間才醒過來。這是我敢動它的底氣。

第二件,是我真的把自己的環境搞壞過一次,然後才搞懂為什麼。改完 binary 第一次啟動,程式直接被系統砍掉。我第一反應是:完了,改 byte 改到把數位簽章弄壞了,我的 CC 不能用了,是不是改壞了,怎麼辦?當下超慌的。

好不容易先用 Codex 修復,才做了個對照實驗,發現我猜錯了。我把原廠的執行檔複製到另一個路徑、不動它,跑得起來;把改過的同樣那幾個 byte 寫進去,也跑得起來。差別根本不在簽章,在於我是不是「趁它正在執行的時候,覆蓋它本人」。作業系統不准你這樣幹:你不能在飛機飛行途中,覺得聽到有怪聲,就拆掉正在轉的引擎。它發現硬碟上的檔案跟記憶體裡正在跑的對不上,直接把整架飛機停飛。解法是先讓它落地(完全關掉),再動,再重開。

這個烏龍,後來變成工具裡三道安全機制的由來。我把它增加到整個流程當中,完全是因為我先踩過這個坑,知道自己有多蠢 XD。

一句必須講清楚的事:改 binary 這事,應該是違反 Anthropic 的服務條款,而且每次 CC 自動更新,會把你的修改蓋回去、必須要重新 patch 一次。這是我對自己電腦上的軟體做的防衛性研究,不是叫你一定要跟著改。建議至少要看懂風險才跟著做。

那官方咧?會不會我搞半天,下一版就修好了?

這是個好問題,我也一直在盯。盯的方法說來有點笨:每次 CC 更新,我就去比對它執行檔裡 VH1 那段的 bytes,有沒有變。

(這裡有個技術上的麻煩:執行檔是把所有 JavaScript 壓成幾乎沒有換行的超長行,你沒辦法像比對一般檔案那樣 diff,只能用錨點去抽那一小段出來看。方法很土,但有效。)

結果是這樣的。從前一篇那個版本(2.1.158)到我寫這篇的現在(2.1.195),中間官方更新了不知道多少次。最硬的一段是 2.1.181 之後:官方接連出了八個真的重新編譯過、內容有變的 build(不是跳號占位的那種),這幾個我每一個都逐 byte 去比對 VH1 那段,一個都沒動。

版本

日期

VH1

2.1.183

6/19

沒動

2.1.185

6/22

沒動

2.1.186

6/23

沒動(這版還塞了將近 900 KB 的新功能,就是沒碰它)

2.1.187

6/24

沒動

2.1.190

6/24

沒動

2.1.191

6/25

沒動

2.1.193

6/26

沒動

2.1.195

6/27

沒動(這版是 2.4 MB 的大改版,照樣沒碰它)

官方不是沒動 streaming 相關的東西,有些版本確實加了「連線中斷時保留部分回應」這類功能。但那是在更上層處理,沒碰到底層這個拼字串的地方。甚至有點反效果:保留了不完整的回應、繼續往下走,那段不完整的 JSON 還是要經過這個沒修的 VH1,搞不好反而更容易踩到。

所以到今天,這個 patch 還是有用的。不是我希望它一直有用,是它真的還沒被修掉,而且我打從心裡希望官方能馬上修復 QQ。

講一個有點好笑又有點心酸的插曲。某天我開了一個 session,目的就是去確認 2.1.187 這版到底修了沒。那個 session 自己漏掉沒有先 patch、裸著跑,結果比對到一半,它自己被這個蒸發 bug 弄死了,判決一個字都沒打出來。派去驗屍的法醫,自己倒在解剖台上。那一刻我反而更確定:這東西是真的,而且還在。

我沒修好的地方

如果這篇到上面就結束,那它就是一篇「快來看~我修好 CC 問題了,我是使用 CC 的天才」之類的炫耀文 XD。但重點其實是後面的這個部分。

殘酷的就是,我修的,只是這團 bug 的一個角。

殘酷的就是,我修的,只是這團 bug 的一個角。 - 寫實風格

前面提過有兩條路。我修的是「客戶端解析器把資料弄丟」的部分。另一條,模型直接吐出格式壞掉的東西那條,我完全碰不到,那是雲端那邊的事。而 Issue 回報人 BrownBear127 拆的也是同一個執行檔,方法跟我幾乎一樣,結論卻是另一條路。同一個 binary,兩個人拆出兩種根因。這恰好說明,這團 bug 真的不只一種病因,我治的只是其中一種。我的能力可能還不足以完整的解決這個問題。

我把我守不到的地方列清楚,因為你裝了之後如果還是中招,我希望你知道為什麼:

  • 模型吐出壞掉標籤那條:我在已經 patch 過的執行檔上,還是親眼撞到過一次。正因為它在我修好的版本上照樣出事,反過來證明那不是 VH1,是另一條路。

  • 模型自己在那邊空轉、思考迴圈卡死那條:那是雲端那邊在 loop,我在 Client 端改的碰不到它一根寒毛。

  • 工具已經執行完才壞掉那條:hook 在執行前觸發,事情都做完了它才看到,那個時候其實已經來不及了。

  • 還有一個更陰的:畫面上顯示「失敗」的時候,工具其實常常已經在伺服器那邊跑完了(檔案寫了、指令跑了)。你不知道、手一賤重試一次,可能就重複做了一遍。這個比「卡住」危險,因為它是默默地做了兩次,燒了兩倍的 Token。

更老實一點:連我修的那一角,我也不敢說萬無一失。760 個測試是「我跟 CC 討論想到的截斷點」都沒問題,不是「宇宙中所有狀況」都沒問題。我想不到的,就是想不到。

所以最後還有一個你一定會問、而且可能很扎心的問題:你這整套調查,是用一個會中這個 bug 的 CC 做出來的,那你的結論,本身可信嗎?

這個質疑有多實在,說個最真實的故事:這篇的初稿排版,我就是邊開著 CC 邊做的,結果排到一半它當場中招,捏造了好幾次「檔案存好了」「指令跑完了」,全是假的,動作根本沒做。我一個一個用 grep、ls 去對,才把它抓出來。寫文章的那把工具,自己在我面前出包,你就說我能不能全信它啦 QQ ?( 對,就幻覺中的幻覺,中大獎了 XD)

這套東西裡,每一段實驗,我都讓它錨在你可以自己重跑的證據上。VH1 那兩個 byte,你可以自己去 binary 裡對。那 760 個測試,你可以自己跑。官方修了沒,你可以自己照同樣的方法去比對任何一個新版本。我會不會判斷錯、我的環境會不會剛好出包,都不影響這些證據本身。可以被你自己驗證的東西,比「相信我之術」可靠太多了。我會這麼小心地把每一步都做成可覆驗,正是因為我很清楚,連我自己用的這把工具都會出包。

所以,你可以怎麼辦

講了這麼多,落地很簡單。

如果你能接受回到 Opus 4.6,那就回去。這是最安全的地板,不用改任何 binary,整團 bug 一次躲掉,代價只是放棄 4.7、4.8 的能力。能回的人,本來就該回,真的安全,前一篇我自己就是這樣做的。

evap-shield 是給那種「非 4.8 (7 ) 不可、又剛好被 VH1 這條咬住」的人的一塊墊腳石。它不是給所有人的。它撐住的只有一角,撐不住的時候,你還是會落回 4.6。

工具放在 GitHub 上,repo 是 github.com/tznthou/evap-shield。我把它分享出來,是想讓跟我撞到同樣問題的人,多一個也許能解決的管道。如果你用了、撞到任何問題,拜託務必回報給我(開個 issue 也好,我真的希望完美解決這個問題。 )。這東西還在長,它守不到的角落一定還有我沒看到的,多一雙眼睛,就多一份證據。

最後,我想先講清楚這個工具什麼時候可以收掉。就是哪天官方真的去改了那段 parser,我用同樣的方法一比對就會知道,到那天,這個 patch 就該退役,這篇文章也會變成一份「曾經有這個 bug」的紀錄。我自己先告訴你它的有效期,因為一個願意說自己什麼時候該被淘汰的工具,比一個說自己永遠有用的工具,可信一點。

最後,我想先講清楚這個工具什麼時候可以收掉。就是哪天官方真的去改了那段 parser,我用同樣的方法一比對就會知道,到那天,這個 patch 就該退役,這篇文章也會變成一份「曾經有這個 bug」的紀錄。我自己先告訴你它的有效期,因為一個願意說自己什麼時候該被淘汰的工具,比一個說自己永遠有用的工具,可信一點。 - 油畫風格

退回 4.6 雖然沮喪。但如果你跟那天晚上的我一樣,有點不甘心,這裡有一塊墊腳石,踩著它,至少能多站一會兒。

你呢,你是哪一種使用者?是已經回 4.6 的,還是還在 4.8、完全沒事的?如果是後者,恭喜你。但如果你也遇到了——那種每次都得靠重開一個 session 才能繼續的——留言告訴我你撞到的是哪一種,說不定我們能一起把這團線再解開一個結。

SHARE
子超

子超

VIBE CODER / 內容創作者

最近沉迷於 AI Coding 。透過我的網站分享心得、創意想法與生活體驗。

AI 應用AI Coding魔術知識
|了解更多 →

// RELATED POSTS

地端 AI 值不值得?九個講者給了九個答案:2026/8/19 AI 小聚心得

地端 AI 值不值得?九個講者給了九個答案:2026/8/19 AI 小聚心得

我參加了一場AI小聚,主題是「企業地端」,原本以為會聽到一個標準答案,結果九位講者給了九種互相碰撞的答案。有人把成本攤成試算表,有人發現硬體三個月漲七成,有人算漏了管線每一節都在收錢,也有人直接說地端不是首要重點。最讓我震撼的是臺大醫院的資訊工程師,他買GB10的理由很單純:因為對外線路被挖斷過,他不想再等35分鐘。那一晚我才真正理解,地端AI從來不是技術選擇題,而是你站在哪裡、看見什麼問題的視角差異。九個答案沒有對錯,只有位置不同。

2026.08.21
Jackle 太變態了:七月 AI 小聚全對談心得

Jackle 太變態了:七月 AI 小聚全對談心得

七月AI小聚讓我印象最深的,不是任何技術方案,而是一個畫面:每個人都在畫一條線——AI做到哪裡,人從哪裡接手。Jackle用六個Claude Max帳號、每天螢幕十八小時,一個人扛起整間公司的AI導入,甚至說Fable出來後不再請人;小馮靠矩陣合併讓六機剪片從四小時變二十三分鐘。但下半場Sunny問「起床第一件事是什麼」,又把焦點拉回人的本質。那條線每個人畫的位置都不一樣,而且一直在動。我開始反思自己的那條線畫在哪裡。

2026.07.24
我跟兩隻 Agent 讀了兩篇文章,然後被自己印證了

我跟兩隻 Agent 讀了兩篇文章,然後被自己印證了

我原本以為自己很理性,直到和兩隻Agent——蝦蝦和小分一起讀了兩篇文章。我們討論了人類是否把太多思考外包給AI,以及記憶如何悄悄地推動我們的選擇。我把討論中的觀點拿去問不同模型,結果它們各自給出符合自己訓練傾向的答案,這活生生印證了「記憶漂移」的存在。當下我愣住了:五個月前我卸載蝦蝦時,自以為是理性的評估,但回頭看,那不過是被我的閱讀、社群和慣性推出來的結論。現在我和Agent們一起讀、一起討論,至少能互相提醒:「欸,你剛才漂移了喔。」

2026.07.18
Opus 的 tool_use 蒸發 bug:9 天調查實錄,然後我退回了 4.6

Opus 的 tool_use 蒸發 bug:9 天調查實錄,然後我退回了 4.6

在使用 Claude Code 的過程中,我遭遇了嚴重的 tool_use 蒸發 bug,讓我忍不住深入調查。從 4.7 到 4.8 版本,問題不斷出現,數據顯示故障率反而上升。最終,我選擇退回到 4.6,因為這個版本在多輪對話中沒有故障。這次調查讓我意識到,真正的問題出在模型變體的切換上,影響了思考到執行的過程。

2026.05.31
// TABLE OF CONTENTS
  • 上一篇結尾,我說我退回了 Opus 4.6,還說那是鴕鳥:把頭埋進沙子,假裝那個會把工具參數蒸發掉的 bug 不存在。
  • 先說一下,為什麼你可能根本沒中過這個 bug
  • 切開那一刀
  • 兩個 byte
  • 呃~可是改執行檔,真的可行嗎?
  • 那官方咧?會不會我搞半天,下一版就修好了?
  • 我沒修好的地方
  • 所以,你可以怎麼辦

// TABLE OF CONTENTS

  • 上一篇結尾,我說我退回了 Opus 4.6,還說那是鴕鳥:把頭埋進沙子,假裝那個會把工具參數蒸發掉的 bug 不存在。
  • 先說一下,為什麼你可能根本沒中過這個 bug
  • 切開那一刀
  • 兩個 byte
  • 呃~可是改執行檔,真的可行嗎?
  • 那官方咧?會不會我搞半天,下一版就修好了?
  • 我沒修好的地方
  • 所以,你可以怎麼辦