Claude APIコスト最適化|品質を落とさない7つの実践手順
代表取締役 上坂大地郎

結論: Claude APIの費用を下げるとき、最初に安いモデルへ替えるのは順番が逆です。先に品質の合格ラインと1タスク単価を測り、キャッシュ、入力、ループ、出力、非同期処理を整え、最後にモデルを下げると、どこで品質を失ったか追えるようになります。
この記事の要点:
- Anthropic公式Cookbookの「13分の1」は特定の評価条件での結果で、一般的な削減率ではありません
- Prompt cachingは再利用回数とTTLを見て選び、
cache_read_input_tokensでヒットを確認します - 料金表の単価ではなく、合格した仕事1件あたりの総額でモデルと構成を比べます
こんな人向け: Claude APIを使った機能やAIエージェントを運用しており、利用量の増加に備えてコストを管理したい開発者、テックリード、サービス運用担当者。
読み終えると: 現在の処理を7段階で棚卸しし、品質を守ったまま最初の改善を1つ実装できます。
「13分の1」は何を意味しているのか
Anthropicは公式のclaude-cookbooksで、Claude APIのコスト最適化を扱うNotebookを公開しています。紹介されている順序は、単なる料金テクニック集ではありません。品質評価を先に固定し、アーキテクチャを軽くしてからモデルを選び直す、という改善手順です。
Notebookでは保険請求の判定エージェントを題材に、10件の評価セットを使っています。開始時の構成はOpusのhigh effortで10件中10件に正答し、掲載結果は約0.29ドル/タスクでした。その後、7つのレバーを比較し、sonnet · mediumと明示的なキャッシュ境界の組み合わせが同じ10/10を維持した試行で、開始時比13分の1になったとしています。
削減率ではなく、検証方法を見る
この13分の1は、Claude API全体に当てはまる保証値ではありません。公式Notebook自体も、モデル出力は非決定的であり、同じ設定でも合格率と費用が変わるため、複数回の試行が必要だと注意しています。
重要なのは数字の大きさではなく、次の比較軸です。
比較するもの | 単位 | 理由 |
|---|---|---|
品質 | 評価セットの合格率 | 安くても仕事を完了できなければ意味がない |
費用 | 合格した1タスクあたり | 1トークンの単価だけでは再試行や長いループを拾えない |
処理回数 | 1タスクのAPI呼び出し数 | 安いモデルでも何度も呼べば高くなる |
入出力 | cache write/read、通常入力、出力 | どの部分が費用を生んだか分けられる |
待ち時間 | 同期/非同期の許容時間 | Batchへ移せるか判断できる |

モデルを下げる前に、品質を変えない改善を上から順に試します。
手順1: 合格ラインと1タスク単価を固定する
最初にやることは、請求額のグラフを見ることではなく、代表的な仕事と合格条件を決めることです。正常系だけでなく、誤りやすい境界例を含めます。
最小の評価セットを作る
たとえば問い合わせ分類なら、次のように10〜30件から始められます。
- 明らかに1カテゴリへ入る正常系
- 2カテゴリに見える境界例
- 必要情報が欠けており、確認を返すべき例
- 対応してはいけない入力
- 長文、表、添付、ツール呼び出しを含む例
各ケースに期待結果を持たせ、設定を変えるたびに同じセットで比較します。LLMの採点だけに任せず、JSON Schema、必須語、計算結果、人間の判定など、その仕事に合う検査を組み合わせます。
usageをタスク単位で残す
少なくとも次の値をログへ残します。
def usage_record(response, task_id: str) -> dict:
u = response.usage
return {
"task_id": task_id,
"input_tokens": u.input_tokens,
"cache_creation_input_tokens": u.cache_creation_input_tokens,
"cache_read_input_tokens": u.cache_read_input_tokens,
"output_tokens": u.output_tokens,
"stop_reason": response.stop_reason,
}料金はモデルごとに違うため、ログにはモデル名、effort、呼び出し回数、合否も入れます。平均値だけでなく、95パーセンタイルや最悪ケースを見ると、長い入力や再試行で膨らむ処理を見つけやすくなります。
手順2: 固定prefixをPrompt cachingへ寄せる
同じsystem prompt、ツール定義、長い規程、例示を毎回送る処理では、Prompt cachingが最初の有力候補です。キャッシュはtools → system → messagesの順に並ぶprefixを対象にします。
まず自動キャッシュで始める
現在のClaude APIでは、リクエストのトップレベルへcache_controlを置くと、最後のキャッシュ可能なブロックに境界を自動配置できます。
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=STABLE_SYSTEM_PROMPT,
messages=[
{"role": "user", "content": current_request},
],
)複数の寿命を使い分けたい場合や、固定部分と可変部分の境界を厳密に管理したい場合は、content blockへ明示的なcache_controlを置きます。

