はじめに
近年、生成系AI(Generative AI)や大規模言語モデル(LLM: Large Language Models)の活用が急速に進んでおり、様々なタスクでの有用性が注目されています。しかし、LLMは常に最新情報を持っているわけではなく、特に特定の企業内情報や最新のドキュメントに対する応答生成には限界があります。そこで注目されているのが、RAG(Retrieval-Augmented Generation, 検索拡張生成)と呼ばれる手法です。
RAGでは、テキスト生成をプライベートデータソースまたは独自のデータソースからの情報で補完して行います。
今回はRAGに関しては初心者の私が実装の際に参考としたサイトをまとめ、実装後の所感や最初から知っていれば良かったと感じた内容をまとめます。
※具体的なコードについて、基本的に本記事では記載しません。
前提事項について
1. LLMに入れるデータは学習に利用されないか
RAGは外部情報(独自データ)をLLMの入力とするため、個人的に最も気になっていた点でした。
こちらの点については、AWSのBedrockを利用した場合は、以下の記事の通りデータがモデルプロバイダーと共有されたり、ベースモデルの改善に使用されたりすることはないようです。そのため、安心してデータを投入できます。
参考動画として記載したURLの後半でも詳しく説明されています。
★参考ページ
★参考動画
Anthropic Claude や Meta Llama を AWS で活用!本番環境で Amazon Bedrock をセキュアに利用する生成 AI 事例3選!
(Amazon Web Services Japan 公式 Youtube)
2. Kendra×Bedrock と Bedrock ナレッジベースの違い
AWSサービスを利用したRAG事例について調べると、大きくAmazon Kendra + Amazon Bedrockの組み合わせによる実装と、Amazon Bedrockのナレッジベース機能を利用した実装の二通りが見受けられます。
これらの違いは何か、どちらを使えば良いのか当初の私は疑問に感じていました。
結論としては、どちらが良いとは一概には言えず、それぞれのサービスの違いを理解した上で目的に応じて検討する必要があります。
Kendraはフルマネージドで良い感じの検索システムを、様々なデータソースからインポートして比較的容易に構築できる点に良さがあります。一方で、Kendraの内部的な仕組みはブラックボックスとなっている部分が多く、チューニングの難易度が高い(検索精度改善のためのチューニング余地としては多くない)です。良くも悪くもマネージドなサービスのため、内部的なベクトルストアの話やチャンク化やインデックスの仕組みについても公式ドキュメントやその他の資料からは分からないです。
Bedrock のナレッジベース機能の利用について、私自身はまだ試せていないですが、比較するとKendraよりは安価に環境を構築できる点や、チャンキング戦略を工夫出来る点が特徴として挙げられるようです。細かくチューニングしたい場合はBedrockのナレッジベースを利用するのも一つの方法と思います。
★参考ページ
① Amazon Bedrock を使ってRAGを実装する際の技術選定
② Comparison of RAG Implementations on AWS: Bedrock Knowledge Bases vs. Amazon Kendra with Detailed Step-by-Step Implementations and Guidance
3. KendraとBedrockの料金体系
Kendraについては、インデックスを作成する際にDeveloper Edition と Enterpise Editionの二つからどちらかを選択します。今回は目的が技術検証のためDeveloper Editionを選択しましたが、Developer Editionでもインデックスを作成したタイミングから1時間当たり1.125 USDがインデックス毎にかかるため注意が必要です。1か月を30日とすると、1.125USD/h × 24h/day × 30day = 810USD かかる計算となります。また、インデックスにドキュメントを登録する際にコネクタを利用しますが、このドキュメント数とコネクタの利用時間ごとにも課金が発生します。
詳細は公式のドキュメント等を参照下さい。
※Kendraの料金
https://docs.aws.amazon.com/ja_jp/whitepapers/latest/how-aws-pricing-works/amazon-kendra.html
https://aws.amazon.com/jp/kendra/pricing/
Bedrockについては、モデルの種類ごとにベースとなる値段が異なります。ベースとなる値段は、一回の問合せでの入力トークン数と出力トークン数に応じて決まります。モデルの中ではClaude 3 Haiku が高速かつ利用料金も低額なため、まず使ってみたいという方にお勧めです。
※Bedrockの料金
https://aws.amazon.com/jp/bedrock/pricing/
今回実装したアーキテクチャ
今回、以下のような一般的な構成でRAGを実装しました。
具体的な環境構築作業内容と参考サイト
環境構築作業の全体で参考とさせていただいた記事は以下の通りです。
本稿では実際の作業内容(作成したコード、作業画面のスクショ等)は記載しませんが、以下の内容に沿って記事を参考に作業を進めることで環境構築が出来ました。
- 全体像の把握
参考1: https://dev.classmethod.jp/articles/amazon-bedrock-kendra-lambda-rag/ - Bedrock 基盤モデルの利用申請・有効化
参考1: https://qiita.com/icoxfog417/items/869e2093e672b2b8a139 - S3バケットの作成・データ用意
参考1: https://qiita.com/sugimount-a/items/e61343561e5800fb5e49 - Kendraのインデックス作成
参考1: https://qiita.com/is_zeal/items/fdc976de108c369f7f56
参考2: https://qiita.com/tatsuki-tsuchiyama/items/0a48cede46a35c4f4f78 - Lambdaの作成①Bedrockとの疎通
参考1: https://qiita.com/nabata/items/5bcc3beb76182f626040 - Lambdaの作成②Kendraとの疎通
参考1: https://dev.classmethod.jp/articles/kendra-lambda-retrieval/ - REST APIの作成
参考1: https://techblog.cartaholdings.co.jp/entry/archives/1399
参考2: https://dev.classmethod.jp/articles/api-gateway/
参考3: https://qiita.com/yuyakato/items/89fcef9746afbf48977a - Lambdaの作成③RAGのプロンプト作り込み
参考1: https://dev.classmethod.jp/articles/amazon-bedrock-kendra-lambda-rag/
参考2: https://qiita.com/kiiwami/items/4a62a3dcbedeb141e605
環境構築をした所感
〇作業コストについて
全体の作業コストの目安として、上記記事を調べつつ丁寧に証跡を残しながら作業をして1~2日ほどで環境については構築が完了出来ました。その後、RAGのプロンプトの作り込みで大きく返戻が変わるため、その調整(Lambdaのコードの修正)は気のすむまで(継続的に)作業することになるかと思います。
〇Bedrockについて
Bedrockについて、デフォルトではベースモデルへのアクセスのステータスが"リクエスト可能"(=利用できない状態)となっているため、許可申請が必要でした。申請自体は無料なため、今回は利用可能な全てのモデルを対象にアクセス許可の申請を行いました。その際、Amazonの基盤モデルであるTitan等は即時付与されましたが、Claudeについては10~15分後に有効化されたため、アクティベートに要する時間はさほど長くなかった印象です。
※Bedrockのベースモデル(東京リージョン, 2024年10月時点)
※リージョン別のモデルサポート
https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/models-regions.html
〇Kendraについて
今回、S3から約6000ドキュメントをインデックスしました。
空インデックスの作成には15~30分ほどかかり、その後、作成したインデックスへのドキュメントのインデクシングが15~30分ほどで完了しました。この所用時間はファイルの内容によって変わるかと思いますが、軽いファイルであればさほど長い時間はかからないと思われます。インデックスへのドキュメント登録の際にはS3側のポリシーでKendraのアクセスを許可する設定を適切に追加する必要があり、こういったロールの扱いになれていない方は初回のインデックス作成時にやや手こずるかなといった印象です。まずは少ないファイル数を登録し、その後対象ファイルを増やすといった進め方がおすすめです。
※S3バケットポリシー例 (ロールARNを指定する場合)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowKendraDataSourceRoleAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<アカウントID>:role/service-role/<ロール名>"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<バケット名>/*"
}
]
}
まとめ
KendraとBedrock(とS3, Lambda, API Gateway)を利用することで、RAGに関する知識ゼロの状態からネット上の記事のみを参考にRAGを容易に実装することが出来ました。今回検証を進める中で、回答の精度や質についてはClaude等のLLMに渡すプロンプトの書き方によって大きく変わると感じたため、環境構築に要する工数を抑え、プロンプトエンジニアリングの作業に工数を分配できる点もこのアーキテクチャのメリットと思いました。
また、Kendraの検索結果の精度が回答生成の質を大きく左右する(=KendraのAPIの返戻に、求めるパッセージが含まれているかどうかで回答の質が大きく変わる)と感じました。一方で、Kendraの検索のチューニングについてはあまり自由度が高くないように感じられました。検索結果の精度を上げるため、Kendra側でチューニングをする以外の方法として、Advanced RAGの一手法であるクエリ拡張についても今後試してみようと考えています。
RAGに関して参考とした記事・サイト
RAG実装の前段として、知識ゼロ状態から脱却し、概要を理解するための参考としたサイトについて改めて以下に記載します。
本稿に記載したすべての記事とそれらを作成された方々に感謝申し上げます。
RAGの概念と研究動向について
以下のQiita記事でRAGの概要や研究動向が日本語でまとめられています。
元の論文についても記載されているため、気になった点は元論文を確認出来ます。
※ サーベイ論文
https://arxiv.org/abs/2312.10997v5
一般的なRAGの利点や課題について
RAGのメリットやデメリットについて記載があります。