6.

RAG (検索拡張生成) とは?仕組み・実装・LangChain 例

編集

本稿は RAG(Retrieval-Augmented Generation / 検索拡張生成) に関する記事です。

この記事の要点
  • RAG は「外部知識を検索 → LLM に渡して回答させる」手法
  • LLM のハルシネーションを抑え、社内文書・最新情報・固有知識を反映できる
  • 基本フロー: 文書分割 → Embedding → ベクトルDB → 検索 → LLM プロンプトに付与 → 回答
  • ファインチューニングより低コストで知識更新が容易(DB を差し替えるだけ)
  • 主要フレームワーク: LangChain / LlamaIndex / Haystack
  • 精度向上の鍵: チャンク分割の質 / Embedding モデル選定 / 再ランク / ハイブリッド検索
  • 限界: 検索でヒットしない情報は答えられない。チャンク分割品質に強く依存

RAG とは?

RAG (Retrieval-Augmented Generation / 検索拡張生成) は、LLM が回答する際に外部の知識ベースから関連情報を検索し、その内容をプロンプトに含めて回答させる手法です。

LLM 単体は学習時点の知識しか持たず、社内文書や最新情報を知りません。RAG は「LLM の言語能力」「検索エンジンの正確性」を組み合わせ、社内 FAQ ボット・ナレッジ検索・カスタマーサポート等で実用性を一気に高めました。

なぜ RAG が必要か

LLM 単体の弱点RAG での対処
学習データのカットオフより新しい情報を知らない最新文書を検索して参照
社内固有情報を知らない社内ドキュメントを RAG の対象に
ハルシネーション(もっともらしい嘘)出典付きの回答で検証可能に
巨大コンテキスト全部投入はコスト高関連箇所だけ抽出して投入
情報更新にはファインチューニングが必要DB を差し替えるだけで反映

RAG の基本フロー

フェーズステップ担当技術
事前準備
(Indexing)
1. 文書を集めるPDF / Web クローラ / DB エクスポート
2. テキスト抽出・前処理PDF パーサ・OCR・HTML 抽出
3. チャンク分割Text Splitter(再帰的 / 文・段落単位)
4. Embedding 生成・DB 格納Embedding モデル + ベクトルDB
クエリ時
(Retrieval & Generation)
5. 質問を受信ユーザ入力
6. 質問を Embedding同じ Embedding モデル
7. ベクトルDB で類似検索近傍 k 件取得
8. (任意)再ランクCohere Rerank / BGE Reranker
9. LLM プロンプトに連結 → 回答生成LLM (GPT / Claude / Gemini)

主要ライブラリ・サービス

分類代表
フレームワークLangChainLlamaIndex、Haystack
EmbeddingOpenAI text-embedding-3、Cohere Embed、BGE、E5
ベクトルDBChroma、Faiss、pgvector、Pinecone、Qdrant、Weaviate
再ランクCohere Rerank、BGE Reranker、Jina Reranker
ドキュメントパースLlamaParse、Unstructured、PyMuPDF、pdfplumber
LLM プロバイダOpenAI、Anthropic、Google、Mistral、ローカル LLM
マネージド SaaSAzure AI Search、Vertex AI Search、AWS Kendra、Pinecone

最小サンプル(LangChain)

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# 1) 文書読込 → チャンク分割
docs = PyPDFLoader("manual.pdf").load()
splits = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=100).split_documents(docs)

# 2) Embedding → ベクトルDB
vs = Chroma.from_documents(splits, OpenAIEmbeddings(), persist_directory="./db")
retriever = vs.as_retriever(search_kwargs={"k": 4})

# 3) RAG チェーン
prompt = ChatPromptTemplate.from_template("以下の参考情報を踏まえて質問に答えてください。\\n\\n参考:\\n{context}\\n\\n質問: {question}")
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
rag = ({"context": retriever, "question": RunnablePassthrough()}
       | prompt | llm | StrOutputParser())

print(rag.invoke("返金ポリシーを教えて"))

精度を上げる工夫

工夫効果
チャンク分割の調整サイズ・重複・分割単位(文・段落・見出し)を調整
メタデータフィルタ部門・公開日・言語等で事前絞り込み
ハイブリッド検索意味検索(ベクトル)+ キーワード検索(BM25)を組合せ
再ランク (Reranker)上位 k 件を再評価。Cohere Rerank / BGE Reranker
クエリ書き換えあいまいな質問を LLM で具体化してから検索
HyDE仮の回答を LLM に生成させ、それで検索
マルチクエリ質問を複数言い換えて広く検索
サブクエリ分解複合質問を細かく分けて個別に検索
埋め込みモデル切替ドメイン特化や多言語モデルへ
引用付き回答「参考: [n]」をプロンプトで強制

発展形: GraphRAG / Agentic RAG

補足: 標準 RAG の限界を超える
  • GraphRAG: 知識グラフを併用。複数文書をまたいだ関係性質問に強い(Microsoft 提唱)
  • Agentic RAG: エージェントが検索 → 評価 → 追加検索を繰り返す。複雑な質問に対応
  • マルチモーダル RAG: 画像・表・PDF を含む検索
  • セルフルーティング RAG: 質問種別で別の DB / 別の手法に振り分け

RAG vs ファインチューニング

観点 RAG ファインチューニング
知識の更新DB を差し替えるだけ再学習が必要
導入コスト低い高い (GPU・データ準備)
出典の提示容易(検索元 URL を返す)困難
レイテンシ検索分のオーバーヘッド追加遅延なし
形式・口調の制御プロンプトで指示得意(学習で固定)
専門ドメインの深い知識検索ヒットに依存強い
用途FAQ、ナレッジ検索、最新情報特定スタイル、構造化出力

多くの業務シナリオでは「RAG で十分」。両方を組合せる選択肢もある。

運用上のヒント

Tips
  • 評価セットを作る(質問 / 期待回答 / 出典)。ベンチマークが無いと改善できない
  • 失敗ログを観察。検索失敗 / 生成失敗 / プロンプト不備のどれか切り分け
  • 引用 ID を返させる: [doc_3] 等を出力に強制 → 検証可能
  • 「分からない場合は分からないと言う」をプロンプトで明示
  • チャンク分割は意味の単位で切る(見出し・段落で分割)
  • 本番では増分インデックスを仕組み化(全件再構築は高コスト)
  • 監視: 検索ヒット率・回答時間・LLM トークン消費・ユーザ評価

注意点

よくある落とし穴
  • 検索ヒットしなければ答えられない。再ランクや HyDE で底上げ
  • チャンクが大きすぎる / 小さすぎる — 情報が薄まる / 文脈が切れる
  • PII / 機密情報を全部 Embedding: アクセス権付き RAG にする
  • Embedding モデルの変更: 既存ベクトルが使えなくなる。再生成が必要
  • 同じ用語の表記揺れ: 検索ヒット率が下がる。前処理で正規化
  • 古い情報 vs 新しい情報の混在: メタデータ(公開日)でフィルタ
  • プロンプトインジェクション: 検索結果に悪意ある指示が紛れる可能性
  • 多言語データ: 単言語 Embedding だと精度劣化。多言語モデルを使う

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. LLM (大規模言語モデル)
  2. Transformer
  3. Attention (注意機構)
  4. Embedding (埋め込み)
  5. Prompt Engineering
  6. RAG (検索拡張生成)
  7. ファインチューニング
  8. AIエージェント
  9. マルチモーダルAI
  10. トークンとコンテキストウィンドウ
  11. Diffusion Model (拡散モデル)

最近更新/作成されたページ