[Amazon Bedrock AgentCore] RuntimeにAIエージェントをデプロイする
はじめに
こんにちは、スーパーマーケットのラ・ムーが大好きなコンサル部の神野です。
今までAgentCore周りの記事を書いてきましたが、コア機能であるRuntimeを記事で解説していなかったなと思い、本記事を作成してみました。
あらためてRuntimeで何ができるのか、どうやって使うのかを説明していければと思います!
Amazon Bedrock AgentCore Runtimeとは
概要
Amazon Bedrock AgentCore RuntimeはAIエージェントをホスティングするためのマネージドサービスです。AgentCoreはIdentityやGatewayなど様々なサービスがありますが、中核を担うのがこのRuntimeです。
イメージ
AIエージェントのフレームワークであるStrands AgentsとLLMはAmazon Bedrockを活用して、サクッとAIエージェントをホスティングする環境を作成できます。
あくまでRuntimeはホスティング環境なので、エージェントフレームワーク・LLMは自由に選択可能です。
下記のようにMastraとAzure OpenAIを使うことも可能です。
Runtimeの使い方
ライブラリのインストール
AgentCoreをCLIで簡単に操作できるBedrockAgentCore Starter Toolkit CLIを使いたいので、bedrock-agentcore-starter-toolkit
をインストールします。
pip install bedrock-agentcore-starter-toolkit
セットアップ(configureコマンド)
BedrockAgentCore Starter Toolkit CLIで提供されているコマンド、agentcore configure
コマンドでデプロイの設定をすることが可能です。
下記のようにエントリーポイントのファイル(例:agent.py
)を指定して実行します。
agentcore configure --entrypoint agent.py
実行すると下記のように対話形式で進んでいきます。
Configuring Bedrock AgentCore...
Entrypoint parsed: file=/path/to/project/agent.py, bedrock_agentcore_name=agent
Agent name: agent
🔐 Execution Role
Press Enter to auto-create execution role, or provide execution role ARN/name to use existing
Execution role ARN/name (or press Enter to auto-create):
✓ Will auto-create execution role
🏗️ ECR Repository
Press Enter to auto-create ECR repository, or provide ECR Repository URI to use existing
ECR Repository URI (or press Enter to auto-create):
✓ Will auto-create ECR repository
🔍 Detected dependency file: requirements.txt
Press Enter to use this file, or type a different path (use Tab for autocomplete):
Path or Press Enter to use detected dependency file:
✓ Using detected file: requirements.txt
🔐 Authorization Configuration
By default, Bedrock AgentCore uses IAM authorization.
Configure OAuth authorizer instead? (yes/no) [no]:
✓ Using default IAM authorization
Configuring BedrockAgentCore agent: agent
⚠️ ℹ️ No container engine found (Docker/Finch/Podman not installed)
✅ Default deployment uses CodeBuild (no container engine needed)
💡 Run 'agentcore launch' for cloud-based building and deployment
💡 For local builds, install Docker, Finch, or Podman
Generated .dockerignore
Generated Dockerfile: /path/to/project/Dockerfile
Generated .dockerignore: /path/to/project/.dockerignore
Setting 'agent' as default agent
╭─────────────────────────────────── Bedrock AgentCore Configured ───────────────────────────────────╮
│ Configuration Summary │
│ │
│ Name: agent │
│ Runtime: None │
│ Region: us-west-2 │
│ Account: xxx │
│ Execution Role: None │
│ ECR: Auto-create │
│ Authorization: IAM (default) │
│ │
│ Configuration saved to: /path/to/project/.bedrock_agentcore.yaml │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯
聞かれていることは下記です。
- AgentCoreの実行ロールARN
- 指定しなければ自動作成
- ECRのARN
- 指定しなければ自動作成
- エージェントで使用するライブラリ、依存関係の設定ファイル
- requirements.txtなど
- 認証の設定
- yesだとIdPのURLなどを設定する必要がある
- noだとIAMの権限でしかアクセスできないようになる(デフォルト)
特に指定しなければ自動で作成してくれるのはすぐ使えるようになるので嬉しいですよね。またカスタムで作成したいときもARNなどを指定すればいいのは便利ですね。
自動生成されるファイル
設定が終わると、3つのファイルが作成されます。下記のようなイメージです。
.bedrock_agentcore.yaml
:デプロイの設定ファイル.dockerignore
:Dockerビルド時に除外するファイルの設定Dockerfile
:コンテナイメージの定義
設定ファイルの詳細
.bedrock_agentcore.yaml
はデプロイの設定ファイルです。
default_agent: agent
agents:
agent:
name: agent
entrypoint: agent.py
platform: linux/arm64
container_runtime: none
aws:
execution_role: null
execution_role_auto_create: true
account: xxx
region: us-west-2
ecr_repository: null
ecr_auto_create: true
network_configuration:
network_mode: PUBLIC
protocol_configuration:
server_protocol: HTTP
observability:
enabled: true
bedrock_agentcore:
agent_id: null
agent_arn: null
agent_session_id: null
codebuild:
project_name: null
execution_role: null
source_bucket: null
authorizer_configuration: null
oauth_configuration: null
このような形で設定ファイルが記載され、デプロイが完了したらagent_arn
などのARNが更新されます。
Dockerfileの定義は下記となります。指定したエントリーポイントを起動する、シンプルな定義となります。Observabilityで必要になるaws-opentelemetry-distro
もインストールされて、自動的にトレースできるような設定がなされます。
FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim
WORKDIR /app
# Configure UV for container environment
ENV UV_SYSTEM_PYTHON=1 UV_COMPILE_BYTECODE=1
COPY requirements.txt requirements.txt
# Install from requirements file
RUN uv pip install -r requirements.txt
RUN uv pip install aws-opentelemetry-distro>=0.10.1
# Set AWS region environment variable
ENV AWS_REGION=us-west-2
ENV AWS_DEFAULT_REGION=us-west-2
# Signal that this is running in Docker for host binding logic
ENV DOCKER_CONTAINER=1
# Create non-root user
RUN useradd -m -u 1000 bedrock_agentcore
USER bedrock_agentcore
EXPOSE 8080
EXPOSE 8000
# Copy entire project (respecting .dockerignore)
COPY . .
# Use the full module path
CMD ["opentelemetry-instrument", "python", "-m", "agent"]
.dockerignore
は下記の通りです。環境変数なども除外されるようになっていますね。もし含めたい場合は注意しましょう。
# Build artifacts
build/
dist/
*.egg-info/
*.egg
# Python cache
__pycache__/
__pycache__*
*.py[cod]
*$py.class
*.so
.Python
# Virtual environments
.venv/
.env
venv/
env/
ENV/
# Testing
.pytest_cache/
.coverage
.coverage*
htmlcov/
.tox/
*.cover
.hypothesis/
.mypy_cache/
.ruff_cache/
# Development
*.log
*.bak
*.swp
*.swo
*~
.DS_Store
# IDEs
.vscode/
.idea/
# Version control
.git/
.gitignore
.gitattributes
# Documentation
docs/
*.md
!README.md
# CI/CD
.github/
.gitlab-ci.yml
.travis.yml
# Project specific
tests/
# Bedrock AgentCore specific - keep config but exclude runtime files
.bedrock_agentcore.yaml
.dockerignore
# Keep wheelhouse for offline installations
# wheelhouse/
自動作成されるIAMロール
自動で作成されるIAMロールには下記ポリシーが付与されます。
基本的なAIエージェントを起動する分には問題ないのですが、IdentityでSecrets Managerにアクセスしたり、Bedrock Knowledge Basesを活用したいケースは権限不足になるので注意が必要です。
ポリシー全量
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ECRImageAccess",
"Effect": "Allow",
"Action": [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer"
],
"Resource": [
"arn:aws:ecr:us-west-2:xxx:repository/*"
]
},
{
"Effect": "Allow",
"Action": [
"logs:DescribeLogStreams",
"logs:CreateLogGroup"
],
"Resource": [
"arn:aws:logs:us-west-2:xxx:log-group:/aws/bedrock-agentcore/runtimes/*"
]
},
{
"Effect": "Allow",
"Action": [
"logs:DescribeLogGroups"
],
"Resource": [
"arn:aws:logs:us-west-2:xxx:log-group:*"
]
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-west-2:xxx:log-group:/aws/bedrock-agentcore/runtimes/*:log-stream:*"
]
},
{
"Sid": "ECRTokenAccess",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:GetSamplingRules",
"xray:GetSamplingTargets"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Resource": "*",
"Action": "cloudwatch:PutMetricData",
"Condition": {
"StringEquals": {
"cloudwatch:namespace": "bedrock-agentcore"
}
}
},
{
"Sid": "GetAgentAccessToken",
"Effect": "Allow",
"Action": [
"bedrock-agentcore:GetWorkloadAccessToken",
"bedrock-agentcore:GetWorkloadAccessTokenForJWT",
"bedrock-agentcore:GetWorkloadAccessTokenForUserId"
],
"Resource": [
"arn:aws:bedrock-agentcore:us-west-2:xxx:workload-identity-directory/default",
"arn:aws:bedrock-agentcore:us-west-2:xxx:workload-identity-directory/default/workload-identity/simple_agent-*"
]
},
{
"Sid": "BedrockModelInvocation",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:ApplyGuardrail"
],
"Resource": [
"arn:aws:bedrock:*::foundation-model/*",
"arn:aws:bedrock:us-west-2:xxx:*"
]
}
]
}
ここまででセットアップの準備が完了しました。
デプロイ(launchコマンド)
さて、configure
コマンドで設定が終わったら、デプロイです。
実際にAgentCore Runtimeにエージェントをホスティングしていきましょう。
agentcore launch
このコマンドを実行すると、裏側では以下のような処理が走ります。
- DockerイメージのビルドとECRへのプッシュ
- デフォルトではAWS CodeBuildを使ってビルドされます
- ARM64アーキテクチャでビルドされる点に注意です
- AgentCore Runtimeの作成
- マネージドなホスティング環境が自動的にセットアップされます
- エンドポイントの有効化
- エンドポイントが自動的に作成され、すぐに呼び出し可能になります
ローカルでのビルドをする場合は--local
オプションで可能となります。
ただ、ローカルビルドの場合はDockerやFinchなどのコンテナランタイムが必要になります。
例:
- Docker (any recent version, including Docker Desktop)
- Finch (Amazon's open-source container engine)
- Podman (compatible alternative to Docker)
agentcore launch --local
環境変数の設定
実際のエージェント開発では、Knowledge BaseのIDなど、環境変数を設定したくなることがありますよね。
launch
コマンドで環境変数を渡すには、--env
オプションを使います。
agentcore launch --env STRANDS_KNOWLEDGE_BASE_ID=kb-abc123 \
--env OPENWEATHER_API_KEY=your-api-key
設定した環境変数はコンソール上からも確認可能です。
エージェントの実行(invokeコマンド)
デプロイが完了したら、invoke
コマンドを使ってデプロイしたエージェントを呼び出すことができます。
agentcore invoke '{"prompt":"Hello"}' --session-id test-id-01
--session-id
を指定することもできます。同一のruntime-session-id
を維持したい場合は同じ値を使います。
またCognitoなどで認証を行う設定がされている場合は、--bearer-token
でアクセストークンを設定することも可能です。
ハンズオン:シンプルなエージェントのデプロイ
それでは、実際に簡単なエージェントをデプロイしてみましょう!
前提条件
今回使用したライブラリや前提などは下記にあたります。
- Python 3.12
- AWS CLI 2.28
- AWSアカウント(us-west-2リージョン)
- Bedrockモデル有効化
- 今回は
anthropic.claude-3-5-haiku-20241022-v1:0
を使用します。
- 今回は
必要なパッケージのインストール
必要なパッケージをインストールしていきます。
requirements.txt
を作成してインストールします。
strands-agents
strands-agents-tools
bedrock-agentcore
bedrock-agentcore-starter-toolkit
# 必要なパッケージをインストール
pip install -r requirements.txt
エージェントの実装
まずはシンプルなエージェントを作ってみましょう!
simple_agent.py
というファイルを作成します。
処理はシンプルにLLMを呼び出すだけです。
from strands import Agent, tool
from strands.models import BedrockModel
from bedrock_agentcore.runtime import BedrockAgentCoreApp
app = BedrockAgentCoreApp()
@app.entrypoint
async def entrypoint(payload):
message = payload.get("prompt", "")
model = payload.get("model", {})
model_id = model.get("modelId","anthropic.claude-3-5-haiku-20241022-v1:0")
model = BedrockModel(model_id=model_id, params={"max_tokens": 4096, "temperature": 0.7}, region="us-west-2")
agent = Agent(model=model)
stream_messages = agent.stream_async(message)
async for message in stream_messages:
if "event" in message:
yield message
if __name__ == "__main__":
app.run()
デプロイと実行
設定とデプロイを進めていきます。
まずはconfigure
コマンドで設定を行います。
# 設定
agentcore configure -e simple_agent.py
今回は全て自動で作成するのでEnterキー連打で進めます。無事.bedrock_agentcore.yaml
など作成されたら今度はデプロイします。
# デプロイ
agentcore launch
本当2コマンドでデプロイできるのはめちゃくちゃシンプルで良いですよね。
デプロイが成功したら、実際に呼び出してみます。
agentcore invoke '{"prompt": "AIに関する面白いジョークを教えて!"}'
呼び出すと結果がストリーミングで返ってきます。CLIなどで見づらいですが下記のようにレスポンスを受け取れます。
Payload:
{
"prompt": "AIに関する面白いジョークを教えて!"
}
Invoking BedrockAgentCore agent 'simple_agent' via cloud endpoint
{"event": {"messageStart": {"role": "assistant"}}}
{"event": {"contentBlockDelta": {"delta": {"text": "は"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "い、いくつかA"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "I関連のジョークをご"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "紹介します:"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "\n\n1. AIアシスタント"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "に聞きました"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "。「君は本当に知"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "的なの?」\nAI"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "は答えました。「私は"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "人工知能です。本当の"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "知性は微妙な"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "質問ですね"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "」\n\n2. "}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "人工知能と"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "人間の違いは?"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "\nAIは考える"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "、人間は"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "悩む。\n\n3. AIに"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "プログラマーが"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "聞きます。"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "\n「人間を信頼でき"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "ますか?」\nAIは答え"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "ます。「まだデ"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "ータ不足です」"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "\n\nこれらのジョ"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "ークは、AIの特性"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "や人工知能への興"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "味深い視点を"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "軽いタッチで表"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "現しています。"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "笑っていただけ"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "たら嬉し"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockDelta": {"delta": {"text": "いです。"}, "contentBlockIndex": 0}}}
{"event": {"contentBlockStop": {"contentBlockIndex": 0}}}
{"event": {"messageStop": {"stopReason": "end_turn"}}}
{"event": {"metadata": {"usage": {"inputTokens": 22, "outputTokens": 212, "totalTokens": 234}, "metrics": {"latencyMs": 5002}}}}
無事結果が返却されましたね!
本当お手軽ですね。最初Runtimeを試した際は、こんなに簡単にデプロイできるんか・・・と感動しました。
料金体系
課金モデル
2025年9月17日から適用される料金は下記の通りです。
- CPU:$0.0895/vCPU時間
- メモリ:$0.00945/GB時間
料金計算例
1000万リクエスト/月のカスタマーサポートエージェントだと下記のような料金計算になります。
公式ドキュメントからの引用ですが確認してみましょう。
チャットとメールでユーザーの問い合わせを解決するカスタマーサポートエージェントを配置する場合を考えてみます。エージェントは、注文に関する問題、アカウントの確認、およびポリシーの明確化を処理します。検索拡張生成 (RAG) を使用して製品ポリシーを取得し、モデルコンテキストプロトコル (MCP) 互換ツールを使用して注文状況のクエリとサポートチケットの更新を行います。各エージェントセッションには、ベクトルストアへの 1 回の RAG 呼び出し、2 回の MCP ツール呼び出し(OrderAPI、TicketAPI など)、および 2 つの LLM 推論ステップによる高度なマルチステップ推論が含まれます。完全なセッション分離と、数秒で数百万セッションまで拡張できる柔軟性が必要なため、エージェントを AgentCore Runtime にデプロイしました。
毎月 1,000万 件のユーザーリクエストを処理し、各セッションは 60 秒間実行され、I/O 待機時間 (LLM 応答の待機または内部 API からのネットワーク応答の待機) は 70% です 。各エージェントセッションは、アクティブな処理中に 1 vCPU を使用し、2 GB のメモリを継続的に使用します。毎月の費用の内訳は次のとおりです。
セッションあたりの CPU コスト: 18 秒 (入出力待機時間の 70% に合わせて調整) × 1 vCPU × (0.0895/3600 USD) = 0.0004475 USD セッションあたりのメモリコスト: 60 秒 × 2 GB × (0.00945 USD/3600 USD) = 0.000315 USD
セッションあたりの総コスト: 0.0007625 USD
月間合計: 1,000 万セッション × 0.0007625 USD = 7,625 USDAgentCore Runtime の使用量ベースの価格設定により、I/O 待機時間ではなく、アクティブな CPU 処理時間に対してのみ支払いが発生するため、従来のコンピューティングオプションと比較して高いコスト効率が得られます。
LLM応答待ちなどのI/O待機時間は課金されないのがポイントですね。
よりAIエージェントに最適化された課金システムですね。
おわりに
Amazon Bedrock AgentCore Runtimeを使うと、AIエージェントのホスティングが簡単ですぐに使用可能になるのが嬉しいですね。
RuntimeでAIエージェントをホスティングすることで、IdentityやGatewayなど他の機能も必要に応じて連携可能なのも魅力です。工夫してより良いAIエージェントを積極的に作って発信していきたいなと思います!
本記事が少しでも参考になりましたら幸いです。最後までご覧いただきありがとうございましたー!!
補足
今回はシンプルにconfigure
コマンドやlaunch
コマンドをCLI上で使用しましたが、Pythonのコードでも同様に実行できます。
# インポート
from bedrock_agentcore_starter_toolkit import Runtime
agentcore_runtime.configure(
entrypoint="strands_full_auth_agent.py",
execution_role=role_arn,
auto_create_ecr=True, # ECRリポジトリを自動作成
requirements_file="requirements.txt",
region="us-west-2",
agent_name=os.environ.get('AGENT_NAME', 'strands_full_auth_agent')
)
agentcore_runtime.launch(env_vars=env_vars)
後はAWS CLIでも下記のように実行可能でもあります。
ただinvoke-agent-runtime
はpayloadをbase64で送る必要があるなど、一手間かかります。
そういった意味ではbedrock-agentcore-starter-toolkitの方が実行しやすいのかもしれませんね。
aws bedrock-agentcore-control create-agent-runtime \
--region us-west-2 \
--agent-runtime-name "sample_agent" \
--role-arn "arn:aws:iam::<accdountId>:role/service-role/AmazonBedrockAgentCoreRuntimeDefaultServiceRole-sample-agent" \
--network-configuration '{
"networkMode": "PUBLIC"
}' \
aws bedrock-agentcore invoke-agent-runtime \
--agent-runtime-arn $RUNTIME_ARN \
--content-type "application/json" \
--accept "application/json, text/event-stream" \
--payload "$(echo -n "$PAYLOAD" | base64)" output.json