Amazon Web Services ブログ

AWS Amplify AI Kit と Neon Postgres を利用した RAG ベースアプリケーション構築

本記事は、2024 年 11 月 22 日に公開された Building RAG-based applications with AWS Amplify AI Kit and Neon Postgres を翻訳したものです。

現代のアプリケーション開発は、優れた開発体験 (DX) を提供するツールだけでなく、入門から本番環境への道のりの間の適切なバランスを含むようになりました。この考え方が、Amplify AI kit のリリースの背景にあります。大規模言語モデル (LLM) との対話やプロンプトからコンテンツを生成するなどの一般的な AI タスクを抽象化することで、開発者は市場投入までの時間を短縮し、ボイラープレートコードの作成を避けることができます。

この記事では、入門の段階を超えて、Amplify のデフォルトのデータベースモデルではなく、Neon からサーバーレス Postgres データベースを使用して製品データを取得します。そうすることで、検索拡張生成 (RAG) を使用して LLM と対話するために必要なコードを簡素化します。

アプリケーションの概要

アプリケーションの利用者にとって魅力的なのは、既存の製品と競合するのではなく、AI を活用して既存の製品を強化するためにどのように使用されるかです。それをわかりやすく説明するシンプルで効果的な方法は、顧客が対話できるチャットボットを作成することです。実際のシナリオでは、顧客が自分で買い物をするのを妨げることはありませんではなく、自然言語を使用して購入へ導くものです。

chat conversation showing conversation between llm and user.

アーキテクチャ的に言えば、ユーザーが当サイトを訪問するたびに、LLM 対応のボットとチャットできます。これらのモデルは一般的なデータで学習されていますが、製品情報も反映できることが望ましいです。製品情報はいつでも変更される可能性があるため、データベースにアクセスして最新情報を引き出すことが重要です。一般情報に加えて特定の情報にもアクセスできる機能を持つのが強力であり、Tools (「function-calling」とも呼ぶ) によってこの機能が実現されます。

diagram showing how a typical conversation wtih an llm interact

覚えておく必要がある重要な概念は、LLM がツールを使用することを選択した場合、ユーザーに代わってデータにアクセスするわけではないということです。LLM は単に、ユーザーのプロンプトに基づいて、最適なツールを伝えているだけです。その後、アプリケーションが呼び出す関数を決定します。

diagram flow of data being sent to an llm that responds with a tool

その関数からのレスポンスは、LLM に送り返され、エンドユーザーに対して自然な言語表現として整形されます。

想像できるように、このパターンを自分で調整するのは面倒なだけでなく、エラーにつながる可能性があります。幸いなことに、この複雑な作業は Amplify AI kit がデフォルトで行ってくれます。

具体的には、本プロジェクトでは Amazon Bedrock の Claude 3.5 Haiku を使用します。Amplify を使えば、データベースの 1 つに対応するツールを指定できます。本プロジェクトの場合、製品情報を含む Neon Postgres データベースが該当します。

Neon でサーバーレス Postgres データベースを作成

既存のデータソースに接続できることは、開発者がデフォルトのデータベースである Amazon DynamoDB 以外で、Amplify の Schema 自動生成機能を使って、デフォルトのデータベースである CRUD 操作を自動的に生成できることを意味します。 Neon データベースのセットアップは簡単です。アカウントを作成すると、プロジェクトの作成を求められます。

project creation in Neon

Neon は Git のようにブランチベースのプロジェクトをサポートしています。これらは main ブランチのコピーです。私の場合、dev/mtliendo という名前のブランチを作成するオプションがあります。これは推奨されますが、必須ではありません。いずれの場合も、ブランチの接続文字列は、次のセクションで必要になるのでコピーしておく必要があります。

screenshot of neon interface that shows a partially hidden connection string

デフォルトのデータベースは設定されましたが、まだテーブルは含まれていません。つまり、テーブルスキーマがまだ定義されていません。SQL を書く方法を知らない方は、がっかりするかもしれません。幸いにも、Neon の「Generate with AI」機能がこの問題を解決します。やりたいことを LLM に伝えると、レスポンスが生成されます。

SQL エディターで、次のように記述します。