キャッシュは「付ける場所」より、固定情報を前、可変情報を後ろへ並べる設計が効きます。
5分と1時間の損益分岐
公式価格では、5分cacheの書き込みは通常入力の1.25倍、1時間cacheは2倍、cache readは0.1倍です。出力や可変部分を除き、同じprefixを使う回数だけで比べると次のようになります。
TTL | 1回目 | 2回目 | 3回目 | キャッシュなしとの比較 |
|---|---|---|---|---|
5分 | 1.25 | +0.1 = 1.35 | +0.1 = 1.45 | 合計2回利用から有利 |
1時間 | 2.0 | +0.1 = 2.1 | +0.1 = 2.2 | 合計3回利用から有利 |
5分以内に再利用しない処理へ機械的にキャッシュを付けると、書き込み割増だけを払う場合があります。短時間に集中する会話は5分、間隔を空けて同じ資料を何度も使う処理は1時間、単発処理はキャッシュなしという判断が基本です。
ヒットしたかを必ず見る
レスポンスのusageには次の3項目があります。
cache_creation_input_tokens: 今回書き込んだtokencache_read_input_tokens: キャッシュから読んだtokeninput_tokens: 最後の境界より後で通常処理したtoken
総入力は3項目の合計です。2回目以降もcache_read_input_tokensが0なら、日時、UUID、ツール配列の順序、system promptの差分など、prefixのどこかが変わっています。
手順3: 送らなくてよい入力を減らす
キャッシュは繰り返し入力を安くしますが、入力そのものを消すわけではありません。次は「その情報を最初から毎回渡す必要があるか」を見ます。
情報を3段階に分ける
入力を次の3種類へ分けると整理しやすくなります。
- 必ず必要: 目的、出力形式、禁止条件など、最初から判断に必要
- 条件つきで必要: 製品別仕様、過去事例、長い規程など、該当時だけ読む
- モデルへ渡す必要がない: 合計、並べ替え、形式変換など、コードで確定できる
この考え方は、Agent Skillsで必要な情報だけを読む設計にも通じます。説明を全部常駐させず、必要な資料や処理を後から選ぶ構造です。
tool定義の二重説明を消す
ツールのJSON Schemaを渡したうえで、同じ説明をsystem promptへ一覧で再掲している実装は珍しくありません。公式Cookbookの例でも、ツール定義の再掲を含む膨らんだprefixは13,462 tokensでした。
まず重複を消し、利用頻度の低いツールはTool searchなどの遅延読込を検討します。長いデータを丸ごと会話へ入れる代わりに、Code executionで集計し、必要な結果だけ戻す方法もあります。
推論前にtoken数を測る
Token counting endpointは、Messages APIと同じsystem、tools、画像、PDFを含めた入力token数を、推論前に見積もれます。
count = client.messages.count_tokens(
model="claude-opus-5",
system=system_prompt,
tools=tools,
messages=messages,
)
if count.input_tokens > INPUT_LIMIT:
raise ValueError("入力が上限を超えています")見積値と実際の入力には小さな差が出る場合があります。また公式文書では、Claude 4.7以降の新しいtokenizerは、同じ入力でも以前のモデルより概ね30%多くなると説明されています。過去モデルの計測値を使い回さず、実際に呼ぶモデルで数え直します。
手順4: エージェントループの増加を止める
AIエージェントは、ツール結果、スクリーンショット、検索結果、thinking blockを次のターンへ持ち回ります。2ターン目で必要だった5,000行のログが、10ターン目にも入力へ残っていれば、その後も費用を生み続けます。
残すのは証拠と結論
ツール結果は次の3分類にします。
種類 | 処理 |
|---|---|
今後も参照する根拠 | 原文または必要箇所を残す |
一度判断に使った大量データ | 必要な抽出結果へ置き換える |
再取得できる一時情報 | 期限後に削除する |

