こんにちは、AI製品開発グループのファイサルです。
この記事では、Know Narrator Searchで使用されている文章参照手法、Retrieval-Augmented Generation(RAG)の精度向上方法について紹介します。
はじめに
ChatGPTを始めとした大規模言語モデル(LLM)の登場により、AI業界、特に自然言語処理分野で多くの素晴らしい応用先が提案されるようになりました。 LLMは素晴らしい技術であることは間違いないですが、同時に幻覚(Hallucination)という問題を抱えています。
このHallucinationという問題は、LLMが事実と異なる情報をあたかも真実であるように回答するというもので、LLMの発表当初から指摘されていました。
この問題を解決するために、さまざまな手法が存在しますが、よく用いられるのが「Retrieval-Augmented Generation(RAG)」です。 RAGでは、ユーザーの質問文に関連するドキュメントを検索し、その検索結果をLLMのプロンプト(LLMへの指示文)に追加します。LLMはドキュメントに含まれる正しい情報を参照し回答を生成することでHallucinationを防止することができます。
現在、LangChainやLlamaIndexなどのフレームワークのチュートリアルに従うことで、シンプルなRAGシステムを構築できます。 ただし、これらの仕組みで構築されたシステムは、必ずしも効果的に動作するわけではありません。 RAGのプロトタイプを作成するのは容易ですが、実際の運用環境に適用するのは非常に難しいのです。 基本的にチュートリアル通りに進めれば、RAGにより、LLMに70%の精度で正しい回答を生成させることができるかもしれませんが、残りの30%(エッジケース)で正確な回答するには、継続的な実験が必要です。ベストプラクティスはまだ確立されておらず、ユースケースによって改善策は異なる可能性があります。
この記事では、RAGの精度を実際の運用に適したレベルに向上させるための方法を簡単に紹介します。精度向上には主に2つの目標があります。
- 関連する参考文書の取得の向上
- 生成される回答の品質向上
これらの2つの目標を達成するために、10個ほどのアプローチを紹介します。
RAGについてはこちらの記事でもご紹介しています。
Tips 0.5: 検索の性能の評価
RAGの精度は主に検索の精度に左右されます。そのため、精度を向上させる前に、まず検索の性能を評価する仕組みを用意する必要があります。
評価データセットの作成
検索のための評価データセットは、以下の要素から構成されています。
- 代表的なクエリのリスト
- 検索対象の文書のリスト
- クエリと文書の関連性を表すバイナリ行列
代表的なクエリとは、実現したいユースケースで一般的に尋ねられる質問になります。
上の図に示される表は、想定されるクエリ(質問文)とRAGにおいて参照されるべき、クエリと関連の高い文書を示すバイナリ行列(1が関連する文書、0が関連しない文書)を表しています。
このバイナリ行列が各クエリに対し正しい関連文書を示しているかは、LLMが評価するだけではなく、人によってダブルチェックすることも有効です
評価メトリックの選択
使用すべきメトリック(評価指標)はユースケースによって異なりますが、主に考慮すべきポイントは以下の2つです。
- 適合率(Precision)と再現率(Recall)のトレードオフ
- プロンプトに含まれる文書の数(k)
これらの観点を考慮して、一般的に使用されるメトリックとしては「Precision@k」または「Recall@k」があり、これらのメトリックを使うとk=3(3件文書をプロンプトに含めた)場合のPrecisionのように、PrecisionまたはRecallと文書の数kを同時に表すことができます。
ただし、これらのメトリックだけでは不十分なユースケースもあるため、詳細なメトリック情報を知りたい場合は、こちらを参考にすることができます。
Tips 1: 文書データのクリーニング
RAGはLLMを文書データに結びつけるため、データの品質が悪い場合、システム全体の精度が著しく低下する可能性があります。たとえば、文書データの内部構造や内容が不明確な場合、システムは内容を理解できず、矛盾した情報や重複した情報を含む文書データの検索が困難になるかもしれません。結果的に、生成ステップの品質も低下する可能性があります。
文書の品質を評価するために、以下の質問を考えることが参考になります。
- 文書は意味のあるトピックに分類できるか?
- 同じトピック(内容)は複数の文書に分散しているか?
質問に答える際、人間であってもどの文書を選ぶべきか分からない場合には、RAGによる検索システムも効果的に機能することは難しいわけです。
そのため、文書データを整理し、適切にクリーニングすることをおすすめします。クリーニングにはさまざまな方法があります。たとえば、PDFファイルからテキストデータを抽出し、明確な段落構造を持つテキストファイルに変換する方法や、同じトピックを持つ複数の文書を統合する方法などがあります。
手動でクリーニングするのが難しい場合でも、プログラムによるルールベースの処理やLLMを使用して複数文書のサマリーを生成する方法が考えられます。予めサマリー生成しておけば、サマリーにはテキストデータのみで必要な情報がまとめられるため、内容の正確性を担保しつつRAGシステムの参照文書とすることができます。
Tips 2: 適切なインデックスの検証
LLMのプロンプトに含める文書の検索システム構築には、文書をインデックス化するプロセスがあります。 RAGの実装に、参照文書のインデックス化は必須です。 最も一般的で簡単な方法として、文書埋め込み(embedding)によるベクトル検索と類似検索・キーワード検索(similarity search)が存在します。 これらの方法は非常に効果的ですが、すべてのユースケースに適しているわけではないので、どちらの手法を使用するか検討する必要があります。
たとえば、商品名や商品番号を検索する場合、埋め込みによるベクトル検索よりも類似検索の方が効果的かもしれません。 両方の利点を組み合わせてハイブリッド検索システムを導入することもあります。
また、最近注目されているのが、ColBERTというニューラル検索手法です。 ColBERTでは文書埋め込みではなく、単語やトークンの埋め込みを使用します。 このアプローチは、単語レベルの埋め込みを使用することで、文書の表現のバリエーションや単語の同義語を考慮しながら、キーワード検索の完全一致にも対応できます。 詳細についてはこちらを参照してください。
さまざまなインデックス手法が存在しますが、Tips 0.5で作成した評価データセットを使用して、特定のユースケースに適したインデックス手法を検証することもおすすめです。
Tips 3: チャンク分割を検証
LLMにはトークンの制限(プロンプトの文字数制限)があるため、長文の文書全体をプロンプトに入れることはできません。 そのため、文書を特定の長さでチャンクに分割する必要があります。 Langchainなどのフレームワークを使用する場合、この分割プロセスは抽象化されがちですが、チャンクの長さや分割方法もシステムの精度に影響する重要な概念です。
基本的に、チャンクが小さい場合、検索の精度は向上しますが、回答生成の部分では文脈が不足するため、精度が低下します。 チャンクの分割にはさまざまなアプローチが存在し、詳細に興味がある方はこちらを参考にしてください。
Tips 4: プロンプトの調整
LLMの生成結果は、プロンプトを変更することで大きく変わることがあります。 LangChainやLlamaIndexなどのフレームワークにはデフォルトのプロンプトが用意されているのですが、実現したいユースケースに適したプロンプトは個別に考えて調整する必要があります。
経験から言えることは、以下のTipsを取り入れることで、結果が改善することが多いです。
- 参照文書が主に日本語である場合、プロンプトも日本語で記述する。
- ユーザーの質問に回答できない場合、または質問が主観的で答えがない場合、システムが回答できない旨をユーザーに明示的に回答するようにプロンプトで指示する。
- システムがどのように動作すべきかをプロンプトに明確に記述する。
- 一般的な質問に関しては、文脈を無視して事前学習の知識から回答することを許容する旨を述べる。
詳細については、こちらを参考にしてください。
Tips 5: メタデータの活用
検索結果の精度向上のための別の方法として、チャンクにメタデータを追加することがあります。 一般的に追加されるメタデータの1つは日付です。 これは、検索結果を最新順に並び替えたり、優先度を付けたりするのに役立つからです。
たとえば、対象となる文書が社内のメール文書である場合、最新のメールが通常、正確性や関連性が高いと考えられます。 しかし、埋め込みやキーワード検索だけでは、期待される関連性を計算するのは難しいことがあります。 検索において、文書の内容がクエリと類似しているだけで十分に関連性があるわけではありません。
そのため、検索プロセスにおいてメタデータと文書の内容の両方を考慮することで、関連性の高い文書を取得できるようになります。
Tips 6: クエリのルーティング
文書データが多様である場合、通常、複数のインデックスを作成することは一般的です。 この場合、RAGシステムではどのインデックスをクエリに対して使用すべきかを選択する仕組みが必要です。 この仕組みは「クエリのルーティング」と呼ばれます。 たとえば、インデックスAは一般的な質問に適しているが、インデックスBは業務プロセスに関連した質問に適しているといった状況を考えてみましょう。 インデックスAとインデックスBを単一のインデックスに統合すると、どちらかのタイプの質問に対する回答が不可能になる可能性があります。 これを避けるために、ユーザーの質問を適切なインデックスにルーティングするコンポーネントを追加する必要があります。
Tips 7: リランカー導入
Tips 5で述べたように、クエリと参照文書の内容が「類似している」と「関連している」は同じではなく、LLMが参照すべき文章は「関連している」文書です。しかし、検索される文章は「類似している」文書であることが多くこのギャップを埋めるために、検索にリランカーと呼ばれる概念を適用する場合があります。このアプローチには、2つのステップが存在します。
- 大量の文書を対象に、埋め込みやキーワード検索を使用して文書を検索します。
- 検索結果に対して、メタデータと文書内容から特徴を抽出し、それに基づいてリランカーモデルにより関連性を計算し、検索結果を並び替えます。
リランカーモデルを効率的に使用するために、第2ステップの前に検索順位上位K個の文書のみを扱うアプローチが一般的に採用されます。 このアプローチを本番環境に導入する場合、必ず評価データを使用してリランカーモデルを評価してください。 また、このアプローチは比較的複雑であり、検索の専門知識が必要です。
Tips 8: クエリの変換
このアプローチでは、クエリの埋め込み(ベクトル化)を実施する前に実施され、検索の類似性をできるだけ関連性に近づけるためにクエリを適切に変換します。
いくつかの方法が提案されています。
- 言い換え: LLMを使用して質問を言い換えます。人間として意味は同じでも、文書埋め込み(embedding)後の埋め込み空間では異なるベクトルになる可能性があるからです。
- HyDE: LLMを使用して質問に対する仮説的な回答を生成し、その仮説的な回答を元の質問に追加して、埋め込み空間に変換します。
- サブクエリ: 複雑な質問の場合、複数の単純な質問に分割することで精度向上させます。
Tips 9: 文書埋め込みモデルのファインチューニング
文書埋め込み(Embedding)ベクトル検索はRAGにおける標準的な参照文書の検索手法です。 一般的に使用されるモデルには、OpenAIのtext-embedding-ada-002があります。 ただし、このモデルはインターネットデータから事前学習されたものであり、一般的な単語の意味を理解できますが、特定のドメインに関連した用語を理解するのは難しい場合があります。
ファインチューニングが必要なケースは多くありませんが、非常に多くの用語が存在し、それらの同義語を理解するためにドメイン知識が必要な場合、埋め込みモデルのカスタマイズが役立ちます。
ファインチューニングの対象は、回答を生成するLLMモデルではなく、文書やクエリの埋め込みを作成するためのモデルです。 したがって、QAペアのデータセットを作成する必要はありません。単純に、対象となる文書を学習データとして使用するだけです。
Tips 10: 分析ツールの利用
Tips 1から9まで、精度向上のためのさまざまな方法を紹介しましたが、どの方法を採用すべきかを判断するには、LLMの誤答の原因を分析する必要があります。 ISIDでは、Know Narrator Insightを開発し、RAGシステムのログを分析する機能を提供しています。
Know Narrator Insightを活用することで、どのケースやどの質問において回答がうまくいかないのかを確認できます。その結果、適切な改善方法を選択できます。Know Narrator Insightの機能について詳しく知りたい方は、以下の記事をご覧いただければ幸いです。
まとめ
Know Narrator SearchのようなRAGシステムを動く形にすることは簡単かもしれませんが、本稼働できる品質を持ち、かつ業務ユースケースに合わせて適切に機能させるのは難しい課題です。 このギャップを埋めるために、前述のTipsを活用することを検討してみてください。 現時点では、RAGのベストプラクティスが確立されていないため、ユースケースに応じた実装を実現するためには、真剣な実験と試行錯誤が必要です。
さまざまな改善方法が存在する中で、どの方法が最適かを理解するためには原因分析が重要です。分析を効率的に行うためには、分析ツールの活用が役立ちます。
AITCで開発されているKnow Narrator Insightは、AIの専門知識がない方でも、今回ご紹介したTipsを含むAITCに蓄積されたノウハウを適用してChatGPTといったLLMシステムの改善を行うことができます。
ご興味がある方はぜひこちらからお問い合わせください。弊社データサイエンティストによるご相談も承っております。