「動くプロトタイプはできました。来週から本番に出していいですか?」と相談を受けるたびに、私はいつも一拍置いて聞き返します。「想定ユーザー数は?SLAは?データはどこに保存されますか?」と。すると、3つとも即答できる方は意外と少ないのです。
Claude API のコードそのものは数十行で書けます。しかし「本番で持つ」ための設計判断は、コードを書き始める前に決めておかないと、後から構造を組み替えるのに何倍もの時間が必要になります。ここでは、私が個人開発と受託案件で繰り返し使っている「インフラ要件を逆算する3軸」をまとめます。
トラフィック規模を3段階で見積もる
最初に決めるのはピーク QPS(Queries Per Second)と月間トークン量です。これが曖昧なまま始めると、Anthropic 側の組織レート制限・モデル選定・キャッシュ戦略すべてがぶれます。
私はこの見積もりを、3段階で粗く区切る方法を好みます。
- Tier S(〜1,000 MAU・10 RPM 程度): 個人開発の MVP や社内ツール。Tier 1 アカウントの初期上限内に収まることがほとんどで、特別な工夫なしに始められます
- Tier M(1,000〜50,000 MAU・100 RPM 程度): 一般公開された Web サービスの初期成長期。Tier 2 への昇格申請、プロンプトキャッシュ、バックグラウンドジョブの非同期化が要件になります
- Tier L(50,000+ MAU・1,000 RPM 以上): ここからは「単一リージョン × 単一モデル」の構成が成立しません。Bedrock や Vertex AI を併用したマルチクラウド、モデルのフォールバック設計が前提になります
ピーク QPS は「想定 DAU × 1人あたり1日のリクエスト数 ÷ 1日の有効秒数(私は10時間 = 36,000秒で計算)× ピーク係数3」で粗く出せます。たとえば DAU 10,000 で1人あたり3リクエストなら、ピーク QPS は約2.5。これを月間に直すとトークン量も逆算できます。
このあたりの詳細な見積もり式はClaude API 月額コスト計算とプロンプトキャッシュ設計ガイドも参考になります。
SLA から可用性アーキテクチャを逆算する
「99.5%」と「99.95%」の差は、月間ダウンタイムにすると約4時間と22分です。この差はそのまま「単一プロバイダで成立するか、フォールバックが必須か」という設計の分岐になります。
私が現場で使っている目安はこうです。
- 99.5%(月4時間以内): Anthropic API 直接呼び出し + リトライ + 軽いタイムアウト管理で十分です。社内ツールや無料サービスはこのラインで設計します
- 99.9%(月43分以内): プロンプトキャッシュ + レスポンスキャッシュ + 同モデルの別リージョン経由(Bedrock 等)でフォールバック先を1つ用意します
- 99.95%以上(月22分以内): 主モデル(Sonnet 5.5 等)→ サブモデル(Haiku 5.5)→ ローカル推論(Gemma 等)まで含めた階層的フォールバックが必要です。SLA 違反時の SLO レポートまで自動化することを前提に設計します
注意したいのは、SLA は「Claude API 側の SLA」と「自社サービスの SLA」を区別する点です。Anthropic 公式の Production SLA を直接保証しない限り、自社の数字は常に Claude 側より低くなります。ユーザーに約束する数字は、必ず内部で SLO(運用目標)として落とし込んでください。
実装パターンの詳細はClaude API マルチモデルフォールバック高可用性設計ガイドで扱っています。
データレジデンシーとコンプライアンスの判断
ここは「BtoB SaaS でつまずきがちな盲点」です。日本企業のクライアントから「データを国内に置いてほしい」と言われた場面で、私は以前、「Anthropic API は米国中心だから直接呼び出しは外れます」と即答していました。今回この記事を見直すために公式ドキュメントを確認し、その答えが古くなっていたと気づきました。
現在は inference_geo パラメータで、推論を米国内に限定できます(Claude 4.6 以降のモデルが対象で、料金は入力・出力・キャッシュを含めて1.1倍です)。ただし、選べるのは「米国内」か「グローバル(既定)」であって、日本国内ではありません。「国内に置く」という要件そのものが満たせるわけではない、という線引きは変わっていません。
判断軸は3つです。
- 個人情報を Claude に送るか: 送るなら、入力時の PII マスキングを設計に含めてください。電話番号・住所・カード番号は、トークン化してから API に渡します
- 規制業界か(金融・医療・自治体): 規制があるなら、Bedrock 経由で AWS 内に閉じるか、Vertex AI 経由で Google Cloud のデータレジデンシー設定を引き継ぐ道を、最初から検討しておきます。なお Bedrock と Google Cloud のリージョン指定エンドポイントには、グローバルより約10%の上乗せがあります
- 顧客データの学習利用: Claude API は学習に使われない設定が標準ですが、契約書面で明示することを顧客から求められるケースが多いです。Enterprise プランなら DPA(データ処理契約)が結べます
送信前のトークン化は、正規表現で拾える範囲だけでも効果があります。私がまず入れるのは、電話番号・メールアドレス・16桁の数字を占位トークンへ置き換え、応答が返ってから元に戻す薄い可逆マスキング層です。
const PATTERNS: [RegExp, string][] = [
[/\b\d{3}-\d{4}-\d{4}\b/g, "PHONE"], // 電話番号
[/\b[\w.+-]+@[\w-]+\.[\w.-]+\b/g, "EMAIL"], // メールアドレス
[/\b\d{16}\b/g, "CARD"], // カード番号
];
function mask(text: string) {
const restore = new Map<string, string>();
let i = 0;
for (const [re, label] of PATTERNS) {
text = text.replace(re, (m) => {
const token = `[[${label}_${i++}]]`;
restore.set(token, m);
return token;
});
}
return { masked: text, restore };
}
function unmask(text: string, restore: Map<string, string>) {
for (const [token, original] of restore) text = text.split(token).join(original);
return text;
}正規表現だけでは氏名や住所のような自由記述は拾いきれません。そこは「Claude に送る前に人間が確認する」運用で補うのが現実的です。可逆マスキングの前処理設計はユーザーレビューやクラッシュログをClaude APIに渡す前の個人情報マスキング設計で詳しく扱っています。
コスト予測の最低限の式
「Claude API はいくらかかるんですか?」と聞かれたときは、まずこの式から始めます。ただし、この節には私自身の失敗が含まれています。
// 月間コスト概算(USD)
function estimateMonthlyCost({
dau, // 想定 DAU
requestsPerUser, // 1人あたり1日のリクエスト数
inputTokensAvg, // 1リクエスト平均入力トークン
outputTokensAvg, // 1リクエスト平均出力トークン
inputPricePerMTok, // 入力 $/Mトークン(Sonnet 5.5 = 2.0)
outputPricePerMTok, // 出力 $/Mトークン(Sonnet 5.5 = 10.0)
cacheHitRate = 0.5, // プロンプトキャッシュのヒット率(実装後)
cacheReadMult = 0.05, // キャッシュ読み取りの倍率(Sonnet 5.5 / Opus 5.5 は 0.05、他は 0.1)
cacheWriteMult = 1.25, // 5分キャッシュの書き込み倍率
geoMult = 1.0, // 米国内推論を指定すると 1.1
safetyFactor = 1.3 // 安全係数(再試行・バースト分)
}) {
const monthlyRequests = dau * requestsPerUser * 30;
const inMTok = (monthlyRequests * inputTokensAvg) / 1_000_000;
const outMTok = (monthlyRequests * outputTokensAvg) / 1_000_000;
// ヒットは読み取り倍率、外れは書き込み倍率で課金される
const inputMult = cacheHitRate * cacheReadMult + (1 - cacheHitRate) * cacheWriteMult;
const base = inMTok * inputPricePerMTok * inputMult + outMTok * outputPricePerMTok;
return Math.ceil(base * geoMult * safetyFactor);
}
const common = {
dau: 5000, requestsPerUser: 3,
inputTokensAvg: 2000, outputTokensAvg: 500,
inputPricePerMTok: 2.0, outputPricePerMTok: 10.0,
};
console.log(estimateMonthlyCost(common)); // 4446
console.log(estimateMonthlyCost({ ...common, geoMult: 1.1 })); // 4891
console.log(estimateMonthlyCost({ ...common, cacheHitRate: 0, cacheWriteMult: 1.0 })); // 5265以前の版では、このコードの例の答えを「約 $3,800」と書いていました。今回、実際に動かして確かめたところ、当時の単価(Sonnet 4.6 の $3/$15)のままでも約 $6,318 になり、数字がまったく合っていませんでした。コードと説明を別々に書き、動かさないまま載せていたのだと思います。単価とキャッシュ倍率も現行に直し、書き込み(外れ)の割増も式に入れました。
Node.js 22 で上のコードをそのまま実行した結果です(DAU 5,000・1人3リクエスト・入力2,000/出力500トークン。単価は2026年10月15日に公式の料金ページで確認した Sonnet 5.5 の値です)。
| 条件 | 月額概算(安全係数1.3込み) |
|---|---|
| キャッシュなし | 約 $5,265 |
| ヒット率50% | 約 $4,446 |
| ヒット率50%+米国内推論(1.1倍) | 約 $4,891 |
単価は改定されます。コードの数字を信じる前に、料金ページの日付を確かめる習慣だけは外さないようにしています。
見積もりの数字は、載せる前に必ず動かします。 手計算の答えを記事に書く夜は、これからも一度だけ立ち止まるようにしています。
安全係数1.3を必ず掛ける点は、いまも変わりません。実運用では再試行・テスト・社内利用・想定外のバーストが積み重なって、見積もりの1.2〜1.5倍に膨らむのが通常です。最初から「想定の3割増」で予算化しておくと、月末の請求書で慌てません。
レート制限(429)を「設計判断」に含める
3軸を決めても、最後に必ず現実へ引き戻されるのがレート制限です。Tier 判定はあくまで平常時の話で、バッチや定期実行が重なった瞬間に、組織全体の RPM を複数のワーカーが食い合います。私自身、複数プロジェクトの夜間ジョブを同じ組織アカウントで走らせていて、片方のバーストがもう片方を 429 に巻き込む事故を何度か経験しました。
対策の骨格はシンプルです。指数バックオフに必ずジッター(ゆらぎ)を足し、サーバーが返す Retry-After を最優先で尊重すること。ジッターを入れないと、同時に弾かれた複数のワーカーが同じ間隔でいっせいに再送し、次の波でまた揃って弾かれます。
async function callWithBackoff(fn, { maxRetries = 5, baseMs = 500 } = {}) {
for (let attempt = 0; ; attempt++) {
try {
return await fn();
} catch (err) {
const status = err?.status ?? err?.response?.status;
if (status !== 429 && status !== 503) throw err; // 一時的な過負荷のみ再試行
if (attempt >= maxRetries) throw err;
// サーバー指示(Retry-After: 秒)があれば最優先で尊重する
const retryAfter = Number(err?.headers?.["retry-after"]);
const serverWait = Number.isFinite(retryAfter) ? retryAfter * 1000 : 0;
// 指数バックオフ + フルジッター
const backoff = Math.min(baseMs * 2 ** attempt, 20_000);
const jittered = Math.random() * backoff;
await new Promise((r) => setTimeout(r, Math.max(serverWait, jittered)));
}
}
}ここで意図的に 429 と 503 だけを再試行対象にしています。400 系のバリデーションエラーまで再試行してしまうと、壊れたリクエストを延々と投げ続けて制限枠を無駄に消費するだけだからです。加えて anthropic-ratelimit-requests-remaining などのレスポンスヘッダーを監視し、枠が尽きる前に自分から送信ペースを落とす「先回りのスロットリング」を入れると、そもそも 429 に当たる回数が目に見えて減ります。
観測とリトライ設計をもう一段深く踏み込みたい方は、Claude API の 429 エラーを本番で観測して書き直したリトライ実装もあわせてご覧いただければと思います。
本番投入前の最終チェックリスト
3軸の判断が終わったら、以下を「決定済み」と「未決定」で仕分けしてください。未決定が1つでもあれば、本番投入は1週間延ばす価値があります。
- [ ] ピーク QPS と月間トークン量の見積もりがある
- [ ] 目標 SLA と、それに対応するフォールバック先が決まっている
- [ ] PII の扱い方針(マスキング・送信可否)が文書化されている
- [ ] 月額コストの概算と、超過時のアラート閾値が設定されている
- [ ] レート制限を超えたときのユーザー向けフォールバック表示が決まっている
- [ ] 障害時に人間(運用担当)に通知が届く経路がある
- [ ] データレジデンシー要件(契約書)と実装が一致している
このチェックリストの「決定済み/未決定」を1枚のドキュメントにまとめて、関係者全員でレビューする会を1時間だけ持つことを強くおすすめします。実装より、この合意形成のほうが本番事故を防ぎます。
次の一歩
この記事を読み終えたら、まず「ピーク QPS の概算」だけを今日中に出してみてください。電卓で5分あれば終わります。その数字が出た瞬間に、Tier 判定・モデル選定・SLA 議論のすべてが動き出します。
Claude API のインフラ設計をさらに深掘りしたい方は、Claude API 本番投入インフラチェックリストで「動くコード」を「本番で持つコード」に変える8つの実装パターンを公開しています。設計判断(この記事)と実装パターン(チェックリスト記事)をセットで読むと、本番投入の手順が一通り揃います。
Claude API に限らず、外部サービスを本番に組み込む全ての設計に通じる視座が得られます。