メインコンテンツに移動

builders.flash

Amazon Bedrock AgentCore を使ってモダンな UI の AI エージェントを IaC 付きで構築しよう

2026-04-02 | Author : 御田 稔 (AWS AI Hero)

はじめに

こんにちは ! AWS AI Hero の御田 稔 (みのるん) です。

普段は AWS を活用した AI エージェントの構築をしながら、テックエバンジェリストとして技術の楽しさを発信する活動をしています。AWS ユーザーグループの JAWS-UG では東京支部の運営も行っています。

昨年ごろから、AI エージェントという言葉をあちこちで耳にするようになりました。AWS からも AI エージェントの構築・運用を支援するサービス「Amazon Bedrock AgentCore」(以下 AgentCore) が登場し、開発者が AI エージェントを本番運用する敷居がぐっと下がっています。

今回はこの AgentCore を使って、認証付きのモダンな Web フロントエンドを備えた AI エージェントアプリケーションを IaC (Infrastructure as Code) 付きでデプロイする方法を、ハンズオン形式でご紹介します。


X ポスト » | Facebook シェア » | はてブ »

Missing alt text value

builders.flash メールメンバー登録

builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。

今すぐ登録 »

そもそも Bedrock AgentCore とは

AI エージェントとは、一問一答のチャットボットとは違い、AI 自ら行動計画を立てて外部ツールなどを使いながらタスクを遂行してくれる仕組みのことです。人間の代わりに複雑な業務をこなせるため、生成 AI 活用の次なる主役として注目を集めています。

AgentCore は、AI エージェントの開発・運用に必要なさまざまな機能を提供するサービス群です。その中核となる AgentCore ランタイムは、AI エージェントをサーバーレスにホスティングするためのサービスで、言うなれば AI エージェント専用の AWS Lambda のようなものです。従来の Bedrock Agents がマネジメントコンソール上の GUI 操作でエージェントを構築する方式だったのに対し、AgentCore では Python などのコードで自由にエージェントを実装し、それをサーバーレスランタイムにデプロイするというアプローチを取ります。コードベースなので IaC との相性も抜群です。

エージェントの実装には Strands Agents (以下 Strands) というオープンソースのフレームワークを利用します。AWS が公式にサポートしている Python フレームワークで、少ないコード量で実用的な AI エージェントを構築できるのが特徴です。

今回のハンズオンでは、この AgentCore と Strands に加えて、フロントエンドには AWS Amplify Gen2 (React + Vite)、インフラ定義には AWS CDK を使います。すべてをコードで管理しつつ、フルサーバーレスで維持費の安いアプリケーションを構築できるのがこの構成の魅力です。


 

サンプルアプリを作ってみよう

新技術を理解する一番の近道は、自分で触ってみることです。それでは一緒にハンズオンを進めてみましょう。

アプリの概要

今回は AWS の最新アップデート情報を RSS フィードから取得し、サマリーして教えてくれる AI エージェントアプリを作成します。Web ブラウザからチャット形式で質問すると、裏で AI エージェントがツールを駆使して情報収集し、ストリーミングで回答を返してくれます。

全体構成

技術スタックは次のような構成です。フロントエンドは AWS Amplify Gen2 でホスティングする React + Vite アプリケーションで、Amazon Cognito によるユーザー認証を備えています。バックエンドは AgentCore Runtime 上で動作する Strands ベースのエージェントで、LLM には Amazon Bedrock 上の Claude Haiku 4.5 を利用します。インフラはすべて AWS CDK で定義し、Amplify CI/CD を通じて自動デプロイされます。

環境準備

筆者は以下の環境で本ハンズオンを実施しています。

  • デバイス:MacBook Air
  • OS:macOS
  • Node.js:18 以上
  • AWS CLI:インストール済み

AWS アカウントをお持ちでない方は、以下を参考に作成してください。

Amplify へのデプロイのため、GitHub アカウントも必要です。お持ちでない方は https://github.com から作成しておいてください。

また、今回の作業は東京 (ap-northeast-1) リージョンで実施します。Anthropic モデルのユースケース提出がお済みでない方は、AWS マネジメントコンソールから Amazon Bedrock の「テキスト/チャットのプレイグラウンド」で任意のAnthropicモデルを起動し、フォームが表示される場合は申請しておきましょう (数分で使えるようになります)。

AWS CLI が未インストールの場合は、公式ドキュメント を参考にセットアップしてください。


 

【手順 1】 ベースプロジェクトの作成

テンプレートからリポジトリを作成

Amplify の公式テンプレートリポジトリをベースに、自分の GitHub リポジトリを作成します。以下のリンクから「Use this template」をクリックし、新規リポジトリを作成してください。

