Amazon Bedrock AgentCoreのフルスタックテンプレート「FAST」を試してみた

Amazon Bedrock AgentCoreのフルスタックテンプレート「FAST」を試してみた

2026.02.12

はじめに

こんにちは、スーパーマーケットが大好きなコンサルティング部の神野(じんの)です。

最近、AWSからFAST(Fullstack AgentCore Solution Template)というフルスタックのスターターテンプレートが公開されました。Amplify、AgentCore Runtime、Gateway、Memory、Code Interpreterを組み合わせた画面付きのエージェントアプリケーションを、CDKを活用しつつ、デプロイできるというものです。

https://aws.amazon.com/jp/blogs/machine-learning/accelerate-agentic-application-development-with-a-full-stack-starter-template-for-amazon-bedrock-agentcore/

今回はこのFASTを実際にデプロイして試してみたいと思います!

FAST

FASTは、Amazon Bedrock AgentCoreを使ったフルスタックなエージェントアプリケーションを素早く構築するためのスターターテンプレートです。

https://github.com/awslabs/fullstack-solution-template-for-agentcore

AWS architecture diagram showing an AI agent application using Amazon Bedrock AgentCore with multi-agent orchestration, including user authentication through Cognito, API Gateway, Lambda compute layer, AgentCore Runtime with code interpreter, memory, gateway, and observability components, DynamoDB storage, and CloudWatch/X-Ray monitoring.

構成図を見るとサーバーレスを中心としたフロント・バックエンド、AgentCoreフルセットですぐに使えそうな構成になっていますね。使わなければ維持費もあまりかからない構成で良いですね。
自分で同じような構成を作るときも参考になりそうです。この構成をベースにカスタマイズしていくというのも考えられますね。

アーキテクチャ

バックエンドはCDKで単一スタックとしてデプロイされ、Cognito User Pool、AgentCore Runtime / Gateway / Memory、ECR、DynamoDB、API Gatewayなどがまとめて作成されます。フロントエンドはAmplify Hostingへ別途デプロイする構成です。

認証周りについては、1つのCognito User Poolに対してユーザーログイン用のクライアント(Authorization Code Flow)とM2M認証用のMachine Client(Client Credentials Flow)の2つが同居する構成になっています。

自分でこの辺りの実装をしなくて良いのはありがたいですね。

Starter Toolkit createコマンドとの違い

Starter ToolkitのcreateコマンドでもIaCコードを含めて環境を作ることが可能ですが、大きな違いとしては画面の有無かと思います。FASTはAmplifyで実際にエージェントの動きが確認できるのが嬉しいポイントですね。

create コマンドで作られる環境については下記ブログで書いているので必要に応じてご参照ください。

https://dev.classmethod.jp/articles/bedrock-agentcore-starter-toolkit-create-command/

前提

今回の検証環境は以下の通りです。

項目 バージョン / 値
OS macOS 15.7
Node.js v25.5.0
Python 3.13.11
AWS CDK CLI 2.1105.0
Docker 29.1.5
AWSリージョン us-west-2
エージェントパターン strands-single-agent

セットアップ

リポジトリのクローン

まずはリポジトリをクローンします。

実行コマンド
git clone https://github.com/awslabs/fullstack-solution-template-for-agentcore.git
cd fullstack-solution-template-for-agentcore

プロジェクト構成の確認

クローンしたリポジトリの構成は以下のようになっています。

fullstack-solution-template-for-agentcore/
├── frontend/              # React フロントエンド
├── infra-cdk/             # CDK インフラコード
├── patterns/              # エージェント実装パターン
│   ├── strands-single-agent/
│   └── langgraph-single-agent/
├── tools/                 # 再利用可能ツール(Lambda関数等)
├── gateway/               # Gateway ユーティリティ
├── scripts/               # デプロイ・テストスクリプト
├── docs/                  # ドキュメント
├── tests/                 # テストスイート
└── vibe-context/          # AIアシスタント用コンテキスト

patterns/ディレクトリにエージェントの実装パターンが入っており、strands-single-agentlanggraph-single-agentの2つが用意されています。今回はデフォルトのstrands-single-agentを使っていきます。

