ブログに戻る

コスト最適化ガイド

Claude Codeのトークン使用量: ツール出力をコンテキストから追い出す

PreToolUseフックとcontext-modeプラグインがテストログをClaude Codeのコンテキストから追い出す方法と、フィルタあり/なしのセッションコスト見積もり。

投稿者: CheapTokens Team公開日 読了時間 7 分

テストコマンドがgrepとheadを通してパイプされ、失敗だけがClaude Codeに届く様子を示すターミナル
このページの内容
  1. なぜ1つのログに何度も支払うのか
  2. 修正1: テスト出力をフィルタするPreToolUseフック
  3. 修正2: 大きなツール結果にはcontext-mode
  4. 長いセッションのコスト、フィルタありとなし
  5. CheapTokensモデルでClaude Codeを実行する
  6. クイックチェックリスト

エージェントがテストスイートを3回実行し、請求額がタスクそのものより大きくなった。原因は書いたコードであることはほとんどない。テストログだ。ツールの結果が一度Claude Codeのコンテキストに入ると、以降のすべてのリクエストがそれを再び運ぶ。修正方法は、モデルが見る前にツール出力を縮めることだ。公式な方法はBashに対するPreToolUseフックで、サードパーティの方法はcontext-modeプラグインだ。どちらも以下に示し、CheapTokensモデルでの長いセッションのコスト見積もりも添える。

なぜ1つのログに何度も支払うのか#

Claude Codeのコストページ(https://code.claude.com/docs/en/costs、2026年10月23日確認)によると、Claude Codeは毎回のリクエストで会話全体を送信し、各ツール使用がツール結果を運ぶ別のリクエストを引き起こす。プロンプトキャッシュは履歴をより安いキャッシュレートで再読み込みするが、トークンは依然としてそこにある。

エージェントがnpm testを実行し、10,000行のログを得たとしよう。ドキュメントによれば、その種のログは数万トークンになり得る。30,000トークンと仮定する。次に何をしようと、その30,000トークンはステップ11、ステップ12、ステップ13、そして/clearするかコンパクトするまでの入力の一部だ。そしてこれが落とし穴だ。ログは1ステップには役立つが、30ステップ分支払うことになる。

修正1: テスト出力をフィルタするPreToolUseフック#

同じドキュメントページは前処理としてフックを提案している。Bashに対するPreToolUseフックはテストコマンド(npm test、pytest、go test)を書き換え、grep -A 5 -E '(FAIL|ERROR|error:)' | head -100を通すようにする。するとエージェントは失敗と数行のコンテキストだけを見て、10,000行の緑の点を見ることはない。ドキュメントによれば、これで数万トークンを数百にできる。

フックの前後でエージェントが見るもの
生のnpm test出力と失敗のみの比較

これはそのドキュメントページのスクリプトだ(2026年10月23日確認)。jqが必要だ。mkdir -p ~/.claude/hooksでフォルダを作成し、スクリプトを~/.claude/hooks/filter-test-output.shとして保存し、chmod +xを実行する:

bash
#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')

pattern='^(npm test|pytest|go test)( [^;&|<>`$#\\[:cntrl:]]*)?$'

if [[ "$cmd" =~ $pattern ]]; then
  filtered_cmd="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100"
  echo "$input" | jq --arg filtered "$filtered_cmd" '{hookSpecificOutput: {hookEventName: "PreToolUse", updatedInput: (.tool_input + {command: $filtered})}}'
else
  echo "{}"
fi

次に~/.claude/settings.jsonに登録する:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/filter-test-output.sh" }]
      }
    ]
  }
}

動作を確認するには、Claude Code内で/hooksを開き、PreToolUseエントリを探すか、claude --debug-file ./claude-debug.txtで開始してエージェントにnpm testを実行するよう依頼する。フックがコマンドを書き換えたとき、ファイルにはcommandフィールドを持つmodified tool input keys行がある。テストが通れば出力は空なので、エージェントは静かな成功を得る。ランナーが失敗を別の形式で出力する場合はパターンを調整すること。

修正2: 大きなツール結果にはcontext-mode#

