オンデマンド vs プロビジョンドスループット、バッチ推論、モデル選定、トークンキャッシュを実数値とともに解説。
要点 ― Bedrockで60〜80%のコスト削減を実現する5つの戦略:
- 非同期workloadsには バッチ推論 → 50%割引、品質への影響なし
- 繰り返し使うコンテキストには プロンプトキャッシュ → キャッシュ済み入力トークンが90%安価
- モデルルーティング(単純なタスクには安価なモデル)→ 40〜70%のコスト削減
- ベンチマーク + LLM-as-a-judge で安価なモデルでも十分かを検証
- 観測性(OTel + DoiT GenAI Intelligence)でドリフトを検知し、削減効果を維持
このプレイブックを使い、あるお客様のコストを月$40Kから$18Kへ削減しました。詳細は以下のとおりです。
私はDoiTでAPACのエンジニアリングチームを率いています。先四半期、ある金融サービスのお客様からBedrockの利用料を見直してほしいと依頼を受けました。チケット分類、文書抽出、顧客向けチャットまですべてClaude Sonnetで処理しており、月額が知らぬ間に$40Kを超えていたのです。2週間後には、出力品質に手を加えることなく$18Kまで削減できました。
本記事はそのときのプレイブックです。エンジニアリングチームやデータチームでBedrockのコストを管理しているなら、ここで紹介するレバーこそが請求額を実際に動かす要素です。
本記事に登場するお客様事例は、複数の支援案件で見られたパターンを基に再構成した複合的な例であり、個別のケーススタディではありません。
2つの料金モデルを理解する
Bedrockには2つの料金モデルがあり、両方向で高くつくミスを目にしてきました。(Bedrock料金の詳細 ― ファインチューニングのコスト、トークン見積もり、タグ付け戦略まで ― はJosh PalmerによるCloudOps向けBedrock料金ガイドを参照してください。本記事では請求額を削減するためのエンジニアリング上の意思決定にフォーカスします。)
オンデマンド料金
課金はトークン単位で、入力と出力に別々の料金が設定されています。コミットメントも最低利用もありません。
バースト的な利用、まだ実験段階、または月額が後述の損益分岐点を下回る場合に向いています。
見落としがちな点があります。出力トークンは通常、入力トークンの3〜5倍のコストがかかります。先ほどの金融サービスのお客様は、入力トークンの料金だけでコストを試算していたため、実際の請求額を3倍近く過小評価していました。入力1,000トークンを消費し出力2,000トークンを生成するタスクでは、出力コストが支配的になります。必ず両側を見積もりに織り込んでください。
プロビジョンドスループット
時間単位(または1か月/6か月のcommitments付き)でモデルユニットを購入します。モデルユニットとはBedrockが予約する容量の単位 ― 「高速道路の1車線」を時間貸しで借りるようなもので、使う使わないにかかわらず料金が発生します。
持続的かつ予測可能なworkloads、モデルユニットの利用率が損益分岐点を継続的に上回る場合、レイテンシ保証が必要な場合に向いています。
昨年、利用率15%でプロビジョンドスループットを動かしていたメディア企業を支援したことがあります。負荷テスト時に設定したまま戻し忘れ、誰も気付かないまま3か月間お金を垂れ流していました。オンデマンドへの切り替えはconfigの1行変更で済み、即座に数千ドルの節約になりました。低利用率のプロビジョンドスループットは、Bedrockで最も高くつく単一のミスです。
損益分岐点を見つける
月額オンデマンドコスト = (input_tokens × input_price) + (output_tokens × output_price)月額プロビジョンドコスト = model_units × hourly_rate × 730 hoursほとんどのモデルでは、モデルユニットの持続的な利用率が60〜70%を超えるあたりでプロビジョンドの方が安くなります。ここで効いてくるのが「持続的」という言葉です ― ピーク利用を見てはいけません。1日中70%前後で推移し小さなスパイクがあるトラフィックは候補ですが、10%でアイドルし、毎時5分間だけ100%にスパイクするトラフィックは候補になりません。
バッチ推論:見落とされがちな50%割引
お客様と話していて私の一番のお気に入りトピックです。反応は決まって同じだからです。「待って、半額で済むの?」
そうです。Bedrockはサポート対象モデルのバッチトークンをオンデマンド料金の約50%で提供しています。同じモデル、同じ品質、半額です。(執筆時点の話なので、ロードマップを賭ける前に料金ページで確認してください。)トレードオフは24時間SLAでストリーミング非対応であること ― ジョブはキューに入り、非同期で完了します。
リアルタイム応答が不要なworkloadsはすべて候補です。サポートチケットの分類、RAG用の文書コーパス処理、商品説明の生成、評価スイートの実行、非構造化文書からの構造化データ抽出など。多くのチームでは、Bedrock workloadsの30〜40%がユーザー体験への影響なくバッチに移行できると見ています。
具体例を挙げましょう。Claude Sonnetで平均500入力トークン・200出力トークンのリクエストを10,000件処理する場合(ap-southeast-2のオンデマンド料金):
| モード | 入力コスト | 出力コスト | 合計 |
|---|---|---|---|
| オンデマンド | $15.00 | $37.50 | $52.50 |
| バッチ | $7.50 | $18.75 | $26.25 |
1回のバッチ実行で$26.25の節約。日次パイプラインなら月数千ドルに積み上がります。実装はS3上のJSONLファイルだけ ― アーキテクチャの変更ではなく、配管工事レベルの変更です。
コスト戦略としてのモデル選定
モデル選びは10〜60倍の差が出るコスト判断です。多くのチームは、プロトタイピング時に選んだモデルを見直さずそのまま使い続け、必要以上に高価なモデルをデフォルトにしてしまっています。
階層型アーキテクチャ
最もコスト効率の良いBedrockデプロイメントは、いずれも階層構造を採用しています:
- Tier 1(Haiku、Mistral 7B、Llama 3 8B)― 分類、ルーティング、抽出、シンプルなQ&A。1リクエストあたり数銭以下。トラフィックの60〜80%を担うべき。
- Tier 2(Sonnet、Mistral Large、Llama 3 70B)― 複雑な推論、ニュアンスのある生成。最上位より5〜10倍安価。
- Tier 3(Opus、Claude 3.5 Sonnet)― 最も難しいタスク専用。プレミアム料金で、本当に必要な作業のみに限定。
ルーターパターン
Bedrockには同一ファミリー内のルーティングに限った組み込みソリューションがあります。Intelligent Prompt Routing は単一のサーバーレスエンドポイントを提供し、プロンプトの複雑さに応じて同一ファミリー内のモデル間でリクエストを振り分けます。モデルファミリーARN(例:Anthropic Claude)を指定すると、各リクエストをHaikuに送るかSonnetに送るかをBedrockが判断します。AWSは最大30%のコスト削減を謳っており、お客様の事例から見ても妥当な水準です。カスタムコード不要で、モデルIDをプロンプトルーターのARNに差し替えるだけです。
クロスファミリーのルーティング(分類はHaiku、抽出はMistral、複雑な推論はSonnet)を行うには自分で構築する必要があります。実際、本番運用しているチームの多くがそうしています。正直なところ、留保なしに推奨できる成熟した既製フレームワークは存在しません。
機能するパターンは3つ。おおむね成熟度順に紹介します。
ルールベース分類 は多くのチームが出発点とし、そのまま留まることも多いアプローチです。タスクタイプのキーワード、入力長、期待される出力フォーマット、会話の深さといった構造的なシグナルを使い、5〜10個のルールを書きます。MLも依存関係も不要、1日でデプロイ可能。ルーティング判断の70〜80%を正しく処理できます。実体は数百行の条件分岐ロジックにすぎません。
信頼度ベースのカスケード は、私が見てきた中で最もROIの高いパターンです。すべてのリクエストをまず最も安価なモデルに送り、応答に曖昧な表現、不正な出力、必須フィールドの欠落がないかをチェック。失敗したら次の階層へエスカレーションします。エスカレーションされる5〜15%のリクエストでは、追加で1回分のモデル呼び出しのレイテンシが発生します。あるお客様(商品クエリを処理するeコマースプラットフォーム)では、この方法で月額$38Kから$15Kになりました。エスカレーション率はわずか8%。分類器は完璧である必要はなく、エスカレーションが例外を吸収できる程度の精度があれば十分です。エスカレーション率が25〜30%を超えるようなら、分類器を直しましょう。
ハイブリッド(ルール + ML分類器) は卒業ステップです。ラベル付き結果を含む本番トラフィックが数週間蓄積されたら、レイテンシを5ms未満しか追加しない小型分類器(DistilBERTやTF-IDF上のロジスティック回帰)を訓練します。分類器自体の遅延は1桁ミリ秒ですが、本当のコストはデータをラベル付けし定期的に再訓練するエンジニアリング上の規律です。これを実践するチームは、ルーティング精度を約78%から約91%へ改善するのが一般的です。
既存フレームワークも入念に調査しました。LMSysチームのRouteLLMは研究に裏打ちされていますが、本質的には汎用チャットデータで訓練された2モデルルーターであり、ドメイン特化のBedrock workloadsには再訓練が必要です。LiteLLMはインフラ(統一API、フォールバック、リトライ)としては優秀ですが、そのルーティングは品質ベースのモデル選択ではなく負荷分散です。どちらもクロスファミリー問題のドロップイン解決策にはなりません。
まずIntelligent Prompt Routingから始めましょう。クロスファミリールーティングが意味のある節約を生むという根拠が得られたら、ルールベースの分類器を構築します。予測可能でデバッグもしやすく、このルートを採った私のお客様は一様に40〜70%のコスト削減を報告しています。
モデル品質 vs コストのベンチマーク
最も高価なモデルが必要だと決めつけないでください。実際のタスクを複数モデルで実行し、自分のユースケースでの精度、タスクあたりのコスト(トークンあたりではなく)、レイテンシを測定しましょう。
金融サービスのお客様でこの演習を行いました。チケット分類タスクの精度はHaikuで94%、Sonnetで97% ― コストはSonnetの15分の1。その3%差は彼らのユースケースでは問題になりませんでした。数値はケースによって異なりますが、パターンは一貫しています。コミットする前にベンチマークを取ることです。
LLM-as-a-Judgeで品質評価を自動化
分類や抽出ではプログラム的に品質を検証できますが、要約・説明・顧客向け応答といったオープンエンドな生成では、従来は人間のレビュアーに頼るしかありませんでした。これではスケールしません。
Bedrockには組み込みの解決策があります。LLM-as-a-judgeモデル評価です。プロンプトのデータセット(任意で正解応答付き)を用意し、評価モデルを選ぶと、Bedrockが候補モデルの出力をジャッジに通し、正確性、完全性、有用性、一貫性、関連性、安全性などの指標で評価します。マネージドジョブとして実行され、プロンプトごとのスコアと集計値がS3に保存されます。
ねらいは、トークンあたり5〜15倍安いモデルが「十分に使える」ことを、本番トラフィックを移す前に証明することです。代表的なプロンプトを収めたJSONLファイルを準備し、Haiku、Sonnet、検討中の他モデルに対して同じ評価ジョブを実行し、スコアを並べて比較します。AWSはコードサンプル付きのウォークスルーを公開しており、GitHubに対応するJupyterノートブックもあります。
お客様と一緒にこれを使って学んだことをいくつか挙げます。
すべての比較で同じ評価モデルを使うこと。Haikuの出力をあるモデルで、Sonnetの出力を別のモデルで判定したら、それは評価モデル間の違いを測っているだけで、モデル間の違いではなくなります。
汎用ベンチマークではなく、実際の本番プロンプトを含めること。MT-Benchはサニティチェックとしては良いですが、チケット分類のプロンプトは学術的なQ&Aとは挙動が異なります。
評価自体にお金がかかります(ジャッジモデルが全出力を処理するため)。データセット全体ではなく、まず代表的な200〜500のプロンプトから始めましょう。安価なモデルが明らかに劣るのか、明らかに問題ないのか、「もう少し調査が必要」なのかを判断するには、たいていそれで十分です。
グラウンドトゥルースは任意ですが価値があります。既知の良い出力があるタスクでは、忠実性と正確性の指標がはるかに意味を持つようになります。
benchmark_bedrock.pyはコストとレイテンシを取得し、LLM-as-a-judgeは品質をスコアリングします。両方を回せば、手動レビューなしでコスト対品質の全体像が掴めます。
プロンプトキャッシュ:繰り返しのコンテキストで90%節約
これを有効化しているチームの少なさには驚かされます。キャッシュ済みの入力トークンは標準料金の90%引きで課金されます。
キャッシュを有効にしてリクエストを送ると、Bedrockはプロンプトのプレフィックスを保存します。同じプレフィックスを共有する後続のリクエストはキャッシュにヒットします。キャッシュヒットは通常料金の約10%。キャッシュ書き込み(初回リクエスト)はわずかに高いため、同じプレフィックスを複数回再利用する場合のみ節約になります ― ただしシステムプロンプトやfew-shotサンプルがあれば、回収はすぐに終わります。
効果が大きいのは、1,500トークンを超えるシステムプロンプト、静的なfew-shotサンプル、RAGアプリケーションでの共有文書コンテキスト、マルチターンの会話履歴です。
計算ははっきりしています。Claude Sonnetで2,000トークンのシステムプロンプト、1日10,000リクエストの場合:
| シナリオ | 1日あたりコスト(システムプロンプト分) |
|---|---|
| キャッシュなし | 2,000 × 10,000 × $0.003/1K = $60.00 |
| キャッシュあり(99%ヒット率) | 約$7.00 |
1日$53、月$1,500超 ― システムプロンプトだけで、です。先月あるお客様とこの計算を一緒に確認したら、通話が終わる前にキャッシュを有効化されました。
注意点もいくつかあります。
- キャッシュ可能な最小プレフィックス長はモデルによって異なる(通常1,024〜2,048トークン)
- 完全プレフィックス一致 ― 空白や順序が重要
- 非アクティブ時のTTL/有効期限(トラフィックが落ちるとキャッシュは冷える)
- すべてのモデルがキャッシュ対応とは限らない ― 最新ドキュメントを確認
ベンチマークフレームワークの構築
最適化の判断は、実際のworkloadsから得たデータに基づくべきです。私のチームの推奨は次のとおりです。
テストするモデルと構成ごとに、タスクあたりコスト、入出力トークン数、レイテンシ(初回トークンまでの時間と総時間)、タスク特化の品質スコアを取得します。
手順:実際のworkloadsの構成を代表する3〜5タスクを選ぶ、各タスクに既知の良い出力を持つ100〜500のテスト例を作成、各タスクをすべての候補モデルで実行、タスクあたりコストを計算(モデルによってトークン化が異なるため、トークンあたりではない)、コスト対品質をプロットしてカーブの「ひざ」を見つける ― 粗い散布図でも十分です。探しているのは「同じ品質ではるかに安い」または「品質はわずかに劣るが劇的に安い」というポイントです。
これを自動化するPythonスクリプト(benchmark_bedrock.py)をまとめました。複数のBedrockモデルでプロンプトを実行し、トークン数とレイテンシを記録、CSVを出力し、サマリー統計を表示します。フォークして、自分のworkloadsに合わせて調整してください。
結果を解釈する際は、品質が頭打ちになるモデルを探す(Haikuで93%、Sonnetで95%。その2%は10倍のコストに見合うか?)、レイテンシの外れ値、トークン効率の差(トークンあたりは安いが2倍冗長なモデルは実際には安くない)、バッチ候補に注目しましょう。
DoiT GenAI IntelligenceでGenAIコストを統合可視化
私が支援するチームのほとんどは、Bedrockだけを動かしているわけではありません。一部のworkloadsでOpenAI、別のworkloadsでAnthropic直接、GCPプロジェクトでVertex AIといった具合です。コストデータは互換性のないディメンションを持つ4つのコンソールに散在することになります。
これを解決するためにGenAI Intelligenceを構築しました。Bedrock、Vertex AI、Azure ML、Databricks、Anthropic、OpenAIのAIコストおよび使用データを、単一の正規化ビューに統合します。Bedrockの利用料が他のすべてと並んで表示されます。カスタムETLは不要です。
Bedrockに関しては、正規化されたラベルに価値があります。Model / Model Family はプロバイダーをまたいでモデル別のコストを追跡します。Usage Type は入力 vs 出力トークンの支出を分解 ― 多くのチームが過小評価している分割です。Cached は操作がキャッシュ済みトークンを使ったかを示すので、キャッシュのROIを請求データから測定できます。GenAI Spend はプロバイダーを問わずすべての生成AIコストにフラグを立て、合計予算の追跡を可能にします。
「先月Claude Sonnetでキャッシュ済みトークンによりいくら節約できたか?」「チケット分類におけるHaikuとSonnetの支出比率は?」といった問いに、プロバイダーをまたいで一箇所で答えられます。
ダッシュボードにはプリセットレポートが付属しています:プロバイダー別支出(月次)、モデルファミリー別コスト(過去14日間の日次 ― スパイクを素早く検出)、モデル別トークン内訳(30日)、プロバイダー別の時間別トークン使用量(過去2日 ― デプロイメントとの相関に有用)。GenAIデータが当社のCloud Analyticsエンジンに流れ込むため、AI支出に対しても予算、配分、異常検知、予測が利用できます。
例えば、分類にHaiku、推論にSonnetを使い、両方でキャッシュを有効にしている場合:
| モデル | Cached | 月額コスト | トークン使用量 |
|---|---|---|---|
| Claude Haiku | true | $45 | 18Mトークン |
| Claude Haiku | false | $320 | 12Mトークン |
| Claude Sonnet | true | $180 | 4Mトークン |
| Claude Sonnet | false | $2,100 | 6Mトークン |
Haikuのキャッシュヒット率は十分(トークンの60%がキャッシュ)。Sonnetは低い(40%)。Sonnetのキャッシュを改善すれば月数百ドルの節約が見込めます ― CloudWatchクエリを1つも書かずに発見できました。
始め方:AWSアカウントをDoiTに接続し、Dashboards → GenAI Intelligenceに進めば、Bedrockのデータが自動的に取り込まれます。Bedrock側での計装は不要です。
OpenTelemetryによる観測性
ベンチマークは特定時点のスナップショットにすぎません。本番workloadsは変動します ― プロンプトが変わり、トラフィックパターンがシフトし、新しいモデルがリリースされます。継続的な可視性のうち、請求面はGenAI Intelligenceがカバーします。アプリケーションレベルの計装(レイテンシ、ルーティング判断、リクエストごとのキャッシュヒット)については、OpenTelemetryをお勧めします。
GenAI semantic conventionsのおかげで、OTel互換のバックエンド(Grafana、Datadog、Honeycomb)はあなたのスパンを理解できます。すべてのBedrock呼び出しを次の属性付きのスパンでラップしましょう:
gen_ai.system―"aws.bedrock"gen_ai.request.model― モデルIDgen_ai.usage.input_tokens/output_tokens― レスポンスメタデータからgen_ai.usage.cost― 料金テーブルから計算task.type― アプリケーションレベルのタスク名
得られるもの:タスクあたりコストの時系列トレンド(請求に響く前にプロンプトドリフトを検出)、モデルルーティングの検証(あるお客様のTier 1は期待していた70%ではなく40%しか処理しておらず、月額$800超過の原因となるバグでした)、キャッシュヒット率の監視(請求サイクルの終わりではなく数時間以内に低下を検知)。
プロビジョンドスループットの判断のためにCloudWatchのModelUnitUtilizationと相関させるデータも得られます。
最小限の計装:
from opentelemetry import trace
tracer = trace.get_tracer("bedrock-client")
def invoke_with_telemetry(client, model_id, prompt, max_tokens, task_type="unknown"): with tracer.start_as_current_span("bedrock.invoke") as span: span.set_attribute("gen_ai.system", "aws.bedrock") span.set_attribute("gen_ai.request.model", model_id) span.set_attribute("gen_ai.request.max_tokens", max_tokens) span.set_attribute("task.type", task_type)
resp = client.invoke_model(modelId=model_id, body=body, contentType="application/json") data = json.loads(resp["body"].read())
in_tok = data["usage"]["input_tokens"] out_tok = data["usage"]["output_tokens"] span.set_attribute("gen_ai.usage.input_tokens", in_tok) span.set_attribute("gen_ai.usage.output_tokens", out_tok)
return dataここから4つのパネル ― モデル別の日次コスト、モデル別のタスクあたりコスト、キャッシュヒット率、p50/p95レイテンシ ― を構築し、週次でレビューしましょう。
よくある落とし穴
最もよく目にするミスを、無駄になる金額の大きさのおおよその順で挙げます。
プロビジョンドスループットの利用率を毎週監視する。 持続的に50%未満なら、オンデマンドへ切り替えましょう。先のメディア企業は、実際の推論よりもアイドル状態のプロビジョンド容量で多くを浪費していました。
出力トークンを見積もり、上限を設ける。 出力トークンは入力の3〜5倍のコストです。あるチームは抽出プロンプトに「JSONで応答、説明不要」と追加するだけで、出力コストを40%削減しました。
24時間未満のレイテンシが不要なものはすべてバッチ化する。 50%割引、品質の妥協なしです。
Sonnetをデフォルトにしないこと。 プロトタイピング時にうまくいったからといってすべてに使うのは、最もよくある過剰支出のパターンです。
プロンプトを再利用する場所ではキャッシュを有効化する。 静的なシステムプロンプトやfew-shotサンプルがありますか? 数分の作業で即座に節約できます。
トークンあたりではなくタスクあたりで測定する。 より冗長な出力を生成する安価なモデルは、タスクあたりではかえってコスト高になり得ます。タスクレベルでベンチマークしましょう。
まとめ:すべてを組み合わせる
私が多くのチームに案内する最適化の道筋です。
- バッチ推論 ― 非同期workloadsを移行。即座に50%節約、品質への影響なし。
- プロンプトキャッシュ ― 繰り返し使うコンテキストで有効化。数分の作業。
- モデル代替案のベンチマーク ― workloadsの60〜80%がTier 1で問題なく動くと判明する可能性が高い。
- モデルルーティング ― 分類器を構築。ルールから始める。
- プロビジョンドスループット ― 上記が安定し、利用が予測可能になってからでよい。
これらは複利で効きます。冒頭で触れた金融サービスのお客様は、6週間でステップ1〜4を実施しました。バッチ推論で22%、キャッシュで18%、モデルルーティングでさらに25%節約。合計で$40Kから$18Kへ。
ただし、これは一度きりのプロジェクトではありません。Bedrockを取り巻く状況は絶えず変わります。Claude 3.5 Haikuがローンチされたとき、ほぼ同じ価格帯でClaude 3 Haikuより明確に優れていましたが ― モデルIDをハードコードしていたチームは、何か月もアップグレードを見逃していました。AWSはBedrockの料金を、大々的な告知なく何度も調整してきました。そしてあなた自身のworkloadsもドリフトします。プロンプトは長くなり、新しいタスクタイプが追加され、トラフィック比率がシフトします。
機能するアプローチは、四半期ごとの軽量レビューです。新しいモデルに対してベンチマークを再実行(ベンチマークスクリプトがあれば午後の作業で済みます)。LLM-as-a-judgeで品質が後退していないかを検証。OTelダッシュボードでルーティングのドリフトを確認 ― Tier 1は期待するトラフィック割合をまだ処理していますか? キャッシュヒット率は変わっていませんか?
DoiTを利用しているなら、GenAI Intelligenceがモデル別コストの推移を表示してくれるので、何かが変化したときに一目でわかります。一度やってみれば、レビュー全体は半日で済みます。
先ほど触れたメディア企業は、こうしたレビューの一つで、プロンプトの変更によってキャッシュヒット率が94%から61%へ静かに低下していたことを発見しました ― 誰も気づいていなかった、月$2Kの余計な支出です。
今日Bedrockを使っていて請求書をもう一度見直したいなら、いつでも喜んで拝見します ― 特にAPACの方は。すでにDoiTのお客様であれば、GenAI Intelligenceダッシュボードがあります ― 四半期レビューの出発点として活用してください。
本記事で参照したベンチマークスクリプトはhttps://github.com/p-obrien/bedrock-cost-model-blogで公開しています。自分のworkloadsで実行し、情報に基づく意思決定に必要なデータを生成してください。