
こんにちは!
入社2年目、プロダクト・サービス事業部のハニーです!
みなさんは RAG(Retrieval-Augmented Generation) をご存じでしょうか?
これは、ChatGPTのような生成AIを「自社の専門家」のように進化させられる技術です。
「社内情報に基づいて正しく答えてほしい…」そんなニーズを解決してくれるのがRAGなんです。
私たちはRAGシステムの開発を見据えて、RAGの回答精度を最大化するにはどんな技術要素が鍵になるのかを検証してきました。
本記事では、RAGの回答精度を高めるために取り組んできた私たちの試行錯誤をご紹介します。
1. RAGとは
ChatGPTのようなLLM(大規模言語モデル)は、膨大な知識を持つ非常に優秀なアシスタントです。しかし、彼らにも弱点があります。それは、「知らないこと」については答えられないということです。例えば、昨日発表されたばかりのニュースや、あなたの会社だけの特別なルールなどは学習データに含まれていません。
この課題を解決する技術が RAG(Retrieval-Augmented Generation) です。
RAGを一言で説明するなら、「LLMにカンニングペーパーを渡してあげる仕組み」です。
具体的には、以下のような流れで動きます。
①質問をすると、RAGはまず社内文書などの指定されたデータベースの中から関連情報を探し出します。
②見つけ出した情報を「カンニングペーパー」としてLLMに渡します。
③LLMは、その「カンニングペーパー」を元にして、正確で信頼性の高い回答を生成します。

この仕組みにより、LLMは未知の情報に対しても根拠に基づいた正確な回答を生成できるようになります。
一見シンプルですが、RAGの回答精度は、この「カンニングペーパーの質」に大きく左右されます。いかに的確で質の高い情報を見つけ出し、LLMに渡せるかが精度の鍵を握っています。次のセクションからは、この回答精度を最大限に高めるために私たちが行った様々な工夫について、ご紹介していきます。
2. 社内での検証
RAGの精度向上は、大きく分けて「インデックス作成(LLMに渡すカンニングペーパーを準備する工程)」と「検索・回答生成(質問に合ったカンニングペーパーを探し、回答を作る工程)」の2つの工程で考えることができます。
私たちは、この2つの工程を構成する各要素について、様々なアプローチを試し、その効果を検証しました。
2.1. インデックス作成(LLMに渡すカンニングペーパーを準備する工程)
ここでの目的は、いかに質の高いカンニングペーパーをデータベースに準備できるか、という点にあります。この準備の質が、後段の検索精度に大きく影響します。

