50
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Bedrock AgentCoreとAmplifyでAI SDK + Next.jsなAIエージェントをスタイリッシュにホストする方法

Last updated at Posted at 2025-10-29

Bedrock AgentCoreとAmplifyを組み合わせてAIアプリを作りたい場合、こんな構成が思いつくと思います。AI SDK、めっちゃ便利ですよね。

image.png

ただ、このアーキテクチャだと、Amplify Histingの制約により ストリーム出力ができません。

我らがHeroもご立腹です。😭😭😭

だがしかし、諦めてはいけません。

これはHeroからの挑戦状なのです!!

AWSにできないわけがありません。だって、ビルディングブロックだもの🧱🧱🧱

ということで、できました🎉🎉🎉

image.png

useChatの機能がそのまま使えるので、開発体験はNext.js単体のものと殆ど変わりません。

ポイントはこのあたりです。

  • フロントエンドとバックエンドを別々のNext.jsアプリとして構築
  • フロントエンドはAmplifyに、バックエンドはそのままコンテナ化しAgentCore Runtimeにデプロイする
  • バックエンドはAgentCore Runtimeの仕様に合わせる
    • ポート番号は8080
    • APIは/invocations(POST)と/ping(GET)とする
  • useChatで/invocationsを呼び出す
  • Amplifyの認証機能とAgentCoreのインバウンド認証を連携させる

チャットの見た目はこちらで紹介したAI Elementsを使ってます。おしゃれ~

ソースコードの全体はこちらです。(Starください!そしてこの投稿にいいねください!)

試してないですが同じ構成でNext.js + MastraもAgentCore上で動作させられると思います

11/3 Cognitoのトークンではなく、IAM認証を使うパターンも作成しました。動作的には変わらないです
Cognito未ログイン状態でも動作させたかったのですが、それは難しそうでした😭
https://github.com/moritalous/agentcore-amplify-nextjs/tree/sigv4

バックエンドを構築

バックエンド用のNext.jsプロジェクトを新規作成します。

npx -y create-next-app@latest backend --yes

ライブラリーをインストールします。

cd backend/
npm add ai @ai-sdk/amazon-bedrock @aws-sdk/credential-providers

APIを2つ(/invocations/ping)作成します。

8080ポートで起動する必要があるのでpackage.jsonのscriptsを修正します。

backend/package.json

  "scripts": {
-   "dev": "next dev",
+   "dev": "next dev --port 8080",
    "build": "next build",
    "start": "next start",
    "lint": "eslint"
  },

ローカル環境で動作確認する際に、クロスオリジンになってしまうのでCORSの設定を追加します。

