2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AIエージェント構築入門】Bedrock AgentCoreで複数のAWSアカウントを自然言語で調査するチャットボットを作る(後編)

2
Last updated at Posted at 2026-08-30

はじめに

前回、Strands AgentsとStreamlitを使って、複数のAWSアカウントを横断調査できるチャットボットをローカル環境で構築しました。

本記事では、このチャットボットをAmazon Bedrock AgentCore Runtime上で動かしてみます。
これからAgentCoreに入門してみようという方の参考になれば幸いです。

Bedrock AgentCore Runtime とは

Amazon Bedrock AgentCore Runtime は、AI エージェントまたはツールをデプロイして実行するための、安全でサーバーレスな専用のホスティング環境を提供します。

AgentCore Runtimeは、リクエストが来たときだけコンテナを起動して、処理が終わったら止まります。課金も処理中のみです。

また、AgentCoreの嬉しいポイントの1つが、セッション管理だと思います。
AgentCore Runtimeでは、セッションIDごとに専用のmicroVMが割り当てられ、同じセッションIDのリクエストは、実行環境が存続している間は同じmicroVMにルーティングされます。そのため、プロセス内の状態などをリクエスト間で引き継ぐことができ、マルチターンのエージェントを実装しやすくなります。(長期的に会話履歴やユーザー情報を保持したい場合は、AgentCore Memoryなどを組み合わせて利用します)

実装

動作環境

Windows 11 の Git Bash (MINGW64) で実行しています。利用しているAWSリージョンはap-northeast-1です。

項目 バージョン
Node.js 22.14.0
Python 3.12
aws-cli 2.33.13
AWS CDK 2.1101.0
@aws/agentcore 0.28.1
bedrock-agentcore 1.22.0
strands-agents 1.53.0

AgentCore CLI のインストール

AgentCore には CLI が2つあります。bedrock-agentcore-starter-toolkit は現在はサポート対象外です。
https://github.com/aws/bedrock-agentcore-starter-toolkit

npm install -g @aws/agentcore

プロジェクトの作成

次のコマンドを実行して、プロジェクトを作成します。

agentcore create \
  --name awsChatbot \
  --framework Strands \
  --model-provider Bedrock \
  --memory none \
  --build CodeZip
オプション 意味
--name エージェント名
--framework エージェントのフレームワーク
--model-provider モデルの提供元
--memory none AgentCore Memory を使わない
--build CodeZip コードをzipにしてS3経由でデプロイ

上記のコマンドを実行すると、次のようなファイル構成が作成されます。

awsChatbot/
├── agentcore/              # 設定とCDKプロジェクト
│   ├── agentcore.json
│   ├── aws-targets.json
│   └── cdk/
└── app/awsChatbot/
    ├── main.py             # エージェントの入口
    └── pyproject.toml      # Pythonの依存

前回ローカルで動かす際に作成したコードを、中身は変えずに次のように配置します。

app/awsChatbot/
├── main.py                 # 後ほど編集
├── agent.py                # 変更なし
├── tools/aws_read.py       # 変更なし
├── config/accounts.yaml    # 変更なし
└── pyproject.toml

pyproject.toml に、前編のツールが使うライブラリを足します。

dependencies = [
    "aws-opentelemetry-distro",
    "bedrock-agentcore >= 1.9.1",
    "botocore[crt] >= 1.35.0",
    "strands-agents >= 1.15.0",
    "boto3 >= 1.43.78",
    "jmespath >= 1.1.0",
    "pyyaml >= 6.0.3",
]

AgentCore用の入口をつくる(main.py)

AgentCore Runtimeは、コンテナに対してHTTPリクエストを投げます。

エージェントは、以下の仕様を満たすコンテナ化されたアプリケーションとしてデプロイする必要があります。
ホスト: 0.0.0.0 
ポート : 8080 - HTTP ベースのエージェント通信用の標準ポート

agent.py はエージェントを組み立てるだけなので、このHTTPリクエストを受け取る入口として main.py が必要になります。
雛形のmain.pyを、前編のagent.pyにあるcreate_agent()を呼ぶように書き換えます。

