AIのセットアップ
このガイドでは、Amplify AIキットの概要を説明します。これには、ConversationとGenerationルートを使用したAIバックエンドの定義、およびフロントエンドアプリケーションからそれらへの安全な接続が含まれます。
前提条件
開始する前に、以下が必要です:
また、ローカル開発用にセットアップされたAWSアカウントと、使用したいBedrockファウンデーションモデルへのアクセス権が必要です。Bedrockモデルへのアクセスは、Bedrockコンソールでリクエストすることによってリクエストできます。
Amplifyバックエンドの作成
プロジェクトディレクトリでcreate amplifyスクリプトを実行します:
npm create amplify@latest次に、Amplify sandboxを実行して、ローカルクラウドサンドボックスを開始します:
npx ampx sandboxこれにより、amplifyフォルダに定義したクラウドリソースがプロビジョニングされ、更新が監視され、再デプロイされます。
AIバックエンドの構築
AIバックエンドを構築するには、Amplify Dataスキーマでai「ルート」を定義します。AIルートは、バックエンドのAI機能と対話するためのAPIエンドポイントのようなものです。現在、2つのタイプのルートがあります:
- Conversation: 会話ルートはストリーミング、マルチターンAPIです。会話とメッセージは自動的にDynamoDBに保存されるため、ユーザーは会話を再開できます。これらの例には、チャットベースのAI体験や会話型UIがあります。
- Generation: 単一の同期リクエスト-レスポンスAPI。生成ルートはAppSync クエリに過ぎません。例としては、画像の代替テキストの生成、非構造化入力からの構造化データの生成、要約などがあります。
AIルートを定義するには、amplify/data/resource.tsファイルを開き、スキーマでa.generation()およびa.conversation()を使用します。
import { a, defineData, type ClientSchema } from '@aws-amplify/backend';
const schema = a.schema({ // This will add a new conversation route to your Amplify Data backend. chat: a.conversation({ aiModel: a.ai.model('Claude 3.5 Haiku'), systemPrompt: 'You are a helpful assistant', }) .authorization((allow) => allow.owner()),
// This adds a new generation route to your Amplify Data backend. generateRecipe: a.generation({ aiModel: a.ai.model('Claude 3.5 Haiku'), systemPrompt: 'You are a helpful assistant that generates recipes.', }) .arguments({ description: a.string(), }) .returns( a.customType({ name: a.string(), ingredients: a.string().array(), instructions: a.string(), }) ) .authorization((allow) => allow.authenticated()),});Amplifyサンドボックスが実行されている場合、このファイルを保存すると変更が取得され、必要なリソースが再デプロイされます。
フロントエンドの接続
クラウドサンドボックスが起動して実行されると、AIルートおよび他のAmplify設定に関連する接続情報を含むamplify_outputs.jsonファイルも作成されます。
フロントエンドコードをバックエンドに接続するには、以下を行う必要があります:
- Amplifyクライアント構成ファイル(
amplify_outputs.json)を使用してAmplifyライブラリを構成します。 - Amplifyライブラリから新しいAPIクライアントを生成します。
- エンドツーエンドの型安全性を備えたAPIリクエストを行います。
クライアントライブラリのインストール
Amplifyクライアントライブラリをプロジェクトにインストールします:
npm add aws-amplify @aws-amplify/ui-react @aws-amplify/ui-react-aiライブラリの構成
import "@/styles/app.css";import type { AppProps } from "next/app";import { Amplify } from "aws-amplify";import outputs from "@/amplify_outputs.json";import "@aws-amplify/ui-react/styles.css";
Amplify.configure(outputs);
export default function App({ Component, pageProps }: AppProps) { return <Component {...pageProps} />;}Amplifyを構成するクライアントコンポーネントを作成します:
"use client";
import { Amplify } from "aws-amplify";import config from "@/../amplify_outputs.json";import "@aws-amplify/ui-react/styles.css";
Amplify.configure(config);
export const ConfigureAmplify = () => { return null;};次に、ルートレイアウトでそのコンポーネントをレンダリングします:
import { ConfigureAmplify } from "./ConfigureAmplify";
export default function RootLayout({ children,}: Readonly<{ children: React.ReactNode;}>) { return ( <html lang="en"> <body> <ConfigureAmplify /> {children} </body> </html> );}データクライアントの生成
次に、バックエンドデータスキーマと、Amplifyライブラリによって提供されるgenerateClient()関数を使用して、バックエンドと通信するための型安全なフロントエンドクライアントを生成します。
生成されたAmplifyデータクライアントと生成されたReactフックをエクスポートするclient.ts/jsファイルを作成すると便利です。
import { generateClient } from "aws-amplify/api";import { Schema } from "../amplify/data/resource";import { createAIHooks } from "@aws-amplify/ui-react-ai";
export const client = generateClient<Schema>({ authMode: "userPool" });export const { useAIConversation, useAIGeneration } = createAIHooks(client);import { generateClient } from "aws-amplify/api";import { Schema } from "../amplify/data/resource";import { createAIHooks } from "@aws-amplify/ui-react-ai";
/** * @type {import('aws-amplify/data').Client<import('../amplify/data/resource').Schema>} */export const client = generateClient({ authMode: "userPool" });export const { useAIConversation, useAIGeneration } = createAIHooks(client);生成の使用
import { useAIGeneration } from "@/client";import { Button, Flex, Heading, Loader, Text, TextAreaField, View,} from "@aws-amplify/ui-react";import React from "react";
export default function Page() { const [description, setDescription] = React.useState(""); const [{ data, isLoading, hasError }, generateRecipe] = useAIGeneration("generateRecipe");
const handleClick = async () => { generateRecipe({ description }); };
return ( <Flex direction="column"> <Flex direction="row"> <TextAreaField autoResize value={description} onChange={(e) => setDescription(e.target.value)} label="Description" /> <Button onClick={handleClick}>Generate recipe</Button> </Flex> {isLoading ? ( <Loader variation="linear" /> ) : ( <> <Text fontWeight="bold">{data?.name}</Text> <View as="ul"> {data?.ingredients?.map((ingredient) => ( <View as="li" key={ingredient}> {ingredient} </View> ))} </View> <Text>{data?.instructions}</Text> </> )} </Flex> );}"use client";import { useAIGeneration } from "@/client";import { Button, Flex, Heading, Loader, Text, TextAreaField, View,} from "@aws-amplify/ui-react";import React from "react";
export default function Page() { const [description, setDescription] = React.useState(""); const [{ data, isLoading, hasError }, generateRecipe] = useAIGeneration("generateRecipe");
const handleClick = () => { generateRecipe({ description }); };
return ( <Flex direction="column"> <Flex direction="row"> <TextAreaField autoResize value={description} onChange={(e) => setDescription(e.target.value)} label="Description" /> <Button onClick={handleClick}>Generate recipe</Button> </Flex> {isLoading ? ( <Loader variation="linear" /> ) : ( <> <Heading level={2}>{data?.name}</Heading> <View as="ul"> {data?.ingredients?.map((ingredient) => ( <Text as="li" key={ingredient}> {ingredient} </Text> ))} </View> <Text>{data?.instructions}</Text> </> )} </Flex> );}会話の使用
AI会話はユーザーの範囲内に限定されるため、ユーザーはAmplify認証でログインする必要があります。これを行う最も簡単な方法は、Authenticatorコンポーネントを使用することです。
import { Authenticator } from "@aws-amplify/ui-react";import { AIConversation } from '@aws-amplify/ui-react-ai';import { useAIConversation } from "@/client";
export default function Page() { const [ { data: { messages }, isLoading, }, handleSendMessage, ] = useAIConversation('chat'); // 'chat' is based on the key for the conversation route in your schema.
return ( <Authenticator> <AIConversation messages={messages} isLoading={isLoading} handleSendMessage={handleSendMessage} /> </Authenticator> );}'use client'import { Authenticator } from "@aws-amplify/ui-react";import { AIConversation } from '@aws-amplify/ui-react-ai';import { useAIConversation } from "@/client";
export default function Page() { const [ { data: { messages }, isLoading, }, handleSendMessage, ] = useAIConversation('chat'); // 'chat' is based on the key for the conversation route in your schema.
return ( <Authenticator> <AIConversation messages={messages} isLoading={isLoading} handleSendMessage={handleSendMessage} /> </Authenticator> );}