設定ファイルの編集

infra-cdk/config.yamlを編集します。

infra-cdk/config.yaml
stack_name_base: FAST-stack

# Optional: Set to automatically create an admin user and email credentials
# If not provided, you'll need to manually create users via AWS Console
admin_user_email: null # Example: admin@example.com

backend:
  pattern: strands-single-agent # Available patterns: strands-single-agent, langgraph-single-agent
  deployment_type: docker # Available deployment types: docker (default), zip

要点としては下記となります。

設定項目 設定値 説明
stack_name_base FAST-stack CloudFormationスタック名のプレフィックス。
admin_user_email null 管理者ユーザーのメール。設定すると自動でCognitoユーザーが作成される
backend.pattern strands-single-agent 使用するエージェントパターン
backend.deployment_type docker デプロイ方式。dockerまたはzipを選択可能

admin_user_emailを設定しておくと、デプロイ時にCognitoユーザーが自動作成され、一時パスワードがメールで届きます。今回は自分のメールアドレスを設定いたしました。

デプロイ

CDK依存関係のインストール

実行コマンド
cd infra-cdk
pnpm install

CDKブートストラップ(初回のみ)

対象アカウント・リージョンで初めてCDKを使用する場合は、ブートストラップを実行します。

実行コマンド
cdk bootstrap

バックエンドのデプロイ

CDKでバックエンドスタックをデプロイします。

実行コマンド
pnpm dlx cdk deploy

このコマンドで以下のリソースが作成されます。

  • Cognito User Pool(ユーザー認証)
  • ECRリポジトリへのエージェントコンテナイメージのプッシュ
  • AgentCore Runtimeの設定
  • AgentCore Gatewayの設定
  • AgentCore Memory
  • CloudFront配信設定
  • Lambda関数(Gatewayツール用)
  • DynamoDBテーブル

デプロイは5分半ぐらいかかりました。

FAST-stack: deploying... [1/1]
FAST-stack: creating CloudFormation changeset...

 ✅  FAST-stack

✨  Deployment time: 329.11s

Outputs:
FAST-stack.AmplifyAppId = dXXXXXXXXXXX
FAST-stack.AmplifyConsoleUrl = https://console.aws.amazon.com/amplify/apps/dXXXXXXXXXXX
FAST-stack.AmplifyUrl = https://main.dXXXXXXXXXXX.amplifyapp.com
FAST-stack.CognitoClientId = XXXXXXXXXXXXXXXXXXXXXXXXXX
FAST-stack.CognitoDomain = fast-stack-xxxxxxxxxxxx-us-west-2.auth.us-west-2.amazoncognito.com
FAST-stack.CognitoUserPoolId = us-west-2_XXXXXXXXX
FAST-stack.FeedbackApiUrl = https://xxxxxxxxxx.execute-api.us-west-2.amazonaws.com/prod/
FAST-stack.MemoryArn = arn:aws:bedrock-agentcore:us-west-2:xxxxxxxxxxxx:memory/XXXXXXXXXXXXX
FAST-stack.RuntimeArn = arn:aws:bedrock-agentcore:us-west-2:xxxxxxxxxxxx:runtime/XXXXXXXXXXXXX
FAST-stack.StagingBucketName = fast-stack-xxxxx-stagingbucket-xxxxxxxxxxxx
Stack ARN:
arn:aws:cloudformation:us-west-2:xxxxxxxxxxxx:stack/FAST-stack/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

✨  Total time: 335.69s

フロントエンドのデプロイ

バックエンドのデプロイが完了したら、フロントエンドをデプロイします。

実行コマンド
cd ..
python scripts/deploy-frontend.py

このスクリプトが自動で以下を実行してくれます。

  1. CDK出力からaws-exports.json(Cognito認証設定)を生成
  2. npmパッケージのインストール
  3. フロントエンドのビルド
  4. ビルド成果物をzipに固めてS3ステージングバケットへアップロード
  5. aws amplify start-deploymentでAmplifyデプロイをトリガー

Amplifyアプリやステージングバケット自体はCDKで作成済みなので、このスクリプトはあくまでソースコードのビルドとデプロイだけを担当する形ですね。