大きなツール結果を使い終えたら、後続判断に必要な証拠と結論だけ残します。
Context editingを使える構成では、古いtool resultやthinking blockをAPI側の仕組みで整理できます。独自ループなら、一定サイズを超えた結果だけを安全な抽出へ置き換える方法もあります。
ただし、毎ターン全履歴を要約し直すと、費用が増えるだけでなく、prefixが変わってキャッシュを壊す可能性があります。整理はタスク境界やサイズ閾値で行い、残した内容が次の評価に必要か確認します。
手順5: 出力を「短く」ではなく「完成形」で指定する
出力tokenを減らすとき、max_tokensだけを小さくするのは危険です。モデルは上限値を見て答え方を調整するわけではなく、上限へ達するとstop_reason="max_tokens"で途中終了します。
正確な出力形を渡す
「簡潔に」よりも、完成条件を数えられる形にします。
次のJSONだけを返してください。
- decision: approve / review / reject のいずれか
- reasons: 根拠を最大3件
- missing: 不足情報を最大2件。なければ空配列
説明文やMarkdownは付けないでください。公式Cookbookの掲載例では、同じ大きなmax_tokensを残したまま、出力形を具体化することで、ある試行の出力が4,096 tokensから61 tokensへ減っています。これはその例の結果であり、常に同じ比率になるわけではありません。確認すべきなのは、短くした後も評価セットへ合格するかです。
3つの役割を分ける
max_tokens: 異常に長い生成を止める安全柵- 出力Schema・例: 普段の回答を必要十分な長さにする
- stop sequence: 入力不備など、答えを続ける意味がない場合に早期終了する
「文章を短くする」と「推論を浅くする」も別です。見える回答だけ短くしたいなら出力形を指定し、thinkingやツール探索を減らしたいなら手順7のeffortを評価します。
手順6: 待てる仕事をBatch APIへ移す
Message Batches APIは、リアルタイム応答が不要な大量処理を非同期で実行し、入力・出力tokenの費用を50%にします。
向いている処理
- 夜間の評価セット実行
- 大量文書の分類・要約
- コンテンツモデレーション
- 商品説明などの一括生成
- 翌朝までに終わればよいデータ分析
同期処理のままにするもの
- ユーザーが画面で待っている処理
- 直前のtool resultを見て次の呼び出しを決めるループ
- 時間制約の厳しい通知・障害対応
- 24時間の失効リスクを許容できない仕事
公式文書では、1バッチは100,000リクエストまたは256MBの早い方が上限です。大半は1時間未満で完了するとされていますが、24時間は処理保証ではなく失効期限です。結果は作成後29日間取得できます。
Prompt cachingとの価格修飾は重なります。ただしバッチ内は並列に処理されるため、同じprefixでも後続リクエストが必ず先行リクエストのcacheを読むとは限りません。共通prefixを確実に再利用したい場合は、1時間TTLや処理分割も含めて実測します。
手順7: 最後にeffortとモデルを下げる
ここまでの変更は、主に同じ能力を無駄なく使う方法でした。最後に、同じモデルのeffortを下げ、それでも合格するならモデル階層を下げます。
評価は階段状に行う
いきなりOpusから最安モデルへ替えるのではなく、次の順で1段ずつ試します。
- 現在のモデル・effortで基準値を再計測
- 同じモデルでeffortを1段下げる
- 合格なら、さらに1段下げる
- 不合格になる直前の設定を候補に残す
- 次のモデル階層へ下げ、effortを高めから再評価

