Amplify AI Kit 解説:ゼロから作るAIチャットアプリ
はじめに
「愛犬との毎日を楽しく便利にするアプリ オトとりっぷ」でエンジニアしています、足立です!
この記事では、AWS Amplify Gen2 と Amplify AI Kit を使用して、AI チャットアプリケーションを構築する方法を詳しく解説します。
Amplify AI Kit とは?
Amplify AI Kit は、AWS Amplify が提供する機能の一つで、Amazon Bedrock の大規模言語モデル(LLM)を簡単にアプリケーションに統合できるツールです。これにより、開発者は複雑な AI 機能を少ないコードで実装できます。
主な特徴:
- 簡単な統合: 数行のコードで AI モデルをアプリケーションに統合
- 会話型 UI: 事前構築された UI コンポーネントでチャットインターフェースを簡単に実装
- カスタマイズ性: システムプロンプトやモデルパラメータを柔軟に設定可能
- 認証連携: Amplify Auth とシームレスに連携し、ユーザーごとの会話履歴を管理
今回作成するアプリケーション
この記事では、以下の機能を持つ AI チャットアプリケーションを構築します:
- ユーザー認証機能(サインアップ、ログイン)
- AI アシスタントとのチャット機能
- チャット履歴の保存と表示機能
- 過去の会話の続きを再開する機能
完成品はこちらのレポジトリで公開しています
それでは、実際に構築していきましょう!
開発環境のセットアップ
Amazon Bedrock のモデル利用申請
Amplify AI Kit を使用するには、まず Amazon Bedrock のモデルへのアクセス権を取得する必要があります。以下の手順で申請を行います:
-
AWS マネジメントコンソールにログイン:
- AWS アカウントにログインし、Amazon Bedrock のコンソールに移動します
-
モデルアクセスページに移動:
- 左側のナビゲーションから「モデルアクセス」を選択します
- このページでは、利用可能なすべての基盤モデルが表示されます
-
モデルアクセスの管理:
- 「モデルアクセスを変更」ボタンをクリックします
- 使用したいモデル(今回は「Claude 3.5 Sonnet」)のチェックボックスをオンにします
- 他にも Anthropic の Claude シリーズや Amazon の Titan モデルなど、様々なモデルが利用可能です
-
アクセス承認の待機:
- 通常、モデルアクセスの承認は数分以内に完了します
- 承認されると、モデルアクセスページでステータスが「アクセスが付与されました」に変わります
モデルアクセスが承認されたら、Amplify AI Kit を使用してアプリケーションに AI 機能を統合できるようになります。なお、Amazon Bedrock の使用には料金が発生しますので、料金体系を確認しておくことをお勧めします。
ローカル環境の設定
公式ドキュメントを参考に、AWS Amplify の関連リソースにアクセス可能な状態にしてください。
Next.js と Amplify Gen2 のセットアップ
まずは、Next.js プロジェクトを作成し、Amplify Gen2 の環境を構築します。
# Next.jsプロジェクトの作成
$ npm create next-app@14 -- next-amplify-gen2 --typescript --eslint --app --no-src-dir --no-tailwind --import-alias '@/*'
$ cd next-amplify-gen2
上記のコマンドでは、以下のオプションを指定しています:
-
--typescript
: TypeScript を使用 -
--eslint
: ESLint を設定 -
--app
: App Router を使用(Next.js 13 以降の新しいルーティング方式) -
--no-src-dir
: src ディレクトリを作成しない -
--no-tailwind
: Tailwind CSS を使用しない -
--import-alias '@/*'
: インポートエイリアスを設定
次に、Amplify Gen2 をプロジェクトに追加します:
# Amplify Gen2のセットアップ
$ npm create amplify@latest
> ? Where should we create your project? (.) # デフォルトの「.」(現在のディレクトリ)を選択
Amplify Gen2 は、TypeScript ベースのインフラストラクチャ定義を使用して、バックエンドリソースを簡単に定義できる新しいアプローチです。従来の Amplify CLI と比較して、より柔軟で TypeScript の型安全性を活かした開発が可能になります。
続いて、必要なライブラリをインストールします:
# Amplify関連のライブラリをインストール
$ npm install aws-amplify @aws-amplify/ui-react
# アイコンライブラリをインストール
$ npm install react-icons
これで基本的なセットアップは完了です。次に、ローカル開発環境で Amplify リソースをテストするためのサンドボックスを起動します:
# Amplifyサンドボックスの起動
$ npx ampx sandbox
サンドボックスモードでは、AWS アカウントにサンドボックス環境が構築され、これにより開発とテストが迅速に行えます。
プロジェクト構造の確認
Next.js と Amplify Gen2 の初期設定が完了すると、以下のようなファイル構成になります:
├── amplify/
│ ├── auth/
│ │ └── resource.ts
│ ├── data/
│ │ └── resource.ts
│ ├── backend.ts
│ └── package.json
│
├── app/
│ ├── favicon.ico
│ ├── layout.tsx
│ └── page.tsx
│
バックエンドリソースの設定
次に、Amplify Gen2 のバックエンドリソースを設定します。主に認証(Auth)とデータ(Data)の 2 つのリソースを設定します。
認証(Auth)の設定
まず、amplify/auth/resource.ts
ファイルを以下のように設定します:
amplify/auth/resource.ts
import { defineAuth } from '@aws-amplify/backend';
export const auth = defineAuth({
loginWith: {
email: true,
},
});
ポイント
-
defineAuth
関数を使用して認証リソースを定義 -
loginWith.email: true
により、メールアドレスとパスワードによるログイン方式を有効
このシンプルな設定だけで、ユーザー登録、ログイン、パスワードリセットなどの機能が自動的に提供されます。
データ(Data)と AI Kit の設定
次に、amplify/data/resource.ts
ファイルを以下のように設定します:
amplify/data/resource.ts
import { a, defineData, type ClientSchema } from "@aws-amplify/backend";
const schema = a.schema({
chat: a
.conversation({
aiModel: a.ai.model("Claude 3.5 Sonnet"),
systemPrompt: "You are a helpful AI assistant.",
})
.authorization((allow) => allow.owner()),
});
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({
schema,
authorizationModes: {
defaultAuthorizationMode: "userPool",
},
});
ポイント
- AI Kit の設定
-
chat
という名前で会話リソースを定義しています -
aiModel: a.ai.model("Claude 3.5 Sonnet")
で使用する AI モデルを指定しています -
systemPrompt
で AI アシスタントの基本的な振る舞いを設定しています - こちらも
.authorization((allow) => allow.owner())
で、各ユーザーは自分の会話のみにアクセス可能です
-
- 認証モードの設定
-
defaultAuthorizationMode: "userPool"
で、Cognito User Pool を使用した認証を指定しています
-
この設定により、ユーザーごとに AI 会話を保存し、過去の会話履歴を取得できるようになります。
バックエンドの統合
最後に、定義した認証とデータリソースを統合するために、amplify/backend.ts
ファイルを設定します:
amplify/backend.ts
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
import { data } from './data/resource';
const backend = defineBackend({
auth,
data,
});
ポイント
-
defineBackend
関数を使用してバックエンド全体を定義 - 先ほど設定した
auth
とdata
リソースをインポートして統合
これでバックエンドの設定は完了です。これにより、認証とデータリソースが連携して動作するようになります。Amplify Gen2 の特徴として、このように TypeScript で型安全にインフラを定義できる点が大きな利点です。設定が直感的で、コード補完も効くため、開発効率が向上します。
フロントエンドの実装
バックエンドの設定が完了したら、次はフロントエンド部分を実装していきます。ここでは、Amplify UI React コンポーネントと、Amplify AI Kit を使用したチャットインターフェースを構築します。
Amplify AI Kit の統合
AI 機能を使用するためには追加のライブラリが必要です。インストールおよびフロントエンドの設定を行います。
必要なライブラリのインストール
$ npm install @aws-amplify/ui-react-ai react-markdown
-
@aws-amplify/ui-react-ai
: Amplify AI Kit の UI コンポーネントとフックを提供 -
react-markdown
: AI の応答をマークダウン形式で表示するためのライブラリ
Amplify 設定コンポーネント
Amplify を使用するには、アプリケーション全体で Amplify の設定を行う必要があります。そのための専用コンポーネントを作成します:
app/_components/ConfigureAmplify.tsx
"use client";
import { Amplify } from "aws-amplify";
import config from "@/amplify_outputs.json";
Amplify.configure(config, { ssr: true });
export function ConfigureAmplifyClientSide() {
return null;
}
ポイント
- Amplify の設定
-
Amplify.configure()
を使用して Amplify を初期化します -
amplify_outputs.json
ファイルから設定を読み込みます(このファイルは Amplify サンドボックスが自動生成) -
{ ssr: true }
オプションにより、サーバーサイドレンダリング環境でも正しく動作するよう設定します
-
- クライアントサイド専用
-
"use client"
ディレクティブにより、このコンポーネントはクライアントサイドでのみ実行されます - 実際には UI を描画せず(
return null
)、初期化処理のみを行います
-
このコンポーネントをルートレイアウトで使用することで、すべてのページで Amplify の機能が利用できるようになります。
AI クライアントの設定
次に、Amplify AI Kit のクライアントを設定し、アプリケーション全体で使用できるようにします:
app/client.ts
import { Schema } from "@/amplify/data/resource";
import { createAIHooks } from "@aws-amplify/ui-react-ai";
import { generateClient } from "aws-amplify/api";
export const client = generateClient<Schema>({ authMode: "userPool" });
export const { useAIConversation, useAIGeneration } = createAIHooks(client);
ポイント
- 型安全なクライアント生成
-
generateClient<Schema>()
を使用して、バックエンドで定義したスキーマに基づいた型安全な API クライアントを生成します -
{ authMode: "userPool" }
オプションで、Cognito User Pool を使用した認証を指定します
-
- AI 機能のフック作成
-
createAIHooks(client)
を使用して、AI 機能用の React フックを生成します -
useAIConversation
: チャット会話を管理できます -
useAIGeneration
: テキスト生成などの単発の AI 機能を使用できます
-
このファイルをインポートすることで、アプリケーション内の任意のコンポーネントから AI 機能にアクセスできるようになります。このクライアント設定ファイルは非常にシンプルですが、アプリケーション全体の AI 機能の基盤となる重要なファイルです。
AI チャット会話コンポーネント
最初に、AI チャット会話のレイアウトを提供する共通コンポーネントを作成します。このコンポーネントは、新規チャットと過去のチャット履歴の両方で使用します。
app/_components/AIConversationLayout.tsx
"use client";
import { View, useTheme } from "@aws-amplify/ui-react";
import { AIConversation } from "@aws-amplify/ui-react-ai";
import Markdown from "react-markdown";
import { useAIConversation } from "@/app/client";
export const AIConversationLayout = ({ id }: { id?: string }) => {
const { tokens } = useTheme();
const [
{
data: { messages },
isLoading,
},
handleSendMessage,
] = useAIConversation("chat", { id });
return (
<View padding={tokens.space.large}>
<AIConversation
messages={messages}
isLoading={isLoading}
handleSendMessage={handleSendMessage}
messageRenderer={{
text: ({ text }) => <Markdown>{text}</Markdown>,
}}
/>
</View>
);
};
ポイント
- AI チャット機能の統合
-
useAIConversation
フックを使用して、Amplify AI Kit のチャット機能を統合しています -
id
パラメータを受け取ることで、新規チャットと既存チャットの両方に対応できます
-
- UI コンポーネント
- Amplify UI の
View
コンポーネントでラッピングし、適切なパディングを適用しています -
AIConversation
コンポーネントを使用してチャット UI を表示しています
- Amplify UI の
- マークダウンレンダリング
-
messageRenderer
プロパティを使用して、AI の応答をマークダウン形式で表示しています - これにより、コードブロックや箇条書きなどの書式が適切に表示されます
-
このコンポーネントを作成することで、アプリケーション内の複数の場所でチャット機能を簡単に再利用できます。
ページコンポーネントの作成
以下の 3 つのページを実装します:
- メインページ
- 新規チャットを開始するためのページです
- チャット詳細ページ
- 過去のチャット履歴を再開した時のページです
- チャット履歴ページ
- 過去のチャット履歴一覧を表示するためのページです
メインページの実装
次に、アプリケーションのメインページを実装します。ここでは、先ほど作成したAIConversationLayout
コンポーネントを使用します。
app/page.tsx
"use client";
import { AIConversationLayout } from "@/app/_components/AIConversationLayout";
export default AIConversationLayout;
このページは非常にシンプルで、AIConversationLayout
コンポーネントをそのままエクスポートしています。
また、新規チャットを始めるための Chat ページも同様に用意しておきましょう。
(将来的にメインページは別の画面を用意するかもしれませんからね)
app/chat/page.tsx
"use client";
import { AIConversationLayout } from "@/app/_components/AIConversationLayout";
export default AIConversationLayout;
これにより、ルートパス(/
) もしくは /chat
パスにアクセスした際に、新しいチャット会話が開始されます。
チャット詳細ページの実装
次に、特定のチャット ID に基づいて過去の会話を表示するページを実装します。このページは動的ルーティングを使用し、URL パラメータからチャット ID を取得します。
app/chat/[id]/page.tsx
"use client";
import { useEffect, useState } from "react";
import { AIConversationLayout } from "@/app/_components/AIConversationLayout";
const App = ({ params }: { params: Promise<{ id: string }> }) => {
const [id, setId] = useState<string>();
useEffect(() => {
const func = async () => {
const { id } = await params;
setId(id);
};
func();
}, []);
return <AIConversationLayout id={id} key={id} />;
};
export default App;
ポイント
- 動的ルーティング
- Next.js の動的ルーティング機能を使用して、
/chat/[id]
パスでチャット ID を取得します -
params
オブジェクトからチャット ID を抽出します
- Next.js の動的ルーティング機能を使用して、
- 状態管理
-
useState
とuseEffect
を使用して、非同期で取得した ID を管理しています - ID が取得できたら、それを
AIConversationLayout
コンポーネントに渡します
-
- コンポーネントの再利用
- 新規チャットと同じ
AIConversationLayout
コンポーネントを使用します -
id
プロパティを渡すことで、特定のチャット会話を表示します -
key={id}
を設定することで、ID が変わるたびにコンポーネントが再レンダリングれます
- 新規チャットと同じ
このアプローチにより、コードの重複を避けながら、新規チャットと過去のチャット表示の両方に対応できます。
チャット履歴ページの実装
ユーザーが過去のチャット履歴を閲覧できるページも実装します。まず、データ取得のためのカスタムフックを作成します:
app/history/useData.ts
"use client";
import "@aws-amplify/ui-react/styles.css";
import { generateClient } from "aws-amplify/data";
import { useEffect, useState } from "react";
import { type Schema } from "@/amplify/data/resource";
const client = generateClient<Schema>();
type Data = {
id: string;
message: string;
createdAt: string;
};
export const useData = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState<Data[]>([]);
const deleteItem = async (id: string) => {
await client.conversations.chat.delete({ id });
setData((prev) => prev.filter((item) => item.id !== id));
};
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
const { data: conversations } = await client.conversations.chat.list();
const tmpList: Data[] = await Promise.all(
conversations.map(async (conversation) => {
const detail = await conversation.listMessages();
const message = detail.data[0]?.content[0].text || "";
return {
id: conversation.id,
createdAt: conversation.createdAt,
message,
};
}),
);
const filteredList = tmpList.filter((item) => item.message !== "");
const noMessageList = tmpList.filter((item) => item.message === "");
await Promise.all(
noMessageList.map(async (item) => {
await deleteItem(item.id);
}),
);
setData(filteredList);
setIsLoading(false);
};
fetchData();
}, []);
return {
data,
isLoading,
deleteItem,
};
};
ポイント
- データ取得
-
client.conversations.chat.list()
を使用して、ユーザーのすべてのチャット会話を取得します - 各会話について
conversation.listMessages()
を呼び出し、最初のメッセージを取得します - 取得したデータを整形して、ID、作成日時、最初のメッセージを含むオブジェクトの配列を作成します
-
- データクリーニング
- メッセージが空の会話を除外(
filteredList
)します - 空のメッセージを持つ会話は自動的に削除(
noMessageList
)します
- メッセージが空の会話を除外(
- データ管理
-
deleteItem
関数で特定のチャット会話を削除する機能を提供しています - 削除後は状態を更新して、UI に反映しています
-
- 状態管理
-
isLoading
状態でデータ読み込み中かどうかを追跡しています -
data
状態で取得したチャット履歴を保持しています
-
このフックを使用することで、チャット履歴ページでデータの取得、表示、削除を簡単に行えます。
チャット履歴ページの UI 実装
次に、取得したチャット履歴を表示するページを実装します:
app/history/page.tsx
"use client";
import {
Button,
Flex,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Text,
useTheme,
} from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";
import { useRouter } from "next/navigation";
import { useData } from "./useData";
const App = () => {
const router = useRouter();
const { tokens } = useTheme();
const { data, deleteItem } = useData();
return (
<Flex padding={tokens.space.large} justifyContent="center">
<Table highlightOnHover={true} variation="striped">
<TableHead>
<TableRow>
<TableCell as="th">Message</TableCell>
<TableCell as="th">CreatedAt</TableCell>
<TableCell as="th"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((item) => (
<TableRow key={item.id}>
<TableCell>
<Button
variation="link"
onClick={() => {
router.push(`/chat/${item.id}`);
}}
>
<Text fontSize="12px">{item.message}</Text>
</Button>
</TableCell>
<TableCell>
<Text fontSize="12px">{item.createdAt}</Text>
</TableCell>
<TableCell>
<Button
colorTheme="warning"
onClick={() => deleteItem(item.id)}
>
delete
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Flex>
);
};
export default App;
ポイント
- データ表示
-
useData
フックを使用してチャット履歴データを取得します - Amplify UI の
Table
コンポーネントを使用して、整形されたテーブルとして表示します
-
- インタラクション
- 行をクリックすると、対応するチャット詳細ページ(
/chat/[id]
)に遷移します - 各行に削除ボタンを配置し、不要な会話を削除できます
- 行をクリックすると、対応するチャット詳細ページ(
- スタイリング
-
highlightOnHover={true}
で行にホバー効果を追加します -
variation="striped"
で縞模様のテーブルデザインを適用します -
cursor: "pointer"
でクリック可能な要素であることを視覚的に示します
-
このページにより、ユーザーは過去のチャット履歴を簡単に閲覧し、特定の会話を再開したり、不要な会話を削除したりできます。
アプリケーションレイアウトの実装
最後に、アプリケーション全体のレイアウトを設定します。このレイアウトは、サイドバーナビゲーション、認証フロー、およびコンテンツ表示領域を含む統一された UI を提供します。
基本レイアウトコンポーネント
まず、アプリケーションの基本レイアウトを定義するコンポーネントを作成します:
app/_components/BasicLayout.tsx
"use client";
import {
Authenticator,
Button,
Flex,
Grid,
ScrollView,
Text,
useAuthenticator,
useTheme,
View,
} from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";
import { useRouter } from "next/navigation";
import { AiOutlineHistory, AiOutlineHome } from "react-icons/ai";
type Props = {
headerTitle?: string;
children: React.ReactNode;
};
const Layout = ({ children, headerTitle = "Amplify AI Kit" }: Props) => {
const { authStatus } = useAuthenticator((context) => [context.authStatus]);
const { tokens } = useTheme();
const router = useRouter();
return (
<Grid
templateColumns="20rem 1fr"
templateRows="1fr"
height="100vh"
overflow="hidden"
>
<View padding={tokens.space.large}>
<Flex
gap={tokens.space.large}
direction="column"
rowGap={tokens.space.medium}
paddingTop={tokens.space.xxxl}
paddingBottom={tokens.space.xxxl}
>
<Button
variation="primary"
onClick={() => {
const pathname = window.location.pathname;
if (pathname === "/chat") {
window.location.reload();
} else {
router.push("/chat");
}
}}
isDisabled={authStatus !== "authenticated"}
>
New Chat
</Button>
<Flex gap={tokens.space.medium} alignItems="center">
<AiOutlineHome />
<Button variation="link" onClick={() => router.push("/")}>
Home
</Button>
</Flex>
<Flex gap={tokens.space.medium} alignItems="center">
<AiOutlineHistory />
<Button variation="link" onClick={() => router.push("/history")}>
History
</Button>
</Flex>
</Flex>
</View>
<View
backgroundColor={tokens.colors.background.secondary}
overflow="auto"
>
<View textAlign="center" padding={tokens.space.large}>
<Text
color={tokens.colors.primary[100]}
as="h1"
fontSize={tokens.fontSizes.xxxl}
fontWeight={tokens.fontWeights.bold}
>
{headerTitle}
</Text>
</View>
{authStatus === "authenticated" ? (
<ScrollView width="100%">{children}</ScrollView>
) : (
<Flex
justifyContent="center"
alignItems="center"
paddingTop={tokens.space.xxxl}
>
<Authenticator />
</Flex>
)}
</View>
</Grid>
);
};
export const BasicLayout = (props: Props) => {
return (
<Authenticator.Provider>
<Layout {...props} />
</Authenticator.Provider>
);
};
ポイント
- グリッドレイアウト
- 2 カラムのグリッドレイアウト(サイドバーと主要コンテンツ領域)を採用しています
- 画面全体を占めるように設計(
height="100vh"
)しています
- サイドナビゲーション
- 左側のサイドバーに新規チャット、ホーム、履歴へのナビゲーションリンクを配置しています
- 未認証状態では「New Chat」ボタンを無効化しています
- 認証統合
-
useAuthenticator
フックを使用して認証状態を取得します - 未認証の場合は
Authenticator
コンポーネントを表示してログインフォームを提供します - 認証済みの場合はコンテンツ(
children
)を表示します
-
- テーマとスタイリング
- Amplify UI の
useTheme
フックを使用して一貫したデザイントークンを適用しています - 色、スペーシング、フォントサイズなどを統一的に管理しています
- Amplify UI の
- コンテキストプロバイダー
-
Authenticator.Provider
でラップして認証コンテキストを提供しています - これにより、アプリケーション全体で認証状態にアクセスが可能です
-
ルートレイアウトの設定
最後に、アプリケーションのルートレイアウトを設定します。Next.js の App Router では、app/layout.tsx
ファイルがアプリケーション全体のレイアウトを定義します。
app/layout.tsx
import { BasicLayout } from "./_components/BasicLayout";
import { ConfigureAmplifyClientSide } from "./_components/ConfigureAmplify";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body
style={{ margin: 0, overflow: "hidden" }}
>
<ConfigureAmplifyClientSide />
<BasicLayout>{children}</BasicLayout>
</body>
</html>
);
}
ポイント
-
ConfigureAmplifyClientSide
コンポーネントを配置して Amplify を初期化 -
BasicLayout
コンポーネントでアプリケーション全体のレイアウトを適用
これで、アプリケーションの基本的な構造と機能が整いました。
アプリケーションの実行と動作確認
すべてのコンポーネントの実装が完了したら、アプリケーションを起動して動作確認を行います。
開発サーバーの起動
# ターミナル1: Amplify Sandboxの起動
$ npx ampx sandbox
# ターミナル2: Next.jsの開発サーバーを起動
$ npm run dev
アプリケーションの使用方法
- ブラウザで http://localhost:3000 にアクセス
- 認証画面が表示されるので、サインアップしてアカウントを作成
- ログイン後、チャット画面が表示される
- メッセージを入力して送信すると、AI アシスタントが応答
- 左側のナビゲーションから「History」をクリックすると、過去のチャット履歴を確認可能
- 履歴から特定のチャットをクリックすると、その会話を再開できる
まとめ
この記事では、AWS Amplify Gen2 と Next.js を使用して、AI チャットアプリケーションを構築する方法を詳しく解説しました。主なポイントは以下の通りです:
-
Amplify Gen2 の利点:
- TypeScript ベースのインフラストラクチャ定義
- 型安全性による開発効率の向上
- ローカル開発環境(サンドボックス)での迅速なテスト
-
Amplify AI Kit の特徴:
- 少ないコードで AI 機能を統合
- 事前構築された UI コンポーネントによる迅速な開発
- 認証と連携したユーザーごとのデータ管理
-
アプリケーションアーキテクチャ:
- コンポーネントの再利用による効率的な開発
- 認証フローの統合
- レスポンシブなレイアウト設計
システムの拡張性
このシステムは非常に拡張性が高く、様々な機能を追加できます。
一例として、Amplify AI Kit 解説:ゼロから作る Deep Search チャットアプリ という解説記事を用意しておりますので、よろしければご覧ください。
もし犬専用の音楽アプリ「オトとりっぷ」に興味を持っていただけたら、ぜひダウンロードしてみてください。
Discussion