"""AgentCore Runtime のエントリポイント。"""

from collections import OrderedDict
from typing import Any

from bedrock_agentcore.runtime import BedrockAgentCoreApp

from agent import create_agent

app = BedrockAgentCoreApp()
log = app.logger

MAX_CACHED_SESSIONS = 128
_agents: "OrderedDict[str, Any]" = OrderedDict()


def get_or_create_agent(session_id: str) -> Any:
    """セッションIDごとにAgentを使い回して、会話履歴を引き継ぐ。"""
    if session_id in _agents:
        _agents.move_to_end(session_id)
        return _agents[session_id]

    if len(_agents) >= MAX_CACHED_SESSIONS:
        _agents.popitem(last=False)

    _agents[session_id] = create_agent()
    return _agents[session_id]


@app.entrypoint
async def invoke(payload: dict[str, Any], context: Any):

    prompt = payload.get("prompt")
    if not isinstance(prompt, str) or not prompt.strip():
        raise ValueError("prompt は文字列で指定してください。")

    session_id = getattr(context, "session_id", None) or "default-session"
    agent = get_or_create_agent(session_id)

    async for event in agent.stream_async(prompt.strip()):
        if not isinstance(event, dict) or "event" not in event:
            continue
        cbs = event["event"].get("contentBlockStart")
        if cbs is not None and not cbs.get("start"):
            continue
        yield event


if __name__ == "__main__":
    app.run()

やっていることは主に3つです。

  • BedrockAgentCoreApp()を作って、入口にしたい関数に@app.entrypointを付ける
  • その中でcreate_agent()を呼ぶ
  • app.run()で待ち受ける

ローカルで動かしてみる

デプロイする前に、手元で動かして確認できます。

agentcore dev

ブラウザで agent inspector が開き、チャット画面で試せます。

image.png

デプロイ

agentcore deploy

CDK が CloudFormation スタックを作り、AgentCore Runtime とIAMロールを一式そろえてくれます。--dry-run を付けると、何も変更せずに確認だけできます。

実行後、無事Runtimeが作成されていることをコンソール上で確認できました。(なぜかawsChatbotが2つ連なっているのですが、原因が分からず...)

image.png

IAMの設定

デプロイすると実行ロールが作られます。このロールが各アカウントの調査用ロールをAssumeRoleできるようにしておく必要があります。

また、AgentCore の実行ロールは最小権限で作られます。Bedrock呼び出しやCloudWatchへの書き込みは入っていますが、sts:AssumeRole は入っていないので、自分で足す必要があります。

① 信頼ポリシーに実行ロールを足す

調査される側のアカウントに置いたロールの信頼ポリシーに、実行ロールを許可する条件を足します。

{
  "Effect": "Allow",
  "Principal": { "AWS": "arn:aws:iam::123456789012:root" },
  "Action": "sts:AssumeRole",
  "Condition": {
    "ArnLike": {
      "aws:PrincipalArn": "arn:aws:iam::123456789012:role/<実行ロール名>"
    }
  }
}

② 実行ロールに sts:AssumeRole を足す

実行ロール側には、どのロールを引き受けてよいかを書きます。

{
  "Sid": "AssumeReadOnlyRolesInTargetAccounts",
  "Effect": "Allow",
  "Action": "sts:AssumeRole",
  "Resource": [
    "arn:aws:iam::111111111111:role/aws-chatbot-readonly",
    "arn:aws:iam::222222222222:role/aws-chatbot-readonly"
  ]
}

動かしてみる

次のようなコマンドで動作確認できます。
無事動いてくれました。

agentcore invoke "kabu-appアカウントのEC2は何台?"

動作確認.png

おわりに

前回ローカルで動いていたAIエージェントがAWS上で動くようになりました。
本当はWebアプリ化までしたかったですが、時間なかったのでまた今度。。。

RuntimeはAgentCoreの基本となるものですが、AgentCoreにはまだまだたくさんの機能があります。GatewayやMemory、Policyなども触ってみて記事化していきます。(今年のre:InventまでにAgentCoreマスターになる!!)

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?