RAGシステム全体ガイド:ゼロから本番品質までの完全な設計手順
バックエンドエンジニアの経験を持ち、AIアプリケーションエンジニアリングを学んでいる開発者に向けた記事です。 各段階が何を行い、なぜ必要で、どのような選択肢があるのかを理解できる、完全なRAGシステムの地図を頭の中へ作ることが目標です。
まず最も基本的な問い:RAGは何を解決するのか
LLMには三つの根本的な弱点があります。知識が学習データの期限で止まること、非公開データへアクセスできないこと、知らない内容についてもっともらしい回答を捏造すること、つまりハルシネーションです。
RAG(Retrieval-Augmented Generation)の解決方法は明快です。モデルに記憶だけで答えさせず、参考資料を見ながら答えさせます。 これは持ち込み可能な試験に似ています。モデルには理解力と推論力が必要ですが、すべての知識を暗記する必要はありません。
具体的な流れは、ユーザーが質問する → ナレッジベースから最も関連する内容の断片を検索する → 断片をcontextとしてLLMのpromptへ入れる → LLMがcontextに基づいて回答を生成する、となります。
この考え方はFacebook AI Researchが2020年の論文で提案し、2026年には知識集約型AIアプリケーションを構築する標準アーキテクチャになっています。
全体マップ
RAGシステム
│
├── 1. データ取り込み層(Ingestion Pipeline)—— オフライン処理
│ ├── 1.1 文書の読み込みと前処理(Document Loading & Preprocessing)
│ ├── 1.2 分割(Chunking)
│ ├── 1.3 コンテキスト拡張(Contextual Enrichment)[任意]
│ ├── 1.4 ベクトル化(Embedding)
│ └── 1.5 インデックスと保存(Indexing & Storage)
│
├── 2. クエリ処理層(Query Pipeline)—— オンライン処理
│ ├── 2.1 クエリ理解と変換(Query Understanding & Transformation)
│ ├── 2.2 検索(Retrieval)
│ ├── 2.3 再ランキング(Reranking)
│ └── 2.4 コンテキストの圧縮と組み立て(Context Compression & Assembly)
│
├── 3. 生成層(Generation)
│ ├── 3.1 Prompt構築(Prompt Construction)
│ ├── 3.2 回答生成(Answer Generation)
│ └── 3.3 引用と出典(Citation & Attribution)
│
├── 4. 評価層(Evaluation)
│ ├── 4.1 検索品質の評価
│ ├── 4.2 生成品質の評価
│ ├── 4.3 エンドツーエンド評価
│ └── 4.4 引用品質の評価
│
└── 5. 運用層(Operations)—— 本番環境固有
├── 5.1 可観測性(Observability)
├── 5.2 インデックス更新(Index Refresh)
├── 5.3 コスト最適化
└── 5.4 セキュリティとコンプライアンス
以下では、層ごとに詳しく説明します。
1. データ取り込み層(Ingestion Pipeline)
オフライン処理の段階です。原文書を検索可能なベクトルインデックスへ変換します。RAGの失敗の80%は、この層までさかのぼれます。
1.1 文書の読み込みと前処理
何をするか: PDF、Word、HTML、Markdown、データベース、APIが返すJSONなど、さまざまな形式の原文書を、きれいな構造化テキストへ統一します。
なぜ重要か: Garbage in, garbage outです。PDFのOCR誤り、HTMLのナビゲーションノイズ、表の抽出位置のずれは、この段階で解決しなければ、後続のすべての段階を汚染します。
主な設計判断:
- 文書解析ツールの選択。 単純なテキストならPyPDFやpython-docxなどの基本ライブラリで十分です。スキャンPDF、複数段組、入れ子の表といった複雑な文書には、Unstructured.io、LlamaParse、Docling、Azure Document Intelligenceなどの専門ツールが必要です。
- メタデータの抽出。 この段階でファイル名、ページ番号、見出し階層、作成・更新日時、文書種別を抽出し、保存します。このmetadataは、後の検索フィルタと結果表示に不可欠です。
- 前処理の正規化。 文字コードをUTF-8へ統一し、ヘッダー、フッター、透かし文字などの書式ノイズを取り除き、特殊文字を処理します。
Javaの経験で考えるなら、ETL pipelineのExtract + Transformに相当します。
1.2 分割(Chunking)
何をするか: 長い文書をembeddingと検索に適した小さな断片へ分けます。
なぜ重要か: 以前に詳しく学んだ内容です。中心となるtrade-offは、chunkが大きすぎると検索精度が落ち、小さすぎるとcontextを失うことです。
推奨する初期設定(2026年の最新benchmarkに基づく):
- 戦略:Recursive Character Splitting
- Chunk size:512 tokens
- Overlap:50〜100 tokens(10〜20%)
- 文書種別ごとに戦略を変える(Markdownは見出し、コードは関数、表は行で分割)
重要な原則: 単純な戦略から始め、evaluationデータに基づいて引数を調整します。最初からsemantic chunkingを追求しないでください。
1.3 コンテキスト拡張(Contextual Enrichment)[任意だが強く推奨]
何をするか: 各chunkに原文内のcontext情報を補い、chunkingによって失われたcontextを埋めます。
主な方法:
- Contextual Chunking(Anthropicの方法):LLMを使い、各chunkへ短いcontext prefixを自動生成し、文書全体における位置と背景を説明します。Anthropicは検索失敗を49%削減したと報告しています。
- 文書要約の追加: 各chunkのmetadataへ文書全体の要約を追加します。
- 見出し階層のprefix: 「第3章 > 認証モジュール > JWT実装」のような見出しパスをchunk本文の前へ付けます。
この段階にはchunkごとに一度LLMを呼び出すコストがありますが、検索品質を大きく改善できます。
1.4 ベクトル化(Embedding)
何をするか: テキストchunkを通常768〜3,072次元の高次元ベクトルへ変換し、意味の近い文章同士がベクトル空間でも近くなるようにします。
主な設計判断:
- モデル選択。 2026年の主要な選択肢:
- 商用API: Voyage AIのvoyage-3-largeはMTEBランキング上位で、32K contextに対応します。OpenAIのtext-embedding-3-large/smallは最も広く普及した選択肢です。
- オープンソースのセルフホスティング: BGE-M3は多言語に強く、E5-large-v2は英語の用途に適し、CPUで10msの遅延です。
- 予定しているBGE-M3は、中国語・日本語・英語の多言語用途に適した選択です。
- 次元数とコストのtrade-off。 高次元は高精度ですが、保存コストが高く、queryも遅くなります。多くのモデルがMatryoshka embeddingに対応し、精度をほとんど落とさずに低次元へ切り詰められます。
- 注意: embeddingモデルの最大入力長は上限であって、目標値ではありません。8,192-token対応モデルでも、window全体を埋めるより512-tokenのchunkのほうが良い結果を得られる場合が一般的です。
1.5 インデックスと保存(Indexing & Storage)
何をするか: ベクトルと対応する文章・metadataを、高速検索できるデータベースへ保存します。
主な設計判断:
- ベクトルデータベースの選択:
- pgvector(予定している選択):PostgreSQLの拡張で、既存のPG基盤を持つチームに適しています。運用に慣れていて、業務データと同じDBに置けることが利点です。大規模、つまり1,000万ベクトルを超える場面では、専用データベースより性能が低い点が弱みです。
- 専用ベクトルデータベース: Pineconeはフルマネージド、WeaviateとQdrantはオープンソース、Chromaは軽量でプロトタイプに適しています。
- インメモリデータベース: Redisはベクトル検索とキャッシュの両方に対応し、構成要素の数を減らせます。
- インデックス種別: HNSWは最も一般的でqueryは高速ですが、メモリ消費が大きくなります。IVFFlatは大規模データセットに適し、精度と速度の調整が必要です。
- 原文とmetadataも同時に保存します。 ベクトルを検索した後、原文を取り出してLLMへ送る必要があります。そのため原文はベクトルと一緒に保存するか、関連queryで取得できなければなりません。
2. クエリ処理層(Query Pipeline)
ユーザーが質問した後のオンライン処理です。各段階が、最終的に検索されるcontextの品質へ影響します。
2.1 クエリ理解と変換(Query Understanding & Transformation)
何をするか: 検索の前にユーザーのqueryを改善し、ベクトル検索に適した形へ変えます。
なぜ重要か: ユーザーの質問は、曖昧、口語的、または複雑すぎる場合がよくあります。そのままembedding検索に使っても、通常は良い結果を得られません。
主な方法:
- Query Rewriting: LLMで口語的な質問を検索向けの表現へ書き換えます。たとえば「これはどう使うの」→「XXX APIの使い方と引数の説明」です。
- Query Expansion: 意味的に関連する複数のqueryを生成し、それぞれで検索して結果を統合し、recallを高めます。
- Query Decomposition: 複雑な質問を複数の部分問題へ分けます。「AとBの性能とコストの違いを比較する」→ Aの性能、Bの性能、Aのコスト、Bのコストを個別に検索し、その後に統合します。
- HyDE(Hypothetical Document Embedding): まずLLMに「仮の回答」を生成させ、元のqueryではなく仮の回答でベクトル検索します。仮の回答は、質問そのものより、本当の回答文書に意味空間上で近いという考え方です。
実践上の提案: 最初の版ではquery変換を一切加えず、元のqueryで直接検索します。evaluationでcontext recallが低いと分かったら、Query RewritingとExpansionを段階的に追加します。
2.2 検索(Retrieval)
何をするか: ベクトルデータベースから、queryに最も関連するchunkを見つけます。
三つの主要戦略:
Dense Retrieval(密検索): queryもembeddingし、ベクトル空間で最近傍を探します。通常はcosine similarityを使います。意味理解に強く、「ユーザーの身元をどう確認するか」という質問をauthenticationについての文書へ対応づけられます。一方で、特定のエラーコードの検索は従来型検索より弱いなど、正確なキーワード一致は不得意です。
Sparse Retrieval(疎検索): BM25などのキーワード一致に基づく従来型検索です。エラーコード、製品名、専門用語など、正確な一致に強い一方、同義語や意味は理解しません。
Hybrid Retrieval(ハイブリッド検索) ⭐ 推奨:DenseとSparseを同時に実行し、Reciprocal Rank Fusion(RRF)で結果を統合します。2026年には、ハイブリッド検索が単独のいずれか一方より、ほぼ常に優れているという認識が広がり、recallを1〜9%改善しています。
検索件数の設定: 一般的な開始点はtop-20の候補を検索し、後段のrerankingでtop-5に絞ってLLMへ送る方法です。具体的な数値はevaluationで調整します。
2.3 再ランキング(Reranking)
何をするか: 検索で返された候補chunkを再度評価し、本当に関連するものを上位へ並べます。
なぜ必要か: ベクトル検索のcosine similarityは粗い関連度です。二つのchunkが近いcosine scoreを持っていても、実際の関連性は大きく異なる場合があります。Rerankerはより精密なモデル、通常はcross-encoderで、各chunkとqueryの関連性を個別に評価します。
動作の流れ:
検索で20個の候補chunkを返す
→ Rerankerが各(query, chunk) pairを採点
→ score順に再配置
→ top-5をLLMへ送る
主要な選択肢: Cohere Rerank(商用API、1,000回の検索で$1)、BGE-Reranker(オープンソース)、ColBERT(late interactionモデルで高精度だが、デプロイが複雑)があります。
実際の効果: Rerankingは、最終回答の品質を大きく改善することが一般的です。LLMへ、ベクトル空間で近いだけのcontextではなく、本当に関連するcontextを確実に見せられるからです。
2.4 コンテキストの圧縮と組み立て(Context Compression & Assembly)
何をするか: chunkをLLMへ送る前に、重複除去、圧縮、並べ替えという最後の最適化を行います。
主な処理:
- 重複除去: overlap部分など、複数のchunkが非常に似ている場合に統合または削除します。
- MMR(Maximal Marginal Relevance): 関連性を保ちながら多様性を最大化し、top-5のchunkがすべて同じ内容を述べることを防ぎます。
- contextの順序: LLMはcontextの冒頭と末尾に最も強く注意を向け、中央の情報を見落としやすいという研究結果があります。これをlost-in-the-middle効果と呼びます。最も関連するchunkを最初と最後へ置きます。
- 長さの制御: context全体をLLMのcontext window内へ収め、system prompt、会話履歴、出力のための十分な領域も残します。
3. 生成層(Generation)
関連するcontextを検索した後、LLMにそのcontextを基に回答させます。
3.1 Prompt構築(Prompt Construction)
何をするか: system prompt、検索したcontext、ユーザー質問を組み立て、最終的なLLM promptを作ります。
典型的なpromptの構成:
[System Prompt]
あなたは、提供された参考資料に基づいて質問へ答えるアシスタントです。
以下の参考資料だけに基づいて回答してください。参考資料に関連情報がなければ、「提供された資料から関連情報を見つけられませんでした」と明記してください。
回答では具体的な出典を引用してください。
[Retrieved Context]
--- 参考資料1(出典:xxx.pdf、3ページ)---
<chunk 1の内容>
--- 参考資料2(出典:yyy.md、章:認証)---
<chunk 2の内容>
...
[User Query]
ユーザーの元の質問
重要な原則:
- 「提供されたcontextだけに基づいて回答する」と明示し、ハルシネーションを減らします。
- 分からない場合は分からないと明示させます。回答を捏造するより適切です。
- 出典を引用させ、検証可能性を高めます。
- Promptテンプレートは専用ファイルに置き、コード内へ散在させないでください。
3.2 回答生成(Answer Generation)
何をするか: LLMを呼び出して最終回答を生成します。
主な設計判断:
- モデル選択: 品質要件とコスト予算によって決めます。GPT-5.4、Claude Opus 4.6は高品質が必要な場面、GPT-5.4 Mini、Claude Sonnet 4.6、MiniMax M2.7はコストを重視する場面に使います。
- Temperature設定: RAGでは通常、低いtemperature(0〜0.3)を使います。創造性よりcontextへの忠実さを求めるからです。
- Streaming: 本番環境では、ユーザーが感じる最初のtokenまでの遅延(TTFT)を減らすため、ほぼ常にstreaming出力を使います。
- Fallback戦略: LLM APIはtimeoutやエラーを起こす可能性があります。retryと縮退処理、たとえば主モデルがtimeoutしたら高速なモデルへ切り替える仕組みが必要です。
3.3 引用と出典(Citation & Attribution)
何をするか: 回答内の各事実が、どの文書のどの位置を根拠としているかを示します。
なぜ重要か: RAGが単純なLLMより持つ中核的な利点の一つが検証可能性です。ユーザーは引用から原文を開き、回答の正確さを確認できます。企業顧客には特に重要です。
実装方法:
- prompt内で各context chunkに[1]、[2]などの番号をつけ、回答で引用番号を示すようモデルへ求めます。
- 生成後、引用番号を原文書の具体的な位置、つまりファイル名、ページ番号、段落へ対応づけます。
- フロントエンドでは、原文へ移動するリンクを表示します。
4. 評価層(Evaluation)
多くのチュートリアルが省略しますが、本番システムには必須です。評価がなければシステムの良し悪しが分からず、引数を変えても改善したのか悪化したのか判断できません。
4.1 検索品質の評価
「検索層が正しいchunkを見つけたか」を評価します。
| 指標 | 意味 |
|---|---|
| Context Recall | 検索されるべきchunkのうち、実際に検索された割合。高いほど良い |
| Context Precision | 検索されたchunkのうち、本当に関連する割合。高いほど良い |
| MRR(Mean Reciprocal Rank) | 最初の正しいchunkが平均で何位にあるか |
Context Recallが低い → chunkが小さすぎる、分割戦略が重要情報を切断している、または検索top-Kが小さすぎる可能性があります。 Context Precisionが低い → chunkが大きすぎて無関係な内容を含む、またはrerankingが不足している可能性があります。
4.2 生成品質の評価
「LLMの回答品質」を評価します。
| 指標 | 意味 |
|---|---|
| Faithfulness | 回答が検索contextに忠実か、それともハルシネーションしているか |
| Answer Correctness | 回答が期待する答えと一致するか |
| Answer Relevancy | 回答がユーザーの質問と関連するか |
Faithfulnessが低い → モデルがcontext外の情報を「捏造」しています。promptを調整するかtemperatureを下げる必要があります。 Answer Correctnessが低く、Faithfulnessが高い → 検索層の問題であり、モデルへ渡したcontextが誤っています。
4.3 エンドツーエンド評価
エンドツーエンド評価では、検索と生成を分けず、ユーザーの質問から最終回答までの全体品質を測ります。
最も効果的な方法は、(question, ground_truth_answer)の組を用意し、pipeline全体を実行して、システム出力とground truthを比較することです。
4.4 引用品質の評価
以前に扱った引用の話題は、ここに位置します。システムが生成した引用が原文を正確に指しているか評価します。
評価ツール: RagasとDeepEvalは2026年に最も広く使われたRAG評価フレームワークで、上記のすべての指標を扱います。学習計画にも両ツールが含まれています。
Evaluation-Driven Developmentの流れ:
- 50〜100件の評価データを用意します。
- 初期設定でbaselineを実行します。
- 各指標を記録します。
- 一度に一つの引数だけを変え、指標の変化を比較します。
- 改善を繰り返します。
5. 運用層(Operations)
プロトタイプと本番の差は、ここにあります。
5.1 可観測性(Observability)
必ず監視する指標:
- 各段階の遅延(embedding、検索、LLM生成)
- リクエストごとのtoken消費量とコスト
- 検索で返したchunk数と関連度scoreの分布
- LLM回答のfaithfulness score(LLM-as-judgeで自動評価可能)
- エラー率(API timeout、embedding失敗、検索結果なし)
ツール: 導入を予定しているLangfuseは、2026年に最も広く使われたLLM observabilityプラットフォームの一つで、各リクエストがpipelineを通る完全な経路をtraceできます。
5.2 インデックス更新(Index Refresh)
文書は更新されます。RAGシステムには、インデックスを原文書と同期させる戦略が必要です。
- 全体再構築: 文書数が1万件未満の小規模な場面に適し、定期的に全件をchunking、embeddingし直します。
- 差分更新: 新規・変更文書だけを処理します。ファイルhashまたは更新日時で文書バージョンを追跡する必要があります。
- 更新頻度: 製品カタログ、サポート知識ベースなど動的な内容は毎日。技術マニュアル、契約書など静的な文書は毎週または手動で実行します。
5.3 コスト最適化
RAGのコストは主に三か所から生じます。
- Embedding API呼び出し: 取り込み時の一度限りのコストと、インデックス更新時の反復コスト
- LLM API呼び出し: ユーザーqueryごとに必要で、継続コストの大半を占める
- ベクトルデータベースの保存とquery: データ量とQPSに比例
最適化方法:
- Semantic Cache: 類似queryには以前の結果を直接返し、LLMを再度呼び出さないことで、LLMコストを大幅に削減します。
- Model Routing: 単純な質問は安価で高速な小型モデル、複雑な質問は強力な大型モデルで処理します。
- embedding次元の削減: Matryoshka embeddingで次元を下げ、保存・queryコストを削減します。
5.4 セキュリティとコンプライアンス
- Prompt injection防御: ユーザーがqueryへ悪意のある指示を埋め込み、LLMにcontextを漏らさせたり、想定外の処理をさせたりする可能性があります。入力フィルタと出力検査が必要です。
- データ分離: マルチテナントシステムでは、tenant Aのqueryがtenant Bの文書を検索してはいけません。query時に
tenant_idの条件を加えるmetadata filterで実現します。 - PII処理: 文書に個人情報が含まれる場合は、取り込み段階でマスキングするか、結果を返すときにフィルタします。
- データ主権: データを国外へ出せない場合は、cloud APIではなく、セルフホストのembeddingモデルとベクトルデータベースを使います。
6. 高度なアーキテクチャパターン
以上が標準RAGアーキテクチャです。標準構成の評価指標が頭打ちになったら、次の高度なパターンを検討できます。
Agentic RAG
検索が必要か、何を検索するか、何回検索するかをLLM自身に判断させます。固定された「一度検索 → 生成」ではなく、agent loopを使います。モデルは一度検索し、情報が足りなければqueryを書き換えて二度目の検索を行い、十分なcontextが集まるまで続けてから回答を生成します。
GraphRAG
ベクトル検索に加えて知識グラフを導入します。ベクトル検索は意味の近い文章を探すことに強い一方、「A社のCEOとB社のCTOは同窓生か」のような、文書をまたぐ推論を必要とする質問は不得意です。知識グラフはエンティティと関係を保存し、構造化推論能力を補います。
Multi-Modal RAG
テキストだけでなく、画像、表、グラフも検索します。たとえばユーザーが「Q3の売上傾向はどうだったか」と質問すると、関連する表やグラフを検索し、多モーダルモデルへ一緒に渡します。
Self-RAG
生成中にモデルが自己評価します。まず回答の一部を生成し、「この記述を裏づけるために、さらに情報を検索する必要があるか」と判断します。必要なら追加検索を実行します。RAGと推論を深く統合する方法です。
最初のRAGプロジェクトをどう作るか
学習計画と技術スタックの選択に基づき、次の経路を提案します。
第1段階:最小構成のRAG
最も単純な設定で全処理を動かします。
- Markdown/PDF文書 → Recursive Splitting(512 tokens)→ BGE-M3 embedding → pgvectorへ保存
- ユーザーquery → ベクトル検索top-5 → Claude/GPTで回答生成
- Ragasでbaseline evaluationを一度実行
第2段階:中核的な最適化を追加
evaluationの結果に基づいて、次の要素を段階的に加えます。
- Hybrid retrieval(ベクトル + BM25)
- Reranking(BGE-RerankerまたはCohere)
- Query Rewriting
- Contextual Chunking
要素を一つ追加するたびにevaluationを実行し、改善を数値化します。
第3段階:本番化
- Langfuse observabilityを追加
- 差分インデックス更新を実装
- Semantic Cacheを追加
- GCP Cloud Runへデプロイ
この経路は、v4学習計画にある、Production RAG Systemを最初のportfolioプロジェクトとする目標に合致します。
参考資料
- Lewis et al., “Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks”, Facebook AI Research, 2020 — RAGの原論文
- NVIDIA Technical Blog: Finding the Best Chunking Strategy for Accurate AI Responses, 2025
- Anthropic: Contextual Retrieval Paper, 2024
- Vectara / FloTorch Benchmark: 50 academic papers, 7 strategies, February 2026
- Redis Blog: RAG at Scale — How to Build Production AI Systems in 2026
- PremAI: Building Production RAG — Architecture, Chunking, Evaluation & Monitoring, 2026
- Towards AI: 9 RAG Architectures Every AI Developer Must Know, 2026
- ZTABS: RAG Architecture Explained — Complete Guide, 2026