aws-samples/amplify-vite-react-template

Missing alt text value

AWS CLI の認証

作成したリポジトリをローカルにクローンしたら、AWS CLI の認証を実施しておきます。

bash
aws login

不要ファイルの削除

テンプレートにはデフォルトで含まれている Data 層 (Amazon DynamoDB + AWS AppSync) のコードなど、今回は使わないファイルが含まれています。以下のコマンドで削除しましょう。

bash
rm -rf .eslintrc.cjs *.md LICENSE
rm -rf amplify/data public src/assets

【手順 2】 フロントエンドの開発

まずフロントエンドを実装していきます。React + TypeScript で認証付きのチャットUIを作り、AgentCore の API を SSE ストリーミングで呼び出す構成です。

Missing alt text value

エントリーポイント

src/main.tsx の zip ファイルをダウンロードし、上書きします。

AmplifyとCognitoの認証を初期化し、日本語化した認証画面でアプリを包んでいます。

main.tsx のダウンロードはこちら »

チャット UI 本体

src/App.tsx の zip ファイルをダウンロードし、上書きします。

AgentCore ランタイムの API を Cognito 認証トークン付きで呼び出し、SSE ストリーミングで受信したイベントをリアルタイムにチャット画面へ反映します。ツール使用中の状態表示にも対応しています。

src/App.tsx のダウンロードはこちら »

スタイルシート

src/App.css にはチャット UI のスタイルを記述します。グラデーションを使ったヘッダーや、ユーザーと AI の吹き出しを色分けしたデザインです。コード全文は以下を参照してください。

src/App.css

追加パッケージのインストール

Markdown 表示用のライブラリを追加します。

bash
npm install react-markdown

【手順 3】 バックエンドとインフラの開発

続いて AI エージェント本体と、それを動かすインフラをコードで定義していきます。

Missing alt text value

AI エージェントの実装

amplify/agent ディレクトリを新規作成し、その中に app.py を以下の内容で作成します。Strands Agents を使って RSS フィードを取得できる AI エージェントを定義し、AgentCore の API サーバーとして起動するコードです。 convert_event 関数では Strands のストリーミングイベントをフロントエンドが扱いやすい JSON 形式に変換しています。

python
from strands import Agent
from strands_tools.rss import rss
from bedrock_agentcore.runtime import BedrockAgentCoreApp

app = BedrockAgentCoreApp()


def convert_event(event) -> dict | None:
    """Strandsのイベントをフロントエンド向けJSON形式に変換"""
    try:
        if not hasattr(event, 'get'):
            return None

        inner_event = event.get('event')
        if not inner_event:
            return None

        content_block_delta = inner_event.get('contentBlockDelta')
        if content_block_delta:
            delta = content_block_delta.get('delta', {})
            text = delta.get('text')
            if text:
                return {'type': 'text', 'data': text}

        content_block_start = inner_event.get('contentBlockStart')
        if content_block_start:
            start = content_block_start.get('start', {})
            tool_use = start.get('toolUse')
            if tool_use:
                tool_name = tool_use.get('name', 'unknown')
                return {'type': 'tool_use', 'tool_name': tool_name}

        return None
    except Exception:
        return None


@app.entrypoint
async def invoke_agent(payload, context):
    prompt = payload.get("prompt")

    agent = Agent(
        model="jp.anthropic.claude-haiku-4-5-20251001-v1:0",
        system_prompt="aws.amazon.com/about-aws/whats-new/recent/feed からRSSを取得して",
        tools=[rss]
    )

    async for event in agent.stream_async(prompt):
        converted = convert_event(event)
        if converted:
            yield converted


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

依存パッケージの定義

同じ amplify/agent ディレクトリに requirements.txt を作成します。

xml
botocore
bedrock-agentcore
strands-agents
strands-agents[otel]
strands-agents-tools[rss]

Dockerfile の作成

AgentCore にデプロイするためのコンテナイメージを定義します。同じく amplify/agent ディレクトリに Dockerfile を作成してください。高速な Python パッケージマネージャーである uv を使ったイメージで、OpenTelemetry によるオブザーバビリティにも対応しています。

python
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim
WORKDIR /app

ENV UV_SYSTEM_PYTHON=1 \
    UV_COMPILE_BYTECODE=1 \
    UV_NO_PROGRESS=1 \
    PYTHONUNBUFFERED=1 \
    DOCKER_CONTAINER=1 \
    AWS_REGION=ap-northeast-1 \
    AWS_DEFAULT_REGION=ap-northeast-1

COPY requirements.txt requirements.txt
RUN uv pip install -r requirements.txt
RUN uv pip install aws-opentelemetry-distro==0.12.2

