「APIコストが想定の10倍になった」
AIエージェントを本番リリースした翌月、そんな相談を受けることが増えています。原因はシンプルです。チャットボットはユーザーが入力した文章だけを処理すればいい。でもAIエージェントは、ツールを呼んで、結果を解釈して、次のステップを決めて、また別のツールを呼ぶ。同じタスクで5〜30倍のトークンを消費します(参照: Zenn「AIエージェントをコスパよく動かす法」)。
私はこれを「エージェント税」と呼んでいます。エージェントにすることで得られる価値は大きいが、コストも比例して増える。このエージェント税をどう抑えるかが、AIエージェントの収益性を左右します。
AIエージェントの基本設計についてはAIエージェント構築完全ガイドを参照してください。本記事ではコスト最適化に絞って5つの戦略を解説します。
エージェントのコスト構造を理解する
最適化の前に、何にコストがかかっているかを把握する必要があります。
| コスト要因 | チャットボット(月100回利用) | エージェント(同規模) | 差 |
|---|---|---|---|
| 入力トークン | 50K | 500K〜1.5M | 10〜30倍 |
| 出力トークン | 20K | 100K〜300K | 5〜15倍 |
| APIリクエスト数 | 100回 | 1,000〜3,000回 | 10〜30倍 |
エージェントの入力トークンが膨れる主な原因は「コンテキストの再送信」です。毎ステップで会話履歴全体をAPIに送るため、ループが深くなるほど指数的に増えます。
戦略1: プロンプトキャッシング(最大90%削減)
最もインパクトが大きい戦略です。長いシステムプロンプトやドキュメントをAPIがキャッシュし、2回目以降はキャッシュ読み取り価格(通常の10%)で処理されます。
# Anthropic Claude API でのプロンプトキャッシング実装
# 動作環境: Python 3.11+, anthropic>=0.40.0
# pip install anthropic
import anthropic
import os
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
# 方法1: 自動キャッシング(推奨 — マルチターン会話向け)
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
cache_control={"type": "ephemeral"}, # これだけでOK
system="あなたは企業の財務分析エージェントです。" + "(長大なシステムプロンプト)" * 100,
messages=[{"role": "user", "content": "2025年度のコスト分析をしてください"}]
)
# キャッシュ効果を確認
print(f"キャッシュ読み取りトークン: {response.usage.cache_read_input_tokens}")
print(f"キャッシュ書き込みトークン: {response.usage.cache_creation_input_tokens}")
print(f"通常入力トークン: {response.usage.input_tokens}")
# 方法2: 明示的キャッシュブレークポイント(セクション別キャッシュ)
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": "あなたは財務分析エージェントです。",
"cache_control": {"type": "ephemeral"} # システム指示をキャッシュ
},
{
"type": "text",
"text": "[50ページのドキュメント全文]",
"cache_control": {"type": "ephemeral"} # ドキュメントをキャッシュ
}
],
messages=[{"role": "user", "content": "第3章を要約してください"}]
)
コスト試算(Claude Sonnet 4.6、2026年4月時点):
- 通常入力: $3.00 / MTok
- キャッシュ書き込み(5分): $3.75 / MTok(1.25倍)
- キャッシュ読み取り: $0.30 / MTok(10%)
- ドキュメントQ&Aで毎回10Kトークンを送る場合: 100回のリクエストで書き込み1回+読み取り99回 → コスト90%削減
料金の最終確認日: 2026-04-09(公式料金ページで最新を確認してください)
戦略2: バッチAPI(50%削減 + キャッシュと併用可能)
リアルタイム応答が不要なタスク(レポート生成、データ分類、メール分析など)はバッチAPIが最適です。非同期処理でAPIコストが50%削減されます。
# Anthropic Batch API の使用例
# 動作環境: Python 3.11+, anthropic>=0.40.0
import anthropic, json, os
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
# バッチリクエストの作成(最大10,000件まで)
requests = [
{
"custom_id": f"analyze-{i}",
"params": {
"model": "claude-haiku-4-5", # バッチ処理はHaikuで十分なことが多い
"max_tokens": 500,
"messages": [{"role": "user", "content": f"以下のテキストを分類してください: {text}"}]
}
}
for i, text in enumerate(["テキスト1", "テキスト2", "テキスト3"])
]
# バッチ送信
batch = client.messages.batches.create(requests=requests)
print(f"バッチID: {batch.id}")
# 結果取得(完了後)
# for result in client.messages.batches.results(batch.id):
# print(result.custom_id, result.result.message.content)
戦略3: モデルの使い分け(コスト10〜50分の1)
全てのタスクに Opus を使う必要はありません。タスクの難易度に応じてモデルを使い分けるだけでコストが劇的に下がります。
| モデル | 入力コスト(/MTok) | 適用タスク |
|---|---|---|
| Claude Opus 4.6 | $5 | 複雑な推論・アーキテクチャ決定・長文分析 |
| Claude Sonnet 4.6 | $3 | メインの開発作業・コードレビュー・一般的なエージェントタスク |
| Claude Haiku 4.5 | $1 | 分類・フォーマット変換・簡単なQ&A・高頻度呼び出し |
# タスク難易度に応じてモデルを動的選択するルーター
# 動作環境: Python 3.11+, anthropic>=0.40.0
def select_model(task_type: str, complexity: str) -> str:
"""タスクの種類と複雑さに応じて最適なモデルを選択"""
model_map = {
("classification", "low"): "claude-haiku-4-5",
("classification", "high"): "claude-haiku-4-5",
("code_review", "low"): "claude-sonnet-4-6",
("code_review", "high"): "claude-sonnet-4-6",
("architecture", "high"): "claude-opus-4-6",
("analysis", "low"): "claude-haiku-4-5",
("analysis", "high"): "claude-sonnet-4-6",
}
return model_map.get((task_type, complexity), "claude-sonnet-4-6")
# 使用例
model = select_model("classification", "low") # → claude-haiku-4-5(最安値)
model = select_model("architecture", "high") # → claude-opus-4-6(最高性能)
戦略4: コンテキスト圧縮(トークン50〜70%削減)
エージェントのループが深くなるほど「過去の会話を全件送り続ける」問題が発生します。要約と選択的コンテキストで対処します。
# 会話履歴の自動要約でコンテキスト圧縮
# 動作環境: Python 3.11+, anthropic>=0.40.0
def compress_conversation_history(
messages: list,
max_recent: int = 5,
summarize_threshold: int = 20
) -> list:
"""
会話履歴が一定数を超えたら古い部分を要約して圧縮
- max_recent: 最新N件はそのまま保持
- summarize_threshold: この件数を超えたら要約を実施
"""
if len(messages) <= summarize_threshold:
return messages # 閾値以下はそのまま返す
# 古い部分を要約
old_messages = messages[:-max_recent]
recent_messages = messages[-max_recent:]
# 要約リクエスト(Haikuで十分)
summary_response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=500,
messages=[
*old_messages,
{"role": "user", "content": "以上の会話を3文以内で要約してください。重要な決定事項と現在の状態を含めること。"}
]
)
summary = summary_response.content[0].text
# 要約を先頭に置いて圧縮済みリストを返す
return [
{"role": "assistant", "content": f"[会話要約] {summary}"},
*recent_messages
]
戦略5: Rerankで検索精度とトークンを同時改善
RAG(検索拡張生成)を使うエージェントでは、検索結果を大量にコンテキストに詰め込みがちです。Rerankで関連度の高い情報だけを絞り込むと、精度を上げながらトークンを削減できます。
# Rerankによるコンテキスト最適化(概念コード)
# 動作環境: Python 3.11+
# 実装はCohere Rerank APIやCross-encoder等を使用
def rerank_and_filter(
query: str,
documents: list[str],
top_k: int = 3
) -> list[str]:
"""
RAG検索結果をRerankして上位k件だけをコンテキストに渡す
トークン削減: 20件 → 3件で85%削減、精度は向上
"""
# スコアリング(実際にはCohere APIやlocal cross-encoderを使用)
scores = score_relevance(query, documents)
# スコア順にソートして上位k件を返す
ranked = sorted(zip(documents, scores), key=lambda x: x[1], reverse=True)
return [doc for doc, score in ranked[:top_k]]
# 効果(2026年1月 ウォータールー大学発表「Rerank Before You Reason」手法より)
# 検索件数は変えずリランクするだけでトークン消費を抑えながら精度が向上
5戦略の組み合わせ効果
戦略を組み合わせると効果が重なります。
| 戦略 | 単体削減効果 | 対象 |
|---|---|---|
| プロンプトキャッシング | 最大90%(入力トークン) | 繰り返し送る長文コンテキスト |
| バッチAPI | 50%(全体コスト) | 非同期・一括処理タスク |
| モデル使い分け | 最大50分の1 | 難易度の低いタスク |
| コンテキスト圧縮 | 50〜70%(入力トークン) | 長い会話履歴 |
| Rerank | 70〜85%(RAG入力) | RAGを使うエージェント |
キャッシング(90%削減)×バッチAPI(50%削減)を組み合わせると理論上95%以上の削減が可能です。ただし、キャッシュのTTL(5分または1時間)内にリクエストが集中しないと効果が出ません。まず自社のトラフィックパターンを分析してから適用してください。
【要注意】コスト最適化で陥りやすい落とし穴
落とし穴1: キャッシュのウォームアップを忘れる
❌ プロンプトキャッシングを設定したのにキャッシュ読み取りが発生しない
⭕ 最初の1リクエスト(キャッシュ書き込み)は通常の1.25倍かかる。2回目以降から節約効果が出る
落とし穴2: Haikuで済むタスクにSonnetを使い続ける
❌ 分類・フォーマット変換にSonnet/Opusを使う
⭕ まずHaikuで試して精度を確認。不足があればSonnetに上げる。コストは3倍差がある
落とし穴3: コンテキスト圧縮しすぎて精度が落ちる
❌ 全ての履歴を1文の要約に圧縮する
⭕ 直近5〜10件はそのまま保持。古い部分だけ要約。精度と効率のバランスを実験で調整する
参考・出典
- Prompt Caching – Claude API Docs — Anthropic公式(参照日: 2026-04-09)
- Claude API Pricing — Anthropic公式(参照日: 2026-04-09)
- AIエージェントをコスパよく動かす法 — Zenn(参照日: 2026-04-09)
- トークン消費70%削減!最新コンテキスト最適化技術 — Zenn(参照日: 2026-04-09)
- Anthropic Just Fixed the Biggest Hidden Cost in AI Agents — Medium(参照日: 2026-04-09)
まとめ:今日から始める3つのアクション
- 今日やること: 既存のエージェントコードにプロンプトキャッシングの
cache_control={"type": "ephemeral"}を追加し、cache_read_input_tokensをログに出力して効果を確認する - 今週中: 非同期タスク(日次レポート生成、データ分類など)をバッチAPIに移行。かつHaikuで代替可能なタスクを洗い出す
- 今月中: 会話履歴の圧縮ロジックを実装し、長期運用時のコスト推移をモニタリングダッシュボードで可視化する
あわせて読みたい:
- AIエージェント構築完全ガイド — コスト最適化の前に読む設計基礎
- AIエージェントのメモリ設計 — 適切なメモリ設計がコスト削減にも直結する
この記事はAIgent Lab編集部がお届けしました。AIエージェントのコスト設計・導入支援については 株式会社Uravation(お問い合わせフォーム) からご相談ください。