皆さん、こんにちは。
クラウド技術部のR.Aです。
Claude Codeのトークン消費を減らすツールとして、rtk・headroom・lean-ctx・h5iなどがあります。
公称の削減率がどれも大きく、気になったのでこのPC(Windows 11)のClaude Code環境に実際に入れて試してみました。
今回はこのうちrtkとheadroomの2つを導入し、lean-ctxとh5iは別日に持ち越しています。
導入前に各ツールの公式リポジトリと第三者評価を調べたところ、公称の削減率にはそのまま鵜呑みにできない誇張が含まれていました。
さらに導入作業では設定ファイルの自動編集や通信エラーなど、いくつかの事象にぶつかりました。
今回はその経緯と、実際に測れた削減率を記録します。
目次
- はじめに(結論)
- 検証環境
- 導入方針
- rtk導入で起きたこと
- headroom導入で起きたこと
- rtkとheadroomの併用
- おまけ: 経緯不明のMCPサーバー登録
- 公称値と実測のギャップ
- おわりに
はじめに(結論)
先に結論を書きます。
rtk・headroomとも実在するツールで、動作もします。
ただし公称の削減率をそのまま信じると期待外れになります。
- rtkの公称値は「Bash出力60〜90%削減」ですが、このPCで
git statusとgit log --oneline -50の2コマンドを実行した範囲では、rtk gainが示す全体の削減率は7.9%でした - headroomの公称値は「コーディングエージェントで20%」ですが、最小限の質問1回(2 API call分)を計測したところ37.9%でした。ただしこれはシステムプロンプトなど質問内容と無関係な固定部分が大半を占めるリクエストでの数字で、継続的なエージェント作業とは前提が異なります
- Microsoft CopilotチームのエンジニアEvan Boyle氏はX投稿 で、rtk・headroomのような圧縮ツールについて「圧縮結果は良くてニュートラル、多くの場合はトークン消費がむしろ増加した。エージェントに必要な情報を圧縮が取り除いてしまい、再読込を誘発するため」と述べています
「入れれば減る」ツールではなく「入れても増える場合がある」ツールとして、慎重に扱う必要があるという前提で導入を進めました。
検証環境
このPCの環境は以下の通りです。
- OS: Windows 11(会社PC)
- WSL: Ubuntuディストリビューションがインストール済み(導入作業時点でStopped)
- Rust/Cargo: 未インストール
- Python: 3.14(
C:\Python314)と3.13(C:\Program Files\Python313)の2系統 - Node.js: インストール済み
事前に4ツールの実在確認と第三者評価をWeb検索・WebFetchで調べた結果は次の通りです。
| ツール | 公称削減率 | 第三者評価 | Windows対応 |
|---|---|---|---|
| rtk (rtk-ai/rtk) | Bash出力60〜90% | Copilotチーム実測で実質約17%程度、誇張ありとの指摘 | 対応(v0.37.2以降ネイティブ.exe) |
| headroom (headroomlabs-ai/headroom) | 20%(コーディングエージェント)〜95%(JSON) | Copilotチーム実測で「ニュートラル〜逆効果」の報告あり | 対応(pip、Python 3.10以上) |
| lean-ctx (yvgude/lean-ctx) | 60〜99% | 第三者による定量評価は未確認、公称値のみ | 対応(PowerShellスクリプトあり) |
| h5i (h5i-dev/h5i) | 最大95% | 第三者による定量評価は未確認、公称値のみ | 非対応(Linux/macOS限定、WSL経由のみ) |
導入方針
「rtk + headroomの積層戦略が最小手間で最大効果」という主張も見かけましたが、上記の第三者評価と矛盾するため、この方針はそのまま採用しませんでした。
代わりに次の方針で進めました。
- 一括導入せず、1ツールずつ有効化して動作確認してから次に進める。同時に複数を有効化すると、問題が起きた際にどのツールが原因か切り分けできなくなるため
- 各ツール導入直後に、小さな出力(
ls程度)と大きな出力(git log、大きめのファイルRead等)の両方で動作確認する - 逆効果が疑われた場合は無効化する。解除コマンドを事前に控えておき、いつでも元に戻せる状態を維持する
- 公称の削減率をそのまま成果として書かず、公称値と実測を分けて記載する
- h5iはWindowsネイティブ非対応のため、導入する場合はWSL(Ubuntu)環境内に限定する
rtk導入で起きたこと
rtkはGitHub Releasesからバイナリを取得してPATHへ配置した後、次のコマンドで初期化します。
rtk init -g
事象: 非対話モードだとsettings.jsonが自動編集されない
rtk init -gを実行すると、~/.claude/RTK.mdの作成と~/.claude/CLAUDE.mdへの@RTK.md参照追加は自動で行われました。
ただし~/.claude/settings.jsonへのフック追記は、次のプロンプトで止まりました。
Patch existing C:\Users\rei.ando\.claude\settings.json? [y/N]
(non-interactive mode, defaulting to N)
原因は、非対話実行(パイプ経由・スクリプト経由)では確認プロンプトが自動的に「N」扱いになる仕様でした。
表示されたJSON片を手動でコピーし、Editツールで~/.claude/settings.jsonに追記して対応しました。
追記後の内容は次の通りです。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "rtk hook claude" }
]
}
]
}
}
CI等で自動化する場合は、対話プロンプトに依存しない導入手順(settings.jsonを直接生成するなど)を検討したほうがよさそうです。
なおrtk init -gは~/.claude/CLAUDE.mdの末尾に@RTK.mdという1行も無断で追加します。
今回は既存ルール本文には影響がなく末尾への追記のみでしたが、個人のグローバル設定ファイルをツールが無断で書き換える点は事前に把握しておくべき挙動でした。
導入前にCLAUDE.mdのバックアップを取っておいて正解でした。
実測: 削減率はコマンドによって一律ではない
同一環境でgit statusとgit log --oneline -50を、rtk経由と素のコマンドで比較しました。
| コマンド | 素の出力 | rtk経由 | 削減率 |
|---|---|---|---|
| `git status` | 11行 | 3行(porcelain形式相当) | 79.8% |
| `git log --oneline -50` | 2225文字 | 2225文字(変化なし) | 0% |
git log --onelineのように出力が既にコンパクトな形式の場合、rtkのフィルタは対象にしておらず圧縮されませんでした。
rtk公式が挙げる「cargo test 91.8%、git status 80.8%、find 78.3%」等の数字は、rtkが個別に最適化ロジックを持つコマンドに限った値で、「rtkを入れれば全コマンドが一律で数十%減る」わけではないと分かりました。
この2コマンドの実行時点でrtk gainが示した全体の削減率は次の通りです。
RTK Token Savings (Global Scope)
════════════════════════════════════════════════════════════
Total commands: 2
Input tokens: 1.2K
Output tokens: 1.1K
Tokens saved: 91 (7.9%)
サンプル数が少ないため参考値ですが、公称値とは印象が異なります。
フック反映には現在のセッションの再起動が必要
settings.jsonへのPreToolUseフック追記は、今動いているClaude Codeセッションには反映されず、次回セッション起動時から有効になります。
今回の動作確認はrtk <command>をターミナルから直接呼び出す形で行いました。
headroom導入で起きたこと
headroomはpipでインストールします。
pip install "headroom-ai[all]" --python 3.13
Python 3.14環境だとLiteLLM非対応(コスト換算機能のみ不可、圧縮自体は可能)のため、Python 3.13系を明示指定しました。
事象: [all]指定だと機械学習系フルスタックの重量インストールになる
pip install "headroom-ai[all]"を実行すると、litellm経由でtorch(122MB)・transformers・sentence-transformers・onnxruntime等が芋づる式にインストールされ、依存パッケージ数は100個を超えました。
「ローカルでトークンを削るだけの軽量ツール」というイメージより、実際のインストールは重量級でした。
回線・ディスク容量に余裕がない環境では、素のpip install headroom-ai(extrasなし)から試すほうが無難です。
事象: headroom.exeがインストール直後PATHに乗らない
pip installの出力に次の警告が出ました。
WARNING: The script headroom.exe is installed in '...\Roaming\Python\Python313\Scripts' which is not on PATH.
ユーザーPATHへの追加を手動で行いました。
事象: 初回起動時にSSL証明書検証エラーで失敗した
requests.exceptions.SSLError: HTTPSConnectionPool(host='openaipublic.blob.core.windows.net', port=443):
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
原因は、このPCにインストールされているNorton AntivirusのHTTPS検査機能(SSLインターセプト)でした。
環境変数NODE_EXTRA_CA_CERTSはNorton証明書(C:\ProgramData\Norton\Antivirus\wscert.pem)を指すよう既に設定済みでしたが、これはNode.js向けの設定で、Python(requests/certifi)は参照しません。
headroomはtiktokenのエンコーディングデータを起動時にネット経由で取得する挙動があり、そこでSSL検証に失敗していました。
回避策として、Python側のcertifi証明書バンドル(certifi.where()で取得できるcacert.pem)とNorton証明書を結合したファイルを作り、REQUESTS_CA_BUNDLE環境変数(およびSSL_CERT_FILE)でそれを指すよう設定したところ、プロキシが正常起動しました。
ウイルス対策ソフトがHTTPS検査を行う環境では、Python製ツールでこの種のSSLエラーが起きうる点は、汎用的な知見として残しておく価値があります。
事象: compress()にプレーンな文字列を渡すとフェイルセーフで原文がそのまま返る
Pythonライブラリとしてheadroom.compress()を単体で試した際、最初は生の文字列を渡してしまい以下のエラーになりました。
Compression failed, returning original messages: 'str' object has no attribute 'get'
compress()はOpenAI Chat Completions形式のmessages配列([{"role": "...", "content": "..."}])を期待しています。
エラー時は例外を投げず、圧縮前の原文をそのまま返すフェイルセーフ設計になっているため、気づかずに使うと「圧縮されているつもり」で実は素通りしている状態になりえます。
正しい形式で渡し直したところエラーは解消しましたが、3メッセージ・500文字弱程度の小規模な入力では圧縮は一切かからず、入力と出力が一致しました。
headroom公式ドキュメントにも「小さい出力は圧縮オーバーヘッドで逆効果になりうる」という記載があり、今回の実測はそれを裏付ける形になりました。
事象: headroom wrap claudeでConnection refusedになった
headroom wrap claudeはプロキシを起動した上でclaudeコマンド自体を起動し続ける常駐型のラッパーです。
今まさに動いているClaude Codeセッション内から実行すると、セッションを入れ子でラップする形になり後始末が難しいため、バックグラウンドジョブとしてプロキシ起動(Starting Headroom proxy on port 8787 Proxy ready)までを確認した後、別セッションでSSL証明書関連の環境変数(REQUESTS_CA_BUNDLE、SSL_CERT_FILE)を設定した上で、独立したターミナルからheadroom wrap claude経由でClaude Codeをprintモード(-p)実行し、実際のAPI経由の圧縮効果を計測しようとしました。
HEADROOM WRAP: CLAUDE
API Error: Connection refused -- a firewall or proxy may be blocking it (ConnectionRefused)
プロキシのバナー表示までは到達しており起動自体はしていましたが、Claude Code側がAnthropic APIへの接続を試みた段階で拒否されました。
この時点では原因未特定で、常駐プロキシの起動失敗・ポート不一致・Nortonアンチウイルスのファイアウォールによるプロキシ宛て通信のブロックのいずれかが疑わしい、という状況でした。
原因調査: プロキシ起動待ちのレースコンディション
headroom proxyを単体でバックグラウンド起動し、headroom doctorで疎通を確認したところ、次の挙動が分かりました。
- 起動直後(数秒以内)は
proxy: ✗ fail -- not reachable at http://127.0.0.1:8787 - 数秒待ってから再実行すると
proxy: ✓ pass -- running at http://127.0.0.1:8787
プロキシログを見ると、起動シーケンスの中でLiteLLMがモデルコストマップをGitHubから取得しようとして証明書エラー(SSL証明書エラーと同種)になり、ローカルのフォールバックに切り替わるまでの間、127.0.0.1:8787のLISTEN開始が遅延していました。
15:13:10 - LiteLLM:WARNING: get_model_cost_map.py:454 - LiteLLM: Failed to fetch remote model cost map from
https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json:
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
headroom wrap claudeはプロキシの起動とclaudeプロセスの起動をほぼ同時に行っており、起動完了を待つ実装にはなっていないとみられます。
Connection refusedは、プロキシがまだLISTENを開始していないタイミングでClaude CLIが接続を試みたことによるレースコンディションが原因である可能性が高いという結論に至りました。
解決策: プロキシ起動を待ってから接続する2段階手順
headroom wrap claudeを直接使わず、次の2段階手順に切り替えたところ回避できました。
export ANTHROPIC_BASE_URL=http://127.0.0.1:8787
claude -p "1+1は?"
headroom doctorでproxy: runningになっているのを確認してから実行したところ、Connection refusedは再現せず正常に応答(2)が返りました。
プロキシの起動完了を待ってから接続する手順にすれば回避できることが確認できました。
実測: headroom経由での圧縮効果
上記の呼び出し後、headroom doctorのsavings項目およびheadroom savingsコマンドで実測値を確認しました。
savings: 1,483 tokens / $0.05 saved lifetime -- last request just now
Today 37.9% saved 40,553 / 107,131 tokens $0.0811
Savings by client: claude-code 2 calls · 40,553 tokens saved
「1+1は?」という最小限の質問1回(2 API calls分)で、107,131トークン中40,553トークン(37.9%)が削減された計算になりました。
ただしこれはシステムプロンプトやツール定義など、質問内容とは無関係な固定部分が大半を占めるリクエストでの結果で、headroomの公称値「20%(コーディングエージェント)」という数字とは前提(単発質問 vs 継続的なエージェント作業)が異なります。
継続的なエージェント作業での実測は別途必要です。
事象: Windows永続自動起動が権限不足で失敗した
headroomにはClaude Code起動時にプロキシを自動起動させる仕組み(headroom install apply)があります。
Claude Codeのみを対象(--providers manual --target claude)、既定のpreset(persistent-service)で実行を試みました。
Warning: persistent-service is not supported on Windows because the Python runner cannot act as a Windows service. Falling back to persistent-task with Task Scheduler.
エラー: アクセスが拒否されました。
Error: Failed to install deployment 'default': Command '['schtasks', '/Create', '/TN', 'headroom-default-startup', '/XML', '...', '/F']' returned non-zero exit status 1.
persistent-serviceはWindowsでは未対応で、Windowsタスクスケジューラ(persistent-task)へ自動フォールバックする仕様ですが、schtasks /CreateがAccess is deniedで失敗しました。
念のため無関係な単純なテストタスクでも同じschtasks /Createコマンドを試したところ、同様にAccess is deniedとなりました。
whoami /groups
# BUILTIN\Administrators Alias S-1-5-32-544 Group used for deny only
whoami /groupsで確認したところ、このアカウントはBUILTIN\Administratorsに所属してはいるもののGroup used for deny only(管理者権限が明示的に拒否される設定)になっていました。
会社PCのグループポリシーによる制限とみられ、headroom側の不具合ではなく、この端末固有の権限制約が原因でした。
~/.claude/settings.jsonへの書き込みは発生しておらず(実行前バックアップと完全一致)、deploymentも未登録のままで副作用は残っていませんでした(headroom install statusで確認済み)。
この環境ではタスクスケジューラ経由の自動起動は使えないため、自動起動は諦め、検証・利用のたびにheadroom proxyを手動起動する運用にしました。
headroom proxy & # プロキシを起動(127.0.0.1:8787)
headroom doctor # "proxy: running" になるまで待つ(起動に数秒かかる)
export ANTHROPIC_BASE_URL=http://127.0.0.1:8787
claude # このシェルから起動したclaudeだけがプロキシ経由になる
rtkとheadroomの併用
~/.claude/settings.jsonのPreToolUseフック(rtk hook claude)が有効な状態のまま、headroom経由の呼び出しを実施しました。
rtk gainで確認したところ、このセッション中の17コマンド(rtk read、rtk grep、rtk git status等)で77.3%の削減が記録されていましたが、claude -pコマンド自体はrtkの圧縮対象一覧には現れませんでした。
rtkはBashツールが実行する個々のコマンド(git status、ls、grep等)の出力をローカルで圧縮し、headroomはAnthropic APIへのリクエスト/レスポンス自体(システムプロンプト・会話履歴)を圧縮する、という別レイヤーで動作しており、今回の検証では相互作用によるエラーや不具合は確認されませんでした。
おまけ: 経緯不明のMCPサーバー登録
今回の検証(rtk・headroom導入)とは別に、~/.claude.jsonのトップレベルmcpServers(全プロジェクト共通のuser configスコープ)にserena(uvx --from serena-agent serena start-mcp-server ...)が登録されており、CONNECTION_CLOSED: Connection closedで接続失敗した状態になっていました。
実装計画にはserena導入の記載がなく、headroomのpip installログを確認しても依存関係として入ったのはMCPプロトコル自体のPython SDKパッケージ(mcp)のみで、serenaサーバー自体のインストール・登録に関する記録は見当たりませんでした。
claude mcp addのような明示的な登録コマンドの実行ログも検証フォルダ内には残っておらず、いつ・何の操作で追加されたかは今回の調査では特定できませんでした。
対応としてclaude mcp remove serena -s userを実行し、user configスコープから削除しました(headroomは影響を受けずConnectedのままでした)。
再度有効化する場合は以下で再登録できます。
claude mcp add serena -s user -- uvx --from serena-agent serena start-mcp-server --project-from-cwd --context claude-code --open-web-dashboard False
公称値と実測のギャップ
今回の検証で分かった、公称値とこのPCでの実測の対応関係をまとめます。
| ツール | 公称値 | このPCでの実測 | 実測時の前提 |
|---|---|---|---|
| rtk | Bash出力60〜90% | `rtk gain`全体で7.9% | `git status`・`git log --oneline -50`の2コマンド |
| headroom | 20%(コーディングエージェント) | 37.9% | 最小限の質問1回(2 API calls)、固定部分が大半を占めるリクエスト |
数字だけ見るとheadroomの実測はむしろ公称値を上回っていますが、前提が「単発の最小質問」であり、継続的なエージェント作業とは条件が異なります。
rtkの実測が公称値を大きく下回っているのは、公称値の元になった数字がrtkが個別に最適化ロジックを持つ特定コマンドに限った値だからです。
どちらも、公称の削減率をそのままこのPCでの効果として見込むのは危険だと分かりました。
Microsoft Copilotチームの指摘の通り、圧縮によってエージェントに必要な情報が失われ再読込が発生すれば、トークン消費はむしろ増加します。
導入する場合は、1ツールずつ有効化して実際のコマンド・実際の作業での削減率を確認し、逆効果が疑われたら無効化する、という運用が必要だと考えます。
おわりに
今回はClaude Codeのトークン削減ツールのうちrtkとheadroomを実際に導入し、公称値と実測のギャップ、そして導入時に起きた事象と解決策を記録しました。
非対話モードでの設定ファイル自動編集の制限、Windows環境固有のSSL証明書エラーやタスクスケジューラの権限問題、プロキシ起動のレースコンディションなど、公式ドキュメントだけを読んでいては分からなかった実態が多く見えてきました。
残るlean-ctxとh5iは、今回の方針(1ツールずつ導入し、公称値と実測を分けて記載する)を踏襲して別日に検証する予定です。
同じようにトークン削減ツールの導入を検討している方の参考になれば幸いです。