2.1.1. 前処理と非構造化データへの対応
まず取り組んだのは、社内に多数存在するPDFなどの非構造化データへの対応です。「Garbage In, Garbage Out(ゴミを入れたら、ゴミしか出てこない)」の原則通り、データの前処理は精度の土台となります。
当初は、PDFの文書をMarkdown形式に変換して取り込む方法を試しました。この方法で文章や表データはある程度の精度でテキスト化できましたが、画像やフロー図などの情報をどう扱うかという課題に直面しました。特に、社内文書にあるフロー図は、画像として抽出すると分解されてしまったり、構造をうまく読み取れなかったりと、情報が大幅に欠落してしまいました。
この課題を解決するため、私たちはAI(LLM)に前処理自体を担わせるというアプローチを考えました。具体的には、PDF等の文書を直接AIに読み込ませ、その内容を構造的に理解させた上で、YAML形式で出力させるという手法です。
title: "〇〇システム設計書"
sections:
- chapter: "1. 概要"
text: "本システムは..."
- chapter: "2. フロー図"
type: "flowchart"
description: "ユーザー登録から利用開始までの流れを示すフロー図です..."
nodes:
- id: "A"
label: "開始"
- id: "B"
label: "ユーザー登録"
edges:
- from: "A"
to: "B"
図3:YAMLデータ例
この方法により、これまで難しかった文章の階層構造、表、さらには画像やフロー図の内容までを、意味のある関係性を保ったままデータ化でき、複雑な社内文書に関する質問に対しても、回答精度の向上が見られました。
2.1.2. チャンク戦略
質の良い情報源があっても、そのまま丸ごとLLMに渡すのは現実的ではありません。なぜなら、LLMが一度に処理できる情報量には限りがあり、たとえ大量のテキストを入力できたとしても効率が悪いからです。たとえばテスト中に教科書1冊を丸ごと渡されても、必要な答えをすぐに探すのは大変ですよね。実際には、答えが載っているページだけを切り取って渡してもらった方が役に立ちます。RAGでも同じで、元の文書を「チャンク」と呼ばれる小さな情報の塊に分割し、データベースに保存しておく必要があります。そして、このチャンクこそが、質問に応じて検索され、LLMに渡される「カンニングペーパー」そのものなのです。
しかし、この分割方法を間違えると、重要な文脈が失われてしまいます。切れ目の悪いカンニングペーパーを渡されたLLMは、的確な回答を生成できません。そこで、最適な分割方法を見つけるために、いくつかのアプローチを試しました。
検証の結果、有効だった手法
- YAMLの構造に基づく分割
前処理で作成したYAMLデータの「章」や「節」といった、文書本来の構造を分割単位として利用しました。この方法は、文脈が失われるリスクをほぼなくすことができ、高い精度を示しました。 - 句読点や改行による分割
句読点や改行といった文章の自然な区切りで分割する方法が有効でした。さらに、チャンクの切れ目で文脈が途切れないよう、前後のチャンクで一部の文章を重複させる「オーバーラップ」を適用することで、情報の欠落を最小限に抑えることができました。
検証の結果、有効ではなかった手法
- 文字数による機械的な分割
文章の構造を一切無視して、単純に文字数で分割する方法です。この手法では、たとえチャンク同士をオーバーラップさせても、意味のない文章の断片が重なるだけで文脈の補強にはならず、根本的な問題は解決できませんでした。結果として、意味のまとまりが破壊されてしまい、回答精度の向上にはつながりませんでした。 - 英語に翻訳してからの分割
エンベディングモデルが英語を得意とする可能性を考慮し、一度日本語を英語に翻訳してから分割する方法も試しました。しかし、翻訳時に日本語の繊細なニュアンスや固有名詞が失われてしまい、情報の質が劣化する結果となりました。
2.1.3. エンベディングモデルの選定
質の高いチャンク(カンニングペーパー)ができたら、次はそれをAIが理解できる数値の羅列、すなわち「ベクトル」に変換する必要があります。この変換を担うのが「エンベディングモデル」です。
ユーザーからの質問も同じモデルでベクトルに変換されます。そして、システムは質問のベクトルと、データベース内にある無数のチャンクのベクトルを比較し、意味的に最も近い(類似度が高い)ものを探し出します。つまり、エンベディングモデルは、質問に合ったカンニングペーパーを見つけ出すための「検索の司令塔」の役割を果たすのです。この司令塔の性能を確かめるために、私たちはいくつかのモデルを比較検証しました。今回ご紹介するのは、以下のモデルたちです。
- text-embedding-3-small(OpenAI)
- text-multilingual-embedding-002(Google)
- hotchpotch/static-embedding-japanese
- intfloat/multilingual-e5シリーズ
検証の結果、どのモデルも高い正解率を示しましたが、私たちはOpenAIのtext-embedding-3-smallが最も良い選択肢ではないかと考えました。
その判断の決め手は、純粋な精度だけではありません。私たちが評価の観点として加えたのは、実運用における「使いやすさ」、特に類似度スコアの「明確さ」です。私たちは将来RAGシステムを運用していく中で、「類似度スコアが80点以上なら関連情報と判断する」といったボーダーライン(閾値)を細かく調整する必要が出てくるかもしれない、と考えています。もしそうなった場合、モデルが出すスコアの傾向が重要になります。
OpenAIのモデルは、関連する情報には「95点」、全く関係ない情報には「30点」というように、スコアがはっきりと分かれる傾向が見られました。これなら、ボーダーラインの調整は比較的簡単そうだと判断しました。一方で、他の高精度なモデルでは、関連情報が「85点」、非関連情報が「75点」のように、スコアが近接するケースが確認されました。そうなると、どこにボーダーラインを引くべきか非常に悩ましく、少しの調整で結果が大きく変わってしまう可能性があります。
このような「将来的な調整のしやすさ」という観点から、スコアが明確なOpenAIのモデルが安定した運用に繋がりやすいのではないかと考えています。
2.1.4. ベクトルデータベースと次元数
ベクトル化されたデータは、「ベクトルデータベース」に保管されます。「次元数」とは、ベクトルが持つ数値の個数であり、その情報量を決定します。
次元数が高いベクトルはより多くの意味的な特徴を捉えることができますが、ノイズが増加したり計算コストが増大したりする可能性があります。逆に次元数が低いと、文章間の微妙なニュアンスの違いを表現しきれないことがあります。
次元数はエンベディングモデルごとに固定されているため、私たちは2.1.3で検証した各モデルの次元数に注目しました。
- text-embedding-3-small(OpenAI): 1536次元
- text-multilingual-embedding-002(Google): 768次元
- hotchpotch/static-embedding-japanese: 768次元
- intfloat/multilingual-e5シリーズ: 384, 768, 1024次元
これらの多様な次元数が検索精度に与える影響を比較検証したところ、次元数が高いほど必ずしも精度が向上するわけではない、ということが分かりました。このことから、検索精度は次元数の大小そのものよりも、各エンベディングモデルが持っている「文章の意味を的確に捉える能力」の方に、より大きく依存するのではないかという結論に至りました。なお、最適な次元数やエンベディングモデルは扱う情報の性質によって変わるため、都度検証が必要かと思います。
2.2. 検索・回答生成(質問に合ったカンニングペーパーを探し、回答を作る工程)
ここでの目的は、準備された「カンニングペーパー」の中から、ユーザーの質問に適した情報を見つけ出し、それをもとに回答を生成することです。
2.2.1. 検索精度向上のアプローチ
質の高いカンニングペーパーを準備しても、ユーザーの質問に合ったものを的確に見つけ出せなければ意味がありません。そこで私たちは、検索精度をさらに向上させるための様々なアプローチを試し、その効果を検証しました。
- クエリ変換
ユーザーの質問を、AIが検索に適した形に書き換える手法です。曖昧な質問には有効でしたが、具体的な質問では逆に意図からずれる場合もありました。
- RAG-Fusion
ひとつの質問から複数の異なる質問をAIが生成し、それぞれで検索した結果を統合する手法です。関連情報を多角的に捉えられる可能性がある一方、元の質問の意図が拡散してしまい、結果的にノイズが増えることもあり、汎用的に使うのは難しいという結論に至りました。
- Hyde
質問に対してまずAIが「仮の答え」を生成し、その答えを使って検索する手法です。AIが生成する「仮の答え」の質に結果が依存します。対象データに関する知識がないAIでは的確な仮説を立てることが難しく、汎用的に使うにはモデルのファインチューニング等が必要になると考えられたため、導入のハードルは高いと判断しました。
- ハイブリッド検索
意味の近さで探す「ベクトル検索」と、単語の一致で探す「キーワード検索」を組み合わせる手法です。固有名詞を含む検索で特に有効でした。
- リランキング
ベクトル検索で一度絞り込んだ候補を、さらに別の基準で評価し、順位を付け直すアプローチです。これには、より高度なAIモデルで再評価する方法や、「キーワードの一致度」「文書の鮮度」といった複数の評価軸に重み付けをして総合スコアを算出する方法など、様々な手法が存在します。どの手法が最適かはユースケースによると考えられ、一概にこれがベストとは言えないものの、検索結果の質を最終調整する上で重要な工程であることが分かりました。
- タグ・メタデータ活用
文書の作成日や部署名といったメタデータを使い、検索結果を絞り込む手法です。これは「昨年〇〇部が作成した資料」のような、より具体的な検索に有効で、実用性を高める上で重要だと分かりました。しかしその一方で、このメタデータをどう設計し、付与するかが大きな課題であることも浮き彫りになりました。例えば、文書の種類によって最適なメタデータの項目は異なりますし、「タグ」を自動生成するにしても、いくつ生成するか、固有名詞をすべてタグにすべきかなど、考慮すべき点が多く、汎用的な仕組みを構築するのは難しいという結論に至りました。
3. 検証してみて
色々と試してみて、「これをやれば一発でOK!」という魔法のような解決策はない、ということが分かりました。地道な工夫を一つ一つ積み重ねることが、とても大切でした。
その中でも、特に効果が大きいと感じたのは、最初のステップである「インデックス作成」です。よく「Garbage In, Garbage Out」と言いますが、これはAIでも全く同じでした。AIが理解しやすいように、ぐちゃぐちゃな資料をきれいに整えること。これが、最終的な答えの質を一番大きく左右すると思いました。
RAGの性能を上げるには、どんなデータを使って、どんな質問に答えさせたいのかをよく考えて、色々な技術を適切に組み合わせていくことが、大事だと思います。
4. まとめと今後
今回の記事では、私たちが取り組んだRAG検証についてご紹介しました。
検証を通じて改めて感じたのは、「Garbage In, Garbage Out」という原則です。AIの精度を左右するのは、与える情報をどれだけ質高く整えられるかという、前処理の重要性でした。
この経験を踏まえつつ、現在は「AIエージェント」の開発や応用的な検証にも取り組んでいます。
今後もさまざまな形でAIを活用したチャレンジを続けていきますので、ぜひ楽しみにしていてください!
この記事を書いた人

【ニックネーム】
ハニー
【経歴】
入社2年目
自社サービスであるBtoBコミュニケーションプラットフォーム「Qube」というSaaS開発に携わっています。
【一言】
資格を取りたい頑張りたい!