推論プロファイルによるアプリ単位のBedrockコスト追跡
アプリケーション推論プロファイルはBedrock呼び出しにコスト配分タグを付与し、共有された請求をチーム別の明細へと変える。難しいのはタグ設計の方だ。

アプリケーション推論プロファイルとは、モデルARNをタグ付きでラップしたものであり、これがあるかないかで、Bedrockの請求書が全社でたった1つの数字になるかどうかが決まる。モデルを指すプロファイルを作成し、コスト配分タグを付与し、モデルIDの代わりにプロファイルARNを呼び出す。タグはCost ExplorerとCost and Usage Reportにそのまま引き継がれる。それだけの仕組みであり、半日もあれば終わる。
半日で終わることが問題なのではない。問題は、タグ付けの体系が組織としてのコミットメントになるという点だ。ほとんどのチームは10分で1つの体系を選び、そのまま2年間付き合うことになる。だからこの記事では、APIの説明には20分ほどの分量を割き、残りはタグ設計に費やす。
解決する問題
プロファイルなしでは、Bedrockの利用はただの「Bedrockの利用」としてしか表れない。モデル別・リージョン別の支出は分かるので、先月Claude Sonnetに多額の費用がかかったことは分かるが、9つのアプリケーションのうちどれが原因だったのかは何も分からない。デフォルトのレポートは、財務部門が唯一気にする問い、つまり「これは誰の予算から出ているのか」に答えられない。この問題のより広い構図についてはYour LLM Bill Is an Observability Problemで書いた。プロファイルは、その中でも帰属の部分に特化した具体的な対策だ。
仕組み
基盤モデル、またはシステム定義のクロスリージョンプロファイルを指すプロファイルを、タグ付きで作成する。
aws bedrock create-inference-profile \
--inference-profile-name "support-assistant-prod" \
--model-source copyFrom=arn:aws:bedrock:eu-central-1::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0 \
--tags key=team,value=support key=app,value=assistant key=env,value=prodそして、これまでモデルIDを渡していた箇所すべてで、プロファイルARNを呼び出す。
response = client.converse(
modelId="arn:aws:bedrock:eu-central-1:123456789012:application-inference-profile/abc123",
messages=messages,
)見落としやすい運用上の細かい点が3つある。
- プロファイルはモデル固有だ。1つのプロファイルは1つのモデルをラップする。6つのアプリ×4つのモデルなら24個のプロファイルになる。この掛け算があるからこそ、タグ設計は見た目以上に重要になる。リソースに名前を付けているのではなく、グリッドを定義しているのだ。
- タグは遡及しない。Billingコンソールでコスト配分タグを有効化すると、それ以降の支出にのみタグが付く。先月分の支出にラベルが付くことはない。誰かにデータを求められてからではなく、必要になる前にタグキーを有効化しておくこと。
- 粒度は利用タイプ別の日次だ。プロファイルによって、Cost ExplorerとCURで日単位の請求額が分かるようになる。リクエスト単位のコストは分からない。リクエスト単位の経済性が必要なら、それはアプリケーション側のトークンロギングの話であり、担当者もシステムも別物になる。
タグ体系を設計する
陥りがちな罠は、誰かが行動を起こせるものではなく、見えやすいものにタグを付けてしまうことだ。すべてのタグキーは、実際の会議で実在の人物が問う質問に答えられるものであるべきだ。
ほとんどの組織はこの4つのキーで足りる。
team: 誰が支払うか。既存のコストセンター分類に正確に合わせること。財務部門がcc-4471と呼んでいるなら、platform-engのような独自名を作らないこと。誰も信用しない対応表のメンテナンスに1年を費やす羽目になる。app: どのワークロードか。実際に止めることになる単位。env: prod、staging、dev。これは最も早く元が取れるタグだ。というのも、多くのBedrock請求書で最初に本当に驚かされる数字は、devにかかっている費用の額だからだ。feature: 任意。1つの機能が支出の大半を占めるアプリ向け。控えめに使うこと。キーを1つ増やすたびに、プロファイル数は掛け算的に増える。
意図的にリストから外したもの: ユーザー単位のタグだ。ユーザーごとにプロファイルを作らないこと。リソース上限に達するうえ、メンテナンスコストが際限なく増える。ID単位での帰属が必要なら、BedrockはIAMプリンシパルベースのコスト配分をサポートしており、1人ずつプロファイルを用意しなくても、呼び出し元のIDに支出を紐づけられる。チーム・アプリの粒度にはプロファイルを使い、どの人間またはサービスロールが急増を引き起こしたかを知りたいときにはIAMプリンシパル帰属を使う。両者は組み合わせられる。
仕組みとして構造化する
規律に依存するタグ体系は必ず崩壊する。それを維持させる仕組みが2つある。
1つ目は、プロファイルをそのアプリを使う場所と同じIaC内に作成し、そのアプリの他のリソースにタグを付けているのと同じ変数からタグ値を取得することだ。コンソールで手作業で作られたプロファイルは、永遠にtestとタグ付けされたままのプロファイルになる。
2つ目は、直接パスを塞ぐことだ。プロファイルが存在するようになったら、生のモデルIDを呼び出すアプリはタグなしの支出を生み出し、タグなしの支出こそ誰も引き取り手のいない明細項目そのものになる。foundation-model ARNに対してbedrock:InvokeModelとbedrock:Converseを拒否し、application-inference-profile ARNに対してのみ許可するIAMポリシーを設定すれば、タグ付きパスだけが唯一の経路になる。これはタスク単位でロールをスコープするのと同じ発想であり、IAM for LLM Apps: Least Privilege When the Caller Is a Modelで論じた議論を繰り返すつもりはないが、それが被害範囲だけでなく請求書にも当てはまることは指摘しておく。
これは初日にやっておくべきだ。すでにモデルIDを呼び出している6つのアプリに拒否ポリシーを後から適用するのは、変更凍結を伴う移行作業になる。
得られるもの、それでも得られないもの
1か月分のタグ付きデータが溜まれば、Cost Explorerをteamでグループ化して内訳を見たり、env=devでフィルタして誰かが動かしっぱなしにしたバッチジョブを見つけたり、CURにアプリ別・日別のコストを問い合わせてリクエスト量と並べたダッシュボードを作ったりできる。異常検知も有用になる。Bedrockの総支出に対するアラートはノイズだが、1つのアプリに対する予算アラートはシグナルになるからだ。
それでも得られないもの: リクエスト単位のコスト、マルチテナントアプリにおける顧客ごとのコスト、そしてその支出に見合う価値があったかどうかだ。1つ目はトークンロギングの領域だ。2つ目には課金システムが決して目にしないテナントのコンテキストが必要であり、だからこそマルチテナントの帰属はアプリケーション側の問題であり続ける。3つ目はそもそも課金の問いではない。プロファイルはお金がどこへ流れたかを教えてくれる。それが妥当だったかどうかについては何も語らない。
結論
アプリケーション推論プロファイルは、モデルARNをラップするだけのコストで、帰属不能なBedrockの請求書をチーム別・アプリ別の明細に変える。履歴が必要になる前にタグキーを有効化し、体系は組織の実際の予算管理の仕方に合った少数のキーにとどめ、プロファイルはIaCで作成し、IAMでタグなしパスを拒否して帰属が誰かの記憶に依存しないようにする。APIの導入は半日で終わる。タグ設計は、それを選んだ人よりも長く生き残る。
次に読む
- Your LLM Bill Is an Observability Problem。トークン支出が明細項目ではなくテレメトリのように振る舞う理由について。
- Multi-Tenant LLM Apps: Isolating Customers on a Shared Model。プロファイルでは届かない帰属の問題について。
この記事が土台にしている一般的なコスト配分の規律、つまりAWS環境全体でのタグ付け戦略については、ercan.cloudのフィールドノートを参照してほしい。ハブはercanermis.comだ。
Ercan の他のサイト
同じ著者、別の領域のサイトが2つ。