Create a table schema called “Products”. Each product has a random id, an “updated at” field that is a date-time, a “created at” field that is a date-time, a “price in cents” field that is a number, a “name”, and a “description”.

screenshot of neon interface that displays the SQL Editor and using an LLM to generate a query

プロンプトを実行した後、次のレスポンスが表示されました。

CREATE TABLE Products (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
    price_in_cents INTEGER NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT 
);
SQL

その後、コードを変更してするオプションがあり、構文が問題なければコマンドを実行できます。

設定が期待どおりに行われたことを確認するには、サイドバーの「Tables」リンクをクリックすると、スキーマを確認できるほか、データを格納できます。

screenshot of Neon interface that allows records to be added

このプロジェクトでは、データベースにいくつかのアイテムを追加しました。また、次のセクションでデータベース接続文字列をコピーしておく必要があるので、忘れずにコピーしてください。接続文字列はサイドバーの「Overview」セクションにあります。

AI Kit による Amplify Gen 2 の強化

AWS Amplify は、フロントエンドアプリケーションを AWS で動作するバックエンドに接続する最も簡単な方法です。NextJS などの JavaScript フレームワークを使用したアプリがすでに作成されている場合は、プロジェクトのルートで次のコマンドを実行して初期ファイルを生成することができます。

npm create amplify 
Bash

これにより、Amplify の依存関係がインストールされ、amplify ディレクトリが作成されます。そのディレクトリのコードを変更する前に、Amplify AI kit に必要な他の依存関係をいくつかインストールします。

npm i @aws-amplify/ui-react @aws-amplify/ui-react-ai 
Bash

これらは、このあとすぐに利用する UI コンポーネントです。

まず、Amplify に products テーブルを含むデータベースを検査させ、バックエンドで利用できるようにします。最初のステップは、接続文字列を秘密鍵として保存することです。このシークレットは、AWS Systems Manager の Parameter Store に保存されます。幸いなことに、Amplify にはシンプルな方法が用意されています。

ターミナルで次のコマンドを実行してください。

npx ampx sandbox secret set SQL_CONNECTION_STRING 
Bash

これにより、SQL_CONNECTION_STRING という環境変数が設定され、その値の入力を求められます。そこで、Neon からコピーした接続文字列を貼り付けてください。そして、Enter キーを押してください。

この節では、ローカルマシンに AWS Amplify が既に設定済みであることを前提としています。Amplify の設定が必要な場合は、ドキュメントの手順を参照してください。

シークレットを保存したら、Amplify にデータベースの内部を調べさせて、フロントエンドアプリケーションで利用できる CRUD 操作を作成するよう指示できます。

npx ampx generate schema-from-database --connection-uri-secret SQL_CONNECTION_STRING --out amplify/data/schema.sql.ts 
Bash

このコマンドを実行すると、amplify/data フォルダに schema.sql.ts ファイルが作成されます。このファイルは Amplify によって管理されているため、修正しないでください。このコマンドを実行した後、ファイルの内容は次のスクリーンショットのようになります。

コードエディターのスクリーンショットで、スキーマ構成の例が表示されています

Amplify はこのファイルを使用して、Postgres データベースを a.model メソッドで機能する形式にマッピングします。

Amplify がこの機能をサポートするために裏で何をしているのかを知りたい場合は、ドキュメントを確認してください

import { type ClientSchema, defineData, a } from '@aws-amplify/backend'
import { schema as generatedSqlSchema } from './schema.sql'

const sqlSchema = generatedSqlSchema.setAuthorization((models) => [
    models.items.authorization((allow) => [allow.authenticated().to(['read'])]),
])
const schema = a.schema({
    chat: a
        .conversation({
            aiModel: a.ai.model('Claude 3.5 Haiku'),
            systemPrompt:
                'You are a helpful assistant, that focuses on selling and upselling merchandise',
            tools: [
                a.ai.dataTool({
                    name: 'MerchQuery',
                    description:
                        'Search for questions regarding merchandise, shopping apparel, and item prices.',
                    model: a.ref('items'), //! This refers to the name of our table
                    modelOperation: 'list',
                }),
            ],
        })
        .authorization((allow) => allow.owner()),
})

