RAG データ パイプラインの品質を向上させる
この記事では、データ パイプラインの変更を実装する実践的な観点から、データ パイプラインの選択肢を試す方法について説明します。
データ パイプラインの主要なコンポーネント
非構造化データを含む RAG アプリケーションの基盤は、データ パイプラインです。 このパイプラインは、RAG アプリケーションが効果的に利用できる形式で、非構造化データを準備する役割を担います。 このデータ パイプラインは、任意に複雑になることがありますが、最初に RAG アプリケーションをビルドするときに考慮する必要がある、次の重要なコンポーネントがあります。
- コーパス コンポジション: 特定のユース ケースに基づいて、適切なデータ ソースとコンテンツを選択します。
- 解析: 適切な解析手法を使用して、生データから関連情報を抽出します。
- チャンクへの分割: 解析されたデータをより小さく管理しやすいチャンクに分割し、効率的に取得できるようにします。
- 埋め込み: チャンクされたテキスト データを、そのセマンティックな意味をキャプチャする数値ベクター表現に変換します。
コーパス コンポジション
RAG アプリケーションは、適切なデータ コーパスがないと、ユーザー クエリに応答するために必要な情報を取得できません。 適切なデータは、アプリケーションの特定の要件と目標によって大きく異なるため、使用可能なデータの微妙な違いを理解するための時間を設けることが重要です (これに関するガイダンスについては、「要件の収集」セクションを参照してください)。
たとえば、カスタマー サポート ボットを構築するときは、次の点を考慮する必要があります。
- ナレッジ ベース ドキュメント
- よく寄せられる質問 (FAQ)
- 製品マニュアルと仕様
- トラブルシューティング ガイド
すべてのプロジェクトで開始時からドメインの専門家や利害関係者と連携し、データ コーパスの品質と対象範囲を向上させる可能性がある関連コンテンツの特定とキュレーションを促進します。 これらの人々は、ユーザーが送信する可能性が高いクエリの種類に関する分析情報を提供でき、含める情報として最も重要なものへの優先順位付けをサポートできます。
解析
RAG アプリケーションのデータ ソースを特定したら、次の手順は、生データから必要な情報を抽出することです。 解析と呼ばれるこのプロセスでは、非構造化データを RAG アプリケーションで効果的に利用できる形式に変換します。
解析手法とツールに何を使用するかは、扱うデータの種類によって異なります。 次に例を示します。
- テキスト ドキュメント (PDF、Word ドキュメント): 非構造化と PyPDF2 などの既製のライブラリは、さまざまなファイル形式を処理し、解析プロセスをカスタマイズするための選択肢を提供できます。
- HTML ドキュメント: BeautifulSoup などの HTML 解析ライブラリを使用して、関連するコンテンツを Web ページから抽出できます。 これらを使用すると、HTML 構造内を移動し、特定の要素を選択し、目的のテキストまたは属性を抽出できます。
- 画像とスキャンされたドキュメント: 光学式文字認識 (OCR) 手法は、通常、画像からテキストを抽出するために必要になります。 人気がある OCR ライブラリには、Tesseract、Amazon Textract、Azure AI Vision OCR、Google Cloud Vision API などがあります。
データ解析のベスト プラクティス
データを解析するときは、次のベスト プラクティスを検討してください。
- データ クリーニング: 抽出されたテキストを前処理して、ヘッダー、フッター、特殊文字など、無関係な情報やノイズの多い情報を削除します。 RAG チェーンが処理する必要がある情報から、不要な情報や形式に誤りがある情報の量を減らす必要があります。
- エラーと例外の処理: 解析プロセス中に発生した問題を特定して解決するために、エラー処理とログ記録のための手段を実装します。 これにより、問題をすばやく特定して修正できます。 これを行うと、多くの場合に、ソース データの品質に関するアップストリームの問題が指摘されます。
- 解析ロジックのカスタマイズ: データの構造と形式によっては、解析ロジックをカスタマイズして、最も関連性の高い情報を抽出する必要がある場合があります。 この場合、事前に追加の作業が必要になることがありますが、これに時間を費やすと、ダウンストリームの品質問題が防げることがよくあります。
- 解析品質の評価: 出力のサンプルを手動で確認することで、解析されたデータの品質を定期的に評価します。 これは、解析プロセスの改善に関する問題や領域を特定するのに役立ちます。
チャンク
生データをより構造化された形式に解析した後は、次の手順は、チャンクと呼ばれるより小さい管理可能な単位にデータを分割することです。 大きなドキュメントを意味に集中した小さなチャンクに分割することで、取得したデータが LLM のコンテキストに収まり、文脈から逸脱した情報や無関係な情報が最小限に抑えられます。 チャンク分割に関して行われる選択は、LLM が提供する取得データに直接影響し、RAG アプリケーションの最適化の最初のレイヤーの 1 つになります。
データをチャンクに分割するときは、次の要因を考慮してください。
- チャンク戦略: 元のテキストをチャンクに分割するために使用する方法。 これには、文、段落、特定の文字またはトークンの数による分割などの基本的な手法から、より高度なドキュメント固有の分割戦略までが含まれる可能性があります。
- チャンク サイズ: チャンクを小さくすると、特定の詳細に集中できる可能性がありますが、ある程度の周辺情報が失われる可能性があります。 チャンクが大きいほど、より多くのコンテキストがキャプチャされる可能性がありますが、無関係な情報が含まれる可能性も高まります。
- チャンク間の重複: データのチャンクへの分割時に重要な情報が失われないようにするには、隣接するチャンク間に多少の重複を含めることを検討してください。 重複部分を設けることで、チャンク間での継続性とコンテキストの保持を確保できます。
- セマンティックの一貫性: 可能な場合は、意味的に一貫性のあるチャンクを作成することを目的とします。つまり、チャンクに関連情報が含まれており、意味のあるテキストの単位として、独自の意味付けを持つものにできます。 これは、段落、セクション、トピックの境界など、元のデータの構造を考慮することで実現できます。
- メタデータ: ソース ドキュメント名、セクション見出し、製品名など、各チャンク内に関連するメタデータを含めると、取得プロセスが向上する可能性があります。 チャンク内のこの追加情報は、チャンクに対する取得クエリとの照合に役立つ可能性があります。
データのチャンクへの分割戦略
適切なチャンクの分割方法を見つけるには、繰り返しとコンテキスト依存の両方が必要です。 何にでも対応できる方法はありません。最適なチャンク サイズと方法は、固有のユース ケースと、処理されるデータの性質によって異なります。 大まかに言えば、チャンク戦略は次のように検討できます。
- 固定サイズのチャンク分割: 固定の文字数やトークン数 (たとえば、LangChain CharacterTextSplitter) などの前もって定めたサイズのチャンクにテキストを分割します。 任意の数の文字またはトークンで分割する方法は、すばやく簡単に設定できますが、一般にこの方法は、意味的に一貫性を持つチャンクに分割される結果にはなりません。
- 段落ベースのチャンク分割: テキスト内の自然な段落境界を使用して、チャンクを定義します。 この方法は、段落に関連情報 (たとえば LangChain RecursiveCharacterTextSplitter) が含まれることが多いため、チャンクの意味上の一貫性を維持しやすくなります。
- 形式固有のチャンク分割: マークダウンや HTML などの形式には、チャンクの境界 (マークダウン ヘッダーなど) を明確にするために使用できる固有の構造があります。 LangChain の MarkdownHeaderTextSplitter や HTML ヘッダー/セクションベースのスプリッターなどのツールを使用できます。
- セマンティック チャンク分割: トピックのモデル化などの手法を適用すると、テキスト内の意味的に一貫性を持つセクションを識別できます。 これらの方法では、各ドキュメントのコンテンツまたは構造を分析し、トピック内のシフトに基づいて最も適切なチャンク境界を決定します。 セマンティック チャンク分割は、基本的な方法よりも複雑ですが、テキスト内の自然なセマンティック分割に適合するチャンクを作成できます (この例については、LangChain SemanticChunker を参照してください)。
例: 固定サイズのチャンク分割
LangChain の RecursiveCharacterTextSplitter を chunk_size=100
と chunk_overlap=20
と一緒に使用した固定サイズのチャンクの例。 ChunkViz は、Langchain の文字スプリッターが結果のチャンクに与える影響とのチャンク サイズとチャンクの重複値の差異の度合いを視覚化する対話的な方法を提供します。
埋め込みモデル
データをチャンクに分割した後は、次の手順は、埋め込みモデルを使用してテキスト チャンクをベクター表現に変換することです。 埋め込みモデルは、各テキスト チャンクをセマンティックな意味をキャプチャするベクター表現に変換するために使用されます。 埋め込みを使用すると、チャンクを密なベクターとして表すことで、取得クエリとのセマンティックな類似性に基づいて、最も関連性の高いチャンクを迅速かつ正確に取得できます。 取得クエリは、クエリ時にデータ パイプラインにチャンクを埋め込むために使用された埋め込みモデルと同じモデルを使用して変換されます。
埋め込みモデルを選択するときは、次の要因を考慮してください。
- モデルの選択: 各埋め込みモデルには微妙な違いがあり、使用可能なベンチマークによっては、データの特性の中にキャプチャされないものがある可能性があります。 既製の埋め込みモデルは、MTEB などの標準ランキングでランクが低いものであっても、さまざまなモデルを試します。 検討する例を次にいくつか示します。
- 最大トークン数: 選択した埋め込みモデルの最大トークン制限に注意してください。 この制限を超えるチャンクを渡すと、超えた分は切り捨てられ、重要な情報が失われる可能性があります。 たとえば、bge-large-en-v1.5 の最大トークン制限は 512 個です。
- モデル サイズ: 一般に、埋め込みモデルが大きいほど、パフォーマンスは向上しますが、より多くの計算リソースが必要になります。 自分の固有のユース ケースと使用可能なリソースに基づいて、パフォーマンスと効率のバランスを取ります。
- 微調整: RAG アプリケーションがドメイン固有の言葉 (社内の略語や用語など) を扱う場合は、ドメイン固有のデータに合わせて埋め込みモデルを微調整することを検討してください。 そうすることで、モデルが特定のドメインの微妙な意味や用語をより適切に捕捉でき、取得パフォーマンスが向上する可能性が高まることがよくあります。