
はじめに
カミナシでエンジニアリングマネージャーをしている、すずけん(@szk3)です。自チームのプロダクト「カミナシ 設備保全」には 2 つの AI 機能があり(プレスリリース)、どちらも Amazon Bedrock AgentCore 上のエージェントから同じ LLM モデルを呼び出しています。
リリースからしばらく経つと、「で、それぞれのAI機能でLLMの呼び出しいくらかかってるの?」という当然の疑問が出てきました。ところがこの2つのAI機能は同じLLMモデルを呼び出しており、請求上は合算されるため、機能ごとのコストを切り分けられていませんでした。
この記事では、Amazon Bedrock の Application inference profile を使って、同じモデルを呼び出す複数の AI 機能のコストを機能別に可視化した話を共有します。
同じモデルを呼ぶと、コストが混ざる
AWS Cost Explorer で Amazon Bedrock のコストを見ると、使用タイプ(モデル × 入出力トークン種別)の単位までは分解できます。請求レコードはこの使用タイプ単位で積み上がるので、同じモデルを使う複数の機能は同じレコードに合算され、そこから先は分解できません。自チームが提供する 2 つの AI 機能に関しても、Bedrock が提供する同一の LLM モデルを利用していました。
この状態では、次の点が困ります。
- 同じモデルを使うため、機能ごとの AI 呼び出しコストが区別できない
- 機能単位での投資対効果を評価できない
- 今後 AI 機能が増えたときのコスト管理の見通しが立たない
AI 機能は作って終わりではなく、どの機能に投資を続けるかを判断しながら育てていくものです。コストの解像度が機能単位まで上がっていないと、その判断の材料が取れません。
Application inference profile とは
2024 年 11 月に Amazon Bedrock に追加された機能です。モデルへの参照となるリソースを自分のアカウント内に作成し、そこにコスト配分タグ(cost allocation tags)を付けられます。
モデル呼び出し時に、モデル ID の代わりにこのプロファイルの ARN を modelId に指定すると、その呼び出しの請求レコードにプロファイルのタグが付きます。これにより AWS Cost Explorer や AWS Cost and Usage Reports(CUR 2.0)でタグ別に集計できるようになります。
Inference Profile には 2 種類あります。
| 種類 | 作成者 | 主な用途 |
|---|---|---|
| System-defined inference profile | AWS | Cross-Region inference(複数リージョンへのリクエストルーティング) |
| Application inference profile | 利用者 | コストと使用状況のトラッキング |
ポイントは、Application inference profile の作成時に、コピー元として System-defined inference profile を指定できることです。これにより Cross-Region inference によるルーティングを維持したまま、コスト追跡だけを足せます。
実装
やることは 4 つです。本記事中のコードは、実際の実装をもとにしたサンプルです。
- 機能ごとに Application inference profile を作成する(Terraform)
- IAM 権限を付与する
- 呼び出し側で、モデル ID の代わりにプロファイルの ARN を指定する
- コスト配分タグを有効化する
1. 機能ごとに Application inference profile を作る
Terraform の AWS Provider には aws_bedrock_inference_profile リソースがあるので、これで作成します。
resource "aws_bedrock_inference_profile" "feature_a_sonnet_4_5" { name = "myapp-feature-a-${var.env}-sonnet-4-5" description = "Feature A Agent Claude Sonnet 4.5" model_source { copy_from = "arn:aws:bedrock:ap-northeast-1::inference-profile/jp.anthropic.claude-sonnet-4-5-20250929-v1:0" } tags = { "myorg:myapp:application" = "myapp" "myorg:myapp:feature" = "feature-a" "myorg:myapp:environment" = var.env } }
copy_from には Foundation Model の ARN(単一リージョン)か、System-defined inference profile の ARN(Cross-Region inference)を指定します。自チームは日本国内リージョン(東京と大阪)でルーティングする jp. プレフィックスの Cross-Region inference を使っているので、後者を指定しています。
別の AI 機能に対して新しく Profile を追加する際も、タグの feature を feature-b に変えただけの同じ構成で作ります。
リソース名にモデル名(サンプルでは sonnet_4_5)を含めているのは、プロファイルがモデルと 1:1 で紐づくためです。モデルを更新するときは、新しいプロファイルを追加して参照を切り替え、古いプロファイルを後から削除します(この運用は後述します)。
タグキーの付け方では、当初 Application / Feature / Environment のような汎用的なキー名を考えていましたが、最終的には myorg:myapp:feature のように組織やチームの名前空間を付けたキーにしました(キー名はサンプルです)。理由としては、コスト配分タグの有効化はアカウントの請求設定として行うため、将来コスト管理用のタグが全社で一元的に統制されると、汎用キーは他チームのタグとキー名が衝突し、自チームのコスト管理が壊れかねないと考えたからです。名前空間は最初に切っておくのが安全だと思います。
2. IAM 権限を付与する
プロファイル経由で呼び出すには、呼び出し元のロール(自チームでは AgentCore Runtime の実行ロール)に、プロファイル自身への許可を追加します。
statement { sid = "BedrockInferenceProfileAccess" effect = "Allow" actions = [ "bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream", "bedrock:GetInferenceProfile" ] resources = [ aws_bedrock_inference_profile.feature_a_sonnet_4_5.arn ] }
ここに注意点がひとつあります。プロファイルの ARN への許可だけでは動きません。AWS のドキュメントに明記されているとおり、Resource に Inference profile を指定する場合は、そのプロファイルに紐づく各リージョンの Foundation Model への bedrock:InvokeModel 系の許可も併せて必要です。自チームでは Foundation Model 側の許可を別のステートメントで付与済みだったため、追加したのは上記のステートメントだけで済みました。
3. 呼び出し側で ARN を渡す
InvokeModel / Converse の modelId は、モデル ID のほかに Inference profile の ARN も受け付けます。そのため呼び出し側の変更は、モデル ID の代わりにプロファイルの ARN を渡すだけです。
自チームのエージェントは Strands Agents SDK を使っています。Terraform 側で AgentCore Runtime の環境変数にプロファイルの ARN を渡し、それを BedrockModel の model_id に指定しています。環境変数が未設定の場合は、モデル ID の直接指定にフォールバックします。
import os from strands.models import BedrockModel DEFAULT_MODEL_ID = "jp.anthropic.claude-sonnet-4-5-20250929-v1:0" def create_bedrock_model() -> BedrockModel: # model_id にはモデルIDの他に Application inference profile の ARN も指定できる model_id = os.environ.get("INFERENCE_PROFILE_ARN", DEFAULT_MODEL_ID) return BedrockModel( model_id=model_id, region_name="ap-northeast-1", )
4. コスト配分タグを有効化する
タグを付けただけでは Cost Explorer には出てきません。AWS Billing and Cost Management コンソールの「コスト配分タグ」で、付けたタグキーを有効化する必要があります。注意点が 2 つあります。
- 有効化してから Cost Explorer / CUR に反映されるまで、最大 24 時間かかる
- タグは遡及しない。有効化した以降に発生したコストにしか、タグは付かない
どちらも、タグの有効化を実装より先に済ませておく理由になります。タグの付いたリソースがまだ存在しなくても有効化はできるので、自チームでは実装 PR を作る前に有効化を済ませました。
Cost Explorer での見え方