const combinedSchema = a.combine([sqlSchema, schema])

export type Schema = ClientSchema<typeof combinedSchema>

export const data = defineData({ schema: combinedSchema })
TypeScript

Neon データベースをアプリケーションに組み込んだので、amplify/data/resource.ts ファイルにインポートし、Amplify AI kit のチャットボット/対話エンジン機能と組み合わせることができます。このファイルで何が行われているかを説明します。

  • 4 行目: ここでは、Neon の products テーブルに対する認証ルールを割り当てています。この場合、サインインしたユーザーのみが read 操作を実行できます。
  • 8 行目: chatという識別子を作成しています。これは、最低限 LLM の名前とそのふるまいを指示するプロンプトを受け取る会話ボットです。モデル名は型付けされており、インテリセンスで利用可能であることに注意が必要です。
  • 13 行目: ツールを与えることでボットを強化しています。名前と説明は自分で定義できますが、model は Neon データベースの名前を参照する必要があります。現在サポートされている modelOperationlist のみです。
  • 22 行目: DynamoDB テーブルがサインインしたユーザーの会話履歴を追跡しています。

これらすべての要素を組み合わせることで、データベース内の項目を認識できる大規模言語モデルと安全に対話できる、フルマネージドなソリューションが実現します。

ソリューションをテストするために、次のコマンドを実行して AWS バックエンドをデプロイします。

npx ampx sandbox 

一度デプロイすると、Amplify の設定を読み込み、クライアントサイドアプリケーションに適用して、Amplify が提供する設定、UI コンポーネント、フックを利用することができます。

import { generateClient } from 'aws-amplify/api'
import { Schema } from '@/amplify/data/resource'
import { useEffect } from 'react'
import { Amplify } from 'aws-amplify'
import awsconfig from '@/amplify_outputs.json'
import { withAuthenticator } from '@aws-amplify/ui-react'
import { AIConversation, createAIHooks } from '@aws-amplify/ui-react-ai'
import '@aws-amplify/ui-react/styles.css'

Amplify.configure(awsconfig)

const client = generateClient<Schema>()
const { useAIConversation } = createAIHooks(client)
TypeScript

一度設定すれば、チャット、会話状況の認識、ストリーミング、ロード状態、認証を備えたフロントエンド全体を、約 20 行のコードで構築できます。

function Home() {
    const [
        {
            data: { messages },
            isLoading,
        },
        handleSendMessage,
    ] = useAIConversation('chat')

    return (
        <div className="flex justify-center items-center m-10 max-w-screen-md">
            <AIConversation
                avatars={{ user: { username: 'Focus Otter' } }}
                messages={messages}
                handleSendMessage={handleSendMessage}
                isLoading={isLoading}
                variant="bubble"
                welcomeMessage="Hello! I'm your helpful storefront assistant. Feel free to ask me questions about my merch!"
            />
        </div>
    )
}

export default withAuthenticator(Home)
TypeScript

上記のコードを、この投稿の最初のスクリーンショットと比較してみてください。Amplify AI kit の新しい AIConversation コンポーネントは、多様なプロパティを設定可能にしながら、フルチャット UI を提供します。これにより、特定のニーズに合わせてさらにカスタマイズできます。

まとめ

この投稿では、検索拡張生成(RAG)を使ってLLMとの会話をサポートするフルスタックアプリケーションを構築する際の複雑さについて説明しました。そして、AWS Amplify の新しい AI kit が、定型的な部分を抽象化することによって、この経験を大幅に簡素化し、開発者がアプリケーションを真に差別化する部分に集中できるようにする方法を見てきました。これまで見てきたように、セットアップが簡単だからといって拡張性が犠牲になることはありません。Neon から Postgres データベースを作成し、我々のツールと一緒に使うことでそれを証明しました。

Amplify AI kit は、スケーラブルでセキュアなフルスタック・アプリケーションを構築するための新たな一歩です。自身のアプリケーションで Amplify AI kit を使い始めるには、ドキュメントを参照して、今すぐ始めましょう。

翻訳は Solutions Architect の 吉村 が担当しました。