デプロイが完了すると、以下のようにAmplifyのURLが出力されます。

実行結果
ℹ S3 Package: s3://fast-stack-xxxxx-stagingbucket-xxxxxxxxxxxx/amplify-deploy-XXXXXXXXXX.zip
ℹ Console: https://console.aws.amazon.com/amplify/apps
ℹ App URL: https://main.dXXXXXXXXXXX.amplifyapp.com
ℹ Cleaned up /path/to/fullstack-solution-template-for-agentcore/frontend/amplify-deploy.zip

このURLにアクセスすればアプリケーションが確認できます!

動作確認

ログイン

Amplify URLにアクセスすると、Cognitoのログイン画面が表示されます。

CleanShot 2026-02-12 at 07.54.53@2x

CleanShot 2026-02-12 at 07.55.13@2x

yamlに入力したメールアドレスとデプロイ時に届いた初期パスワードでログインします。
初回ログイン時にはパスワード変更が求められるので、新しいパスワードを設定します。

ログインすると、チャットUIが表示されます!シンプルな画面ですね。

CleanShot 2026-02-12 at 07.56.36@2x

エージェントとの会話

チャット画面でメッセージを送信すると、AgentCore Runtime上で動作するStrandsエージェントが応答を返してくれます。

まずは挨拶してみましょうか。こんにちはと声をかけてみます。

CleanShot 2026-02-12 at 07.58.04@2x

挨拶と自分の役割、エージェントが利用可能なツールとして以下を返してくれました。

  • AgentCore Gateway経由のMCPツール(テキスト分析ツール)
  • Code Interpreter(Pythonコードの安全な実行)

テキスト分析ツールは、AgentCore Gateway経由で呼び出されるLambda関数で、入力テキストの単語数カウントや文字頻度分析を行うデモツールです。まずはこちらを試してみます。

シンプルに下記お願いをしてみます。

「The quick brown fox jumps over the lazy dog」という一文を分析してください。

CleanShot 2026-02-12 at 08.12.36@2x

分析してくれました!Gatewayが動いたかObservabilityで確認してみます。

image-20260212081847337

ツール利用されていそうです。念の為、Gatewayからターゲットに指定しているLambda関数のログも見てましょうか。

CleanShot 2026-02-12 at 08.18.35@2x

しっかりと連携されていますね!

次にCode Interpreterを試してみます。「1から100までの素数を列挙して」と聞いてみると、エージェントがCode Interpreterを使ってPythonコードを実行し、結果を返してくれました!

CleanShot 2026-02-12 at 07.58.50@2x

本当にCode Interpreterを使ったかわからないので、Observabilityで確認してみます。

CleanShot 2026-02-12 at 08.04.51@2x

image-20260212080511246

ツール利用からCodeInterpreterが使われていそうでした!Thinkingのプロセスやツール利用とかも画面で表示されると嬉しいですね・・・この辺りは自分でカスタマイズしていく感じですかね。

会話履歴の保持

AgentCore Memoryによって会話履歴が保持されています。FASTではデフォルトでShort-term Memory(セッション内の会話履歴)が有効になっています。

CleanShot 2026-02-12 at 08.05.59@2x

会話履歴タブはないですが、セッションが続いている間は記憶されていそうですね。ブラウザをリロードしたら記憶は保持していなさそうでした。また過去の会話を一覧で見れる機能は現時点ではありませんでした。

フィードバックボタンの挙動

会話しているとそれぞれの返信にフィードバックボタンがありますよね。試しに押してみますか。

CleanShot 2026-02-12 at 08.21.24@2x

押すとポップアップが開いてコメントが入力可能です。この状態で送信してみます。

CleanShot 2026-02-12 at 08.22.05@2x

Thanksと表示されていますね。このフィードバックですが、DynamoDBに格納されます。FAST-stack-feedbackといったテーブルに格納されています。

CleanShot 2026-02-12 at 08.23.24@2x

管理者用のフィードバック収集機能もあるんですね。ここも自前で作るのは少し面倒なのであるとありがたいです。

エージェントのコード解説

FASTのデフォルトエージェント実装(Strandsパターン)を見ていきます。

