【GenU】RAG 用 S3 のデータ管理 UI を作成する方法(Storage Browser for Amazon S3)

記事タイトルとURLをコピーする

こんにちは。 AWS CLI が好きな福島です。

はじめに

今回は、GenU におけるRAG 用 S3 のデータ管理 UI を作成する機会があったため、ご紹介します。

余談ですが、GitHub で要望を上げている方がいるため、GenU にも標準で組み込まれるといいですね。

github.com

GenU とは

Generative AI Use Cases JP (略称:GenU)と呼ばれており、AWS が提供しているサンプルの生成 AI アプリになります。

github.com

前提

  • GenU のデプロイが完了していること
  • KnowledeBase の RAG オプションを有効化していること

概要図

概要図は以下の通りです。 GenU で構築される Cognito と RAG 用の S3 は利用するのですが、UI は GenU と別に作成します。

これは今回実装するような機能が GenU に標準で実装された際に切り離しやすいと考えたためです。

また、ソースコード管理には、GitHub など契約していないケースを考え、S3 を利用します。

作業の流れ

  • S3 にソースコードをアップロード
  • Amplify を活用したデプロイ
  • RAG 用 S3 に CORS の設定
  • Cognito の認証許可時に渡される IAM ロールの更新

S3 にソースコードをアップロード

  • サンプルコードを Clone
git clone git@github.com:kazuya9831/blog-sample.git

上記リポジトリのコードは、以下のサンプルコードを基に作成しました。

github.com

  • ソースコード管理用の S3 バケットの作成
aws s3api create-bucket \
   --bucket sample-amplify-storage-browser-$(aws sts get-caller-identity --query "Account" --output text) \
   --create-bucket-configuration LocationConstraint=ap-northeast-1
  • ディレクトリの移動
cd blog-sample/genu-storage-browser-for-s3/
  • モジュールのインストール
npm ci
  • .env の作成
./scripts/generate-env.sh
  • ソースコードのビルド
npm run build
  • ビルド成果物の zip 化
cd dist
zip -r storage-browse-for-genu.zip ./
  • ビルド成果物を S3 にアップロード
aws s3 cp \
   storage-browse-for-genu.zip \
   s3://sample-amplify-storage-browser-$(aws sts get-caller-identity --query "Account" --output text)

Amplify を活用したデプロイ

  • Amplify のコンソールに移動し、新しいアプリを作成を押下

  • 「Git なしでデプロイ」にチェックをつけ、「次へ」を押下

  • 「アプリケーションの名前」、「ブランチ名」を任意で付ける

  • 「Amazon S3」 にチェックをつけ、コードをアップロードした S3 のパスを指定
  • 「保存してデプロイ」を押下

  • デプロイが完了後、表示されているドメインにアクセス

  • ログイン後、以下の画面が表示されますが、docs を押下すると...

  • 「Network Error」になります
  • 開発者ツールから詳細なエラーを確認できますが、原因は S3 に CORS の設定をしていないためです

RAG 用 S3 に CORS の設定

  • GenU の RAG で利用している S3 の CORS 設定画面の URL 確認
    • 以下のコマンドを全行一気に実行すると、URL が表示されます
MAIN_REGION="ap-northeast-1"
MAIN_STACK_NAME="GenerativeAiUseCasesStack"
RAG_STACK_NAME="RagKnowledgeBaseStack"

RAG_REGION=$(aws cloudformation describe-stacks \
    --stack-name "${MAIN_STACK_NAME}" \
    --query "Stacks[].Outputs[?OutputKey=='ModelRegion'].[OutputValue]" \
    --output text \
    --region ${MAIN_REGION}
)

KNOWLEDGE_BASE_ID=$(aws cloudformation describe-stack-resources \
    --stack-name ${RAG_STACK_NAME} \
    --logical-resource-id KnowledgeBase \
    --query "StackResources[].PhysicalResourceId" \
    --output text \
    --region "${RAG_REGION}"
)

DATA_SOURCE_ID=$(aws bedrock-agent list-data-sources \
    --knowledge-base-id "${KNOWLEDGE_BASE_ID}" \
    --query "dataSourceSummaries[].dataSourceId" \
    --output text \
    --region "${RAG_REGION}"
)

STORAGE_BUCKET_NAME=$(aws bedrock-agent get-data-source \
    --data-source-id "${DATA_SOURCE_ID}" \
    --knowledge-base-id "${KNOWLEDGE_BASE_ID}" \
    --query "dataSource.dataSourceConfiguration.s3Configuration.bucketArn" \
    --output text \
    --region "${RAG_REGION}" \
    | awk -F: '{print $NF}'
)

echo "https://${RAG_REGION}.console.aws.amazon.com/s3/buckets/${STORAGE_BUCKET_NAME}?region=${RAG_REGION}&bucketType=general&tab=permissions"
  • URL にアクセス後、1番下に CORS 設定があります

  • CORS の設定を追加します

