省 token 工具:省不了多少,但風險不小
最近一直看到有人在丟「省 token」「省 context」的工具,數字都很漂亮,60%、90%、98% 隨便喊。用 Claude Code 用得兇的人應該都懂那種心情:額度燒得快、錢包也燒得快,看到「幫你省 90%」當然會手癢去裝。
我前後試了五個,路線各不一樣:一個命令列代理、一個 MCP server、一個壓縮輸出的 skill、一個語意檢索 MCP,最後一個是上下文壓縮層 proxy。試完的結論一句講完:省不了多少,而且真正的代價不在省多少,在你拿什麼去換。
這篇就照這五個案例一路拆,看「宣稱的數字」跟「實際省到的數字」差多遠,再看代價到底長什麼樣。
第一層:工具報的數字,跟你帳單上的差很多
先講最直觀的 RTK(rtk-ai/rtk),Rust Token Killer,掛一個全域 hook 把每次 Bash 的輸出攔下來截斷過濾。它自己的報表很好看,我試的兩天平均縮減 52.7%,官方對外更喊到 60-90%。
問題是這個百分比算的是「砍掉多少輸出」,不是「省了多少送進模型的總量」。我拿工具報表去對 ccusage 的實際帳,一天半下來對總 input 真實只省 7.0%(957K 比 13.72M),如果算上 cache create 的 fresh 量更只有 2.94%,換算成錢大概省 $2-4。報表的 52.7% 跟真實的 7%,差了七八倍,體感上根本是兩個世界。
semble(MinishLab/semble)也一樣。它的 dashboard 自報省 96%,看起來嚇人,但那個基準是「假設你每次都把整個檔案讀完」這種沒人真的會做的最爛比法。我早期做過一次 A/B,開跟不開的真實成本是 $4.06 比 $5.93,省下來大概 32%。從 96 掉到 32,又是差不多三倍的水分。
context-mode(mksglu/context-mode)喊 98%,那是拿沙箱裡的子行程 315KB 壓成 5.4KB 算的,單看那個動作成立,但它在我這裡 132 個 session 真實被自然拿起來用的次數是 0 次,數字再漂亮也一次都沒兌現。
第二層:真正的代價在風險(這才是重點)
省得少其實還好,頂多是裝心酸的。真正讓我把工具拔掉的,是省的方式會出事。而「出事」有三種完全不同的型態,不能混為一談。
第一種,砍事實的無聲降級。這是 RTK 退役的真因。它截斷起來很沒分寸:ps aux 直接縮 98%,只留 CPU 或記憶體最高的幾行;rtk grep 預設上限 200 筆、每行超過 80 字元就無聲砍掉;大目錄的 ls -la 縮 50-70%。最毛的地方是模型完全不知道自己少看了什麼,於是錯誤很少用「報錯」的形式出現,反而都是「結論偏掉」「漏掉一個行程」「比對少一筆」這種事後很難歸因的樣子冒出來。我手上跑的東西大多不能出錯,這種無聲降級的容錯特別低,所以試了一天 13 小時就把它拔了。
第二種,裝了不穩定燒資源。context-mode 不只是沒人用,它還會留孤兒行程。5 天累積 18 個,其中 2 對進了空轉迴圈各吃 98%、99% 的 CPU,整機飆到約 290%,kernel_task 開熱保護降頻,耗電從正常 idle 的 0.2-0.4%/min 衝到 1.27%/min。我把它移掉之後,load avg 一分鐘內從 10.29 掉到 4.81。一個號稱幫你省資源的工具,自己在背景把機器燒到降頻,這帳怎麼算都不划算。它另外還掛著一些 open issue,像任意檔案讀取沒有 deny、字串插值的 shell injection、PreToolUse hook 過度刪 settings.json 砍到別的 hook,加上兩個多月發了 165 版、平均一天兩版以上的節奏,回歸 bug 的機率本來就高(這些 issue 是查核當時的狀態,後續沒再追)。這些安全問題不是我退它的主因,但會讓我更不想把它放進常駐工作流。為了省那幾 % 的 token,去養一個還在快速變動、又掛在本機操作鏈上的東西,實在划不來。
caveman(JuliusBrussee/caveman)這個壓縮輸出的 skill 我也順帶提一句。它最安全,因為只動 Claude 講話的措辭,砍冠詞、砍客套、砍填充詞,理論上不碰事實。但全 jsonl grep 下來被呼叫的紀錄是 0 次,裝著從來沒被觸發過。連它自己的 SKILL.md 都寫了一個「遇到安全警告、不可逆操作、多步驟序列就退出壓縮」的例外,等於工具自承在這些情境壓縮會帶誤讀風險。最安全的反而沒人用,這件事本身就說明問題。
第三層:那換個「更該有效」的省法呢
試到這邊很容易冒出一個念頭:是不是這幾個工具爛,換個方向省就好?比方說別截輸出,改成砍掉常駐載入的東西,這聽起來「更該有效」。
我也試了,結果它在省 token、省錢這件事上,連 RTK 那點 7% 都贏不了。
清掉沒在用的 stdio MCP(我從 13 個砍到 6 個),cold run 的時間從十秒級掉到七秒上下,省了大概 4-15 秒。但這省的是啟動時間,不是 token,因為 MCP 的 schema 走 deferred pool、要等 ToolSearch 才取,本來就不進 system prompt(tool 名稱還是佔一點點)。所以「省 token」這欄基本是 0。
唯一真的省 prompt token 的,是控 always-on 的 skill 清單。我本機這份清單吃了 6098 token,但它在 cache prefix 裡,走的是 cache_read,價格大概只有 fresh 的十分之一,砍掉一半省下來的錢一天也就 $0.2-0.4,比 RTK 一天省的那 $2-4 還少一個檔次。(這裡的百分比設定是我本機自訂的,CC 官方預設其實小得多;毫秒數跟 cache 倍率都是抓個大概,不是精確 benchmark。)
換句話說,「那換個更有效的省法」這條退路也封死了。省 token 能做的空間本來就很小,所以為了省這一點點去裝一個有損的工具,更不划算。(真正還算划算的省法是把任務外包給更便宜的模型,但那是另一篇的題目。)
壓軸:連「做對了」的 headroom,最後也不值得裝
五個裡,headroom 之前那四個多少都有明顯毛病。最後這個 headroom(chopratejas/headroom)不一樣,它是五個裡最新的、也是我唯一用 dry-run 專門量過壓縮效果的,而且它很多地方都做對了。正因為它做對了還是被我否決,才是這篇最想講的一段。
它是個「上下文壓縮層」,把工具輸出、log、檔案、對話歷史在送進模型前先壓一道,宣稱省 60-95%,招牌數字是「省 90%」,可以用 proxy 零改 code 接進來。它不是沒人用的小玩具,所以更值得認真看。
先把公道給它。headroom 的核心招式叫 CCR,是透明可逆的:它把一大塊內容搬走,原地留一張提貨單 <<ccr:hash,size>>,外加標題跟連結,模型看得到「這裡有東西、可以去領」,要用的時候自己呼叫 retrieve 把原文取回。這跟 RTK 那種直接刪行、模型根本不知道少了什麼的無聲截斷,本質上是兩回事。在「透明還是無聲」這條軸上,headroom 明顯比 RTK 好一截。它是個做對了的工具,我不想把它寫成「又一個 RTK」,因為那不準。
但接下來就是落差。我用純 library、零全域設定,拿 47 筆真實的工具輸出跑 dry-run,用它自帶的 tiktoken 算:不開 ML、只走無損結構化那條路,總共只壓掉 15.6%,而且只有 9 筆真的被壓到,集中在搜尋結果那種清單型內容,正在改的 code 是 0% 壓。這個數字,又掉回 RTK 那種低個位數、十幾 % 的程度了。
要省到招牌喊的那種數字,就得開那顆 ML 壓縮器。開下去帳面衝到 69.7%,47 筆裡 44 筆都縮了,連 code read 都從 0% 壓到 80%。但代價是 inline 的內容被壓成一堆拆散的關鍵詞,我抽查關鍵欄位後估,存活率大概只剩三成,倒出來是一堆斷頭句加行號碎片。所以 README 那個招牌「省 90%」,是靠這顆 ML 模型撐出來的,不是無損那條路。順帶一提,這顆 ML 是寫死架構的 ModernBERT 抽取式編碼器,逐 token 打分留高分丟低分,它不是讀懂改寫,也不能換成更強的通用 LLM 或本地小模型,「不夠強就換顆強的」這個直覺在這裡不成立。
而且這些都還只是「壓的當下省的」。真正落袋的,要再扣掉模型之後去取回(retrieve)拉回來的那一份。所以 15.6% 跟 69.7% 都只能先當上限,不是真實帳單上省到的數字。
真正壓垮它的,不是壓縮品質,是它要 proxy 接。一旦用 proxy,它就站在 Claude Code 到 Anthropic 的主流量動脈上,所有流量都穿過它,這跟 RTK 那種旁路掛在每個 Bash 上的 hook 重太多了:
- 單點故障,它掛了整條線都斷,而且它本身就是一坨 FastAPI 加上一堆東西,不是薄薄一層轉發那麼簡單。
- Max 訂閱靠的是 OAuth,轉址 base URL 要原封不動轉 OAuth bearer,多數 proxy 預設是 API-key 那套,接錯就直接破登入。
- 最尖銳的一點,它跟 prompt caching 本質互斥。壓縮會改 prefix,prefix 一變 cache 全 miss。你省了 15% 的 token,卻丟掉 90% 的 cache 折扣,在 Max 上很可能是淨虧。
- CC 的 jsonl 存的是沒壓過的版本、模型看到的是壓過的版本,兩邊紀錄分岔,重啟之後那些 hash 還可能變死的領不回來。
保守路線能省的也就 RTK 實測那種個位數到十幾 %,要去換這一整包整合風險,怎麼算都不值得。
寫到這裡,headroom 逼我想通一件更根本的事。
省 token 跟資訊損失,其實是同一條軸
我原本以為「省 token」跟「保真」是兩件可以分開談的事,省得多不多是一回事、有沒有失真是另一回事。dry-run 跑完才發現,它們根本是同一條軸。
可逆壓縮報的那個漂亮數字,是「搬走的當下省了多少」,但它能省的前提,就是賭模型大部分時候不會回頭去讀原文。每省掉一個 token,就是賭那塊內容真的不需要。取回率高,安全,但真正省到的就縮水;取回率低,實際省的接近帳面數字,可是模型就在拿那堆拆散的關鍵詞硬答,那是另一種無聲誤讀。
所以那種「一百塊內容最後只取回兩塊」的大省,只在清單型、掃過就丟的內容上才安全成立,像搜尋結果、log 那種。而那剛好就是無損那條路省的 15.6%。ML 那個漂亮的 69.7%,是硬把壓縮套到你正在用的內容上換來的,比方正在改的 code,那裡偏偏是取回最該發生、不領風險最高的地方。再疊上 Claude Code 本來就會選擇性地讀(grep、分頁),加上 Max 既有的 prompt caching,能省的邊際比帳面上小很多。
講白了,「省很多又完全保真」這件事本質上做不到,除非你省掉的本來就是冗餘。
反過來看:唯一被我留下的,不是因為它省 token
五個裡面只有 semble 被我留著繼續用。但留它的理由,恰好不是省 token。
它在省 token 這件事上其實兩頭都歪:數字誇大(自報 96%、實測 32%),而且根本量錯了東西。真正讓它留下來的,是它能做一件 grep 做不到的事,跨語言的概念檢索。
我手上一個專案後端是 ClojureScript、前端是 TypeScript。我用自然語言問一個概念,semble 一次就把兩端都撈出來,grep 做不到,因為 grep 得先分語言、還得先知道確切的 symbol 名才搜得到。我靠它撈出來、Read 確認、最後修掉一個篩選邏輯的 bug,一路進了 merged PR,證據鏈是完整的,不是玩具用法。
換個角度看:semble 在「省 token」上既誇大、又根本沒量到重點,卻是唯一值得留的。這反過來剛好說明,省 token 從來就不是一個工具值得用的真正理由。
一句帶走
裝省 token 工具之前,先問自己三個問題:我到底在省哪一種成本、省得到多少、要賠掉什麼。
我這五個試下來的答案幾乎都一樣:省得有限,又要拿無聲降級、燒機、或者一個跟 caching 互斥的 proxy 去換。連 headroom 那種方向比較對的工具,最後也輸在省得有限、整合風險又太重。
更別忘了最後想通的那一層:省 token 多數時候就是拿資訊損失去換。所以省 token 不該是裝工具的理由。真要省成本,我再找時間寫一篇講「外包便宜模型」。