コード全体(patterns/strands-single-agent/basic_agent.py)
patterns/strands-single-agent/basic_agent.py
import os
import traceback

import boto3
from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig
from bedrock_agentcore.memory.integrations.strands.session_manager import (
    AgentCoreMemorySessionManager,
)
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from gateway.utils.gateway_access_token import get_gateway_access_token
from mcp.client.streamable_http import streamablehttp_client
from strands import Agent
from strands.models import BedrockModel
from strands.tools.mcp import MCPClient
from strands_code_interpreter import StrandsCodeInterpreterTools

app = BedrockAgentCoreApp()

def get_ssm_parameter(parameter_name: str) -> str:
    """Fetch parameter from SSM Parameter Store."""
    region = os.environ.get(
        "AWS_REGION", os.environ.get("AWS_DEFAULT_REGION", "us-east-1")
    )
    ssm = boto3.client("ssm", region_name=region)
    try:
        response = ssm.get_parameter(Name=parameter_name)
        return response["Parameter"]["Value"]
    except ssm.exceptions.ParameterNotFound:
        raise ValueError(f"SSM parameter not found: {parameter_name}")
    except Exception as e:
        raise ValueError(f"Failed to retrieve SSM parameter {parameter_name}: {e}")

def create_gateway_mcp_client(access_token: str) -> MCPClient:
    """Create MCP client for AgentCore Gateway with OAuth2 authentication."""
    stack_name = os.environ.get("STACK_NAME")
    if not stack_name:
        raise ValueError("STACK_NAME environment variable is required")

    gateway_url = get_ssm_parameter(f"/{stack_name}/gateway_url")

    gateway_client = MCPClient(
        lambda: streamablehttp_client(
            url=gateway_url, headers={"Authorization": f"Bearer {access_token}"}
        ),
        prefix="gateway",
    )
    return gateway_client

def create_basic_agent(user_id: str, session_id: str) -> Agent:
    """Create a basic agent with Gateway MCP tools and memory integration."""
    system_prompt = (
        "You are a helpful assistant with access to tools via the Gateway "
        "and Code Interpreter. When asked about your tools, list them and "
        "explain what they do."
    )

    bedrock_model = BedrockModel(
        model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0", temperature=0.1
    )

    memory_id = os.environ.get("MEMORY_ID")
    agentcore_memory_config = AgentCoreMemoryConfig(
        memory_id=memory_id, session_id=session_id, actor_id=user_id
    )
    session_manager = AgentCoreMemorySessionManager(
        agentcore_memory_config=agentcore_memory_config,
        region_name=os.environ.get("AWS_DEFAULT_REGION", "us-east-1"),
    )

    code_tools = StrandsCodeInterpreterTools(
        os.environ.get("AWS_DEFAULT_REGION", "us-east-1")
    )

    access_token = get_gateway_access_token()
    gateway_client = create_gateway_mcp_client(access_token)

    agent = Agent(
        name="BasicAgent",
        system_prompt=system_prompt,
        tools=[gateway_client, code_tools.execute_python_securely],
        model=bedrock_model,
        session_manager=session_manager,
        trace_attributes={
            "user.id": user_id,
            "session.id": session_id,
        },
    )
    return agent

@app.entrypoint
async def agent_stream(payload):
    """Main entrypoint for the agent using streaming with Gateway integration."""
    user_query = payload.get("prompt")
    user_id = payload.get("userId")
    session_id = payload.get("runtimeSessionId")

    agent = create_basic_agent(user_id, session_id)

    async for event in agent.stream_async(user_query):
        yield event

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

全体は長いので要点をピックアップして説明します。

エージェントの生成

patterns/strands-single-agent/basic_agent.py
bedrock_model = BedrockModel(
    model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0", temperature=0.1
)

agent = Agent(
    name="BasicAgent",
    system_prompt=system_prompt,
    tools=[gateway_client, code_tools.execute_python_securely],
    model=bedrock_model,
    session_manager=session_manager,
    trace_attributes={
        "user.id": user_id,
        "session.id": session_id,
    },
)

