はじめに
近年生成AIの進化により、企業の業務プロセスや顧客対応の自動化が進んでいます。中でも、RAG(Retrieval-Augmented Generation)はLLMの回答生成に外部ストレージに格納された独自データを参考にユーザーからの質問に回答するため、回答精度が向上し、かつ既存の知見を有効に活用した情報検索が可能となります1。
従来のLLM単体での回答生成では、学習データから回答を生成するため新情報には対応できない点や、存在しない誤った情報を生成してしまうハルシネーションなどの課題がありました。RAGは、LLMの知識不足を外部のデータベースに格納したデータを活用することで補うことが可能なため、様々な場面での活用が期待されています。一方で、RAGを使って欲しい情報を取得するためには工夫が必要であり、そのためのチューニングポイント(検索精度を向上させる要素)が多数あります。
概要
本記事では、RAGの検索精度向上に向けたチューニングポイントについて紹介します。
中でも、検索時に外部データベースに格納されたデータから参考情報を抽出するための「ナレッジチューニング」に焦点を当て、ナレッジを解析する仕組みや抽出情報の精度を向上させるためのチューニングポイントについて解説します。
本記事は、RAGについて勉強しはじめたけれど、検索精度が上がらず困っている、またそもそも検索精度にどのような要素が関係しているのか分からないという方の参考になれば幸いです。
そもそもRAGの仕組みはどうなっているのか
RAGを使った検索では、外部のデータベースから検索内容に関連するドキュメントを抽出し、抽出された情報を参考に回答を生成していきます。つまり、RAGのシステム構成は大きく2つに分類することができ、「参考情報を蓄える(そして抽出する)データベース構築部分」と「抽出された参考情報や質問文などから回答を生成する部分」となります。
データベース構築部分
先ほどRAGを用いた回答生成はLLM単体に比べて、最新情報をもとに回答を生成できる利点があることついて述べましたが、検索の参考となる情報をデータベースに保存するのがこの工程です。
追加情報がデータベースに格納されるまでの流れは以下の通りです。
- データソースからドキュメントを読み込む(pptxやPDF、テキストファイルなどからテキストを読み込む)
- ドキュメントを変換する(チャンク分割、HTMLをプレーンテキストに変換するなど)
- テキストを情報の類似度をもとにベクトル化する(Embedding)
- ベクトル化したドキュメントをデータベースに保存する
このようにして保存された情報は、検索内容に応じてデータベースから類似したドキュメントを抽出するために利用されます。構築されるデータベースの種類はベクトルデータベースが一般的ですが、他にもSQLデータベースを用いたSQL RAG2や、エンティティ間の関係性を活用するグラフデータベースを用いたGraph RAG3といった手法もあります。本記事では、ベクトルデータベースを活用したRAGを中心に紹介します。
回答を生成する部分
この工程では、データベースから抽出したドキュメントをプロンプトとしてLLMにインプットし、回答を生成させます。
- ユーザーからの検索内容をベクトル化する
- ベクトル化した質問文に関連した情報をデータベースから抽出する
- 抽出した情報と、質問文をLLMに入力する
- LLMが回答を生成する
これらの工程を踏まえてユーザーに回答を返答しています。
RAGのチューニングポイント
以上、RAGの仕組みについて簡単に説明しましたが、回答精度を向上させるために工夫すべきチューニングポイントは多数あります。LLM開発に関するライブラリを提供するLlamaIndex社のAndrei氏による「A Cheat Sheet and Some Recipes For Building Advanced RAG」4によると、構築データベースから関連情報を抽出する部分と、回答を生成する部分において以下のようなチューニングポイントが挙げられています。
データベース構築部分のチューニングポイント
- チャンクサイズ、チャンク分割方法の最適化
- データベース内の情報の構造化
- チャンクにメタデータを付加する
- ナレッジグラフの追加(グラフデータベースで情報を管理)
- キーワード検索とベクトル検索を用いたベクトル検索
- 質問文のベクトル化
- embeddingモデルのファインチューニング
回答生成部分のチューニングポイント
- 取得した関連情報の精査
- 取得した関連情報の再ランク付け
- LLMの追加学習
- アダプター層の追加
抽出される参考情報の精度向上に向けた具体的なチューニングポイント
このように、RAGの精度に影響を与えるチューニングポイントは多数ありますが、検索した情報を元に回答が生成されるため、データベースに格納される追加情報の品質が低いといくら生成モデルをチューニングしても高品質の回答を得ることはできません。そこで、「データベース構築部分」で精度が高い情報を抽出するための具体的な手法として、チャンク分割とEmbedding(ベクトル化)について紹介します。
チャンク分割
チャンク分割とは、大きなテキストをより小さな単位に分割するプロセスです。これにより、検索アルゴリズムが検索結果をより効率的に処理できるようになります。例えば、PDFや長文のテキストは、コンテンツの長さが検索において障害となることがあるため、適切なサイズでチャンク化することが重要です。
チャンク分割の目的
・検索精度の向上
長すぎるテキストをそのまま検索にかけると、必要な情報がうまく抽出できない場合があります。テキストを適切なサイズのチャンクに分けることで、検索時に関連性の高い情報を短時間で抽出できます。
・モデルへの負荷軽減
一度に処理するテキストのサイズを小さくすることで、生成AIモデルが効率的に動作し、より正確な応答を生成できます。
例えば、記事やFAQのドキュメントでは、1文ごとにチャンク分けすることや、複数の文を1つの意味的な塊にまとめることで、情報検索と生成の両方を最適化できます。さらに、意味的な整合性を保つために、適切にチャンク化することが重要です。ランダムに分割するのではなく、意味的に一貫性のある部分に分けることで、検索結果の精度が向上します。
チューニングポイント
・チャンクのサイズ
大きなチャンクでは情報が多くなり、検索精度が低下するため、最適なサイズを見極めることが必要です。
・意味的な分割
意味が途切れないようなチャンク分けを行い、情報が文脈としてつながった状態で検索されるようにすることが必要です。
(参考)チャンク分割の手法
・MoGG(Mix-of-Granularity-Graph)
MoGGは、複数のチャンクサイズを用意し動的に使い分け、チャンクを意味的な類似度に基づいてグラフ構造を作成する手法です。MoGGは、「MoG」というチャンク分割手法の拡張版です。MoGでは、複数のチャンクサイズを用意しておき、ユーザーからの質問に基づいて最適なチャンクサイズを選択します(MoGルーターがサイズの選択を行う)。これに対し、MoGGでは最適なチャンクサイズを選択した上で、意味的な関連性で構造化されたグラフをもとに、関連したチャンクを探索し参考情報を抽出します。
この手法により、「脚注」や別のファイルに用語の説明がある場合など、テキストの上から順にチャンクサイズを分割する場合に対応できないケースで参考情報抽出の精度向上が見込めます。
Embeddinng(ベクトル化)の最適化
Embeddingとは、テキストデータをベクトル(数値の集合)に変換するプロセスです。このベクトル化されたデータを用いることで、従来のキーワード検索だけではなく、意味的な関連性に基づいた検索を行うことができます。EmbeddingはRAGにおける情報検索の核となる技術であり、適切なベクトル化を行うことがRAGの精度に大きく影響します。
Embeddingの目的
・意味的な検索
ベクトル化された情報は、意味的な関連性に基づいて検索されるため、単なるキーワードマッチングではなく、より高度な検索が可能になります。
・柔軟な情報処理
テキストが高次元空間のベクトルとして表現されることで、モデルはより柔軟に情報を処理できます。
Embeddingの精度を向上させるためには、ベクトル化用のモデルやパラメータをチューニングすることが効果的です。例えば、BERTやGPTなどの事前学習モデルを使用したり、特定のドメインに特化したEmbeddingモデルを作成することで、データベース内の意味的に関連性の高い情報をより精度良く検索できるようになります。
チューニングポイント
・Embeddingモデルの選定
使用するEmbeddingモデルの選定が重要です。基本的には、日本語のテキストに対する高精度な埋め込みが可能なOpenAI社のtext-embedding-ada-002やtext-embedding-003が使われることが多いですが、ドメインに合わせたモデルを選ぶことで検索精度が向上します。
・Embeddingのファインチューニング
事前学習されたモデルをそのまま使うのではなく、特定のドメインやデータセットに合わせてファインチューニングすることで、さらに精度を向上させることができます。
ドメイン(対象データセット)に応じた、Embeddingモデルの選定例は以下の通りです。
ドメイン | 適したEmbeddingモデル例 | 理由・特徴 | ファインチューニングのポイント |
---|---|---|---|
一般的なテキスト検索 | Sentence-BERT | 文単位の類似度計算に強く、一般的な質問応答やテキスト分類に適している | 事前学習済みのモデルを使用しつつ、ドメイン特有のデータで微調整 |
法律関連(リーガルテック) | Legal-BERT | 法律文書専用のBERTモデルで、契約書や判例データなど専門性の高い文書に対応可能 | 法律データセットでのファインチューニング |
医療分野 | BioBERT、ClinicalBERT | 医学論文や臨床データに特化したBERTモデルで、専門用語や医療データに適した埋め込み生成を実現 | 医療機関データや論文を追加したトレーニング |
技術分野(IT/プログラミング) | CodeBERT、GraphCodeBERT | ソースコードや技術ドキュメント向けに設計されており、プログラム構造や技術用語を理解可能 | 技術文書データセットや特定のプログラミング言語に基づいたファインチューニング |
eコマース | DistilBERT、Sentence-BERT | 商品レビューやFAQなど短文での検索に適しており、計算コストが低い | 商品データや購入履歴を使ったトレーニング |
金融分野 | FinBERT | 金融ニュースや報告書を扱うのに適しており、投資分析やリスク評価に役立つ | 金融データやレポートデータを用いた微調整 |
カスタマーサポート | Sentence-BERT、T5 | 質問応答形式のデータに強く、FAQやユーザーサポート向けに適している | 実際の問い合わせデータを使用して調整 |
特定のカスタムドメイン | OpenAI Embeddings(Adaなど) | OpenAIの事前学習済みモデルを利用して、柔軟なベクトル生成を行う | ドメイン特化データでカスタマイズ |
ベクトル化によりデータベースから検索内容に意味的に関連した情報が抽出されますが、さらに再ランク付けを行うことで最も関連性の高い情報を上位に表示することが可能です。再ランク付けは、検索結果が最適ではない場合に、より関連情報を精度高く絞り込む手法です。ベクトル化されたデータベースから、関連した情報を多めに取得し、再ランク付けで再度質問との関連性の順に並び替えます。これにより、よりユーザーからの質問に適した参考情報を取得することが可能です。再ランク付けは、ユーザーからのフィードバックや、検索結果のスコアリングモデルを使用することで効率的にRAGのパフォーマンスを上げることが可能になります。
また、データベースから抽出された情報をLLMに渡す際のプロンプト設計を工夫することで、抽出情報をより効果的に活用することができます。このプロンプト設計次第で回答の精度や品質が大きく変わるため、「プロンプトエンジニアリング」と呼ばれる技術が注目されています。Sander Schulhoff や Michael Ilieらが執筆した「The Prompt Report: A Systematic Survey of Prompting Techniques」5では、プロンプトエンジニアリングの手法が体系的に分類されており、手法をRAGのプロセスに適用することで、ユーザーの質問に対する回答の関連性や正確性をさらに高めることが期待できます。
まとめ
RAG(Retrieval-Augmented Generation)は、外部の最新情報を活用する有用な技術であり、回答生成における精度を高めるためには、ナレッジのチューニングが不可欠です。具体的なチューニングポイントとして、チャンク分割とEmbeddingの最適化が重要となります。これらを適切に調整することで、情報検索の精度が向上し、より高品質な検索結果が得られるようになります。
また、情報検索だけでなく、プロンプトエンジニアリングの工夫や回答生成部分の再ランク付けやアダプター層の追加などLLM側のチューニングも合わせて行うことで、RAG全体のパフォーマンスを向上させることができます。
参考文献
-
https://www.nri.com/jp/knowledge/glossary/lst/alphabet/rag ↩
-
https://zenn.dev/umi_mori/books/llm-rag-langchain-python/viewer/rag-method-sql ↩
-
https://zenn.dev/umi_mori/books/llm-rag-langchain-python/viewer/rag-method-graph ↩
-
https://www.llamaindex.ai/blog/a-cheat-sheet-and-some-recipes-for-building-advanced-rag-803a9d94c41b ↩