AI業務活用 2026.05.01
Claude API暴走で$437請求された実例|費用爆発の原因と防止策5つ
実際に起きた$437請求の原因分析
# ❌ これが$437請求を引き起こしたコードのパターン
import anthropic
import time
client = anthropic.Anthropic()
def bad_agent_loop(task: str):
"""やってはいけない実装例: 無限ループ+エラー時のリトライ"""
messages = []
while True: # ← 終了条件なし
try:
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=10000, # ← 大きすぎる上限
messages=messages + [{"role": "user", "content": task}]
)
messages.append({"role": "assistant", "content": response.content[0].text})
# ループ継続...(終了条件なし)
except Exception:
time.sleep(1)
continue # ← エラーでも無限リトライ
防止策1: Usage Limits(最重要)
console.anthropic.com → Settings → Limits → Usage Limits
設定値の目安:
- 個人開発: Hard Limit $20/月、Soft Limit $10/月
- チーム開発: Hard Limit $100/月、Soft Limit $50/月
- 本番サービス: Hard Limit $500/月、Soft Limit $250/月
この設定だけで「一晩で$437」は防げます。
防止策2: 安全なエージェント実装
# safe_agent.py
# 費用暴走を防ぐ安全なエージェントの実装
import anthropic
import time
from datetime import datetime
client = anthropic.Anthropic()
DAILY_BUDGET = 5.0 # $5/日の上限
MAX_ITERATIONS = 20 # 最大20ループ
MAX_TOKENS = 1024 # 出力上限
PRICES = {
"claude-sonnet-4-5": (3.00, 15.00),
"claude-haiku-4-5-20251001": (0.80, 4.00),
}
class SafeAgent:
def __init__(self, model: str = "claude-haiku-4-5-20251001"):
self.model = model
self.total_cost = 0.0
self.iterations = 0
def ask(self, message: str) -> str | None:
"""費用・ループ回数の上限チェック付きAPIコール"""
# ① 予算チェック
if self.total_cost >= DAILY_BUDGET:
print(f"⛔ 予算上限${DAILY_BUDGET}に達しました。処理を停止します。")
return None
# ② ループ回数チェック
if self.iterations >= MAX_ITERATIONS:
print(f"⛔ 最大反復回数({MAX_ITERATIONS}回)に達しました。")
return None
try:
response = client.messages.create(
model=self.model,
max_tokens=MAX_TOKENS, # ③ 出力上限を必ず設定
messages=[{"role": "user", "content": message}]
)
inp = response.usage.input_tokens
out = response.usage.output_tokens
inp_price, out_price = PRICES.get(self.model, (3.00, 15.00))
cost = (inp * inp_price + out * out_price) / 1_000_000
self.total_cost += cost
self.iterations += 1
print(f"[Iteration {self.iterations}] コスト: ${cost:.5f} | 累計: ${self.total_cost:.4f}")
return response.content[0].text
except Exception as e:
print(f"[Error] {e}")
time.sleep(5) # ④ エラー時は5秒待ってから終了
return None
def summary(self):
print(f"\n実行完了: {self.iterations}回 | 合計コスト: ${self.total_cost:.4f}")
# 使用例
agent = SafeAgent(model="claude-haiku-4-5-20251001")
for task in ["タスク1", "タスク2", "タスク3"]:
result = agent.ask(task)
if result is None:
break # ← 必ず中断する
agent.summary()
防止策3: Slackコスト通知
# cost_monitor.py
# APIコストをリアルタイムでSlackに通知する
import json
import urllib.request
from datetime import date
from pathlib import Path
SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
ALERT_THRESHOLD = 10.0 # $10超えたら通知
cost_log = Path(".api_cost_log.json")
def alert_slack(message: str):
"""Slackにアラートを送る"""
payload = json.dumps({"text": message}).encode()
req = urllib.request.Request(SLACK_WEBHOOK, data=payload,
headers={"Content-Type": "application/json"})
urllib.request.urlopen(req)
def check_daily_cost():
"""日次コストをチェックしてアラートを送る"""
if not cost_log.exists():
return
log = json.loads(cost_log.read_text())
today_cost = log.get(str(date.today()), {}).get("total", 0)
if today_cost >= ALERT_THRESHOLD:
alert_slack(f"⚠️ Claude API コスト警告: 本日 ${today_cost:.2f} を超えました。\n上限: ${ALERT_THRESHOLD}/日")
print(f"Slackに通知送信: ${today_cost:.2f}")
check_daily_cost()