はじめに
こんにちは、HEROZ ASK の開発チームです。
今回のポストでは、このプロダクトの開発で活用している検索精度の向上技術についてお話します。
知識抽出におけるRAGの役割
そもそも現在公開されているLLMをそのまま用いて社内ナレッジについて質問すると、事実に基づかない文章を生成してしまう、いわゆる『ハルシネーション』が起きてしまいます。
このハルシネーションに対抗する手段のひとつがRAGです。RAG(Retrieval Augmented Generation)は、検索ベースのモデル(Retrieval)と生成ベースのモデル(Generation)を組み合わせたアプローチです。RAGは特定のクエリに関連する情報を集め、その情報を元に詳細な回答を生成する仕組みのため、ハルシネーションの軽減に貢献します。
HEROZ ASKでは、ベクトル型データベースを用いて関連する情報をドキュメントから取得し、それを元に回答を生成しています。RAGを通じて、生成される回答がドメインの内容に沿った一貫性を確保できると期待されます。
RAGの限界
シンプルなRAGで検索対象にできるドキュメントの範囲は、ユーザが入力したクエリの内容を超えられません。例えば「旅行の予約方法」とだけ入力されたとき、LLMは航空券やホテルの予約方法について一般的な回答が行えます。しかしユーザが実際にはツアーパックの予約方法について知りたがったり、割引チケットの購入方法に知りたいときにLLMはそれらの情報を提供することができません。
LLMによるクエリ拡張
クエリ拡張とは、検索クエリに関連するキーワードやフレーズを追加してより適切な検索結果を得るための手法です。
一般的なクエリ拡張の手法としてはシソーラスを用いたものなどがあります。シソーラスによるクエリ拡張は同義語や関連語を検索クエリに追加し、より幅広い検索結果を引き出します。しかしながら、シソーラスによるクエリ拡張はドメイン知識を必要とするため、すべてのクエリに対して効果的とは限らない問題があります。
これに対してLLMを用いるクエリ拡張では、広範な知識を開発者の実装なしに利用できます。与えられたクエリから複数パターンの質問を生成することで、より適切なドキュメントを検索対象に取りやすくなります。LLMによるクエリ拡張の最大の利点は柔軟性と精度の両立です。多くの発表されているLLMは様々な文脈やトピックに対応する能力を持ち、ドメインに関する知識を必要としません。
しかし、LLMによるクエリ拡張には生成するクエリが必ずしもユーザの意図を正確に反映するとは限らないという問題があります。この問題を克服するため、たとえばLLMからの返答に対してユーザがgood/bad評価でフィードバックするRLHF(人間のフィードバックによる強化学習)を採り入れるなどの施策が必要になります。
Multi Query Retrieverによるクエリ拡張
LLMによるクエリ拡張手法のひとつに、Multi Query Retrieverがあります。
Multi Query Retrieverはユーザが入力したクエリに対してLLMを用いてクエリを複数パターンに拡張する手法です。
(参考)MultiQueryRetriever | 🦜️🔗 Langchain
今回LLMへ渡すテンプレートは上記リンク先にあるものの日本語訳です。
あなたは AI 言語モデルのアシスタントです。 あなたのタスクは、指定されたユーザーの質問から5つの異なるバージョンを生成し、 ベクトルデータベースから関連するドキュメントを取得することです。 ユーザーの質問に対して複数の視点を生成することで、 ユーザーは、距離ベースの類似性検索の制限の一部を克服します。 これらの代替質問を改行で区切って入力してください。 元の質問: {question}
Multi Query Retrieverを利用したクエリ拡張時の性能とコストの評価
シンプルなRAGとMulti Query Retrieverをクエリ拡張に用いた場合の性能とコストを比較していきます。
実験では当社の社内wikiに該当するドキュメントが存在する、または無関係な25の設問に対してRAGを用いて知識抽出を行いました。正しい文章を生成している、または該当するドキュメントが存在しないときに回答しないケースを正答としています。
使用モデルはGPT-4で、LangChainのDebugモード下で実行しています。
下表はMulti Query RetrieverでのRAGとシンプルなRAGに対する比を掲載しています。
シンプルなRAG | Multi Query Retriever | 比率 | |
---|---|---|---|
正答数 | 19/25 | 24/25 | 126.32% |
平均処理速度(s) | 25.4 | 26.4 | 103.94% |
平均消費トークン数 | 2821.6 | 2832.1 | 100.37% |
- LLM生成によるクエリ拡張を施したMulti Query Retrieverでは、シンプルなRAGに対して26.32%精度が向上しました。
- 処理速度は大きく変わらない。
- Multi Query Retrieverでクエリ拡張を行っても、全体の消費トークン数は大きく跳ね上がることはないと言えます。
まとめ
以上から、多少の処理速度と消費トークン数の増加と引き換えに、LLM生成によるクエリ拡張によって精度を向上させることができたと言えます。
本実験の時点ではチャンク分割には段落などを気にせず文字列を分割する RecursiveCharacterTextSplitter
を利用していました。その後ドキュメントのチャンク分割にMarkdownのヘッダー構造をメタデータに持てる MarkdownHeaderTextSplitter
を用いることでドキュメント内の意味的階層構造をLLMが解釈できるようになり、検索精度の向上に繋がることが分かりました。
別の実験でEmbeddingモデルを切り替えることでも精度が向上する場合があると分かったため、今後はドキュメントの読み込み方法を工夫しつつ、プロンプトを改善して更なる精度向上を目指していきます。