今回のAIエージェントは、モデルにClaude Sonnet 4.5を使用し、ツールとしてGateway MCPクライアントと自作のCode Interpreterを使用するためのツールを渡しています。

また、session_managerにAgentCore Memoryのセッションマネージャーを設定することで、会話履歴の保持が実現されています。Session Managerについての詳細なブログも書いているので必要に応じてご参照ください。

https://dev.classmethod.jp/articles/strands-agents-agentcore-memory-session-manager/

AgentCore Gateway連携

patterns/strands-single-agent/basic_agent.py
def create_gateway_mcp_client(access_token: str) -> MCPClient:
    gateway_url = get_ssm_parameter(f"/{stack_name}/gateway_url")

    gateway_client = MCPClient(
        lambda: streamablehttp_client(
            url=gateway_url, headers={"Authorization": f"Bearer {access_token}"}
        ),
        prefix="gateway",
    )
    return gateway_client

Gateway URLはSSM Parameter Storeから取得し、OAuth2のアクセストークンで認証を行っています。

Gatewayアクセストークンの取得

ここで気になったのが、get_gateway_access_token()の実装です。AgentCore RuntimeからGatewayを呼び出す際のトークン取得は、デコレーターやSDK組み込みの仕組みではなく、OAuth2 Client Credentials Flowを自前で実装しています。

gateway/utils/gateway_access_token.py
def get_gateway_access_token() -> str:
    stack_name = os.environ["STACK_NAME"]

    # SSM Parameter Store / Secrets ManagerからCognito設定を取得
    cognito_domain = get_ssm_parameter(f"/{stack_name}/cognito_provider")
    client_id = get_ssm_parameter(f"/{stack_name}/machine_client_id")
    client_secret = get_secret(f"/{stack_name}/machine_client_secret")

    # OAuth2トークンエンドポイントへリクエスト
    token_url = f"https://{cognito_domain}/oauth2/token"

    credentials = f"{client_id}:{client_secret}"
    b64_credentials = base64.b64encode(credentials.encode()).decode()

    headers = {
        "Authorization": f"Basic {b64_credentials}",
        "Content-Type": "application/x-www-form-urlencoded",
    }

    data = {
        "grant_type": "client_credentials",
        "scope": f"{stack_name}-gateway/read {stack_name}-gateway/write",
    }

    response = requests.post(token_url, headers=headers, data=data, timeout=30)
    token_data = response.json()
    return token_data.get("access_token")

M2M(Machine-to-Machine)認証のClient Credentials Flowですね。デコレーターのような抽象化されたレイヤーはなく、Cognitoとの認証フローを明示的に実装しているので、何をやっているかわかりやすい反面、トークンのキャッシュやリフレッシュの仕組みは入っていない点は把握しておくと良さそうです。

ちなみに、bedrock-agentcore SDKにはAgentCore Identityの@requires_access_tokenデコレーターが用意されており、これを使えばトークン取得をもっとシンプルに書けます。

ただし、このデコレーターにはAgentCore IdentityのOAuth2 Credential Providerが必要で、本記事執筆時点では公式ドキュメント上CLI/SDK経由の手順が中心であり、CloudFormationリソースタイプは確認できませんでした。FASTはCDK完結のワンコマンドデプロイを重視しているため、Cognito直接連携を選択しているように見えます。

カスタマイズ

FASTをベースに自分のエージェントアプリケーションを構築する場合、
主に以下の箇所をカスタマイズしていくことになります。

ツールの追加

Gatewayにツールを追加するには、フォルダを置くだけではなく、以下の3ステップが必要です。

  1. gateway/tools/{ツール名}/にLambdaハンドラーとツールスキーマ(tool_spec.json)を作成
  2. infra-cdk/lib/backend-stack.tsにLambda関数とCfnGatewayTargetのCDKコードを追加
  3. cdk deployで再デプロイ

デフォルトで入っているサンプルツールの構成を見ると、以下のようになっています。

gateway/tools/sample_tool/
├── sample_tool_lambda.py   # Lambdaハンドラー
└── tool_spec.json          # MCPツールスキーマ定義(JSON)

