CLIコーディングエージェントは便利ですが、何も制御しないとトークンコストがすぐに膨らみます。Claude CodeやCodexにリポジトリ全体を渡して「このモジュールをリファクタリングして」と依頼すると、エージェントは多数のファイルを読み込み、テストを何度も実行し、不要なコンテキストまでモデルに送ります。8人のチームがこれを毎日繰り返すと、請求額は無視できません。多くの無駄は、モデルを変えたり品質を落としたりせず、CLIの使い方と設定で削減できます。
TL;DR
CLIエージェントのトークンコストを下げる基本方針は、モデルに渡す前にコンテキストを削ることです。
実践することは次のとおりです。
- 作業対象ファイルを明示して、リポジトリ全体を探索させない
-
CLAUDE.mdなどのメモリファイルを短く保つ - 長いセッションは
/compactまたは/clearで整理する - 安定したシステムプロンプトやリポジトリ規約にはプロンプトキャッシュを使う
- コミットメッセージや要約などの軽い作業は安価なモデルに回す
- テストログや
git diffなどのツール出力を絞る - 実行ごとのトークン数とコストを記録する
はじめに
CLIエージェントのコスト問題は、主に2つの形で現れます。
- 週次またはセッション制限に到達し、作業途中で止まる
- 月次のAPI請求書を見て、想定以上の支出に気づく
原因は同じです。CLIエージェントはデフォルトで大量のトークンを使います。
たとえば、10行だけ確認すればよい場面でもファイル全体を読み込みます。毎ターン会話履歴を再送信します。テストログやスタックトレースをそのままコンテキストに戻します。同じシステムプロンプトやリポジトリ規約も何度も送信します。
リファクタリング対象が実質2,000トークンのコードで済むなら、180,000トークンのコンテキストは不要です。この差分が削減余地です。
この記事では、CLIエージェント実行でトークンがどこに使われるかを整理し、次の観点で削減手順を示します。
- コンテキストの衛生管理
- メモリファイルの整理
- プロンプトキャッシュ
- モデルルーティング
- ツール出力と検索結果のトリミング
- 実行ごとのコスト測定
例はClaude CodeとCodexを想定しますが、考え方はトークン課金APIを使う多くのCLIエージェントに適用できます。
また、見落とされがちな隣接コストとして、APIデバッグがあります。エージェントが不安定な内部APIを呼び出すと、失敗、再試行、エラーボディの読解、ドキュメント再読み込みを繰り返し、そのたびにトークンを消費します。
💡 エージェントがAPIに触れる場合は、先にApidogでAPIを設計、モック、テストしておくと、高価な試行錯誤を減らせます。エージェントは予測不能なライブエンドポイントではなく、契約どおりに動作するAPI仕様に対して作業できます。
CLIエージェント実行でトークンが使われる場所
最適化する前に、1回のエージェント実行で何に課金されるかを把握します。
通常、1ターンでは次の2つに対して料金が発生します。
- モデルに送る入力トークン
- モデルから返る出力トークン
多くのプロバイダーでは、出力トークンは入力トークンより高価です。あるフロンティアモデルファミリーの例では、入力が100万トークンあたり約3ドル、出力が約15ドルです。同じファミリーの安価なモデルでは、入力が約1ドル、出力が約5ドルのような価格帯になることがあります。
これはあくまで例です。実際の価格はプロバイダーの最新料金ページを確認してください。重要なのは、出力は高価で、入力は量が膨らみやすいという構造です。
入力ペイロードには、主に次のものが含まれます。
システムプロンプトとツール定義
エージェントの指示、ツールのJSONスキーマなど。ターンごとに送信されます。メモリファイルとプロジェクト規約
CLAUDE.md、リポジトリ規約、永続的な指示など。関連性に関係なく読み込まれがちです。会話履歴
以前のユーザーメッセージ、モデル応答、ツール呼び出し、ツール結果。長いセッションほど大きくなります。読み込まれたファイル内容
エージェントがReadしたソースコード。大きなファイル全体を読み込むと一気に増えます。ツール出力
テストログ、npm installの出力、git diff、スタックトレースなど。デフォルトでは冗長です。
特に重要なのは、会話履歴が毎ターン再送信されることです。
30ターンのセッションは、単純に1ターンの30倍ではありません。後半のターンは、前半の履歴をすべて背負って実行されます。そのため、長く蛇行したセッションほど高コストになります。
Claude Codeのセッション制限やウィンドウの考え方を詳しく確認したい場合は、Claude Codeのトークンウィンドウがどのようにリセットされるかも参考になります。
コンテキストの衛生管理とメモリファイル
最も安いトークンは、送信しないトークンです。
まずは、エージェントに渡すコンテキストを明示的に絞ります。
作業対象ファイルを指定する
悪い例は、リポジトリルートで漠然と依頼することです。
claude "課金ロジックをリファクタリングして"
この依頼では、エージェントは関連ファイルを探すために広範囲を探索します。
代わりに、対象ファイルと制約を明示します。
claude "指数関数的バックオフを使うようにリトライロジックをリファクタリングして。
変更対象は src/payments/retry.ts と対応するテストファイルのみ。"
これにより、エージェントが20個の候補ファイルを読み込む前に、必要な作業セットを絞れます。
探索が必要な場合も、リポジトリ全体ではなくディレクトリを指定します。
claude "src/payments/ 配下だけを調べて、リトライ処理の実装箇所を特定して"
CLAUDE.md を短く保つ
CLAUDE.md や同等のメモリファイルは、ターンごとにコンテキストに入ります。ここに長いオンボーディング文書や設計背景を書くと、毎回課金対象になります。
まずサイズを確認します。
# 文字数 / 4 をトークン数の概算として見る
wc -c CLAUDE.md | awk '{print "≈", int($1/4), "トークン/ターン"}'
CLAUDE.md に入れるべき内容は、短く実行に必要なものだけです。
例:
# Project instructions
- Package manager: pnpm
- Run tests: pnpm test
- Run typecheck: pnpm typecheck
- Do not edit generated files under dist/
- Follow existing error handling patterns in src/shared/errors.ts
- API contract docs are in docs/api/
避けるべき内容:
- 長いアーキテクチャ解説
- 月に一度しか使わない手順
- 過去の意思決定の詳細
- 外部ドキュメントの全文コピー
詳細は別ファイルに置き、必要なときだけエージェントに読ませます。
長いセッションは圧縮またはリセットする
同じセッションで無関係なタスクを続けると、前の履歴がすべて残ります。
Claude Codeでは、長くなったら次を使います。
/compact
これは履歴を短い要約に圧縮し、生のトランスクリプトを破棄します。
タスクが完全に変わる場合は、次でリセットします。
/clear
実践ルールはシンプルです。
- 1セッション = 1論理タスク
- タスク間では
/compactまたは/clear - 古いデバッグログを次の作業に持ち込まない
この習慣は、Claude Codeのワークフローでも重要なパターンです。
無視ファイルを設定する
生成物や依存関係をエージェントの探索対象から外します。
例:
node_modules/
dist/
build/
coverage/
.tmp/
*.lock
エージェントが dist/ や node_modules/ を見なければ、それらを読み込んだり差分に含めたりするトークンも発生しません。
プロンプトキャッシュ: 同じプレフィックスに毎回課金されないようにする
プロンプトキャッシュは、繰り返し実行で大きな効果があります。
プロンプトキャッシュでは、システムプロンプト、ツール定義、リポジトリ規約などの安定したプレフィックスをプロバイダー側で保存します。同じプレフィックスを使う後続リクエストでは、その部分を割引価格で読み込めます。
Anthropicのプロンプトキャッシュでは、概念的に次のような経済性になります。
- キャッシュ書き込み: 通常入力より高い
- キャッシュ読み込み: 通常入力より大幅に安い
- 短寿命キャッシュでは、1回程度ヒットすれば元を取りやすい
- 大きく安定したプレフィックスほど効果が大きい
実装上の基本は、安定した内容を前に置き、変わる内容を後ろに置くことです。
順序は概ね次のように考えます。
tools → system → messages
タイムスタンプ、ユーザー入力、取得したファイル内容などの可変要素を、キャッシュしたいプレフィックスの前に入れないようにします。
独自のCLIラッパーでAnthropic APIを呼ぶ場合の例です。
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT + REPO_CONVENTIONS,
"cache_control": {"type": "ephemeral"},
}
],
messages=[
{
"role": "user",
"content": user_task,
}
],
)
u = response.usage
print("キャッシュ書き込み:", u.cache_creation_input_tokens)
print("キャッシュ読み込み:", u.cache_read_input_tokens)
print("新規入力:", u.input_tokens)
運用時の注意点は2つです。
キャッシュ対象のプレフィックスをバイト単位で安定させる
タイムスタンプやランダムな値を入れるとキャッシュが無効化されます。関連する実行をまとめる
キャッシュ寿命が短い場合、作業をまとめるほどヒット率が上がります。
OpenAI APIでも、対応モデルではキャッシュ済み入力に割引が適用される場合があります。細かいノブは異なりますが、原則は同じです。
Codex側のフリーティアやルーティングも併用する場合は、Codexを介してGPT-5.5を無料で実行するも参考になります。
モデルルーティング: 安価な作業には安価なモデルを使う
すべてのタスクに最上位モデルは不要です。
次のような作業は、軽量モデルでも十分なことが多いです。
- コミットメッセージ作成
- 差分の要約
- changelogの下書き
- 単純なリネーム
- ボイラープレートテスト生成
- lintエラーの説明
一方で、次のような作業では強いモデルを使います。
- アーキテクチャ変更
- 複数モジュールにまたがる設計判断
- セキュリティ影響のある変更
- 複雑なバグ調査
CLIでは、タスクごとにモデルを切り替えます。
# 軽い作業
claude --model haiku "ステージングされた差分に対して conventional commit メッセージを書いて"
# 重い設計作業
claude --model sonnet "支払いサービスのキャッシングレイヤーを再設計して"
推奨は、デフォルトを安価なモデルに寄せ、必要なときだけ上位モデルにエスカレートする運用です。
多くのチームは逆に、「安全のため」すべてを高価なモデルに投げます。その結果、コミットメッセージにも高価な出力単価を支払うことになります。
サブエージェントにも小さいモデルを使う
エージェントフレームワークがサブエージェントをサポートしている場合は、狭い作業を子エージェントに委譲します。
例:
- 子エージェント: 検索、要約、候補抽出
- 親エージェント: 設計判断、最終編集
子エージェントには、安価なモデルと最小限のコンテキストだけを渡します。親エージェントは、子が返した短い要約だけを読むようにします。
この構造は、CodexとClaude Codeにおける目標コマンドでの自律ループパターンでも扱われています。
使用量制限付きプランでは、モデルルーティングはコスト削減だけでなく、割り当てを長持ちさせる効果もあります。Claude Codeの週次制限の増加のような変更があっても、上限内で長く使うにはルーティングが重要です。
ツール出力と検索結果をトリミングする
ツール出力は、静かにコストを増やします。
エージェントが実行したコマンドの出力は、そのままコンテキストに戻ります。その後のターンでも再送信されます。
特に危険なのは次です。
-
npm installの長いログ - 冗長なテスト出力
- 巨大な
git diff - スタックトレース全文
- 生成ファイルやロックファイルの差分
必要なのは、多くの場合「成功/失敗」と「関連するエラー部分」だけです。
コマンドを静かにする
# 冗長
npm test
# 静か
npm test --silent -- --reporter=dot
# 冗長
npm install
# 静か
npm install --silent --no-audit --no-fund
出力をフィルタリングする
# pytest の最後の30行だけ返す
pytest -q 2>&1 | tail -n 30
# 巨大な差分ではなく統計だけ見る
git diff --stat
# 失敗行だけ抽出する
npm test 2>&1 | grep -E "(FAIL|✗|Error)" | head -n 20
エージェントに実行させるコマンド自体を、最初からこの形で指定します。
claude "テストは 'pytest -q 2>&1 | tail -n 30' で実行して。失敗箇所だけを見て修正して。"
ファイル全体ではなく必要な範囲だけ読む
1つの関数を変更するために、1,500行のファイル全体を読む必要はありません。
エージェントには明示的に指示します。
ファイル全体を読まず、retry を処理している関数だけを検索して、その周辺だけ読んでください。
または、先に人間が範囲を指定します。
sed -n '120,220p' src/payments/retry.ts
大きなファイルでは、これだけで数万トークンを数百〜数千トークンに抑えられます。
検索結果の件数とサイズを制限する
RAGやコード検索を使うエージェントでは、取得チャンクが多すぎるとコストが膨らみます。
良い設定の方向性は次です。
- 取得件数を少なくする
- チャンクサイズを小さくする
- 関連度の低い結果を返さない
- ドキュメント全文ではなく該当セクションだけ渡す
モデルが実際に使うかどうかに関係なく、取得されたトークンには課金されます。
実行ごとのコストを測定する
削減できているかを判断するには、実行ごとのコストを記録します。
APIレスポンスに usage が含まれる場合は、それを保存します。
u = response.usage
# 例示用の単価。実運用では最新料金に置き換える。
INPUT_RATE = 3.00 / 1_000_000
OUTPUT_RATE = 15.00 / 1_000_000
CACHE_READ = 0.30 / 1_000_000
CACHE_WRITE = 3.75 / 1_000_000
cost = (
u.input_tokens * INPUT_RATE +
u.output_tokens * OUTPUT_RATE +
u.cache_read_input_tokens * CACHE_READ +
u.cache_creation_input_tokens * CACHE_WRITE
)
print(
f"実行コスト ≈ ${cost:.4f} "
f"(入力={u.input_tokens} 出力={u.output_tokens} "
f"キャッシュ読み込み={u.cache_read_input_tokens})"
)
CLIを直接使っている場合は、次の方法で測定します。
# Claude Codeのセッションコストを確認する例
claude /cost
より実用的には、ラッパースクリプトを用意して、タスク単位でログを残します。
#!/usr/bin/env bash
TASK_LABEL="$1"
shift
START=$(date -Iseconds)
claude "$@"
END=$(date -Iseconds)
echo "$START,$END,$TASK_LABEL" >> agent-runs.csv
さらに精度を上げるなら、次を分けて記録します。
- プロジェクト名
- タスク種別
- モデル名
- 入力トークン
- 出力トークン
- キャッシュ読み込み
- キャッシュ書き込み
- 推定コスト
代表的なタスクごとに、時系列で比較します。
例:
- 日常的なリファクタリング
- PRレビュー
- テスト修正
- コミットメッセージ生成
- APIクライアント更新
キャッシュを有効化した後、軽い作業を安価なモデルに回した後、ツール出力を絞った後に、この数値が下がるか確認します。
下がらなければ、その施策は想定ほど効いていません。月末の請求書ではなく、1回の実行で気づけるようにします。
戦術の比較
| 戦術 | 典型的なトークン削減量 | 労力 |
|---|---|---|
| 作業セットを絞る | 実行あたりの入力で30〜60% | 低 |
| メモリファイルを短く安定させる | ターンごとに5〜15% | 低 |
タスク間で /compact または /clear
|
長いセッションで40〜80% | 低 |
| 安定したプレフィックスでプロンプトキャッシュ | キャッシュ対象部分で約90% | 中 |
| モデルルーティング | ルーティング対象タスクで50〜80% | 中 |
| 静かなツール出力 | ツール多用時に20〜50% | 低 |
| ファイル全体ではなく必要範囲だけ読む | 大きなファイル編集で70〜95% | 低 |
| 検索範囲を制限する | RAG多用時に30〜60% | 中 |
| 実行ごとのコスト測定 | 直接の削減は0%。他の施策を検証できる | 低 |
削減率は目安です。実際の効果は、現在どれだけ無駄なコンテキストを送っているかによって変わります。
結論
CLIエージェントのトークンコストは、かなりの部分をコマンドライン運用で削減できます。
最初にやるべきことは次です。
- 作業対象ファイルを明示する
-
CLAUDE.mdを短くする - 長いセッションを
/compactまたは/clearで区切る - テストログやdiffを絞る
- 軽い作業を安価なモデルに回す
- 実行ごとのコストを記録する
その上で、安定したプレフィックスにプロンプトキャッシュを適用します。
品質を落とす必要はありません。モデルに渡す不要な情報を減らし、安いモデルで十分な作業を切り出し、ツール出力を制御するだけです。
Top comments (0)