RAGインフラに500ドル費やして学んだ、7つの失敗
プライベートドキュメント検索用のRAGパイプラインを構築しました。計算コストに500ドル、デバッグに数週間を費やしましたが、結果は散々なものでした。ユーザーには無関係な回答が返され、クエリの応答も遅かったのです。
パイプラインを監査したところ、7つのよくある間違いが見つかりました。これらを修正したことで、すべてが変わりました。
- 固定トークン数によるチャンク分割 ドキュメントを固定のトークン数で分割していました。これにより文脈が破壊されてしまいました。文章が途中で切れてしまい、LLMは断片的なデータを受け取ることになり、回答の精度が低下しました。
- 修正策: parent-document retrieval(親ドキュメント検索)を用いたセマンティック・チャンキング(semantic chunking)を使用する。
- 段落や見出しなどの自然な境界で分割する。
- 検索用に小さな子チャンク(child chunks)を作成する。
- マッチした場合は、LLMに親ドキュメント全体を返す。
- チャンク間に10〜20%のオーバーラップ(重複)を持たせる。
- デフォルトの検索ウェイト ベクトル検索とキーワード検索の比率を50/50にしていました。技術文書の場合、正確なキーワードの方が重要です。
- 修正策: 動的なウェイトを使用する。
- 事実に関するクエリ: ベクトル 35%、キーワード 65%。
- セマンティックなクエリ: ベクトル 75%、キーワード 25%。
- HNSWパラメータの過剰な最適化
ef_constructionを最大値に設定していました。大規模なインデックスでは、これによりサーバーがクラッシュし、RAMを使い果たしてしまいました。
- 修正策: 適切なHNSW設定を使用する。
Mは 8 から 32 の間に保つ。ef_constructionを 200 に設定する。ef_searchを 50 に設定する。
- 不適切な埋め込み(Embedding)モデル ウェブテキストで学習された汎用モデルを使用していました。そのため、私の技術的なエンジニアリング文書を理解できませんでした。
- 修正策: 技術文書やコードの内容に特化して微調整(fine-tuned)されたモデルに切り替える。
- 自然言語のミスマッチ ユーザーは「なぜビルドが遅いのか」といった質問をしますが、ドキュメントには「CIパイプラインの最適化」といった用語が使われています。両者の間に共通点が全くありませんでした。
- 修正策: LLMによるクエリ書き換え(query rewrite)ステップを追加する。
- 検索を行う前に、ユーザーのクエリを技術用語に書き換える。
- 重複するコンテキスト 上位10個のチャンクを取得すると、同じ段落が3回も出てくることがよくありました。これがハルシネーション(幻覚)の原因となっていました。
- 修正策: Maximal Marginal Relevance (MMR) を使用して、結果の多様性を確保する。
- エンドツーエンドの評価のみ 最終的な回答のみを確認していました。問題が検索(retrieval)にあるのか、LLMにあるのかが分かりませんでした。
- 修正策: 検索を個別に評価する。
- ヒット率(hit rate)と平均逆順位(Mean Reciprocal Rank: MRR)を追跡する。
- 100個のクエリとドキュメントのペアからなるテストセットを作成する。
修正後の結果: • 回答の関連性: 45% から 85% • クエリのレイテンシ: 3.2秒 から 1.8秒 • 月額コスト: $180 から $95
まずはチャンキングの修正から。次に重み。そして埋め込みの品質。
RAGで最も頭を悩ませていることは何ですか?コメント欄で教えてください。
学習コミュニティ(任意): https://t.me/GyaanSetuAi