[
    {
        "ID": "S3CORSRuleId1",
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "HEAD",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "last-modified",
            "content-type",
            "content-length",
            "etag",
            "x-amz-version-id",
            "x-amz-request-id",
            "x-amz-id-2",
            "x-amz-cf-id",
            "x-amz-storage-class",
            "date",
            "access-control-expose-headers"
        ],
        "MaxAgeSeconds": 3000
    }
]

参考: Storage Browser for Amazon S3 | Amplify UI for React

  • 再度、Web アプリにアクセスすると次は以下のエラーが出ます。

これは、Cognito の認証許可時に渡される IAM ロールの権限不足になります。

Cognito の認証許可時に渡される IAM ロールの更新

  • Cognito の認証許可時に渡される IAM ロールの URL 確認
MAIN_REGION="ap-northeast-1"
MAIN_STACK_NAME="GenerativeAiUseCasesStack"

ID_POOL_ID=$(aws cloudformation describe-stacks \
--stack-name "GenerativeAiUseCasesStack" \
--query "Stacks[].Outputs[?OutputKey=='IdPoolId'].[OutputValue]" \
--output text \
--region ${MAIN_REGION})

AUTH_IAM_ROLE=$(aws cognito-identity \
get-identity-pool-roles \
--identity-pool-id ${ID_POOL_ID} \
--query "Roles.authenticated" \
--output text \
--region ${MAIN_REGION} \
| cut -d/ -f 2)

echo "https://us-east-1.console.aws.amazon.com/iam/home?region=us-east-1#/roles/details/${AUTH_IAM_ROLE}?section=permissions"
  • URL にアクセス後、インラインポリシーを追加

  • 以下のポリシーを追加

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::【S3バケット名】",
                "arn:aws:s3:::【S3バケット名】/*"
            ]
        }
    ]
}

※【S3バケット名】は変数が残っていれば以下で確認できます。

echo ${STORAGE_BUCKET_NAME}
  • ポリシー名を任意でつけ、ポリシーを作成します。

  • 再度、Web アプリにアクセスすると、正しく表示されます
  • これで GenU の RAG 用 S3 のデータをアップロード、削除することができます。

補足) KnowledeBase の同期

RAG のデータソースとして利用するためには、GenU の RAG 用 S3 のデータをアップロード後、KnowledeBase にて同期処理が必要になります。 参考の CFn テンプレートを用意しているため、デプロイ方法をご紹介します。 実装方法は簡単で、EventBridge Schedule を活用しています。

https://github.com/kazuya9831/blog-sample/blob/main/genu-storage-browser-for-s3/cfn-templates/BedrockIngestion.yml

  • 変数の設定
MAIN_REGION="ap-northeast-1"
MAIN_STACK_NAME="GenerativeAiUseCasesStack"
RAG_STACK_NAME="RagKnowledgeBaseStack"

RAG_REGION=$(aws cloudformation describe-stacks \
    --stack-name "${MAIN_STACK_NAME}" \
    --query "Stacks[].Outputs[?OutputKey=='ModelRegion'].[OutputValue]" \
    --output text \
    --region ${MAIN_REGION}
)

KNOWLEDGE_BASE_ID=$(aws cloudformation describe-stack-resources \
    --stack-name ${RAG_STACK_NAME} \
    --logical-resource-id KnowledgeBase \
    --query "StackResources[].PhysicalResourceId" \
    --output text \
    --region "${RAG_REGION}"
)

DATA_SOURCE_ID=$(aws bedrock-agent list-data-sources \
    --knowledge-base-id "${KNOWLEDGE_BASE_ID}" \
    --query "dataSourceSummaries[].dataSourceId" \
    --output text \
    --region "${RAG_REGION}"
)
  • blog-sample/genu-storage-browser-for-s3 配下で以下を実行
  • 以下では、9時、13時、17時に同期処理を実行するよう設定しています。
aws cloudformation create-stack \
   --stack-name BedrockIngestion \
   --template-body file://cfn-templates/BedrockIngestion.yml \
   --parameters \
      "ParameterKey=DataSourceId,ParameterValue=${DATA_SOURCE_ID}" \
      "ParameterKey=KnowledgeBaseId,ParameterValue=${KNOWLEDGE_BASE_ID}" \
      "ParameterKey=ScheduleExpression,ParameterValue='cron(0 9,13,17 * * ? *)'" \
   --capabilities CAPABILITY_IAM \
   --region ${RAG_REGION}

終わりに

今回は、GenU におけるRAG 用 S3 のデータ管理 UI を作成する方法をご紹介しました。 どなたかのお役に立てれば幸いです。

福島 和弥 (記事一覧)

2019/10 入社

AWS CLIが好きです。