CDKコードで明示的にGatewayターゲットとして登録する必要がある点は把握しておきましょう。とはいえ、サンプルツールのコードをコピーして改変すれば新しいツールの追加自体はそこまで大変ではなさそうです。

エージェントフレームワークの変更

infra-cdk/config.yamlbackend.patternlanggraph-single-agentに変更することで、LangGraphベースのエージェントに切り替えられます。また、patterns/配下に独自のパターンを追加することで、完全にカスタムなエージェントも構築可能です。

フロントエンドのカスタマイズ

フロントエンドはReact + TypeScript + Viteで構成されており、UIにはTailwindとshadcn/uiが採用されています。

テーマカラーやフォントなどのデザイントークンはsrc/styles/globals.cssにCSS変数としてまとまっているので、見た目の変更はここを起点にすると良さそうです。

チャットUIのコンポーネントはsrc/components/chat/配下に集約されています。

src/components/chat/
├── ChatInterface.tsx    # チャット全体のコンテナ
├── ChatHeader.tsx       # ヘッダー(タイトル・ログアウト)
├── ChatInput.tsx        # メッセージ入力フォーム
├── ChatMessage.tsx      # メッセージ表示・フィードバックボタン
├── ChatMessages.tsx     # メッセージ一覧
└── FeedbackDialog.tsx   # フィードバックダイアログ

ちなみにChatSidebar.tsxというセッション一覧用のサイドバーコンポーネントも用意されていますが、現時点ではどこからもimportされていません。会話履歴の一覧表示が欲しくなったら、このコンポーネントを組み込むところから始められそうです。

shadcn/uiのコンポーネント(Button、Dialog等)はsrc/components/ui/に配置されており、必要に応じてバリアントの追加や見た目の調整が可能です。現状のチャットUIはシンプルなので、ツール呼び出しの可視化など、実用に向けては手を入れたい箇所が出てきそうですね。

vibe-context: コーディングAIエージェント向けコンテキスト

FASTのリポジトリにはvibe-context/というディレクトリが用意されています。これはClaude CodeやKiroなどのコーディングAIエージェントに対して、プロジェクト固有のルールやベストプラクティスを伝えるためのコンテキストファイルです。

vibe-context/
├── AGENTS.md                      # AIアシスタント向けの基本ルール
├── coding-conventions.md          # コーディング規約
└── development-best-practices.md  # 開発ベストプラクティス

例えばAGENTS.mdには以下のようなルールが記載されています。

  • 新しいセクションのコードに触れる前にREADMEを必ず読むこと
  • docs/ディレクトリのドキュメントを最優先で参照すること
  • node_modulescdk.outをgrepから除外すること
  • 新機能はローカルテストまたはユニットテストで検証すること

coding-conventions.mdには「すべての関数にdocstringを付ける」「デフォルト値へのfallbackは実装せず、明示的にfailさせる」といった規約、development-best-practices.mdには「複雑な変更は実装前に計画を立て、人間の承認を得る」といったルールが書かれています。

最近流行りのコーディングAIエージェントと一緒にカスタマイズしていくことを前提として設計されているのが面白いですね。

クリーンアップ

検証が完了したら、リソースを削除しておきます。DEPLOYMENT.mdに記載のある通り、以下のコマンドで削除できます。

実行コマンド
cd infra-cdk
pnpm dlx cdk destroy --force

AmplifyHostingStackもCDKスタックに含まれているので、このコマンドでバックエンド・フロントエンドまとめて削除されます。

おわりに

認証、フロントエンド、エージェントランタイム、メモリ、ツール連携といったフルスタック構成をCDKでまるっとデプロイできるのは、エージェントアプリケーション開発の入り口としては良いなと思いました。ゼロから作るのは大変ですからね。
認証やフロントエンド連携周りなどは最初に触るのには複雑なので、この辺りもカバーされているのは嬉しいですね。

一方で画面周りやツール連携など物足りないところも若干あるように感じたので、そこは自前でカスタマイズしてより良いAIエージェント基盤を作っていく形ですかね。今後活用できると良いなと思いました!

本記事が少しでも参考になりましたら幸いです。最後までご覧いただきありがとうございました!

この記事をシェアする

FacebookHatena blogX

関連記事