Amazon Bedrock RAGの「パフォーマンス」は、主に以下の3つの側面から成り立っています。これらをバランス良く、または目的に応じて重点的に改善していくことがチューニングの鍵となります。
- 回答精度 (Relevance/Accuracy): 最も重要な指標。質問に対して、いかに的確で正しい情報に基づいた回答を生成できるか。
- 応答速度 (Latency): 質問を投げてから回答が返ってくるまでの時間。ユーザー体験に直結します。
- コスト (Cost): 1回のクエリにかかる費用。特に大規模な利用では重要になります。
これらを踏まえ、RAGの処理フローである「① データ取り込み(チャンキング)」→「② 検索(Retrieval)」→「③ 回答生成(Generation)」の各段階で何をすべきかを解説します。
Part 1: 回答精度のチューニング(最優先事項)
回答精度が低い場合、その原因は「検索(②)」または「生成(③)」のいずれか、あるいは両方にあります。
A. データ取り込み・チャンキング戦略の見直し
検索精度は、元のデータをいかに適切に分割(チャンキング)するかに大きく依存します。
- チャンクサイズ (
maxTokens
) の調整:- 課題: 1つのチャンクが大きすぎると、無関係な情報が多く含まれ、LLMが混乱する原因になります。逆に小さすぎると、回答に必要な文脈が失われます。
- 対策: Bedrock Knowledge Base作成時の「Chunking strategy」で
maxTokens
を調整します。デフォルトは300ですが、ドキュメントの性質に合わせて200
〜500
程度の間で実験します。表形式のデータが多い場合は小さめ、長文の物語的なデータが多い場合は大きめに設定すると良い結果が得られることがあります。
- オーバーラップ (
overlapPercentage
) の調整:- 課題: チャンクの切れ目で重要な文章が分断され、文脈が失われることがあります。
- 対策:
overlapPercentage
(デフォルトは20%)を設定することで、チャンク間に重なりを持たせ、文脈の連続性を保ちます。10
〜25
%の範囲で調整し、精度が改善するか確認します。
- データの前処理(クリーニング):
- 課題: 元データに不要なヘッダー・フッター、ページ番号、無関係な画像の説明文などが含まれていると、検索ノイズになります。
- 対策: Knowledge Baseに取り込む前に、スクリプトなどで不要な部分を自動的に除去します。PDFからテキストを抽出する際の精度も重要で、表データが崩れていないかなどを確認し、必要であれば表をMarkdown形式に変換するなどの前処理を行います。
B. 検索(Retrieval)戦略の改善
適切なチャンクが検索結果の上位に返ってきているかを確認します。
- 検索結果数 (
numberOfResults
) の調整:- 課題: LLMに渡すチャンクの数が少なすぎると正解にたどり着けず、多すぎるとノイズが増えて精度が低下し、コストと遅延も増大します。
- 対策:
Retrieve
またはRetrieveAndGenerate
APIのパラメータnumberOfResults
を調整します。デフォルトは5ですが、まずは3
〜10
の範囲で試し、最適な数を見つけます。 - 確認方法:
Retrieve
APIを単体で実行し、特定の質問に対してどのようなチャンクが返ってくるかを確認します。意図したチャンクが上位に来ていなければ、データの前処理やチャンキング戦略に戻って見直します。
- Embeddingモデルの選択:
- 現状: 現在、Bedrock Knowledge Baseでは
Amazon Titan Embeddings G1 - Text
が主に使用されます。将来的に他のモデルが選択可能になった場合、ドキュメントの言語やドメインに合わせて最適なモデルを選択することが重要になります。
- 現状: 現在、Bedrock Knowledge Baseでは
C. 回答生成(Generation)の改善 – プロンプトエンジニアリング
検索はうまくいっていても、最終的な回答の質が低い場合は、LLMへの指示(プロンプト)に問題があります。
- プロンプトテンプレートの最適化:
- 課題: LLMが提供されたコンテキスト(検索されたチャンク)を無視してしまったり、情報を要約する際にハルシネーション(幻覚)を起こしたりすることがあります。
- 対策:
RetrieveAndGenerate
APIやAgentで利用するプロンプトテンプレートを工夫します。以下の指示を明確に含めることが非常に効果的です。- 役割の付与: 「あなたはこの分野の専門家です」
- 情報源の限定: 「提供された『コンテキスト』の情報のみを使用して回答してください」
- 不明時の対応: 「コンテキストに情報が見つからない場合は、憶測で答えず、『分かりません』と回答してください」
- 出力形式の指定: 「回答は簡潔に、箇条書きでまとめてください」
<role>あなたは製品マニュアルに精通したカスタマーサポートのエキスパートです。</role> <instructions> 以下の<コンテキスト>に記載されている情報のみを厳密に利用して、ユーザーからの質問に日本語で回答してください。 もし<コンテキスト>の中に回答に該当する情報が見つからない場合は、絶対に憶測で回答せず、「提供された情報の中には、ご質問に対する回答が見つかりませんでした。」と明確に答えてください。 </instructions> <context> {{$chunks}} </context> <question> {{$query}} </question>
<role>あなたは製品マニュアルに精通したカスタマーサポートのエキスパートです。</role>
<instructions> 以下の<コンテキスト>に記載されている情報のみを厳密に利用して、ユーザーからの質問に日本語で回答してください。もし<コンテキスト>の中に回答に該当する情報が見つからない場合は、絶対に憶測で回答せず、「提供された情報の中には、ご質問に対する回答が見つかりませんでした。」と明確に答えてください。 </instructions>
<context> {{$chunks}} </context>
<question> {{$query}} </question>
Part 2: 応答速度(Latency)のチューニング
- 生成モデル(LLM)の選択:
- 対策: より軽量で高速なモデルを選択します。例えば、
Anthropic Claude 3 Sonnet
よりもClaude 3 Haiku
の方が応答は高速です。精度とのトレードオフになりますが、チャットボットのように即時性が求められる場合はHaikuが有効です。
- 対策: より軽量で高速なモデルを選択します。例えば、
- 検索結果数 (
numberOfResults
) の削減:- 対策: Part 1-Bで述べた通り、LLMに渡すチャンクの数を減らせば、その分プロンプトが短くなり、生成速度が向上します。精度を維持できる範囲で最小の数に設定します。
- ストリーミング応答の活用:
- 対策:
RetrieveAndGenerate
やInvokeModel
APIでは、ストリーミング形式でレスポンスを受け取ることができます。これにより、全ての文章が生成されるのを待たずに、生成された部分から順次ユーザーに表示できるため、体感速度(Perceived Performance)が劇的に向上します。
- 対策:
Part 3: コストのチューニング
- 生成モデル(LLM)の選択:
- 対策: 応答速度と同様、
Claude 3 Haiku
のような軽量モデルは、Sonnet
のような高性能モデルに比べてトークンあたりの料金が安価です。タスクの要件を満たす最も安価なモデルを選択することがコスト削減の基本です。
- 対策: 応答速度と同様、
- 検索結果数とチャンクサイズの最適化:
- 対策: LLMに渡す
入力トークン数
がコストに直結します。numberOfResults
(検索結果数) ×maxTokens
(チャンクサイズ)がおおよその入力トークン数になるため、これらを精度要件を満たす範囲で最小限に抑えます。
- 対策: LLMに渡す
- プロンプトの簡潔化:
- 対策: プロンプトテンプレート自体もトークン数を消費します。指示は明確さを保ちつつ、できるだけ簡潔に記述することで、わずかですがコストを削減できます。
チューニングの実践ステップ(まとめ)
体系的にこれらの項目を一つずつ試していくことで、お使いのBedrock RAGアプリケーションのパフォーマンスを確実に向上させることができます。
- 目標設定: 今回のチューニングで最も優先するのは「精度」なのか、「速度」なのか、「コスト」なのかを明確にする。
- ベースライン測定: 現状の構成で、いくつかの代表的な質問に対する回答品質、応答時間、コストを記録しておく。
- 仮説と実行: 上記のチューニング項目から、目標に対して最も効果が高いと思われるものを一つ選択し、変更を加える。(例:「チャンクサイズを300から250に変更してみる」)
- 効果測定と比較: 変更後の構成で再度同じ質問を試し、ベースラインと比較してパフォーマンスが改善したか、あるいは悪化したか(トレードオフ)を確認する。
- 反復: 満足のいくパフォーマンスが得られるまで、このサイクルを繰り返す。
コメント