このように、Cost Explorer で「サービス」の絞り込みで LLM モデルを指定した上で、「グループ化の条件」に feature を表すタグキー(サンプルでは myorg:myapp:feature)を指定すると、feature-a と feature-b のコストが分かれて表示されます。同様に environment のタグキーで dev と prod を切り分けられます。
これで「feature-a 機能に月いくら、feature-b 機能に月いくら」という問いに答えられるようになりました。
とはいえ、完璧ではない
リクエスト単位のコストは分からない
Application inference profile が Cost Explorer / CUR に届けるのは集計済みの金額で、粒度は「使用タイプ × 日」が最小です。「このプロンプト 1 回にいくらかかったか」を知りたい場合は、リクエスト単位のメタデータタグ付け(per-request metadata tagging)とモデル呼び出しログ(model invocation logging)を組み合わせる別のアプローチが必要です。機能単位の月次コストが見たいだけなら、Application inference profile で足ります。
プロファイルはモデルと 1:1 で増えていく
プロファイルは特定のモデルに紐づくので、「モデル × 機能 × 環境」の組み合わせの数だけ増えます。自チームは 2 機能 × 2 環境 = 4 個で済んでいますが、機能やモデルのバリエーションが多い組織では、モデル更新のたびにプロファイルの作り直しが発生し、管理対象が膨らみます。AWS のドキュメントでも、スケールするコスト追跡では、タグの粒度をチームやコストセンター単位に留めることなどが推奨されています。
タグは遡及しない
前述のサンプル画像にあるとおり、導入前に発生したコストは合算されたままで、後から分けられません。
ほかの按分手段
Bedrock のコスト按分は Application inference profile だけではありません。OpenAI 互換の Responses / Chat Completions API(bedrock-mantle エンドポイント)を使う場合は、モデルに紐づかない Projects が使え、本記事で触れた「プロファイルがモデルごとに増える」問題自体が起きません。bedrock-runtime のままでも、呼び出し元の IAM ロール / ユーザー単位で按分する IAM principal attribution が追加コードなしで使え、Application inference profile と併用できます(こちらは「機能単位」ではなく「誰が呼んだか」の軸です)。用途に応じて、機能別は Application inference profile、ID 別は IAM principal attribution、リクエスト別は per-request metadata tagging、と使い分けるとよいです。
振り返り
導入のコア部分は、機能ごとに数十行の Terraform と、modelId の差し替えだけでした。アプリケーションコードのロジックには手を入れずに「AI 機能ごとに月いくらかかっているか」へ答えられるようになったので、投資対効果は良い部類だと思います。
AI 機能の開発がこれからも増えていくことは、容易に想像がつきます。1 つ目、2 つ目の時点ではコストの内訳は気にならないかもしれませんが、「どの機能に投資を続けるか」という判断はいずれ必ず来ます。そのときコスト配分タグは遡及できないので、過去分のデータは後から取れません。Bedrock で複数の AI 機能を作るなら、最初の機能をリリースするタイミングで Application inference profile をセットで導入しておくのがおすすめです。
参考リンク
- Application inference profiles - Amazon Bedrock
- Create an application inference profile - Amazon Bedrock
- Use an inference profile in model invocation - Amazon Bedrock
- Prerequisites for inference profiles - Amazon Bedrock
- Amazon Bedrock announces support for cost allocation tags on inference profiles
- Terraform Registry - aws_bedrock_inference_profile