はじめに
AWS と OpenAI が共同開発した Amazon Bedrock Managed Agents, powered by OpenAI(以下 BMA)がプレビューで公開。
AI エージェントを自前で作ると、「モデルを呼ぶ → ツールを選ぶ → 実行する → 結果を見てまたモデルを呼ぶ」というループや、会話履歴の管理を自分で書く必要があります。
BMA は、OpenAI の Codex のハーネスを AWS 上で動かし、このループと会話の保持を AWS 側が肩代わりしてくれるサービス とのことです。
この記事では、公式チュートリアル Get started with Amazon Bedrock Managed Agents (with OpenAI) on AgentCore Runtime に沿って、作業場を AgentCore Runtime に立ててエージェントにファイルを作らせるところまで を試します。
BMA で何がうれしいのか
モデルの呼び出しと会話の管理は BMA、コマンドの実行は自分のアカウント と分かれているのがポイントです。
| 担当 | やること | どこで動くか |
|---|---|---|
| BMA | エージェントループ(モデル呼び出し → ツール実行の依頼 → 結果をモデルに戻す)、会話履歴の保持 | AWS 側(マネージド) |
| 作業場(exec-server) | エージェントが決めたコマンドの実行、ファイル操作 | 自分のアカウントの AgentCore Runtime か、手元のマシン |
- セッションが保持される ので、2 回目の指示で「さっき作ったファイル」を前提にした作業を頼めます
- AgentCore Runtime を作業場にすると、セッションごとに独立した microVM で動き、VPC につないで社内リソースにも届かせられるようです
- モデル呼び出しは セッションロール、コマンド実行は Runtime の 実行ロール と、自分で管理する IAM ロールの下で動く ので、既存の AWS の権限管理に乗せやすそうです
従来のモデル呼び出しとの違い
| モデル呼び出し(Responses API) | BMA | |
|---|---|---|
| 1 回の指示で起きること | レスポンスが 1 つ返る。手元でコマンドを実行させるなら、ループは自分で書く | BMA がモデルと作業場を何往復もさせ、作業を終えてから返す |
| 渡すもの | モデル、入力 | モデル、指示、作業場、IAM ロール |
| 用意するもの | クライアントだけ | クライアント、作業場(Runtime か手元のマシン)、IAM ロール |
SDK(OpenAI SDK)と接続先(bedrock-mantle)は共通です。
コードで比べる(クリックで展開)
共通部分:
from openai import OpenAI
from aws_bedrock_token_generator import provide_token
client = OpenAI(
api_key=provide_token(region="us-east-1"),
base_url="https://bedrock-mantle.us-east-1.api.aws/openai/v1",
)
モデル呼び出し(1 回のリクエストに 1 つのレスポンス):
r = client.responses.create(model="openai.gpt-5.6-luna", input="Say hi")
print(r.output_text)
BMA(今回の client.py から要点を抜粋):
events = client.beta.agents.sessions.create(
agent={
"model": "openai.gpt-5.6-luna",
"instructions": "Use the available tools to complete the task.",
},
environment={ # コマンドを実行する作業場
"type": "aws_bedrock_agentcore",
"runtime_arn": runtime_arn,
"runtime_qualifier": "DEFAULT",
"workspace_directory": "/home/app/workspace",
"capability_directories": ["/opt/bma/plugins"], # スキルの置き場所
},
input="Use the acr-report skill to save an ACR report in the workspace.",
stream=True,
extra_body={"role_arn": role_arn}, # BMA が引き受けるセッションロール
)
for event in events: # コマンド実行・出力・回答がイベントとして流れてくる
print(event.type)
# 続きの指示は同じセッションに送るだけ(結果を受け取るストリームは先に開いておく)
events = client.beta.agents.sessions.events.stream(session_id, extra_query={"stream": "true"})
client.beta.agents.sessions.events.create(
session_id,
events=[{
"type": "agent.session.input.message",
"input": [{"role": "user", "content": [{"type": "input_text", "text": "続きの指示"}]}],
}],
)
IAM ロール
IAM ロールは役割ごとに 3 つに分かれます(Security and IAM roles)。
対応リージョンと料金
バージニア北部・オレゴン・オハイオ の 3 つで、プレビュー中は BMA 自体の追加料金はなく、モデル推論や Runtime など使ったリソース分だけ課金されます。
やってみた
手順 0: AgentCore CLI を入れる
アカウントで モデル openai.gpt-5.6-luna が使える状態 になっている前提です。
作業場(Runtime)は AgentCore CLI で作ります。BMA 用のテンプレートが用意されています。
npm install -g @aws/agentcore
agentcore --version # 0.31.1 で確認
export AWS_REGION=us-east-1
手順 1: BMA 用のプロジェクトを作る
--framework BedrockManagedAgents を指定すると、作業場のコンテナ一式とサンプルクライアント が生成されます。
agentcore create --name MyManagedAgent --framework BedrockManagedAgents
cd MyManagedAgent
非対話で作ると デプロイ先を書く agentcore/aws-targets.json が空([])のまま なので、アカウント ID を入れておきます。
cat > agentcore/aws-targets.json <<EOF
[{"name":"default","account":"$(aws sts get-caller-identity --query Account --output text)","region":"us-east-1"}]
EOF
生成物のうち、押さえておくのは次の 3 つです。
| ファイル | 中身 |
|---|---|
app/MyManagedAgent/Dockerfile |
Codex の exec-server(BMA からの指示を受けてコマンドを実行する常駐プロセス)を入れたコンテナ |
app/MyManagedAgent/plugins/acr-report/ |
サンプルの プラグイン。中に スキル(エージェントに渡す再利用可能な手順書)が 1 つ入っていて、ワークスペースにレポートを保存する |
app/MyManagedAgent/client.py |
OpenAI SDK でセッションを作るサンプルクライアント |
手順 2: 作業場(Runtime)をデプロイする
agentcore deploy -y
コンテナのビルドは CodeBuild が自分のアカウントで行う ので、手元に Docker は不要です。数分で ✓ Deployed to 'default' と出ます。
後の手順で使うので、Runtime の ARN を変数に入れておきます。
RUNTIME_ARN=$(aws bedrock-agentcore-control list-agent-runtimes \
--query "agentRuntimes[?agentRuntimeName=='MyManagedAgent_MyManagedAgent'].agentRuntimeArn | [0]" \
--output text)
echo $RUNTIME_ARN
手順 3: エージェントにスキルを使わせる
サンプルクライアントを実行すると、セッションロール BmaSessionRole-us-east-1 の作成 → セッション作成 → 最初の指示(acr-report スキルでレポートを保存して) までを一気にやってくれます。
cd app/MyManagedAgent
uv run client.py --runtime "$RUNTIME_ARN" | tee run1.log
SESSION_ID=$(awk '/^Session sess_/{print $2}' run1.log)
$ で始まる行が、BMA の指示で Runtime 側が実際に実行したコマンド です。手元のマシンではなく、Runtime の /home/app/workspace にファイルができています。
手順 4: 同じセッションで続きを頼む
--session-id を付けると、同じ会話・同じワークスペースの続き として指示できます。
uv run client.py --runtime "$RUNTIME_ARN" --session-id "$SESSION_ID" \
--input "さっき作ったレポートの Python バージョンを使って、1から100までの素数の個数を数える Python スクリプトを primes.py として作って実行し、結果を日本語で教えて"
「さっき作ったレポート」だけで前回のファイルを読みに行っている ので、会話の文脈もワークスペースのファイルも引き継がれていることが分かります。
ただし既定では アイドル状態が 30 分続くと Runtime のセッションが止まり、ワークスペースのファイルも消えます。残したい場合は セッションストレージ を設定するようです。
手順 5: 後片付け
セッション → Runtime → セッションロール → ロググループ の順に消します。
# セッションを削除
uv run python - <<EOF
from openai import OpenAI
from aws_bedrock_token_generator import provide_token
client = OpenAI(api_key=provide_token(region="us-east-1"),
base_url="https://bedrock-mantle.us-east-1.api.aws/openai/v1")
client.beta.agents.sessions.delete("$SESSION_ID")
print("deleted $SESSION_ID")
EOF
# Runtime とスタックを削除(remove で設定を空にして、deploy で反映)
cd ../..
agentcore remove all -y
agentcore deploy -y
# client.py が作ったセッションロールは deploy では消えない
aws iam delete-role-policy --role-name BmaSessionRole-us-east-1 --policy-name BmaSession
aws iam delete-role --role-name BmaSessionRole-us-east-1
# ロググループも残るので削除
for p in /aws/bedrock-agentcore/runtimes/MyManagedAgent_MyManagedAgent- /aws/codebuild/AgentCore-MyManagedAgent-default- /aws/lambda/AgentCore-MyManagedAgent-; do
for g in $(aws logs describe-log-groups --log-group-name-prefix "$p" --query 'logGroups[].logGroupName' --output text); do
aws logs delete-log-group --log-group-name "$g" && echo "deleted $g"
done
done
まとめ
- BMA は エージェントのループと会話管理を AWS 側に任せ、コマンド実行だけを自分の Runtime で行う 構成でした
次は MCP サーバーや Gateway をつないで、社内ツールを使わせるところも試してみたいと思います。



