Add an AI agent to your Amplify app
This guide adds a conversational AI agent to an Amplify Gen 2 app using the AWS Blocks Agent Block. The agent streams responses, persists conversations, and authenticates each request against the Cognito user pool your Amplify backend already provisions.
This guide assumes you have already added AWS Blocks to your Amplify project.
Install the Agent Block
Add the Block to your aws-blocks workspace:
npm install @aws-blocks/bb-agent zodThe Agent Block uses Zod schemas (v4) to validate tool parameters, so zod is a required peer dependency.
Define the agent
In aws-blocks/index.ts, create an Agent and expose API methods that authenticate the caller with the Amplify Cognito pool before touching a conversation. The CognitoVerifier scaffolded into your project verifies the same tokens Amplify issues:
import { ApiNamespace, Scope } from '@aws-blocks/blocks';import { Agent, BedrockModels } from '@aws-blocks/bb-agent';import { CognitoVerifier } from './cognito-verifier.js';
const scope = new Scope('my-app');
const auth = new CognitoVerifier({ userPoolId: process.env.COGNITO_USER_POOL_ID!, clientId: process.env.COGNITO_CLIENT_ID!, tokenUse: 'id'});
// `model` is optional and defaults to BedrockModels.BALANCED.const agent = new Agent(scope, 'support-agent', { model: { deployed: BedrockModels.BALANCED }, systemPrompt: 'You are a helpful support agent.'});
// These methods return the shapes the `useChat` client hook expects// ({ conversationId } and { messages }) so the frontend can wire in directly.export const api = new ApiNamespace(scope, 'api', (context) => ({ // Start a conversation for the signed-in Amplify user async createConversation() { const user = await auth.requireAuth(context); return { conversationId: await agent.createConversationId(user.sub) }; },
// Send a message — the agent streams chunks to the given Realtime channel async sendMessage(conversationId: string, message: string, channelId: string) { const user = await auth.requireAuth(context); await agent.stream(message, { conversationId, channelId, userId: user.sub }); },
// Read history — verify the conversation belongs to this user first async getConversation(conversationId: string) { const user = await auth.requireAuth(context); const owned = await agent.listConversations(user.sub); if (!owned.some((c) => c.conversationId === conversationId)) { throw new Error('Not found'); } return { messages: await agent.getConversation(conversationId) }; },
// Expose the Realtime channel so the client can subscribe to streamed chunks async getChannel(channelId: string) { return agent.getChannel(channelId); }}));Deploy
The agent runs on Amazon Bedrock, so deploy it with the rest of your backend:
npm run sandboxMake sure model access is enabled for the Bedrock model your agent uses in your account and Region.
Call the agent from your frontend
Generate the native client for your platform from your backend's blocks.spec.json and attach your Amplify Auth session token as a Bearer token on each request, as described in Connect your frontend. Call createConversation to get a conversation ID, then sendMessage with a channel ID, and subscribe to that Realtime channel to receive streamed chunks.
Next steps
- Add tools to your agent so it can call your other Blocks or external APIs — see the AWS Blocks Developer Guide.
- Use BasicAuth with an Amplify backend if you need lightweight auth instead of Cognito.