RAGをゼロから構築する
私が最初に作ったAIは、私が油圧ショベルを販売していると言い出しました。私はショベルなんて売っていません。それは、さも当然のように、架空の価格と架空の説明文を提示してきました。
その瞬間、私はプロンプトだけを信じるのをやめました。私は一つのルールを掲げてシステムを再構築しました。「カタログに基づいて回答するか、さもなくば一切回答しないか」です。
PostgresとPythonを使用して、信頼性の高いRAG(検索拡張生成)システムを構築した方法を以下に紹介します。
データ準備 ほとんどのチュートリアルは、最も困難な部分である「データのクリーニング」を飛ばしてしまいます。私はプロセスを2つのステージに分けました。
- ステージ1:HTMLファイルをディスクにダウンロードする。メタデータは各ファイルの先頭にコメントとして保存します。これにより、プロセスが冪等(べきとう)になります。ファイルが既に存在する場合は、スキップします。
- ステージ2:それらのファイルをオフラインでパースする。これにより、HTMLがクリーンなJSONカタログに変換されます。
パース後にフィールドの網羅性をチェックします。重量や価格などのフィールドが空であれば、すぐに判明します。真の作業は、クリーンなデータを作ることにあります。
AI部分 各製品をテキストブロックに変換し、bge-m3モデルを使用してベクトルに変換します。これらのベクトルは、pgvector拡張機能を使用してPostgresに保存します。
製品を見つけるために、ハイブリッド検索アプローチを採用しています。
- セマンティック検索:ベクトルを使用して、質問の意味に一致する製品を見つけます。
- 構造化フィルタ:LLMを使用して、「2000ユーロ以下のシーメンス製モーター」といったクエリをJSONに変換します。これにより、ブランドや価格の正確なフィルタリングを用いたSQLクエリを実行できます。
1つのSQL文で、曖昧な検索(fuzzy search)と厳密なフィルタリングの両方を処理します。これにより、すべてが同期された状態に保たれます。
ガードレール 優れたRAGは、いつ黙るべきかを知っていなければなりません。ハルシネーション(幻覚)を防ぐために、2つのレイヤーを使用しています。
- 類似度しきい値:すべてのマッチングにスコアが付与されます。スコアが設定された制限を下回る場合、その結果は破棄されます。合格する結果が一つもない場合、システムはLLMを呼び出すことさえせず「見つかりません」と回答します。モデルにデータを見せなければ、ハルシネーションは起こり得ません。
- 厳格なシステムプロンプト:モデルに対し、提供された製品のみに基づいて回答するよう指示します。製品が関連していない場合は、回答を拒否しなければなりません。
しきい値は不適切な挙動を不可能にし、プロンプトは適切な挙動を促します。両方を使いましょう。
要約
- 注意深く収集する。
- 誠実にクリーニングする。
- シンプルに埋め込む。
- 設計段階から拒否を組み込む。
「拒否」することこそが、システムの信頼性を生みます。信頼は、モデルに「行儀よくして」と頼むことではなく、アーキテクチャから生まれるのです。
ソース: https://dev.to/utku_catal/building-a-rag-from-scratch-collect-clean-embed-refuse-20ob
オプションの学習コミュニティ: https://t.me/GyaanSetuAi