生成AI入門 2026.04.19

Claude Sonnet APIコスト完全解説【2026年版】トークン計算・バッチ割引・月額試算

タグ:AI / 料金 / Claude / API / Anthropic

2026年の現行Sonnetモデルと料金

「Claude 3.5 Sonnet」は2024年のモデルです。2026年の現行Sonnetは claude-sonnet-4-5 です。

モデル入力 /1M出力 /1Mバッチ入力 /1Mバッチ出力 /1M
claude-sonnet-4-5$3.00$15.00$1.50$7.50
claude-haiku-4-5-20251001$0.80$4.00$0.40$2.00
claude-opus-5$15.00$75.00$7.50$37.50

コスト計算の基本

# sonnet_cost_calculator.py

# 2026年現行Sonnetの料金
SONNET_INPUT_PER_1M = 3.00   # USD
SONNET_OUTPUT_PER_1M = 15.00  # USD

def calculate_request_cost(input_tokens: int, output_tokens: int) -> float:
    """1リクエストのコストを計算"""
    return (
        input_tokens * SONNET_INPUT_PER_1M / 1_000_000 +
        output_tokens * SONNET_OUTPUT_PER_1M / 1_000_000
    )

def calculate_monthly_cost(
    daily_requests: int,
    avg_input: int,
    avg_output: int,
    days: int = 30,
) -> dict:
    monthly = daily_requests * days
    cost_per = calculate_request_cost(avg_input, avg_output)
    total = cost_per * monthly
    
    return {
        "monthly_requests": monthly,
        "cost_per_request": cost_per,
        "monthly_total_usd": total,
        "monthly_total_jpy": int(total * 150),  # 参考換算(為替レートで変動)
    }

# よくあるユースケースのコスト試算
print("=== Claude Sonnet 4.5 月額コスト試算 ===\n")

cases = [
    ("小規模(1日10件・短めの応答)", 10, 500, 300),
    ("中規模(1日50件・通常応答)", 50, 1000, 600),
    ("大規模(1日500件・長めの応答)", 500, 2000, 1000),
    ("バッチ処理(1日1000件)", 1000, 1000, 500),
]

for label, daily, inp, out in cases:
    r = calculate_monthly_cost(daily, inp, out)
    print(f"【{label}】")
    print(f"  月間{r['monthly_requests']:,}リクエスト")
    print(f"  1件: ${r['cost_per_request']:.5f}(約{r['cost_per_request']*150:.2f}円)")
    print(f"  月額: ${r['monthly_total_usd']:.2f}(約{r['monthly_total_jpy']:,}円)")
    print()

バッチ処理で50%コスト削減

# batch_processing.py
import anthropic
import time
import os

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

def process_batch(texts: list[str]) -> dict:
    """Message Batches APIで一括処理(50%割引)"""
    
    # バッチリクエストを作成
    requests = [
        {
            "custom_id": f"task_{i}",
            "params": {
                "model": "claude-sonnet-4-5",
                "max_tokens": 512,
                "messages": [{"role": "user", "content": text}]
            }
        }
        for i, text in enumerate(texts)
    ]
    
    batch = client.messages.batches.create(requests=requests)
    print(f"バッチ作成: {batch.id}")
    print(f"ステータス: {batch.processing_status}")
    
    # 処理完了を待つ(数分〜数時間かかる場合がある)
    while True:
        batch = client.messages.batches.retrieve(batch.id)
        if batch.processing_status == "ended":
            break
        print(f"処理中... {batch.processing_status}")
        time.sleep(30)
    
    # 結果を収集
    results = {}
    for result in client.messages.batches.results(batch.id):
        if result.result.type == "succeeded":
            results[result.custom_id] = result.result.message.content[0].text
    
    return results

# 使用例(急ぎでない大量の翻訳・要約タスク)
texts = [
    "このPythonコードの問題点を指摘して: def f(x): return x/0",
    "FastAPIとFlaskの違いを200字で説明して",
    "O(n log n)の時間計算量とは何ですか",
]

results = process_batch(texts)
for task_id, text in results.items():
    print(f"{task_id}: {text[:100]}...")

Prompt Cachingで90%コスト削減

# prompt_cache_example.py
import anthropic
import os

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

# 長いシステムプロンプトをキャッシュ(通常1000トークン以上で効果的)
SYSTEM_PROMPT = """あなたはベテランのPythonエンジニアです。
以下のコーディング規約に従ってください:
- PEP 8準拠
- 型ヒントを必ず書く
- docstringはGoogle形式
- テストはpytestで書く
[...長い規約が続く...]
""" * 3  # デモ用に繰り返して長くする

def cached_request(user_message: str) -> dict:
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        system=[{
            "type": "text",
            "text": SYSTEM_PROMPT,
            "cache_control": {"type": "ephemeral"}  # キャッシュ指定
        }],
        messages=[{"role": "user", "content": user_message}]
    )
    
    usage = response.usage
    cache_hit = getattr(usage, "cache_read_input_tokens", 0)
    cache_write = getattr(usage, "cache_creation_input_tokens", 0)
    
    # コスト計算
    normal_cost = usage.input_tokens * SONNET_INPUT_PER_1M / 1_000_000
    cached_cost = (
        cache_hit * 0.30 / 1_000_000 +       # キャッシュ読込は90%引き
        cache_write * 3.75 / 1_000_000 +      # キャッシュ書込は125%
        (usage.input_tokens - cache_hit - cache_write) * SONNET_INPUT_PER_1M / 1_000_000
    ) + usage.output_tokens * SONNET_OUTPUT_PER_1M / 1_000_000
    
    return {
        "text": response.content[0].text,
        "cache_hit_tokens": cache_hit,
        "cache_write_tokens": cache_write,
        "cost_without_cache": normal_cost,
        "cost_with_cache": cached_cost,
        "savings": normal_cost - cached_cost,
    }

月額コストが想定外に高くなる原因と対策

# cost_monitor.py - リアルタイムコスト追跡

from dataclasses import dataclass, field
from datetime import datetime

SONNET_INPUT_PER_1M = 3.00
SONNET_OUTPUT_PER_1M = 15.00

@dataclass
class CostMonitor:
    budget_usd: float = 50.0
    total_input_tokens: int = 0
    total_output_tokens: int = 0
    request_count: int = 0
    
    @property
    def total_cost(self) -> float:
        return (
            self.total_input_tokens * SONNET_INPUT_PER_1M / 1_000_000 +
            self.total_output_tokens * SONNET_OUTPUT_PER_1M / 1_000_000
        )
    
    @property
    def budget_remaining(self) -> float:
        return self.budget_usd - self.total_cost
    
    def record(self, input_tokens: int, output_tokens: int) -> None:
        self.total_input_tokens += input_tokens
        self.total_output_tokens += output_tokens
        self.request_count += 1
        
        if self.budget_remaining < self.budget_usd * 0.1:
            print(f"⚠️ 予算残り10%以下: ${self.budget_remaining:.2f}")
    
    def report(self) -> None:
        print(f"リクエスト数: {self.request_count:,}")
        print(f"総コスト: ${self.total_cost:.4f}")
        print(f"残り予算: ${self.budget_remaining:.4f}")

# 使用例
monitor = CostMonitor(budget_usd=50.0)

# APIレスポンス後にrecordを呼ぶ
# monitor.record(response.usage.input_tokens, response.usage.output_tokens)

あわせて読みたい

参考ソース