RUN useradd -m -u 1000 bedrock_agentcore
USER bedrock_agentcore

EXPOSE 8080
EXPOSE 8000

COPY . .

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8080/ping || exit 1

CMD ["opentelemetry-instrument", "python", "-m", "app"]

CDK によるインフラ定義

同じく amplify/agent ディレクトリに resource.ts を作成します。AgentCore ランタイムの CDK L2 コンストラクトを使って、Cognito 認証付きのランタイムリソースを定義しています。Docker イメージのビルドには deploy-time-build というライブラリを利用し、CodeBuild 上で ARM64 イメージ (AgentCore ランタイムの要件) をビルドする構成にしています。

typescript
import { Stack } from 'aws-cdk-lib';
import * as agentcore from '@aws-cdk/aws-bedrock-agentcore-alpha';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
import { ContainerImageBuild } from 'deploy-time-build';
import { IUserPool, IUserPoolClient } from 'aws-cdk-lib/aws-cognito';
import * as path from 'path';
import { fileURLToPath } from 'url';

export function createAgentCoreRuntime(
  stack: Stack,
  userPool: IUserPool,
  userPoolClient: IUserPoolClient
) {
  const agentImage = new ContainerImageBuild(stack, 'AgentImage', {
    directory: path.dirname(fileURLToPath(import.meta.url)),
    platform: Platform.LINUX_ARM64,
  });

  const stackNameParts = stack.stackName.split('-');
  const rawEnvId = stackNameParts.length >= 4 ? stackNameParts[3] : stack.stackName.slice(-10);
  const envId = rawEnvId.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();

  const runtime = new agentcore.Runtime(stack, 'UpdateCheckerRuntime', {
    runtimeName: `update_checker_${envId}`,
    agentRuntimeArtifact: agentcore.AgentRuntimeArtifact.fromEcrRepository(
      agentImage.repository,
      agentImage.imageTag
    ),
    authorizerConfiguration: agentcore.RuntimeAuthorizerConfiguration.usingCognito(
      userPool,
      [userPoolClient],
    ),
    networkConfiguration: agentcore.RuntimeNetworkConfiguration.usingPublicNetwork(),
  });

  runtime.addToRolePolicy(
    new iam.PolicyStatement({
      actions: [
        'bedrock:InvokeModel',
        'bedrock:InvokeModelWithResponseStream'
      ],
      resources: [
        'arn:aws:bedrock:*::foundation-model/*',
        'arn:aws:bedrock:*:*:inference-profile/*',
      ],
    })
  );

  return { runtime };
}

Amplify バックエンドの統合

amplify/backend.ts を以下の内容で上書きします。Amplify 標準の認証機能に加えて、先ほど定義した AgentCore ランタイムの CDK スタックを追加しています。

typescript
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { createAgentCoreRuntime } from './agent/resource';

const backend = defineBackend({
  auth,
});

const agentCoreStack = backend.createStack('AgentCoreStack');

const { runtime } = createAgentCoreRuntime(
  agentCoreStack,
  backend.auth.resources.userPool,
  backend.auth.resources.userPoolClient
);

backend.addOutput({
  custom: {
    agentRuntimeArn: runtime.agentRuntimeArn,
  },
});

追加パッケージのインストール

CDK と AgentCore コンストラクト関連のパッケージをインストールします。

bash
npm install aws-cdk@latest aws-cdk-lib@latest
npm install @aws-cdk/aws-bedrock-agentcore-alpha@latest
npm install deploy-time-build
npm install -D @types/node
npm pkg set "overrides.@aws-sdk/client-cloudformation"="3.936.0"

最後の overrides は、CDK と Amplify の依存関係の競合を回避するための設定です。

【手順 4】 AWS へのデプロイ

コードの準備ができたら、AWS へデプロイしましょう。

CDK ブートストラップ

CDK を使うリージョンで初回のみブートストラップが必要です。

bash
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
npx cdk bootstrap aws://$ACCOUNT_ID/ap-northeast-1

Amplify へのデプロイ

変更を GitHub リポジトリにプッシュします。

bash
git add .
git commit -m "初回デプロイ"
git push

その後、AWS マネジメントコンソールから AWS Amplify を開き、「新しいアプリを作成」から GitHub リポジトリを接続します。Amplify がフレームワークを自動検出してくれるので、設定はほぼデフォルトのまま進めてください。デプロイが開始されると、フロントエンドのビルドと CDK スタックのデプロイが自動で実行されます。

初回デプロイには AgentCore ランタイムのコンテナイメージビルドも含まれるため、完了まで少し時間がかかります。

【手順 5】 動作確認