単価の安いモデルではなく、評価へ合格した中で1タスク総額が最小の構成を選びます。
高性能モデルは1tokenあたり高くても、少ないターンで完了すれば総額が安い場合があります。反対に、定型分類や抽出は小さいモデルで十分なことがあります。モデル別の単価だけでなく、再試行、tool call、出力、失敗時の人手まで含めて比べます。
API単価の変化も判断へ影響します。GPT-5.6の価格改定を整理した記事でも触れたとおり、モデルの価格は固定ではありません。評価セットと1タスク単価のログを残しておけば、価格改定や新モデル公開時に同じ条件で再比較できます。
【要注意】コスト最適化で起きやすい5つの失敗
1. 請求額だけ見て品質を測らない
総額が下がっても、誤分類や再試行が増えれば、仕事1件の総費用は上がります。先に合格条件を固定します。
2. 動的な日時をsystemの先頭へ入れる
日時、UUID、並び順が変わるツール定義をprefixの前方へ置くと、後続の固定情報までcache missになります。変わる情報は最後のuser message側へ寄せます。
3. 1時間cacheを単発処理へ付ける
1時間cacheの書き込みは通常入力の2倍です。同じprefixを期限内に3回以上使わないなら、かえって高くなる可能性があります。
4. max_tokensを小さくして完成前に切る
max_tokensは回答を賢く短くする設定ではありません。通常出力はSchemaと例で整え、上限は安全柵として余裕を持たせます。
5. Batchを同期エージェントへ無理に入れる
前のtool resultで次の操作が変わる処理は、単純に一括化できません。入力を事前取得して単発処理へ変形できるか、変形が品質へ影響しないかを評価します。
1週間で導入するチェックリスト
すべてを一度に変える必要はありません。次の順なら、原因を切り分けながら進められます。
1日目: 現状を測る
- [ ] 代表タスク10〜30件と期待結果を用意する
- [ ] モデル、effort、呼び出し回数、4種類のtoken、合否を記録する
- [ ] 合格した1タスクあたりの費用を出す
2日目: cacheの再利用地点を探す
- [ ] tools、system、messagesのどこまでが固定か色分けする
- [ ] 自動cacheを1経路へ入れる
- [ ] 2回目の
cache_read_input_tokensを確認する
3日目: 入力を分類する
- [ ] 重複するtool説明を消す
- [ ] 長い資料を「必須/条件つき/コード処理」に分ける
- [ ] 利用モデルで
count_tokensを再計測する
4日目: ループの増加を止める
- [ ] 大きいtool resultが何ターン残るか確認する
- [ ] タスク境界またはサイズ閾値で整理する
- [ ] 整理後も根拠が追えるか評価する
5日目: 出力と非同期処理を分ける
- [ ] 出力Schema、最大件数、早期終了条件を指定する
- [ ] 夜間評価や一括処理をBatch候補へ分ける
6〜7日目: effortとモデルを比較する
- [ ] 1段ずつ設定を下げる
- [ ] 各設定を複数回実行する
- [ ] 品質、1タスク費用、待ち時間の3軸で採用を決める
まとめ
Claude APIのコスト最適化は、安いモデル探しではなく、品質を測りながら無駄な再処理を外す作業です。
最初に評価セットと1タスク単価を固定し、Prompt caching、入力整理、エージェントループ、出力形、Batch APIを順に見直します。モデルとeffortは最後です。この順序なら、費用が下がった理由と、品質が変わった地点を説明できます。
まずは1つのAPI経路で、同じ固定prefixを2回呼び、cache_read_input_tokensを確認してください。ヒットしなければprefix差分を直し、ヒットしたら評価セットを再実行します。最初の改善は、それだけで十分に測れます。
参考・出典
- Anthropic公式「Cost Optimization on the Claude API」Cookbook(参照日: 2026-08-20)
- Claude Platform Docs: Prompt caching(参照日: 2026-08-20)
- Claude Platform Docs: Batch processing(参照日: 2026-08-20)
- Claude Platform Docs: Token counting(参照日: 2026-08-20)

