HeadroomはClaude Codeのサブスクリプションの使用量をほとんど減らさない — VS Codeでは1〜2個のプロキシが必要
HeadroomはClaude Codeのリクエストをローカルのプロキシで圧縮します。2.1.292で測ると、サブスクリプションの使用量の変化は前後5%以内で、API料金なら4〜16%減でした。

目次
はじめに
HeadroomでClaude Codeのトークン使用量を減らせると聞き、導入するか決める前に仕組みを知りたくなりました。私のClaude CodeはサブスクリプションでVS Code拡張機能として動いていて、claude.aiのコネクタもつないでいます。そのため、APIの手前に何かを置くなら、コネクタには手を出さないものである必要がありました。
Headroomはローカルのプロキシでリクエストを圧縮します。このプロキシをClaude CodeとAPIの間に置く方法は2通りあります。ANTHROPIC_BASE_URLをプロキシに向けると、ToolSearchとRemote Controlが止まり、コンテキストメーターの値も膨らみます。代わりにapi.anthropic.comへの接続を途中で横取りするフォワードプロキシを使うと、測れた範囲の機能はすべて残りましたが、プロキシが2つ必要です。
私のサブスクリプションでは、使用量はほとんど変わりませんでした。増減は5%以内です。Headroomが圧縮するものの大半はキャッシュ済みで、キャッシュ済みのトークンはサブスクリプションの上限にほとんど効かないからです。API料金で換算すると同じ実行は4〜16%安くなりますが、どちらのルートでも払うコストのほうがはるかに大きいため、私は導入しないことにしました。この記事では、2つのルートと、このトレードオフが割に合う場面を説明します。
Headroomはリクエストの経路のどこに入るのか?
Headroomはコーディングエージェント向けのオープンソースの圧縮レイヤーで、Pythonパッケージheadroom-aiとして公開されています。モデルへのリクエストに入るもの(ツールスキーマ、ツール出力、ログ、会話履歴)を縮め、元のデータはディスクに残します。モデルはheadroom_retrieveツールで元データを取り戻せます。
ネットワークの経路に入る必要があるのは、Claude Codeの内部にはリクエストを書き換えられる仕組みがないからです。フックとは、Claude Codeが決まったタイミングで自動的に実行するコマンドです。PreToolUse、PostToolUse、Stopなどのフックはツール呼び出しやターンの前後で動きますが、どれもAPIのリクエストボディを受け取りません。
入り方は2つです。ルート1は、Claude Codeの送信先のエンドポイントを差し替える方法で、Headroom自身のセットアップコマンドもこの方法を使います。
headroom proxy --port 8787ANTHROPIC_BASE_URL=http://127.0.0.1:8787 claudeルート2は、エンドポイントはそのままにして、外に出ていく接続を途中で横取りする方法です。こちらは別のツールが必要なので、後の節で扱います。
ルート1では、プロキシは/v1/messages(モデルを呼び出すAPIのパス)をapi.anthropic.comに転送します。サブスクリプションのサインインはそのまま通ります。プロキシ経由のセッションも直接接続と同じくapiKeySource: noneを報告しました。これは、APIキーを使わず、サブスクリプションのアカウントでサインインしたままだという意味です。リクエストはすべて成功しました。
ルート1:ANTHROPIC_BASE_URLを差し替える
Claude CodeはANTHROPIC_BASE_URLがapi.anthropic.comを指しているかを確認し、指していなければ一部の機能を止めます。私はClaude Codeに、バージョン2.1.292で同じヘッドレスセッション(対話画面を開かずclaude -pで動かすセッション)を直接接続とプロキシ経由で1回ずつ起動し、それぞれが受け取ったツールとコマンドを比べるよう頼みました。
| 直接接続 | プロキシ経由 | |
|---|---|---|
| claude.aiのコネクタ | 13 | 13(13回中12回) |
/schedule | 使える | 使える |
ToolSearchツール | 使える | ない |
Artifactツール | 使える | ない |
| Remote Control | 使える | 起動を拒否 |
プロキシ経由ではRemote Controlが起動を拒否し、理由も表示します。
入力ANTHROPIC_BASE_URL=http://127.0.0.1:8787 claude remote-control出力Error: Remote Control is only available when using Claude via api.anthropic.com. ANTHROPIC_BASE_URL is set and does not point at api.anthropic.com, so this session is using a custom endpoint — unset it (or run in a shell without it) to use Remote Control.ToolSearchは、MCPのツール定義を毎回すべて送る代わりに、必要になったときに読み込むツールです。ENABLE_TOOL_SEARCH=trueを設定すればプロキシ経由でも戻りますが、Artifactツールは戻りません。
/scheduleはプロキシ経由のすべてのセッションにあり、13個のコネクタはプロキシ経由の13回中12回でそろっていました。残る1回はclaude.aiのコネクタがひとつもない状態で起動し、これは直接接続の8回では一度も起きていません。
ベースURLをプロキシに向けると/contextの値がずれる
/contextは、セッションがコンテキストウィンドウをどれだけ使っているかを表示します。プロキシ経由では、この値が3倍以上に増えました。
| 条件 | /contextの合計 | MCPのツール定義 |
|---|---|---|
| 直接接続 | 47.4k | 107.7kは遅延読み込みで、計上されない |
| プロキシ経由 | 156.1k | 109.1kを読み込み済み |
プロキシ経由、ENABLE_TOOL_SEARCH=true | 191.5k | 137.9kを読み込み済み |
ツール定義の読み込みを遅らせるのはToolSearchの役目です。ベースURLのチェックがこれを止めるため、Claude CodeはMCPのツール定義をすべて最初から読み込み済みとして数えます。しかもHeadroomが圧縮する前の大きさで数えるため、モデルが実際に受け取るトークンはメーターの表示より少なくなります。ENABLE_TOOL_SEARCH=trueを設定しても、遅延読み込みの行は戻りませんでした。
料金はモデルが実際に受け取った内容で決まるので、この膨らんだ値に費用はかかりません。自動コンパクトもこの値には左右されません。自動コンパクトのウィンドウを120kに設定し、表示上の使用量がしきい値を超える状態にしても、2回続けてメッセージを送ってコンパクトは起きませんでした。
wrap vscode-claudeでVS Code拡張機能を経由させる
headroom wrap claudeはプロキシを起動し、その1つのプロセスにだけANTHROPIC_BASE_URLを設定してClaude CodeのCLIを立ち上げます。対象になるのはターミナルのセッションだけです。VS Code拡張機能はVS Codeの環境から自分のClaude Codeバイナリを起動するので、Headroomには拡張機能用の別のサブコマンドがあります。headroom wrap vscode-claude --helpは次のように表示します。
Usage: headroom wrap vscode-claude [OPTIONS]
Route VS Code's official Claude Code extension through Headroom.
Run this from your project, reload VS Code after first setup, and keep this command running while using Claude Code. Authentication and model selection remain unchanged. Run `headroom unwrap vscode-claude` to restore settings.このラッパーは、Claude Codeのユーザー設定のsettings.jsonに2つの項目を書き込みます。http://127.0.0.1:8787/p/<project>を指すANTHROPIC_BASE_URLと、"true"に設定したENABLE_TOOL_SEARCHです。ユーザー設定はそのマシンのすべてのClaude Codeセッションに適用されます。そのため、このファイルに項目が残っている間は、すべてのVS Codeウィンドウとターミナルのセッションがプロキシを通ります。コマンドをどのプロジェクトで実行したかは関係ありません。
Headroomのドキュメントには、プロキシが止まってもAnthropicへの直接接続には切り替わらないと書かれています(「A stopped proxy intentionally does not fall back to a direct Anthropic connection.」)。そのため、ラッパーのプロセスが止まると、それらのセッションはすべて接続できなくなります。
ルート2:ベースURLを変えないフォワードプロキシ
フォワードプロキシとは、クライアントが外向きの接続をすべて預ける先のプロキシで、https_proxyで設定します。Headroomのissueへのコメントで紹介されたclaude-rc-proxyは、まさにこの用途のためのものです。復号するのはapi.anthropic.comへの接続だけで、それ以外のホストは中身を読まない生のトンネルで素通しします。
その接続の中でも、ローカルのバックエンドに回すのは/v1/messagesへのリクエストだけです。Remote ControlのブリッジやOAuthの呼び出しを含むそれ以外は、そのまま本物のAnthropicに届きます。ANTHROPIC_BASE_URLは設定しないままなので、ファーストパーティのチェックを通過します。
何かを動かす前にClaude Codeがソースを読み、公開されている状態ではHeadroomと組み合わせて使えないことが分かりました。モデルゲートウェイ向けに作られているため、リクエストのAuthorizationヘッダーをゲートウェイのトークンに差し替え、/v1/messagesのリクエストをゲートウェイがいる127.0.0.1:8317に送ります。
Headroomと組み合わせるには、送り先をHeadroomのポートに変え、呼び出し元のトークンをそのまま残すようにローカルでフォークする必要がありました。
upstreamPool = "127.0.0.1:8317" // CLIProxyAPIupstreamPool = "127.0.0.1:8787" // Headroom// …r.URL.Scheme, r.URL.Host = poolURL.Scheme, poolURL.Hostr.Header.Set("Authorization", "Bearer "+poolToken)このフォークでは、ゲートウェイのトークンが設定されていないときに/v1/messagesのリクエストを拒否するガードも外しています。rc-proxyが接続を復号するには、Claude Codeがrc-proxyの署名した証明書を信頼する必要があります。そこでテスト用に認証局(TLS証明書に署名するルート証明書)を作り、NODE_EXTRA_CA_CERTS経由でClaude Codeのプロセスにだけ信頼させました。ANTHROPIC_BASE_URLは設定していません。
export https_proxy=http://127.0.0.1:9801 http_proxy=http://127.0.0.1:9801export no_proxy=localhost,127.0.0.1,::1,datadoghq.com,statsig.com,sentry.ioexport NODE_EXTRA_CA_CERTS=/tmp/rcproxy/ca/ca-cert.pem同じシェルから、直接接続のセッションと、2つのプロキシを通したセッションを比べました。
| 直接接続 | ルート2 | |
|---|---|---|
| claude.aiのコネクタ | 8回中8回で13個 | 9回中9回で13個 |
/schedule | 使える | 使える |
ToolSearchツール | 使える | 使える |
/contextの合計 | 32.3k | 33.7k |
apiKeySource | none | none |
測れた範囲では、失われたものはありませんでした。MCPのツール定義は遅延読み込みのままだったので、メーターは直接接続のセッションと同じ値を示します。Headroomのログには/v1/messagesへのリクエストが12回届き、失敗は0回でした。推論は確かにHeadroomを通っています。
リクエストで減った量
ルート1とルート2は別々のバッチで測定しました。各バッチではいくつかの接続方法(以下、条件と呼びます)を交互に回し、同じ数分間に測っています。ルート1の条件は、直接接続、ベースURLをプロキシに向けたもの、さらにENABLE_TOOL_SEARCH=trueを加えたものの3つです。ルート2は、直接接続と、2つのプロキシを通したものの2つです。
ルート1の21回はClaude Codeが自分のシェルで実行し、ルート2の16回は私が自分のターミナルで実行しました。プロンプトは2種類で、一方は1行の返答だけを求め、もう一方はgit log --stat -40を実行してその出力を読ませます。どの条件でも、答えはすべて一致しました。
各回は1つのコマンドで実行し、出力の最後の行に使用量が入ります。2つのルートの違いは環境変数だけです。
ANTHROPIC_BASE_URL=http://127.0.0.1:8787 claude -p "Reply with exactly: OK" \ --output-format stream-json --verbosehttps_proxy=http://127.0.0.1:9801 NODE_EXTRA_CA_CERTS=/tmp/rcproxy/ca/ca-cert.pem \ claude -p "Reply with exactly: OK" --output-format stream-json --verboseサブスクリプションの上限に効くもの
サブスクリプションにはトークン単位の請求がないので、問題になるのはセッションが上限をどれだけ早く使い切るかです。Anthropicの使用上限に関するガイドは、プロンプトのキャッシュ済みの部分は「count less against your limits than new content」(新しい内容よりも上限への影響が少ない)と説明していますが、重みは公表していません。サブスクリプションのアカウントを追跡している第三者のサイトは、回帰分析から、キャッシュ読み取りは上限を「close to none」(ほぼ消費しない)と推定しています。
テスト1:1行のプロンプトとgit log --stat
これをそのまま受け取ると、サブスクリプションで見るべき値は、キャッシュ読み取りを除いた、キャッシュされない入力とキャッシュ書き込みの合計です。
| プロンプト | ルート | 直接接続 | Headroom経由 | 変化 |
|---|---|---|---|---|
| 1行 | ルート1、ToolSearchなし | 16,245 | 11,220 | −31% |
| 1行 | ルート1、ToolSearchあり | 16,245 | 16,993 | +5% |
git log --stat | ルート1、ToolSearchあり | 18,434 | 17,779 | −4% |
| 1行 | ルート2 | 13,636 | 12,989 | −5% |
git log --stat | ルート2 | 17,271 | 17,118 | −1% |
ToolSearchが残る条件では、サブスクリプションの使用量の変化は−5%から+5%の範囲でした。これは同じ条件の実行どうしのばらつきの中に収まります。ルート1の直接接続だけでも、1行のプロンプトで14,090から17,452まで幅がありました。
大きく減ったのは、ToolSearchを失ったルート1の条件の31%だけです。これは圧縮ではなく、読み込むツール定義が減ったことによるものです。
テスト2:ツール出力の多い8ターンのセッション
1行のプロンプトは中身のほとんどが固定のプレフィックスなので、実際の使い方に近いワークロードも測りました。各セッションは8ターンで、どのターンも大きなファイルを読むか、出力の長いコマンドを実行します。各条件を私のターミナルで交互に2回ずつ実行しました。
| 条件 | 1回目 | 2回目 | 2回の平均(直接接続比) |
|---|---|---|---|
| 直接接続 | 40.9k | 44.8k | — |
ルート1、ToolSearchあり | 34.0k | 37.2k | −17% |
| ルート2 | 46.1k | 39.1k | ほぼ0% |
数値は、2〜8ターン目のサブスクリプションの使用量(キャッシュされない入力とキャッシュ書き込みの合計)です。1ターン目はセッションのキャッシュ済みプレフィックスを書き込むターンで、キャッシュがまだ有効かどうかで16kから57kまで振れたため、除いています。
Headroomはツール出力をほとんど圧縮しませんでした。報告された76回のリクエスト全体で、メッセージの内容は1.9%しか縮んでいません。12%という全体の削減の大半はツールスキーマの344,690トークンで、これはキャッシュ済みのプレフィックスにあるため、上限に効く削減はほとんどありません。
ルート1の17%は2回対2回の比較にすぎず、ルート2は同じHeadroomに同じリクエストを送りながら、ほとんど減っていません。そのため、これは圧縮の効果ではなく実行ごとのばらつきだと判断しています。
API料金で見た場合
API料金では、キャッシュ読み取りにも入力単価の10分の1がかかるため、キャッシュ済みのプレフィックスを圧縮すれば多少は安くなります。以下は、テスト1の結果をAPI料金で計算し直したものです。入力トークンの合計は、モデルが受け取ったすべてのトークンを数えたものです。重み付きコストは、キャッシュ済みのプレフィックスの課金方法に合わせてトークン数を換算したものです。キャッシュ書き込みは基本の入力単価の1.25倍、キャッシュ読み取りは0.1倍で計算しています。
ルート1:
| プロンプト | 条件 | 回数 | 入力トークンの合計 | 重み付きコスト |
|---|---|---|---|---|
| 1行 | 直接接続 | 5 | 59,218 | 24,603 |
| 1行 | プロキシ経由、ToolSearchなし | 5 | 35,963 | 16,499 |
| 1行 | プロキシ経由、ToolSearchあり | 5 | 40,825 | 23,727 |
git log --stat | 直接接続 | 3 | 121,077 | 39,338 |
git log --stat | プロキシ経由、ToolSearchあり | 3 | 113,323 | 33,154 |
ルート2:
| プロンプト | 条件 | 回数 | 入力トークンの合計 | 重み付きコスト |
|---|---|---|---|---|
| 1行 | 直接接続 | 5 | 44,550 | 20,153 |
| 1行 | ルート2 | 5 | 37,985 | 18,735 |
git log --stat | 直接接続 | 3 | 94,313 | 29,100 |
git log --stat | ルート2 | 3 | 81,255 | 27,822 |
どの値も、その条件の各回の中央値です。2つの直接接続の値が違うのは、バッチごとに別のシェルで、読み込まれたツールも違ったためです。それぞれのルートは、同じバッチの直接接続とだけ比べてください。ルート1でToolSearchなしの条件は33%減でいちばん安く見えますが、その分ツールが1つ欠けています。
削れたトークンのほとんどは、もともと10分の1の値段で課金されるキャッシュ済みのプレフィックスの分です。1行のプロンプトでは、ToolSearchありのルート1はトークンを31%減らしても、コストは4%しか減りませんでした。ルート2はトークンを15%、コストを7%減らしました。
Headroom自身のレポートでは、削減率はルート1のバッチで36.5%、ルート2のバッチで15.0%でした。ただし、これはトークン数だけを数えた値で、キャッシュ済みのトークンが安いことは考慮されていません。
Headroomの導入をおすすめしない理由
サブスクリプションでは、Headroomによる使用量の増減はどちらの方向にも5%以内で、どちらのルートにもコストがかかるため、導入はおすすめしません。
ルート1で失うのは機能です。
- Remote Controlが起動を拒否する。
ENABLE_TOOL_SEARCH=trueを設定しない限りToolSearchが消え、Artifactツールは設定に関係なく消える。- コンテキストメーターが、モデルの受け取るリクエストの3〜4倍の大きさを表示する。
- プロキシ経由の13回中1回で、claude.aiのコネクタがつながらなかった。
ルート2は機能を残す代わりに、信頼を差し出します。
- ローカルのプロセスが、OAuthトークンを含む
api.anthropic.comへのすべての接続を復号する。 - Headroomと組み合わせるには第三者のツールをフォークする必要があり、そのフォークは自分で保守することになる。
- Anthropicが証明書ピンニング(Claude CodeがAnthropic自身の証明書しか受け付けない仕組み)を導入した日に動かなくなる。
どちらのルートでも、マシン上のすべてのClaude Codeセッションがローカルのプロキシの稼働に依存します。ルート2では、その経路にプロキシが2つ入ります。
HeadroomのREADMEはJSONで60〜95%の削減をうたっていますが、Claude Codeではその場面がほとんど生まれません。JSONを出力するコマンドをClaude Codeに36回実行させたところ、31回は自分でjqに通して絞り込んでおり、生のJSONはコンテキストに入りませんでした。過去195セッションを見ても、ツール出力に占めるJSONは2%程度です。
まとめ
- Claude Codeのフックではリクエストボディを書き換えられないため、Headroomはローカルのプロキシでリクエストを圧縮します。
- ルート1は
ANTHROPIC_BASE_URLの差し替えです。2.1.292ではRemote Control、ToolSearch、Artifactツールが止まり、/contextの値も膨らみます。ENABLE_TOOL_SEARCH=trueでToolSearchは戻りますが、Artifactツールは使えないままです。 - ルート2はclaude-rc-proxyのようなフォワードプロキシです。コネクタ、
/schedule、ToolSearchが残り、/contextの値も正しく出ますが、第三者のツールをフォークして保守する必要があります。 - サブスクリプションでは、
ToolSearchを残した状態で、1行のプロンプトでもツール出力の多いセッションでも、使用量の変化は前後5%以内でした。しかも削れたトークンのほとんどはキャッシュ済みのプレフィックスの分で、上限にはほとんど効きません。API料金に換算すると、4〜16%ほど安くなります。 - Claude CodeはたいていJSONを先に
jqで絞り込むため、READMEがうたう60〜95%はなかなか効いてきません。どちらのルートでも実質的な使用量の削減は見込めないので、Headroomの導入はおすすめしません。
claude -p --output-format stream-jsonの出力を試せば、導入を決める前に比較できます。init行にはそのセッションで使えるツールが、usage行には使ったトークン数が出ます。ぜひ試してみてください。
参考リンク
- headroomlabs-ai/headroom
- Headroom CLIリファレンス
- VS CodeのClaude CodeでHeadroomを使う
- プロキシ経由でRemote Controlが無効になる問題 (headroomlabs-ai/headroom#1779)
- コメント:ANTHROPIC_BASE_URLを設定しないフォワードプロキシを使う
- dthinkr/claude-code-workarounds内のclaude-rc-proxy
- MCPでClaude Codeをツールにつなぐ(ENABLE_TOOL_SEARCHを含む)
- プロンプトキャッシュのキャッシュ書き込み・読み取りの料金
- 使用上限のベストプラクティス(キャッシュ済みの内容がサブスクリプションの上限にどう数えられるか)
- サブスクリプションのアカウントで測ったClaudeの使用上限(キャッシュ読み取りを含む)