backend/next.config.ts
  import type { NextConfig } from "next";
  
  const nextConfig: NextConfig = {
    /* config options here */
+   async headers() {
+     return [
+       {
+         source: "/invocations",
+         headers: [
+           { key: "Access-Control-Allow-Credentials", value: "true" },
+           { key: "Access-Control-Allow-Origin", value: "*" },
+           { key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT" },
+           { key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" },
+         ]
+       }
+     ]
+   }
  };
  
  export default nextConfig;

フロントエンドを構築

続いてフロントエンド用のNext.jsプロジェクトを新規作成します。

npx -y create-next-app@latest frontend --yes

ライブラリーをインストールします。

cd frontend
npm add ai @ai-sdk/react

AI Elementsをインストールします。

npx -y ai-elements@latest

Chatbotコンポーネントを作成します。useChatのオプションで明示的にバックエンドAPIのURLを指定します。

未指定の場合は、デフォルトでフロントエンドと同じホストの/api/chatが使われます

frontend/components/Chatbot.tsx
const transportOptions: HttpChatTransportInitOptions<UIMessage> = {
    api: 'http://localhost:8080/invocations',
}

const { messages, sendMessage, status } = useChat({
    transport: new DefaultChatTransport(transportOptions),
})

Chatbot.tsxの全体はこんな感じです。

app/page.tsxでChatbotコンポーネントを呼び出します。

ローカル環境で動作確認

それではローカル環境で動作確認します。まずはバックエンドを起動します。バックエンドAPIは8080ポートを使用します。

Shell
# backendディレクトリで実行
npm run dev
> nextjs-agentcore-server@0.1.0 dev
> next dev --port 8080

   ▲ Next.js 16.0.0 (Turbopack)
   - Local:        http://localhost:8080
   - Network:      http://172.17.0.2:8080

 ✓ Starting...
 ✓ Ready in 675ms

続いてフロントエンドを立ち上げます。フロントエンドは3000ポートを使用します。

Shell
# frontendディレクトリで実行
npm run dev
> nextjs-agentcore-client@0.1.0 dev
> next dev

   ▲ Next.js 16.0.0 (Turbopack)
   - Local:        http://localhost:3000
   - Network:      http://172.17.0.2:3000

 ✓ Starting...
 ✓ Ready in 1293ms

ブラウザでhttp://localhost:3000にアクセスしてみましょう。チャットの入力に対して、ストリーミング形式で応答があれば成功です。

フロントエンドにAmplify Gen2を追加

フロントエンドにAmplify Gen2を追加します。

npm create amplify@latest
✔ Where should we create your project? .

ライブラリーを追加します。

npm add @aws-amplify/ui-react

Amplify Gen2のサンドボックスを起動します。これでCognitoが作成されます。

npx ampx sandbox

Cognitoさえ作成できればいいので、ここでサンドボックスを停止して大丈夫です。

バックエンドをAgentCore Runtimeへデプロイ

コンテナイメージをECRへ登録

AgentCore Runtimeへデプロイするために、コンテナ化します。

Next.jsアプリをDockerコンテナとしてデプロイする場合は、standaloneを指定すると良いそうです。

参考
https://nextjs.org/docs/app/getting-started/deploying#docker
https://github.com/vercel/next.js/tree/canary/examples/with-docker

next.config.ts
  import type { NextConfig } from "next";
  
  const nextConfig: NextConfig = {
    /* config options here */
+   output: "standalone",
  };
  
  export default nextConfig;

コンテナをビルドしてECRにプッシュします。
AgentCoreの要件に合わせ、arm64アーキテクチャでコンテナイメージを作成します。

Shell
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
AWS_REGION=us-west-2

AGENT_NAME=agentcore-amplify-nextjs-backend

docker buildx create --use

aws ecr create-repository --repository-name ${AGENT_NAME} --region ${AWS_REGION}
aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

docker buildx build --platform linux/arm64 -t ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${AGENT_NAME}:latest --push .

これでECRにコンテナイメージが登録されました。

AgentCore Runtimeにバックエンドを登録

マネジメントコンソールで登録します。

us-west-2.console.aws.amazon.com_bedrock-agentcore_agents_create_region=us-west-2.png

us-west-2.console.aws.amazon.com_bedrock-agentcore_agents_create_region=us-west-2 (1).png

インバウンドIDの設定を行います。

  1. インバウンドIDのタイプは「JSON Web Tokens(JWT)を使用」を選択
  2. JWTスキーマ設定は「既存のIDプリバイダーの設定を使用」を選択
  3. 検出URLはhttps://cognito-idp.{リージョン名}.amazonaws.com/{CognitoのユーザープールID}/.well-known/openid-configurationを入力
  4. 許可されたクライアントは、Cognitoのクライアント IDを入力

Cognitoの設定はfrontend/amplify_outputs.jsonにあります

us-west-2.console.aws.amazon.com_bedrock-agentcore_agents_create_region=us-west-2 (3).png

フロントエンドに認証機能を実装

page.tsxにAmplifyの認証を追加します。ログインしたらアクセストークンを取得し、Chatbotへ渡すようにします。

Chatbotコンポーネントでは、トークンを受けとり、環境変数にAgentCore Runtimeの設定がある場合はAgentCore宛に、ない場合はlocalhost宛に送信するよう修正します。

headersも追加します。

frontend/components/Chatbot.tsx
function buildApiUrl() {
  if (process.env.NEXT_PUBLIC_AGENT_ARN) {
    const agentArn = process.env.NEXT_PUBLIC_AGENT_ARN!
    const region = process.env.NEXT_PUBLIC_AWS_REGION!
    const escapedArn = encodeURIComponent(agentArn)
    const qualifier = process.env.NEXT_PUBLIC_QUALIFIER
    return `https://bedrock-agentcore.${region}.amazonaws.com/runtimes/${escapedArn}/invocations?qualifier=${qualifier}`
  } else {
    return 'http://localhost:8080/invocations'
  }
}

const ChatBot = ({ token }: { token: string }) => {
  const [input, setInput] = useState('')
  const [model, setModel] = useState<string>(models[0].value)
  const [reasoning, setReasonings] = useState(reasonings[1].value)

  const [sessionId] = useState(() => `session-${Date.now()}-${Math.random().toString(36)}`);

  const transportOptions: HttpChatTransportInitOptions<UIMessage> = {
    api: buildApiUrl(),
    headers: {
      'Authorization': `Bearer ${token}`,
      'X-Amzn-Trace-Id': `trace-${Date.now()}`,
      'Content-Type': 'application/json',
      'X-Amzn-Bedrock-AgentCore-Runtime-Session-Id': sessionId,
    },
  }

.env.localファイルを作成し、AgentCore Runtimeの設定を記述します。

.env.local
NEXT_PUBLIC_AGENT_ARN=arn:aws:bedrock-agentcore:{リージョン名}:{アカウントID}:runtime/{ランタイム名}
NEXT_PUBLIC_AWS_REGION=us-west-2
NEXT_PUBLIC_QUALIFIER=DEFAULT

AgentCore Runtimeのバックエンドをローカル環境のフロントエンドから呼び出す動作確認

フロントエンドを起動します。

# frontendディレクトリで実行
npm run dev

Cognitoのサインイン画面が出るので、新しくアカウントを作成します。サインイン後、先ほどと同じチャットが動作すると思います。

フロントエンドをAmplify Hostingへデプロイ

AI Elementsのバージョンアップに巻き込まれ、本日時点でそのままではnpm run buildが通りません。なので、Q Developerにビルドが通るように細工をしてもらいました。

https://github.com/moritalous/agentcore-amplify-nextjs/commit/e2816cd6bde2da0b2317b3d939741f8160c0a2e9

GitHubからデプロイします。

us-west-2.console.aws.amazon.com_amplify_create_add-repo.png

今回のディレクトリ構成の場合、モノレポを選びfrontendと入力します。

us-west-2.console.aws.amazon.com_amplify_create_add-repo (1).png

アプリケーション設定の下の方に「詳細設定」があるのでこれを開きます。

us-west-2.console.aws.amazon.com_amplify_create_add-repo (4).png

3つの環境変数を入力します。

  • NEXT_PUBLIC_AGENT_ARN
  • NEXT_PUBLIC_AWS_REGION
  • NEXT_PUBLIC_QUALIFIER

us-west-2.console.aws.amazon.com_amplify_create_add-repo (3).png

デプロイを進めます。

デプロイ完了後、作成されるCognitoのリソースを特定します。

us-west-2.console.aws.amazon.com_amplify_create_add-repo (5).png

Cognitoの管理画面にアクセスし、ユーザープールIDとクライアントIDを取得します。そして、AgentCoreのインバウンドIDの設定を上書きします。

これで、Amplify + AgentCore環境が完成です!

まとめ

いい勉強になりました!ありがとう、Hero!

AgentCore SDKを使うと、ストリームレスポンスの「data: を取り除く」という謎コードが必要でしたが、Next.jsをホスティングした場合はもとのフォーマットのままでした。

また、ずっとやりたかったCognitoのトークンでAgentCoreのインバウンド認証をするものも、意外とあっさりでした。

AgentCore、奥が深いです

(再掲)

ソースコードの全体はこちらです。(Starください!そしてこの投稿にいいねください!)

50
22
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
50
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?