[開発者プレビュー]Amplify AI をためしてみた

:::note warn 
注意
こちらの記事はプレビュー時の記事です。GAの記事は下記のとおりです。
:::

https://qiita.com/MK_Tech/items/c407664631ebf09b0251

https://qiita.com/MK_Tech/items/008451a6c4dd95ad370f

## はじめに
Ampify UIのGitリポジトリにてRFC中のAmplify AIが気になったのでためしてみました。

https://github.com/aws-amplify/amplify-ui/issues/5773

:::note alert
注意
2024年9月28日現在、開発者プレビュー段階にあります。一般公開で重大な変更が加えられる可能性があります。利用の際は要注意です。
:::

## Amplify AIとは
Amplify Gen2でバックエンド、クライアントライブラリ、UIコンポーネントが提供されており、爆速でAI Chatアプリを開発できるもの。

バックエンドはAmplify Backendが[L3コンストラクト](https://github.com/aws-amplify/amplify-backend/blob/main/packages/ai-constructs/README.md)を提供しているようで、フロントはAmplify UIが提供しておりカスタマイズも可能。

AIルートというアイデアが導入されていて、ルートとはAIと対話するためのエンドポイントのようなもので、開発者プレビューでは以下の2種類のルートに焦点を当てている。


### 1. Conversation
会話用のAPIが提供される。非同期のマルチターン API。

### 2. Generation
生成のためのAPIが提供される。同期リクエスト応答 API。

## ためしかた
今回はConversationを使用してChatのUIを作成しようと思います。

手順はざっと下記のような感じです。
1. Bedrockのモデルへのアクセス
2. Amplifyのセットアップ
3. Amplify UIのインストール
4. バックエンドの定義
5. フロントエンドの定義

### 1.  Bedrockのモデルへのアクセス
事前準備としてはBedrockのモデルにアクセスできるようしておきましょう。

https://console.aws.amazon.com/bedrock/home#/modelaccess
### 2. Amplify（React）のセットアップ

Amplify UIはReactコンポーネントを使用するので下記のスターターからセットアップします。
https://docs.amplify.aws/react/start/quickstart/ 

### 3. ライブラリのインストール
BedrockとUIコンポーネントをインストール
#### Bedrock
```sh bedrock
npm i -D @aws-sdk/client-bedrock-runtime
```
#### UI
```sh
npm i @aws-amplify/ui-react-ai
```

### 4. バックエンド設定
Amplify Dataリソースにa.conversationを追加します。
```typescript
// amplify/data/resource.ts
const schema = a.schema({
  chat: a.conversation({
    aiModel: a.ai.model("Claude 3 Haiku"),
    systemPrompt: `You are a helpful assistant`,

    inferenceConfiguration: {
      maxTokens: 1000,
      temperature: 1,
      topP: 0.5,
    },
  }),
```
たったこれだけでCloude 3 Haikuを利用するAppSyncがされます。

### 5. フロントエンド設定
React UIのコンポーネントを使用する定義を行います。


```tsx
import { generateClient } from "aws-amplify/data";
import { createAIHooks, AIConversation } from "@aws-amplify/ui-react-ai";
import type { Schema } from "../amplify/data/resource";

const client = generateClient<Schema>({ authMode: "userPool" });
const { useAIConversation } = createAIHooks(client);

export function App() {
  const [
    {
      data: { messages },
    },
    sendMessage,
  ] = useAIConversation("chat");


  return (
    <AIConversation
      messages={messages}
      handleSendMessage={(context) =>
        sendMessage({
          ...context,
        })
      }
    />
  );
}

export default App;
```
AIConversationとuseAIHooksというHooksが準備されているので、そちらを利用してバックエンドとフロントエンドを繋げるようですね。

たったこれだけで対話インターフェースの完成です。

あとは下記のコマンドを実行するのみ。
```sh
// sandboxの作成
npx ampx sandbox 
// ローカル開発環境
npm run dev
```


## 完成品
こんな感じのUIができました。ちゃんと対話もできます。

![amplify-ai-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/903de67a-874e-1c5a-4680-e1f5f58ba99f.png)

ページ下部に入力インターフェースがあり、会話履歴が上部に表示されます。

## カスタマイズ
AIConversationのporpを調整することでUIをカスタマイズできます。

```tsx
return (
    <AIConversation
      messages={messages}
      handleSendMessage={(context) =>
        sendMessage({
          ...context,
        })
      }
      isLoading={isLoading}
      
      avatars={{
        user: {
          username: "masachika",
          avatar: "☺️",
        },
        ai: {
          username: "Haiku",
          avatar: "🤖",
        },
      }}
    />
  );

```
![amplify-ai-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/395139ac-2eae-6b44-35d7-f425ae015662.png)

アバターが変更されました。左の添付マークを触ると画像も渡せるので、マルチモーダルにも対応してますね。

![amplify-ai-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/a04bf21b-764e-8a60-9369-41476da11f1c.png)

会話もできています。

propsにvariantを指定するとLine風なUIに変更すること
もできます。文字の色や背景を調整することも可能です。

![amplify-ai-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/6856206e-2ca8-101c-5b89-f9d0646b7bfd.png)

### tools
なんとAIがfunctionを実行するようにできるようです。
今回はwebのURLを指定すると要約するfunctionsを追加してみます。

```typescript
const schema = a.schema({
  chat: a.conversation({
    aiModel: a.ai.model("Claude 3 Haiku"),
    systemPrompt: `You are a helpful assistant`,
    // all inference configuration is optional,
    // if it is not provided it will use the Bedrock defaults
    tools: [
      {
        query: a.ref("webLoader"),
        description: "Returns the content of a web page from a url.",
      },
    ],
    inferenceConfiguration: {
      maxTokens: 1000,
      temperature: 1,
      topP: 0.5,
    },
  }),

  webLoader: a
    .query()
    .arguments({ url: a.string() })
    .returns(a.string())
    .handler(a.handler.function(webLoader))
    .authorization((allow) => allow.authenticated()),

});
```
toolsに利用したいfunctionsを指定するだけです。複数のtoolsを使用することもできます。

### iPhone16のページを要約させてみた
最近のWebページを要約させてみた。

![amplify-ai-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/21614073-9b3c-e363-cce2-3a3f40eb8076.png)

ちゃんとfuncitonsを使えてますね。

![amplify-ai-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831737/223fd0da-c861-8bb0-d1a1-2988131a0061.png)

長かったので要約してもらいました。会話も成り立っています。

### まとめ
Amplify AIを使うと簡単にChat UIを作成できました。L3コンストラクトのおかげで、バックエンドを意識せずAI Chatが利用できます🚀
toolsまで利用できるのは驚きました😱

AmplifyGen2の良さであるTypescriptによるDX向上が体験できるよい機能だと思います。
この機能で生成AIがさらに身近に感じされるのではないでしょうか？
個人的には[Streamlit](https://streamlit.io/)みたいなAmplifyほしかったので今後のアップデート、GAに期待です😁