Bedrock AgentCoreを東京リージョンで動かす——us.は失敗、global.は動く、jp.を選ぶ理由
Bedrock AgentCoreを東京リージョンで動かすとき、モデルIDのプレフィックスで何が変わるかを実測しました。us.は失敗し、global.は動きます。それでもjp.を選ぶ理由を、推論プロファイルの宛先リージョンから説明します。

医療クラウド — AIエージェント基盤編
- 1.Bedrock AgentCoreを東京リージョンで動かす——us.は失敗、global.は動く、jp.を選ぶ理由
目次
30分で課題を整理しませんか?
記事の内容についてのご質問や、自社への適用についてお気軽にご相談ください。
「サンプルのまま東京で動かしたら、エラーも出ずに普通に返ってきました」
Bedrock AgentCore を東京リージョン(ap-northeast-1)で試したとき、いちばん厄介だったのはこれです。落ちれば原因を調べます。でも動いてしまうと、誰も調べません。
この記事では、モデルIDのプレフィックスを us. / global. / jp. と変えたときに、東京で何が起きるかを実測しました。あわせて、推論プロファイルの宛先リージョンを AWS API で確認した数値も示します。医療情報のようにデータの所在地を説明する必要がある場合、「動く」だけでは足りない理由がここにあります。
この記事で分かること
- 東京リージョンで
us.プレフィックスのモデルIDが失敗する理由と、そのエラーメッセージの読み方 - 同一モデルでプレフィックスだけを変えた対照実験の結果(
us.3回中3回失敗 /jp.6回中6回成功) jp./apac./global.それぞれの推論プロファイルが、実際にどのリージョンへルーティングされるか- AWS 公式CLI
@aws/agentcoreが生成する雛形の既定値と、Strands Agents SDK 本体の既定値 - 東京で
jp.に直す具体的な書き換えと、それでも残る IAM 側の穴
前提知識
- Amazon Bedrock でモデルを呼び出したことがある(
converseまたは SDK 経由) - AWS CLI でプロファイルを切り替えて操作できる
- クロスリージョン推論という言葉を聞いたことがある(詳細は本文で説明します)
検証した範囲と、していない範囲
先に線を引いておきます。この記事の主張がどこまで裏付けられているかを、読者が判断できるようにするためです。
実際に手を動かして確認したのは、次の範囲です。
- 東京リージョンからの Bedrock 呼び出し(
us./jp./global.の各プレフィックス) get-inference-profile/list-inference-profilesによる宛先リージョンの確認(2026年8月18日時点)@aws/agentcorev0.27.0 での雛形生成とdeploy --dry-run(CloudShell と macOS の2環境)- 合成された CloudFormation テンプレートの読解
逆に、次のことはしていません。
- AgentCore Runtime への実デプロイと
invoke。 この記事で作成リソースに触れる箇所は、--dry-runが合成した CloudFormation を読んだ結果です global.が実際にどのリージョンで推論したかの特定。 宛先の範囲は AWS 公式ドキュメントの記述で確認しましたが、実際の経路を観測したわけではありません(後述しますが、そもそもログに残りません)- Strands Agents SDK の既定値の動作確認。 該当箇所はソースコードを読んだ結果であり、実行して確かめてはいません
検証にかかった AWS 料金は、モデル呼び出しの数円のみです。--dry-run でリソースは作成していません。
それでは、最初に起きたことから順に見ていきます。
東京で最初に起きること(us.プレフィックスは通らない)
AWS のサンプルコードやチュートリアルでは、モデルIDが us. 付きで書かれていることがよくあります。
model = BedrockModel(
model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
streaming=True,
)
この us. はクロスリージョン推論プロファイルの接頭辞です。単一リージョンではなく、複数リージョンにまたがって推論をルーティングする仕組みで、us. は米国内のリージョン群を指します。
これを東京リージョンでそのまま呼ぶと、次のエラーになります。
ValidationException: The provided model identifier is invalid.
エラーメッセージから読み取れること
このメッセージは「権限がない」とは言っていません。「識別子が不正だ」と言っています。つまり東京リージョンから見て、そのIDのリソースは存在しないということです。
実際、権限の問題と切り分ける必要があります。Bedrock で東京リージョンが絡むと、少なくとも3種類のエラーが出ます。
| 出るエラー | 意味 |
|---|---|
ValidationException: The provided model identifier is invalid. |
そのリージョンにそのIDが存在しない |
AccessDeniedException: ... is not authorized to perform: bedrock:InvokeModel |
IAM で許可されていない |
AccessDeniedException: Model access is denied ... AWS Marketplace actions |
モデルの利用契約が未締結 |
us. のケースは1番目です。IAM ポリシーをいくら直しても解決しません。この切り分けは次回の記事で詳しく扱いますが、いまは「ValidationException は権限の話ではない」とだけ押さえてください。
では、本当にプレフィックスだけが原因なのでしょうか。ここを詰めます。
プレフィックスだけを変えた対照実験
最初の検証では、うまくいかないときに複数の要素を同時に変えてしまいました。モデルを Sonnet から Haiku に変え、同時にプレフィックスも us. から jp. に変えたのです。これでは、どちらが効いたのか分かりません。
同一モデル・同一リージョンで3文字だけ変える
そこで、条件を揃え直しました。
- モデル:
anthropic.claude-sonnet-4-5-20250929-v1:0に固定 - リージョン:
ap-northeast-1に固定 - 変えるもの: プレフィックスの
us.とjp.のみ(3文字)
結果です。
| プレフィックス | 試行 | 結果 |
|---|---|---|
us.anthropic.claude-sonnet-4-5-20250929-v1:0 |
3回 | 3回とも ValidationException |
jp.anthropic.claude-sonnet-4-5-20250929-v1:0 |
6回 | 6回とも成功 |
同じモデル、同じリージョン、同じ認証情報です。違うのはプレフィックスの3文字だけでした。
IAM を疑う前に確認したこと
「結局は権限不足では」という反論はもっともなので、そこも潰しました。
IAM ポリシーで bedrock:InvokeModel を明示的に許可する前と後で、us. のエラーメッセージを比較しました。変わりませんでした。 どちらも ValidationException のままです。権限が原因なら、付与後に AccessDeniedException へ変わるか、成功するはずです。
これで「東京では us. プレフィックスのIDが存在しない」ことが確定しました。
ここまでは、日本語の技術記事でも触れられている内容です。問題はこの先にあります。
global. は動く。だから気づかない
us. が使えないと分かったとき、代替としてよく挙がるのが global. です。
日本語で東京リージョンへのデプロイ手順をまとめた記事に、Qiita「Dockerなし、Windows、東京リージョンでAmazon Bedrock AgentCore FASTをデプロイする」があります。us. が東京から使えない理由を、こう説明しています。
FAST のデフォルトでは
us.プレフィックス付きのクロスリージョン推論プロファイルが使われています。これは US リージョン専用で、ap-northeast-1からは利用できません。
そのうえで global.anthropic.claude-sonnet-4-5-20250929-v1:0 へ差し替える手順が示されています。東京で動かすという目的に対して、これは有効な解です。 実際に動きますし、エラーも出ません。Docker を使わない構成まで踏み込んでいて、同じところで詰まったときに助かる記事です。
この記事が扱いたいのは、そこに条件をもう一つ足した場合です。医療情報のようにデータの所在地を説明する必要があると、「動く」だけでなく「どこで処理されたか」も問われます。同じ global. という選択が、条件次第で意味を変えます。
そして厄介なのは、確認するきっかけが生まれにくいことです。us. は失敗するので全員が調べます。global. は成功するので、そこで手が止まります。「動かない既定値」より「静かに動いてしまう既定値」のほうが、後から効いてきます。
global. を選ぶと何が決まるのか。推測ではなく AWS API の応答と公式ドキュメントで確認しました。
推論プロファイルの宛先を実測で比べる(jp. / apac. / global.)
推論プロファイルには、ルーティング先のモデルARNが登録されています。get-inference-profile で取得できます。以下はすべて2026年8月18日に東京リージョンから実行した結果です。
jp. は東京と大阪の2つ
aws bedrock get-inference-profile \
--inference-profile-identifier "jp.anthropic.claude-sonnet-4-5-20250929-v1:0" \
--query 'models[].modelArn' --output text
返ってきたのは2件だけです。
arn:aws:bedrock:ap-northeast-3::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0
arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0
東京(ap-northeast-1)と大阪(ap-northeast-3)です。どちらも日本国内で、それ以外の宛先はありません。AWS Japan による解説記事「Amazon Bedrock の JP Cross-Region Inference で日本国内に閉じた推論を実現するぞ!」でも、この2リージョンに閉じることが目的として説明されています。
apac. は8リージョン
同じ確認を apac. に対して行うと、範囲が大きく広がります。なお apac.anthropic.claude-sonnet-4-5-20250929-v1:0 は ResourceNotFoundException になったため、プロファイルが存在する apac.anthropic.claude-sonnet-4-20250514-v1:0 で確認しました。
ap-northeast-1 ap-northeast-2 ap-northeast-3
ap-south-1 ap-south-2
ap-southeast-1 ap-southeast-2 ap-southeast-4
8リージョンです。日本の3つに加えて、韓国・インド・シンガポール・オーストラリアが含まれます。ap-northeast-2 がソウル、ap-south-1 と ap-south-2 がインド、ap-southeast-1 がシンガポール、ap-southeast-2 と ap-southeast-4 がオーストラリアです。
範囲は広いものの、どこへ行きうるかは完全に列挙できます。これは重要な性質です。
global. はリージョン欄が空のARNを含む
同じことを global. でやると、応答の形が変わります。
arn:aws:bedrock:::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0
arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-sonnet-4-5-20250929-v1:0
2行目は東京です。問題は1行目です。
arn:aws:bedrock:::foundation-model/...
^^ リージョンを書く位置が空
ARN のリージョン欄が空になっています。jp. や apac. のように具体的なリージョン名が並ぶのではなく、リージョンを特定しない宛先が含まれている状態です。
API では宛先を列挙できませんが、AWS 公式ドキュメントには範囲が明記されています。Global cross-Region inference のページでは、次のように説明されています。
Global cross-Region inference extends cross-Region inference beyond geographic boundaries, enabling the routing of inference requests to supported commercial AWS Regions worldwide.
地理的な境界を越えて、世界中の商用 AWS リージョンへルーティングされるというのが公式の説明です。リージョン欄が空の ARN についても、「グローバルな FM ARN にはリージョンもアカウントも指定されておらず、これはクロスリージョン機能のために意図されたもの」と明記されています。
つまり global. は「宛先が不明」なのではなく、**「宛先が世界中の商用リージョン」**です。そのうえで、実際にどこで処理されたかは追跡できません。AgentCore のクロスリージョン推論のページには、こう書かれています。
Amazon CloudWatch and AWS CloudTrail logs won't specify the AWS Region in which data inference occurs.
CloudWatch にも CloudTrail にも、推論が行われたリージョンは記録されません。 事後に確認する手段がない、ということです。
医療情報を扱う場合、データの所在地を説明できることが求められます。範囲が世界中で、ログにも残らない構成では、その説明ができません。動くかどうかとは別の話です。
AWS 自身も注意を促しています。AgentCore のドキュメントには、データレジデンシーやコンプライアンス要件を持つ顧客は、グローバルクロスリージョン推論が自社のコンプライアンスフレームワークに適合するかを評価すべきと書かれています。評価したうえで選ぶもの、という位置づけです。
関連記事 Bedrock Guardrailのデプロイが2回失敗した話——日本語トピック名が引き金だった 同じく Bedrock を日本語・東京リージョンで扱ったときに詰まった記録です。
ここまではモデルIDを自分で書く前提の話でした。次は、書かない場合に何が入るかを見ます。
AgentCore の公式CLIが生成する雛形は global. だった
AWS 公式の @aws/agentcore CLI(v0.27.0)には、プロジェクトの雛形を生成する agentcore create があります。実行してみました。
agentcore create --project-name uniprotTokyo --name uniprot \
--defaults --build CodeZip --language Python --framework Strands \
--model-provider Bedrock --memory none --protocol HTTP \
--idle-timeout 60 --max-lifetime 600
モデルIDは一切指定していません。 指定したのはプロバイダが Bedrock であることだけです。
なお --memory none を付けているのは、検証時の課金を抑えるためですが、結果的にもう一つの経路も避けています。AgentCore Memory はクロスリージョン推論を使います。公式ドキュメントによると、Asia Pacific の推論先には東京のほかにソウル・ムンバイ・シンガポール・シドニーが含まれます。モデルIDとは別に、Memory を有効にした時点で日本国外が宛先に入ります。 この記事では扱いませんが、有効にする場合は確認が必要な箇所です。
生成されたファイルを開くと、こう書かれていました。
# app/uniprot/model/load.py:6
from strands.models.bedrock import BedrockModel
def load_model() -> BedrockModel:
"""Get Bedrock model client using IAM credentials."""
return BedrockModel(model_id="global.anthropic.claude-sonnet-4-5-20250929-v1:0")
AWS 公式のCLIが、既定値として global. を書き込みます。
これは AWS CloudShell と手元の macOS の2環境で実行し、どちらでも同じ結果になりました。環境依存ではなく CLI の仕様です。
ここで先ほどの話が効いてきます。この雛形をそのまま東京にデプロイすると、動きます。エラーは出ません。そして宛先は世界中の商用リージョンです。利用者が明示的に直さない限り、その状態のまま本番へ進みます。
雛形を疑う必要があるのは分かりました。では、雛形を使わずに Strands SDK を直接書けば安全でしょうか。
Strands SDK 本体の既定も global.(警告にも到達しない)
雛形に同梱されていた Strands Agents SDK v1.52.0 のソースコードを読みました。strands/models/bedrock.py の冒頭にこうあります。
# strands/models/bedrock.py:42-44
DEFAULT_BEDROCK_MODEL_ID = "global.anthropic.claude-sonnet-4-6"
_DEFAULT_BEDROCK_MODEL_ID = "{}.anthropic.claude-sonnet-4-6"
DEFAULT_BEDROCK_REGION = "us-west-2"
model_id を指定せずに BedrockModel() を作った場合の既定値が global. です。CLI の雛形とは別に、ライブラリ層でも同じ選択がされています。
興味深いのは、この SDK にリージョン別の判定ロジックが実装されている点です。_get_default_model_with_warning() には、リージョン名からプレフィックスを導く処理と、対応していないリージョンへの警告が書かれています。ところが、その手前で早期リターンします。
model_config = model_config or {}
if model_config.get("model_id"):
return model_config["model_id"]
if DEFAULT_BEDROCK_MODEL_ID != _DEFAULT_BEDROCK_MODEL_ID.format("us"):
return DEFAULT_BEDROCK_MODEL_ID
DEFAULT_BEDROCK_MODEL_ID は "global.anthropic.claude-sonnet-4-6" で、_DEFAULT_BEDROCK_MODEL_ID.format("us") は "us.anthropic.claude-sonnet-4-6" です。両者は一致しないため、この条件は常に真になります。
その結果、以降にあるリージョン判定も、"You're using default model '...', which is subject to change." という警告も実行されません。モデルIDを指定しなければ、警告なしで global. が使われるというのが、ソースを読む限りの挙動です。
なお、この節はソースコードの読解であり、実際に model_id を省略して東京リージョンで実行し、選ばれたIDを確認したわけではありません。
つまり、雛形を使っても、SDK を素で使っても、何も指定しなければ global. に落ち着きます。「CLI の雛形が悪い」という話ではなく、エコシステム全体の既定がそこにある、というのが実態でした。
だからこそ、使う側が明示的に指定する必要があります。
東京リージョン向けに jp. へ直す(書き換えは1箇所)
雛形に対して加えた変更は1ファイルだけです。
import os
from strands.models.bedrock import BedrockModel
DEFAULT_MODEL_ID = "jp.anthropic.claude-haiku-4-5-20251001-v1:0"
DEFAULT_REGION = "ap-northeast-1"
DEFAULT_MAX_TOKENS = 1024
def load_model() -> BedrockModel:
"""東京リージョン + jp. 推論プロファイルに固定する。"""
return BedrockModel(
model_id=os.environ.get("BEDROCK_MODEL_ID", DEFAULT_MODEL_ID),
region_name=os.environ.get("AWS_REGION", DEFAULT_REGION),
max_tokens=int(os.environ.get("MAX_TOKENS", DEFAULT_MAX_TOKENS)),
)
環境変数で上書きできるようにしつつ、既定値を日本国内ルーティングに寄せるのが趣旨です。上書きされなかったときに安全側へ倒れる形にしています。検証段階ではコストを抑えるため Haiku を既定にしました。
max_tokens を明示しているのは、既定が無制限だとトークン予算の上限がなくなるためです。
東京で使える jp. プロファイルの一覧
自分の環境で何が使えるかは、コマンドで確認できます。
aws bedrock list-inference-profiles --region ap-northeast-1 \
--query "inferenceProfileSummaries[?starts_with(inferenceProfileId,'jp.')].inferenceProfileId" \
--output text
2026年8月18日時点で返ってきたのは6件でした。
jp.anthropic.claude-sonnet-4-5-20250929-v1:0
jp.anthropic.claude-haiku-4-5-20251001-v1:0
jp.amazon.nova-2-lite-v1:0
jp.anthropic.claude-sonnet-4-6
jp.anthropic.claude-opus-4-7
jp.anthropic.claude-opus-4-8
us. や global. で使えるモデルすべてに jp. があるわけではありません。先にこの一覧を確認してから、使うモデルを決めるほうが手戻りがありません。
モデルIDを直せば終わり、と言いたいところですが、もう一段あります。
直してもまだ残る穴(実行ロールのIAMはリージョンワイルドカード)
agentcore deploy --dry-run を実行すると、CloudFormation テンプレートが合成されます。実デプロイはしていませんが、何が作られるかはこの時点で読めます。
作成されるのは AWS::BedrockAgentCore::Runtime と AWS::IAM::Role、AWS::IAM::Policy の3つでした。その IAM Policy の中身がこれです。
関連記事 源内(genai-web)をAWSにCDKでデプロイする手順とハマりやすい注意点 AgentCore CLI も内部は CDK です。CDK デプロイ全般でつまずきやすい点はこちらにまとめています。
[Allow] bedrock:CountTokens, bedrock:InvokeModel, bedrock:InvokeModelWithResponseStream
Resource:
arn:aws:bedrock:*:<アカウントID>:inference-profile/*
arn:aws:bedrock:*::foundation-model/*
リージョンの位置がワイルドカードです。 このロールは全リージョンの全モデルを呼び出せます。
通常、モデルIDの指定を誤ってもIAMが最後の砦になります。リージョンを絞ったポリシーにしておけば、意図しないリージョンでの推論はIAMで止まります。ところが CLI が生成する既定のロールは、リージョンを絞っていません。
整理するとこうなります。
| 層 | 東京の外での推論を止められるか |
|---|---|
モデルID(既定の global.) |
止められない(宛先が世界中の商用リージョン) |
| IAM(CLI 既定の実行ロール) | 止められない(リージョンが *) |
2つの既定値が重なって、どちらの層でも止まりません。 モデルIDを jp. に直すのは必要ですが、それだけでは IAM 側は開いたままです。
なお、ここを絞るときに注意点が2つあります。
1つ目は宛先の数です。jp. の宛先は先ほど実測したとおり東京と大阪の2つです。IAM を ap-northeast-1 だけに絞ると、大阪へルーティングされた呼び出しが弾かれます。公式ドキュメントの Geographic cross-Region inference でも、必要な許可は3つと明記されています。推論プロファイル、ソースリージョンの基盤モデル、そしてプロファイルに列挙されたすべての宛先リージョンの基盤モデルです。
2つ目は、リージョン指定の Deny が global. には効かないことです。公式ドキュメントにこう書かれています。
The service sets this field to
globalrather than the actual destination AWS Region.
aws:RequestedRegion に実際の宛先リージョンが入らないため、"aws:RequestedRegion": "us-west-2" のようなリージョン名を指定した Deny ポリシーは期待どおりに動きません。global. を明示的に塞ぎたい場合は、"aws:RequestedRegion": "unspecified" という条件を使うと公式に案内されています。「リージョンを絞る既存のガードレールがあるから安全」とは言えない、ということです。
実行ロールのポリシー修正は次回以降に実際にやってみて、結果を記録する予定です。
まとめ
Bedrock AgentCore を東京リージョンで動かすとき、モデルIDのプレフィックスは3通りの振る舞いを見せました。us. は ValidationException で失敗し、同一モデルでプレフィックスだけを jp. に変えると6回中6回成功しました。global. はエラーを出さずに動きます。公式ドキュメントによれば、その宛先は世界中の商用 AWS リージョンで、CloudWatch にも CloudTrail にも処理されたリージョンは記録されません。
そして、明示的に指定しなければ global. が選ばれます。AWS 公式CLI @aws/agentcore v0.27.0 の雛形は global. を書き込みます。Strands Agents SDK v1.52.0 も、ソースを読む限り既定を global. に置いています。東京で動かす手順として global. が広まっているのは、実際に動くからです。
医療情報のようにデータの所在地を説明する必要がある場合、この既定値のままでは説明ができません。jp. の宛先は東京と大阪の2リージョンに限られ、そこは実測でも公式の説明でも確認できます。ただしモデルIDを直すだけでは足りません。実行ロールのIAMはリージョンワイルドカードのまま残りますし、global. に対してはリージョン名を指定した Deny ポリシーが効きません。Memory を有効にすれば、そこにも別の経路が生まれます。
まずは aws bedrock list-inference-profiles で、自分の環境で使える jp. プロファイルを確認するところから始めてみてください。次回は、モデルIDを直した後に待っている3つの関門(モデルIDの不一致、IAM、そしてモデルの利用契約)を、エラーメッセージで区別する方法を扱います。
参考文献
- Global cross-Region inference — Amazon Bedrock ユーザーガイド —
global.の宛先が世界中の商用リージョンであること、リージョン欄が空のARNの意味、Deny ポリシーの注意点 - Geographic cross-Region inference — Amazon Bedrock ユーザーガイド — 地理単位のクロスリージョン推論と、すべての宛先リージョンを許可する IAM 要件
- Cross-region inference in Amazon Bedrock AgentCore Memory, Policy, and Evaluations — AgentCore Memory の推論先リージョンと、ログにリージョンが記録されない旨
- Amazon Bedrock の JP Cross-Region Inference で日本国内に閉じた推論を実現するぞ! — AWS Japan による
jp.推論プロファイルの解説 - Dockerなし、Windows、東京リージョンでAmazon Bedrock AgentCore FASTをデプロイする — 東京リージョンで AgentCore を Docker なしでデプロイする手順。
us.が使えない理由と差し替え方が具体的にまとまっています - Amazon BedrockのClaude 4.5 Sonnetを日本国内だけで実行する方法 — アプリケーション推論プロファイルによるリージョン制御
- クロスリージョン推論が東京リージョンを含むアジアパシフィック地域で利用可能になりました —
apac.プレフィックスの提供開始について - Amazon Bedrock AgentCore Runtime に最小構成のエージェントをデプロイする — AgentCore Runtime の最小構成例
- aws-samples/amazon-bedrock-agents-healthcare-lifesciences — 本検証の出発点にした AWS 公式のヘルスケア向けエージェント集