フックはパイプできるコマンドしかカバーしない。Playwrightのページスナップショットや20件のGitHub issueのリストはMCPツールから来る。それがcontext-modeの対象だ。README(https://github.com/mksglu/context-mode、2026年10月23日確認。バージョンや日付は表示されていない)によれば、生のツール出力をコンテキストウィンドウの外に保ち、セッション状態をSQLiteに保存し、フックを通じてツール呼び出しをルーティングするMCPサーバー兼プラグインだ。Claude Code v1.0.33以降が必要で、ライセンスはElastic License 2.0であり、OSIオープンソースライセンスではない。

Claude Code内でインストール:

text
/plugin marketplace add mksglu/context-mode
/plugin install context-mode@context-mode

再起動するか/reload-pluginsを実行し、/context-mode:ctx-doctorで確認する。MCPのみのバリアントclaude mcp add context-mode -- npx -y context-modeはツールを追加するが、自動ルーティングはない。

プロジェクトは大幅な削減を報告している。315 KBが5.4 KB(98%)、56 KBのページスナップショットが299バイト、986 KBが62 KBになる。これらは作者自身の数値だ。上限として扱い、自分のセッションで/contextを使って前後を測定すること。

長いセッションのコスト、フィルタありとなし#

仮定した1セッションでの計算を示す。20,000トークンの平均ベースコンテキスト、1ステップあたり500出力トークン、3回のテスト実行(ステップ10、20、30)の40ステップのコーディングセッションだ。各生ログは30,000トークン、フィルタ版は500だ。

  • ステップ10のログはその後の30リクエストで再送される: 30 × 30,000 = 900,000トークン。ステップ20: 20 × 30,000 = 600,000。ステップ30: 10 × 30,000 = 300,000。追加入力: 900,000 + 600,000 + 300,000 = 1,800,000。
  • フィルタあり: (30 + 20 + 10) × 500 = 30,000追加入力。
  • ベース入力: 40 × 20,000 = 800,000。出力: 40 × 500 = 20,000。
  • したがってセッションはフィルタなしで800,000 + 1,800,000 = 2,600,000入力トークン、フィルタありで800,000 + 30,000 = 830,000、出力トークンはどちらも20,000だ。

計算はすべての入力トークンをフルレートで数えている。キャッシュは実際の数値を下げるが、同じ論理で両方のケースを下げる。MiniMax-M2.7(MiniMaxAI/MiniMax-M2.7、180Kコンテキスト、最大8,192出力トークン)のライブ価格は以下のチャートにある。これはこのような入力重視のエージェントループに適したモデルだ。

MiniMax-M2.7でのセッションコスト、40ステップ
  • フィルタなし$0.133
  • フックあり$0.0445

前提: 40ステップ、20,000トークンのベースコンテキスト、1ステップあたり500出力トークン、30,000トークンのテスト実行3回(フィルタあり: 500)。

MiniMax-M2.7ではセッションはフィルタなしで$0.133、フィルタありで$0.0445かかり、入力と出力を合計するとOpenRouterの参考価格より安い。フィルタなしの場合の入力の約3分の2は、エージェントが一度読んだログだ。

重要なのは正確な金額ではない。フィルタが任意のモデルで2,600,000入力トークンのうち約1,770,000(2,600,000 − 830,000 = 1,770,000)を削減し、安いモデルが残ったすべてのトークンの価格を下げるということだ。

CheapTokensモデルでClaude Codeを実行する#

Claude CodeはAnthropic Messagesプロトコルで通信し、CheapTokensはそれをサポートしている。Claude Code用のベースURLには/v1がない。完全なセットアップはClaude CodeをCheapTokensに接続する方法にある。プレースホルダーキーを使った短縮版:

bash
export ANTHROPIC_BASE_URL=https://api.cheaptokens.dev
export ANTHROPIC_AUTH_TOKEN=YOUR_CHEAPTOKENS_KEY
export ANTHROPIC_MODEL=MiniMaxAI/MiniMax-M2.7
claude

ドキュメントの完全なIDを使用すること。価格表の短い名前はAPIに受け入れられない。すべてのモデルの価格は価格ページにある。Claude Codeの請求を削減する他の習慣(/clear、/compact、/mcp、サブエージェント)については、Claude Codeを安くする方法を参照。実際のリクエストで入力と出力がどのように数えられるかは、APIリクエストは何トークン使うかを読んでほしい。

クイックチェックリスト#

  1. 長いセッションで/contextを実行し、何がスペースを取っているか見る。
  2. テストコマンド用のBashフックを追加し、/hooksまたはデバッグログで書き換えを確認する。
  3. MCPツールが大きなスナップショットを返すなら、context-modeを試し、/contextを前後で比較する。
  4. 無関係なタスク間で/clearし、古いログが付いてこないようにする。