デプロイが完了したら、Amplify コンソールに表示される URL にブラウザからアクセスしてみましょう。初回は新規ユーザー登録が必要です。

ログイン後、チャット画面が表示されたら「最近の AWS アップデートを教えて」などと質問してみてください。AI エージェントが RSS フィードを取得し、ストリーミングで回答が表示されるはずです。

Missing alt text value

おかたづけ

今回のアーキテクチャはフルサーバーレス構成のため、利用していないときのコストはほとんどかかりません。検証が終わったら、以下のリソースを削除しておきましょう。

Amplify コンソールからアプリケーションを削除すれば、紐づく AWS CloudFormation スタック (Cognito、AgentCore ランタイム等) もまとめて削除されます。

CDK ブートストラップ用のスタック CDKToolkit も不要であれば、CloudFormation コンソールから削除してください。

余裕があれば

Amplify サンドボックスの活用

Amplify Gen2 にはサンドボックスという便利な機能があり、ローカルの開発マシンから AWS 上に一時的なバックエンド環境を立ち上げることができます。コードを変更するたびに自動でクラウド側にも反映されるため、開発中の動作確認に重宝します。

bash
npm install
npx ampx sandbox

開発サーバーの立ち上げ

サンドボックスが起動したら、別のターミナルでフロントエンドの開発サーバーを立ち上げましょう。

bash
npm run dev

ブラウザから http://localhost:5173/ にアクセスすれば、ローカルのフロントエンドとクラウド上のバックエンドが接続された状態で開発を進めることができます。

ブランチ連動環境の構築

Amplify には GitHub のブランチごとに独立したバックエンド環境を自動構築してくれる機能もあります。例えば dev ブランチを作成してプッシュすると、そのブランチ専用の Cognito や AgentCore ランタイムが自動で作られます。

bash
git switch -c dev
git push

本番環境を壊すことなく新機能の開発やテストを進められるので、チーム開発にも便利な機能です。(事前にマネジメントコンソールから「ブランチ自動検出」の設定をオンにしておきましょう)

こんなアプリも作れます

1. パワポ作るマン

今回のアーキテクチャはそのまま応用が利きます。例えば AI エージェントのモデルを Claude Sonnet に変えてより高度な推論をさせたり、Strands Agents のツールを追加して Web 検索や SaaS 操作などエージェントができることを増やしていけば、業務に役立つ AI エージェントを手軽に揃えていくことができます。

実際に筆者がこの構成をベースに作って公開しているアプリをいくつか紹介します。

1 つ目は「パワポ作るマン」というプレゼン資料自動生成アプリです。テーマを入力すると AI エージェントが Web 検索しながらスライドを自動生成してくれます。

minorun365/marp-agent

Missing alt text value

2. 秘書 AI エージェント

2 つ目は OA ツールを自動操作してくれる秘書 AI エージェントです。チャットで指示すると Outlook のカレンダーや Confluence などを代わりに操作してくれます。

minorun365/m365-agent

Missing alt text value

3. LINE から使える Web 検索チャットボット

3 つ目は LINE から使える Web 検索チャットボットです。LINE のトーク画面から質問すると、AgentCore で動くエージェントが Web 検索や AWS ドキュメント検索を駆使して回答してくれます。

minorun365/agentcore-line-chatbot

いずれも GitHub でオープンソースとして公開しているので、ぜひ参考にしてみてください。

Missing alt text value

おわりに

今回は Amazon Bedrock AgentCore と Strands Agents、そして AWS Amplify Gen2 と CDK を組み合わせて、フルサーバーレスな AI エージェント Web アプリケーションを構築する手順をご紹介しました。すべてのインフラをコードで管理できるため、再現性が高く、チーム開発にも適した構成になっています。

今回のサンプルアプリケーションのコードは、以下の GitHub リポジトリで公開しています。

minorun365/amplify-agentcore-cdk

もしハンズオンを実施して動作しない箇所があれば、上記リポジトリに Issue を投稿してください。ベストエフォートにはなりますが、解消のお手伝いをさせていただきます。

筆者プロフィール

御田 稔 (みのるん @minorun365)

KDDIアジャイル開発センター株式会社 テックエバンジェリスト。クラウドや AI を用いた開発を行いながら、技術の楽しさを広める活動をしています。

AWS AI Hero、AWS Samurai 2023/2024 認定。著書「Amazon Bedrock 生成 AI アプリ開発入門」(SBクリエイティブ刊)、「やさしい MCP 入門」、「AI エージェント開発/運用入門」(SBクリエイティブ刊)

登壇資料 (Speaker Deck)  / ブログ (Qiita)

A person wearing glasses and a white t-shirt, crossing their arms and smiling, standing against a plain background.