Claude Code に「API課金ゲート」を設計する:暴走を防ぐヒューマン・イン・ザ・ループ
はじめに
Claude Code を含む AI コーディングエージェントを業務で運用していると、必ず一度はぶつかる事故があります。
「気づいたら従量課金 API を何百回も叩いていて、月末に数千円〜数万円の請求が来た」
筆者の環境でも、外部 LLM API(Grok / Gemini)の連続呼び出しを agent に丸投げしていたタイミングで、想定外の課金事故を経験しました。コストもさることながら、本当に怖いのは「ユーザーが知らないうちにエージェントが意思決定して従量課金リソースを消費している」という統制の崩壊です。
この記事では、Claude Code(および同等の CLI エージェント)に API 課金ゲート という仕組みを組み込んで、外部 API を呼ぶ前に必ず人間の確認を挟むためのプロンプト設計とガードレール運用を紹介します。
なぜ「課金ゲート」が必要なのか
LLM エージェントには、典型的に 3 つの暴走パターンがあります。
- 無限ループ系:失敗したリクエストを「もう一度試してみます」と自動リトライし続ける
- 過剰探索系:問題解決のために「念のため」関連 API を 5〜10 個叩く
- 委譲爆発系:sub-agent や Tool が連鎖的に外部 API を呼び出す
これらは個別には合理的な振る舞いですが、従量課金 API に対しては全部アンチパターンです。1 回 0.5 円のリクエストが 200 回走れば 100 円。これが日次タスクで繰り返されれば、月間では 3,000 円が「気づかないうちに」消えます。
「Rate Limit 制」のサブスク(ChatGPT Plus / Claude Pro 等)であればコストは固定ですが、Pay-as-you-go の API は人間の確認を挟まないと安全に運用できない、というのが筆者の結論です。
設計方針:3 つの原則
1. プロバイダごとに「課金タイプ」を分類する
すべての外部 API を一律に扱わず、従量課金 / Rate Limit 制 / 自社内 の 3 階層に分けます。
| 分類 | 例 | ゲートの厳しさ |
|---|---|---|
| 従量課金(Pay-as-you-go) | OpenAI API, Anthropic API, Grok API, Gemini API | 必ず確認 |
| Rate Limit 制サブスク | ChatGPT Plus 連携 CLI など | 明示依頼時のみ起動 |
| 自社・ローカル | ローカル LLM, 自社 RAG | 確認不要 |
このマトリクスを CLAUDE.md(Claude Code のグローバルルール)に書いておくのがポイントです。
2. 確認フォーマットを固定化する
エージェントが毎回違う言い回しで確認すると、ユーザーが流し読みしてしまいます。テンプレート化された短い確認文に揃えます。
⚠️ 課金が発生します
- API: [API名]
- モデル: [モデル名]
- 操作: [何をするか]
- 推定コスト: [概算]
実行してよいですか?(yes/no)
「推定コスト」を入れるのが効きます。gpt-4-turbo で 5,000 トークン消費するなら「約 $0.05」と書く。金額が見えると人間の判断速度が上がります。
3. グローバル CLAUDE.md に絶対ルールとして書く
エージェントの「人格」(system prompt 相当)に、以下のような Instruction レベルのルール を埋め込みます。
## [I] API課金ゲート
外部LLM APIを呼ぶ前に **必ず** 確認を挟む。「やって」だけでは実行しない。
- 対象: 従量課金API全般
- 例外: Rate Limit制のサブスクは事前許可で省略可
- フォーマット: 上記テンプレート参照
[I] は Instruction(絶対ルール)の意。[G] Guidance(推奨)と区別することで、AI 側の優先度判定が安定します。
実装:プロンプトと CLI フックの 2 段構え
レイヤー 1:プロンプトでの自己制御
~/.claude/CLAUDE.md に以下を書いておくと、Claude Code 起動時に毎回読み込まれます。
### [I] API課金ゲート
以下のコマンド・ツールを呼ぶ前に必ず確認:
- `mcp__grok__*`
- `gemini` CLI
- 外部 LLM API を内包する任意のスキル
確認フォーマット:
⚠️ 課金が発生します
- API: <名前>
- モデル: <モデル>
- 操作: <内容>
実行してよいですか?(yes/no)
これで、明示的に許可しない限りエージェント側が「念のため Grok を呼んで補強します」のような勝手な意思決定をしなくなります。
レイヤー 2:シェル側のガードレール(保険)
プロンプトだけでは「忘れる」リスクがあるため、CLI 呼び出しに wrapper を噛ませて、実行前に確認を強制 します。
# ~/bin/gemini-gated(PATH の先頭に置く)
#!/usr/bin/env bash
set -euo pipefail
echo "⚠️ Gemini CLI(従量課金)を呼び出します"
echo " 引数: $*"
read -r -p "実行しますか? [y/N]: " ans
case "$ans" in
y|Y|yes) exec /usr/local/bin/gemini "$@" ;;
*) echo "キャンセルしました"; exit 1 ;;
esac
alias gemini='~/bin/gemini-gated' を .zshrc に書けば、Claude Code が Bash ツールから呼んでも必ず確認が出ます。プロンプト統制とシェル統制の二重化 が実運用では効きます。
レイヤー 3:環境変数でコストキャップ
API クライアント側が対応していれば、環境変数で月次コスト上限を切ります(例:擬似コード)。
import os
from anthropic import Anthropic
MONTHLY_BUDGET = float(os.environ.get("LLM_MONTHLY_BUDGET_USD", "10"))
client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
# 呼び出し前にコスト累計を確認するラッパーを噛ませる
def safe_create(**kwargs):
if get_current_month_spend() >= MONTHLY_BUDGET:
raise RuntimeError(f"月次予算 ${MONTHLY_BUDGET} 到達")
return client.messages.create(**kwargs)
「気づかないうちに」をなくす最終防衛線です。
運用してわかった落とし穴
筆者の環境で半年運用した結果、いくつかの落とし穴が見えました。
- Sub-agent からの呼び出しが抜け落ちる:親エージェントが課金ゲートを尊重しても、Task ツールで起動した子エージェントが内部で API を叩くことがある。子側の system prompt にも同じルールを継承する必要がある
- 「やって」の意味が曖昧:ユーザーが「Grok でリサーチして」と書いた時点で「明示的承認」と解釈してよいかが揺れる。コマンド名を含む依頼のみ事前承認扱い にすると安全
- 確認疲れ:1 タスクで 10 回確認が出ると人間が「全部 yes」を機械的に押す。バッチ確認(「これから 5 回呼びます」)で集約する設計が必要
まとめ
API 課金ゲートを設計するときの実践ポイント。
- プロバイダを 3 階層(従量課金 / Rate Limit / ローカル)に分類 し、ゲートの厳しさを変える
- 確認フォーマットを固定 し、「推定コスト」を必ず含める
- プロンプトとシェル wrapper の二重化 で、AI が忘れても止まる仕組みにする
- 環境変数で月次予算上限 を切り、最終防衛線を作る
- sub-agent への継承 と バッチ確認の設計 を忘れない
AI コーディングエージェントは生産性を劇的に上げますが、コスト統制を最初に設計しないと「速い・安い・うまい」のうち「安い」が崩壊します。仕組みで止める発想が、長期運用の鍵だと感じています。