RAG: 検索拡張生成の説明
I 大規模言語モデル (LLM) それらは技術革新の一つを表しています 近年で最も破壊的なもの: GPT-4、Claude、Gemini、Llama はコードを書くことができます。 文書を要約し、複雑な質問に答え、さらには抽象的な問題について推論することもできます。 しかし、それらは適用性を大幅に制限する構造的欠陥に悩まされています。 専門的な背景: 幻覚.
LLM は答えがわからないとき、「わかりません」とは言いません。代わりに、もっともらしいテキストを生成します しかし、それは完全に誤りであり、検証可能な事実を自信を持って提示しています。 ビジネス、法律、医療の現場では、このような行為は容認できません。解決策 この問題に対してより効果的で成熟したものは、 検索拡張生成 (RAG).
このシリーズの最初の記事では AIエンジニアリングと高度なRAG、出発します 基本から: RAG とは何か、RAG がどのように機能するか、なぜ RAG が幻覚の問題を解決するのか 動作する RAG システムを最初から構築する方法についても説明します。終わったら理解できるようになります アーキテクチャ全体に関する確かな知識があれば、個々のコンポーネントをさらに深く掘り下げる準備が整います 以降の記事で。
シリーズ概要
| # | アイテム | 集中 |
|---|---|---|
| 1 | あなたはここにいます - RAG の説明 | 基礎と完全なアーキテクチャ |
| 2 | 埋め込みとセマンティック検索 | テキストがベクトルになる仕組み |
| 3 | ベクトルデータベースの詳細 | ストレージ、インデックス作成、類似性検索 |
| 4 | LangChain と Python を使用した RAG | 実用的なエンドツーエンドの実装 |
| 5 | ハイブリッド検索と再ランキング | ハイブリッドキーワード + セマンティック検索 |
| 6 | コンテキストウィンドウとプロンプトエンジニアリング | LLM のコンテキストを最適化する |
| 7 | 本番環境の RAG | スケーリング、モニタリング、評価 |
| 8 | ナレッジグラフとRAG | ナレッジグラフ + 検索 |
| 9 | マルチエージェントシステム | 協調型 AI エージェント |
| 10 | RAGの未来 | トレンド、調査、次のステップ |
何を学ぶか
- RAG とは何か、LLM にとって RAG が解決する根本的な問題
- 完全なアーキテクチャ: 文書の準備から応答の生成まで
- 埋め込み、ベクター ストア、類似性検索の仕組み
- チャンク戦略とそのトレードオフ
- Python を使用して最小限の動作する RAG システムを構築する方法
- Naive RAG と Advanced RAG の違い
- RAG をいつ使用するか、微調整を使用するか、プロンプト エンジニアリングを使用するか
1. LLM における幻覚の問題
なぜ RAG が必要なのかを理解するには、まず RAG が解決する問題を理解する必要があります。 大規模言語モデルは本質的に、 言語の確率モデル: 入力テキストが与えられると、最も可能性の高いトークンのシーケンスが継続として予測されます。 このアーキテクチャは、 注意 トランスフォーマーのプロデュース 驚くべき結果が得られますが、本質的な制限があります。モデルは人間の感覚では何も「認識」しません。 用語の。学習したパターンに基づいて統計的に妥当なテキストを生成する トレーニング。
LLM の 3 つの構造的問題
| 問題 | 説明 | 実用的な影響 |
|---|---|---|
| 知識の遮断 | 知識はトレーニング当日に凍結されます | 最近のイベントや独自のデータに関する情報はありません |
| 幻覚 | もっともらしいが完全に捏造された回答を生成する | 高い信頼度で提示された虚偽の情報 |
| 引用符なし | 彼は自分の発言の出典を明らかにできない | 回答の正しさを検証することができません |
| 個人データなし | 彼は会社の内部文書を知りません | コンテキストのない特定のユースケースには役に立たない |
幻覚は一度限りのバグではなく、アーキテクチャの直接的な結果です。 モデルに応答するのに十分な情報がない場合、エラーは返されません。 代わりに、テキストの最も可能性の高い継続を生成します。 発明した。モデルは、流暢で一貫したテキストを生成するようにトレーニングされたものではありません。 事実が正確であること。
幻覚の具体例
問題の深刻さを理解するために、幻覚が起こる実際のシナリオを考えてみましょう。 重大な影響を及ぼします:
- 法的範囲: LLM は、信頼できるが発明された項目番号を使用して、存在しない判決や制定されたことのない法律を引用する可能性があります。
- 医療分野: 間違った薬物投与量や文書化されていない薬物相互作用を示唆する可能性があります
- 技術文書: 存在しないパラメータや実装されていない機能を含む API が記述されている可能性があります。
- カスタマーサポート: 彼らは会社のポリシー、返品手順、または存在しない保証をでっち上げる可能性があります
統計は問題の規模を裏付けています:幻覚の割合はさまざまです 医学や法律などの専門分野ごとに大きく分かれています。 最も先進的なモデルでも 10 ~ 20% のレートを記録します。 RAGは技術を表します この問題を軽減するのに最も効果的であり、最大 71% の削減が文書化されています。
2. RAG とは: 定義と起源
検索拡張生成 (RAG) それは建築パラダイムです のシステムを組み合わせます 情報検索 (ドキュメントのリカバリ) テンプレートを使用 生成 (LLM) は、実際のデータに基づいて回答を生成します。 The concept has been formalized 2020年、パトリック・ルイスとメタAIの同僚による独創的な論文 「知識集約型 NLP タスクのための検索拡張生成」.
重要な洞察はシンプルです。モデルにすべてを「記憶」するよう求めるのではなく、 彼のトレーニングから得た情報に基づいて、私たちはトレーニングの際に関連する文書を彼に提供します。 世代。このプロセスはと呼ばれます 接地: アンカーの生成 具体的で検証可能な情報源に。
LLM TRADIZIONALE:
Domanda utente ──────────────────> [LLM] ──> Risposta
|
Basata SOLO su training data
Rischio allucinazione: ALTO
RAG (Retrieval-Augmented Generation):
Domanda utente ──> [RETRIEVAL] ──> Documenti rilevanti
| |
| v
└───────> [LLM + Contesto] ──> Risposta con citazioni
|
Basata su DATI REALI recuperati
Rischio allucinazione: BASSO
例え: オープンブック試験
大学受験を想像してみてください。従来の LLM は、答えなければならない学生のようなものです 暗記:多くのことを知っていますが、混乱したり、詳細を考え出すことがあります。 RAG は次のようなものです 試験 開いた本: 学生は自分のノートや本を参照できます 答える前に。答えは確立されているため、より正確かつ検証可能になります。 具体的な情報源について。
グラウンディングの概念は非常に重要です。生成された応答内のすべてのステートメントは次のようになります。 ナレッジベース内の特定のドキュメントまで遡ります。これは次のことを意味します。
- 答えは次のとおりです。 検証可能な:ソースドキュメントを確認できます
- 答えは次のとおりです。 更新可能: 文書を更新すると、回答が自動的に変わります
- 答えは次のとおりです。 制御可能な: システムがどのドキュメントを参照できるかを決定します
- 答えは次のとおりです。 追跡可能: 出典を参照して引用符を含めることができます
3. RAG の仕組み: 完全なパイプライン
RAG システムは 2 つのマクロフェーズで構成されます。 インデックス作成パイプライン、 文書を 1 回限り (または定期的に) 作成します。 クエリパイプライン、 ユーザーのクエリをリアルタイムで処理します。
3.1 インデックス作成パイプライン (オフラインフェーズ)
インデックス作成フェーズでは、生のドキュメントを最適化された構造に変換します。 セマンティック検索用。これは 4 つの連続したステップで構成されます。
[Documenti Sorgente]
| PDF, HTML, Markdown, CSV, database, API, email...
v
[1. DOCUMENT LOADING]
| Estrazione del testo grezzo dai formati sorgente
| Preservazione dei metadati (autore, data, titolo)
v
[2. CHUNKING (Text Splitting)]
| Divisione in frammenti di dimensione gestibile
| Strategie: fixed-size, semantic, recursive
| Overlap tra chunk per preservare contesto
v
[3. EMBEDDING]
| Trasformazione di ogni chunk in un vettore numerico
| Modelli: OpenAI, Sentence Transformers, Cohere
| Dimensioni tipiche: 384, 768, 1536, 3072
v
[4. VECTOR STORE]
| Salvataggio dei vettori in un database specializzato
| Indexing per ricerca veloce (HNSW, IVF)
| ChromaDB, Pinecone, Weaviate, Milvus, Qdrant
v
[Knowledge Base Pronta per le Query]
3.2 クエリ パイプライン (オンライン フェーズ)
ユーザーが質問すると、クエリ パイプラインが動作を開始して検索します。 最も関連性の高い文書を抽出し、十分な根拠のある応答を生成します。
[Domanda dell'Utente]
| "Come configuro l'autenticazione OAuth nella nostra app?"
v
[1. QUERY EMBEDDING]
| La domanda viene trasformata in vettore
| Stesso modello usato nell'indicizzazione!
v
[2. SIMILARITY SEARCH]
| Ricerca dei chunk più simili nel vector store
| Metriche: cosine similarity, L2, dot product
| Restituisce i top-k risultati (tipicamente k=3..10)
v
[3. CONTEXT ASSEMBLY]
| I chunk recuperati vengono assemblati in un contesto
| Ordinamento per rilevanza, deduplicazione
v
[4. PROMPT CONSTRUCTION]
| Costruzione del prompt con contesto + domanda
| Template: "Basandoti sui seguenti documenti, rispondi..."
v
[5. LLM GENERATION]
| Il modello genera la risposta basandosi sul contesto
| Può includere citazioni ai documenti sorgente
v
[Risposta Fondata + Citazioni]
基本ルール: 埋め込みの一貫性
E' 義務的な 両方で同じ埋め込みモデルを使用します。 クエリフェーズよりもインデックスを作成します。異なるモデルがベクトル空間を生成する 互換性がない: モデルによって生成されたベクトルは、モデルによって生成されたベクトルと比較できません。 別の。埋め込みモデルを変更するには、完全な再インデックスが必要です すべての書類の。
4. ドキュメント処理: チャンク化と準備
Il チャンク化 これは、RAG パイプライン全体の最も重要なフェーズの 1 つです。 結果の品質は、ドキュメントがどのように分割されているかに大きく依存します。 大きすぎるチャンクは意味信号を薄め、コンテキスト ウィンドウ内のスペースを無駄にします。 LLMの。チャンクが小さすぎると、理解するために必要なコンテキストが失われます。
4.1 固定サイズのチャンク化
最も単純な戦略: テキストを固定サイズのブロックに分割します (例: 500 トークン) 連続するチャンク間のオーバーラップはオプションで可能です。
固定サイズのチャンク化パラメータ
| パラメータ | 説明 | 代表値 |
|---|---|---|
| チャンクサイズ | トークンまたは文字の各チャンクの最大サイズ | 300~500トークン |
| チャンク_オーバーラップ | 連続するチャンク間のオーバーラップ | chunk_size の 10 ~ 20% |
| セパレータ | 分割に使用する文字/文字列 | "\n\n"、"\n"、" " |
Documento originale (1500 token):
"Lorem ipsum dolor sit amet... [1500 token di testo]"
Con chunk_size=500 e overlap=50:
Chunk 1: token 1-500 ────────────┐
Chunk 2: token 451-950 ──┐ overlap │
Chunk 3: token 901-1400 ──┘ │
Chunk 4: token 1351-1500 │
────────────┘
L'overlap garantisce che il contesto ai bordi non venga perso.
4.2 再帰的な文字分割
文書の構造を尊重しながら分割を試みる、より洗練された戦略。 区切り記号の階層を使用します。まず段落 ("\n\n") で区切ってみてください。 次に行単位 ("\n")、次に文単位 (". ")、最後に単語単位 (" ") です。 これにより、固定サイズよりもセマンティック コンテキストが保持されます。
4.3 セマンティックチャンク化
最も高度な戦略: エンベディング自体を使用して、分割する場所を決定します。 連続した文間の類似度を計算し、類似度が一致した場合に新しいチャンクを作成します。 しきい値を下回った場合は、話題の変更を示します。サイズの塊を生成します 可変ですが意味的には一貫しています。
チャンキング戦略の比較
| 戦略 | 品質 | 複雑 | いつ使用するか |
|---|---|---|---|
| 固定サイズ | 基本 | 最小限 | プロトタイピング、均質なドキュメント |
| 再帰的 | 良い | 低い | 汎用の構造化ドキュメント |
| セマンティクス | 素晴らしい | 高い | 高品質が求められる異種ドキュメント |
メタデータの重要性
それぞれの塊には神が宿るはずです メタデータ: ドキュメントのタイトル、 著者、日付、セクション、ページ。このメタデータはフィルタリングに重要です 検索中に、応答内で正確な引用を生成するために。何もないチャンク メタデータはコンテキストのない段落のようなものです。
5. 埋め込み: テキストをベクトルに変換する
Gli 埋め込み それらは RAG の数学的中心部です。埋め込みとは、 をキャプチャする数値表現 (10 進数のベクトル) 意味論的な意味 テキストの。似た意味を持つ 2 つの文は次のようになります。 使用される単語に関係なく、多次元空間内の「近くの」ベクトル。
INPUT: Frase di testo
OUTPUT: Vettore di numeri decimali (es. 1536 dimensioni)
Esempio:
"Il gatto dorme sul divano" --> [0.23, -0.45, 0.67, 0.12, -0.89, ...]
"Il felino riposa sul sofa" --> [0.22, -0.44, 0.68, 0.11, -0.88, ...]
^^ Vettori molto SIMILI (stesso significato)
"Il prezzo dell'oro sale" --> [-0.56, 0.78, -0.12, 0.91, 0.34, ...]
^^ Vettore molto DIVERSO (significato diverso)
埋め込みモデルは、膨大な量のテキストでトレーニングされたニューラル ネットワークです。 単語、文、概念間の意味的な関係を学びます。ただ生み出すだけではなく、 構文表現 (bag-of-words や TF-IDF など) ですが、意味を捉えています 文章の深さ。
主要な埋め込みモデル (2025 ~ 2026 年)
| モデル | 寸法 | プロバイダー | 参考コスト |
|---|---|---|---|
text-embedding-3-small |
1536年 | OpenAI | ~$0.02 / 100 万トークン |
text-embedding-3-large |
3072 | OpenAI | ~0.13ドル/100万トークン |
voyage-3-large |
1024 | 航海AI | ~$0.06 / 100万トークン |
all-MiniLM-L6-v2 |
384 | ハグ顔 | 無料(自己ホスト型) |
nomic-embed-text |
768 | オラマ (地元) | 無料(ローカル) |
embed-v4 |
1024 | コヒア | ~0.10ドル/100万トークン |
埋め込みモデルの選択はユースケースによって異なります。最大のモデル (3072 寸法) はより豊富な表現を提供しますが、コストが高くなります ストレージと計算。多くのユースケースでは、768 ~ 1536 サイズのモデルが優れた性能を発揮します。 品質とコストの優れた妥協点。
6. Vector Store: 埋め込み用データベース
Un ベクトルストア (またはベクトル データベース) は、 高次元ベクトルを保存、インデックス付け、検索します。とは異なり、 完全一致を探す従来のデータベース (SQL WHERE)、ベクトル ストア 他の通信事業者を検索する 似ている クエリのものに。
6.1 類似性メトリクス
ベクトル ストアの検索は、ベクトル間の距離/類似性メトリクスに基づいています。 最も一般的な 3 つの指標は次のとおりです。
類似性メトリックの比較
| メトリック | 範囲 | 説明 | いつ使用するか |
|---|---|---|---|
| コサイン類似度 | [-1、1] | 2 つのベクトル間の角度を測定します。大きさは無視します。 | ほとんどの場合デフォルト (推奨) |
| ユークリッド距離(L2) | [0, +inf) | 空間内の幾何学的距離、大きさに敏感 | ベクトルの大きさが重要な場合 |
| 内積 | (-inf、+inf) | スカラー積、方向と大きさを組み合わせたもの | すでに正規化されたベクトル、最大内積検索 |
6.2 ベクトルデータベースの概要
RAG の採用により、ベクトル データベース市場が爆発的に拡大しました。概要は次のとおりです 利用可能な主なツール:
ベクターデータベースの比較
| データベース | タイプ | 言語 | 理想的な用途 |
|---|---|---|---|
| クロマDB | 組み込み/サーバー | パイソン | プロトタイピング、ローカル開発、小規模データセット |
| 松ぼっくり | クラウド管理 | 多言語対応 | 本番環境、自動スケーリング、ゼロオペレーション |
| ウィアビエイト | セルフホスト型 / クラウド型 | Go | ハイブリッド検索、マルチテナント、GraphQL |
| ミルバス | セルフホスト型 / クラウド型 | Go / C++ | 大容量、高性能、エンタープライズ |
| クドラント | セルフホスト型 / クラウド型 | さび | パフォーマンス、高度なフィルタリング、REST API |
| ベクター | PostgreSQL 拡張機能 | C | 既存の PostgreSQL スタック、リレーショナル + ベクター データ |
| フェイス | インメモリライブラリ | C++ / Python | リサーチ、ベンチマーク、最大限の最適化 |
始めるには、 クロマDB これは最も単純な選択です。pip でインストールされます。 メモリ内またはディスク上で永続的に動作し、LangChain とネイティブに統合されます。 運用環境の場合、Pinecone (マネージド) と Qdrant (セルフホスト) がオプションの 1 つです 最も人気のある。
7. 検索: 関連文書の検索
の段階 検索 ユーザーの質問が来た瞬間です ベクトルに変換され、ベクトル ストア内のすべてのベクトルと比較されて見つかります。 最も関連性の高いチャンク。このプロセスは数百万秒かかっても数ミリ秒で行われます HNSW などの近似インデックス作成アルゴリズムのおかげで、インデックス付きドキュメントが作成されます。 (階層型ナビゲート可能なスモールワールド)。
Query: "Come configuro OAuth nella nostra app?"
|
v
[1] Embedding della query ──> [0.34, -0.21, 0.56, ...]
|
v
[2] Similarity Search nel Vector Store
| Confronta il vettore della query con tutti i vettori salvati
| Usa cosine similarity come metrica
|
v
[3] Top-K Results (es. k=5)
|
| Score: 0.92 - "Configurazione OAuth 2.0 per applicazioni web..."
| Score: 0.87 - "Guida ai flussi di autenticazione OAuth..."
| Score: 0.83 - "Impostazione dei redirect URI per OAuth..."
| Score: 0.76 - "Confronto tra OAuth e SAML per SSO..."
| Score: 0.71 - "Sicurezza delle API con token JWT..."
|
v
[4] Filtering e Reranking (opzionale)
| Filtra per metadati (data, categoria, fonte)
| Reranking con modello cross-encoder
|
v
[Chunk Rilevanti Pronti per il Prompt]
7.1 Top-K パラメータ
パラメータ トップ-k 復元されるチャンクの数を決定します。選択 それはトレードオフです:
- K が低すぎる (1-2): 関連情報が欠落するリスク
- K が高すぎる (20+): コンテキスト内のノイズが多すぎる、トークンの無駄、モデルを混乱させるリスク
- 最適な K (3-7): カバレッジと精度のバランスが良い
7.2 関連性スコアリング
それぞれの結果には、 関連性スコア (関連性スコア)。チャンク スコアが低い場合は、無価値なノイズが追加されるため、フィルタリングする必要があります。 コサイン類似度の一般的なしきい値は 0.7 で、以下のものはすべて破棄されます。 実際には、最適なしきい値はドメインによって異なるため、実験的に調整する必要があります。
8. 生成: LLM を使用した応答の構築
RAG パイプラインの最終段階: 取得されたチャンクが組み立てられて 構造化されたコンテキスト とともに LLM プロンプトに挿入されます。 ユーザーの質問。モデルは、(または 主に) 提供されたコンテキストに基づいて。
8.1 プロンプトテンプレート
優れた RAG プロンプト テンプレートでは、モデルに次のことを指示する必要があります。
- 使用 一人で 提供されたコンテキストからの情報
- 書類に答えが見つからない場合は認める
- 可能な限り出典を引用する
- 文脈にない情報をでっち上げないでください
Sei un assistente tecnico. Rispondi alle domande SOLO basandoti
sul contesto fornito. Se la risposta non è presente nel contesto,
rispondi "Non ho trovato informazioni sufficienti nei documenti
disponibili."
CONTESTO:
---
{context}
---
DOMANDA: {question}
ISTRUZIONI:
1. Rispondi in modo chiaro e conciso
2. Cita il documento sorgente tra parentesi quadre [Fonte: nome_doc]
3. Se il contesto non contiene la risposta, dillo esplicitamente
4. Non inventare informazioni non presenti nel contesto
RISPOSTA:
8.2 引用追跡
RAG の最も価値のある機能の 1 つは、引用を追跡する機能です。 コンテキスト内の各チャンクには識別子 (例: [DOC-1]、[DOC-2]) を付けることができます。 そしてモデルは応答でこれらの識別子を参照するように指示されます。これ ユーザーは元の文書を参照して各ステートメントを検証できます。
コンテキストウィンドウと制限
挿入できるコンテキストの量は次の制限によって制限されます。 コンテキストウィンドウ LLMモデルの。復元されたチャンクが制限を超える場合は、 最も関連性の高いもの、またはそれらを要約したもの。 GPT-4o (128K トークン) や Claude 3.5 などの最新モデル (200K トークン) は非常に大きなコンテキスト ウィンドウを持ちますが、それでも、挿入するコンテキストが多すぎます 無関係な場合は、回答の質が低下します (いわゆる「途中で迷った」問題)。
9. 完全な RAG アーキテクチャ: 概要
各コンポーネントを個別に見てきたので、アーキテクチャを組み立ててみましょう。 エンドツーエンドの RAG システムが完成します。
FASE OFFLINE (Indicizzazione)
┌──────────────────────────────────────────────────────┐
│ │
│ [Documenti] ──> [Loader] ──> [Chunker] │
│ PDF, HTML Estrazione Divisione │
│ MD, CSV testo in frammenti │
│ │ │
│ v │
│ [Embedding Model] │
│ Testo ──> Vettore │
│ │ │
│ v │
│ [Vector Store] │
│ ChromaDB, Pinecone │
│ Weaviate, Qdrant │
│ │
└──────────────────────────────────────────────────────┘
FASE ONLINE (Query)
┌──────────────────────────────────────────────────────┐
│ │
│ [Domanda Utente] │
│ │ │
│ v │
│ [Query Embedding] ──> [Similarity Search] │
│ Stesso modello Top-K chunk │
│ dell'indicizzazione │ │
│ v │
│ [Context Assembly] │
│ Chunk + Metadati │
│ │ │
│ v │
│ [Prompt Template + Contesto + Domanda] │
│ │ │
│ v │
│ [LLM] │
│ GPT-4, Claude │
│ Llama, Gemini │
│ │ │
│ v │
│ [Risposta con Citazioni] │
│ │
└──────────────────────────────────────────────────────┘
メンバーと責任
| 成分 | 責任 | 代表的なツール |
|---|---|---|
| ドキュメントローダー | さまざまなソースからドキュメントをアップロードする | LangChain ローダー、非構造化、LlamaIndex |
| テキストスプリッター | ドキュメントを最適なチャンクに分割する | RecursiveCharacterTextSplitter、SemanticChunker |
| 埋め込みモデル | テキストを意味ベクトルに変換する | OpenAI エンベディング、センテンス トランスフォーマー、Cohere |
| ベクターストア | ベクトルの保存とインデックス付け | ChromaDB、松ぼっくり、Qdrant、pgvector |
| レトリバー | 最も関連性の高いチャンクを検索する | 類似検索、MMR、ハイブリッド検索 |
| LLM | コンテキストから最終応答を生成する | GPT-4o、クロード 3.5、ラマ 3、ジェミニ プロ |
10. 実践例: Python を使用した最小 RAG
必要な最小限のコードで動作する RAG システムを構築しましょう。使用します ラングチェーン オーケストレーションフレームワークとして、 OpenAI 埋め込みと生成の場合、e クロマDB ローカルのベクトル ストアとして。
10.1 プロジェクトのセットアップ
# Crea un ambiente virtuale
python -m venv rag-env
source rag-env/bin/activate # Linux/Mac
# Installa le dipendenze
pip install langchain langchain-openai langchain-community
pip install chromadb
pip install pypdf # Per caricare PDF
10.2 インデックス作成パイプライン
import os
from langchain_community.document_loaders import (
PyPDFLoader,
TextLoader,
DirectoryLoader
)
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
# Configura la API key
os.environ["OPENAI_API_KEY"] = "sk-..."
# 1. DOCUMENT LOADING
# Carica tutti i PDF da una cartella
loader = DirectoryLoader(
"./documenti/",
glob="**/*.pdf",
loader_cls=PyPDFLoader
)
documents = loader.load()
print(f"Caricati {len(documents)} documenti")
# 2. CHUNKING
# Divisione ricorsiva con overlap
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 500 caratteri per chunk
chunk_overlap=50, # 50 caratteri di overlap
length_function=len,
separators=["\n\n", "\n", ". ", " ", ""]
)
chunks = text_splitter.split_documents(documents)
print(f"Creati {len(chunks)} chunk")
# 3. EMBEDDING + 4. VECTOR STORE
# Crea gli embeddings e salvali in ChromaDB
embedding_model = OpenAIEmbeddings(
model="text-embedding-3-small"
)
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embedding_model,
persist_directory="./chroma_db",
collection_name="documenti_aziendali"
)
print("Vector store creato e salvato su disco")
10.3 クエリパイプライン
import os
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
os.environ["OPENAI_API_KEY"] = "sk-..."
# Carica il vector store esistente
embedding_model = OpenAIEmbeddings(
model="text-embedding-3-small"
)
vectorstore = Chroma(
persist_directory="./chroma_db",
embedding_function=embedding_model,
collection_name="documenti_aziendali"
)
# Configura il retriever
retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 5} # Recupera i 5 chunk più simili
)
# Definisci il prompt template
prompt_template = PromptTemplate(
template="""Sei un assistente tecnico esperto.
Rispondi alla domanda basandoti SOLO sul contesto fornito.
Se non trovi la risposta nel contesto, dillo esplicitamente.
CONTESTO:
{context}
DOMANDA: {question}
RISPOSTA (con citazioni ai documenti fonte):""",
input_variables=["context", "question"]
)
# Crea la chain RAG
llm = ChatOpenAI(
model="gpt-4o",
temperature=0 # Deterministic per risposte fattuali
)
rag_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # Inserisci tutti i chunk nel prompt
retriever=retriever,
return_source_documents=True,
chain_type_kwargs={
"prompt": prompt_template
}
)
# Esegui una query
result = rag_chain.invoke(
{"query": "Come configuro l'autenticazione OAuth?"}
)
# Stampa la risposta
print("RISPOSTA:")
print(result["result"])
print("\nFONTI:")
for doc in result["source_documents"]:
print(f" - {doc.metadata.get('source', 'N/A')}"
f" (pagina {doc.metadata.get('page', 'N/A')})")
期待される出力
RISPOSTA:
Per configurare l'autenticazione OAuth nella nostra applicazione,
segui questi passaggi:
1. Registra l'app nel provider OAuth (Google, GitHub, etc.)
2. Configura i redirect URI nel file config.yaml [Fonte: guida-oauth.pdf]
3. Implementa il flusso Authorization Code [Fonte: architettura-auth.pdf]
...
FONTI:
- documenti/guida-oauth.pdf (pagina 12)
- documenti/architettura-auth.pdf (pagina 5)
- documenti/faq-sicurezza.pdf (pagina 3)
10.4 プロジェクトの構造
rag-project/
├── documenti/ # I tuoi documenti sorgente
│ ├── guida-oauth.pdf
│ ├── architettura.pdf
│ └── faq.pdf
├── chroma_db/ # Vector store persistente (generato)
├── indexing.py # Script di indicizzazione
├── query.py # Script di query
├── requirements.txt # Dipendenze
└── .env # API keys (mai committare!)
11. 単純な RAG と高度な RAG
私たちがこれまで構築してきたシステムは、コミュニティで呼ばれるものです ナイーブ RAG: 単純かつシンプルな実装で、多くのユースケースで驚くほどうまく機能します。 ただし、テクニックには限界があります 高度な RAG 彼らは求めています 克服するために。
11.1 Naive RAG の制限
- クエリとドキュメントの不一致: 質問では文書とは異なる用語が使用されている可能性があります。 「パスワードをリセットするにはどうすればいいですか?」 vs ドキュメント「資格情報の回復手順」
- チャンク境界の問題: 関連情報が 2 つの連続するチャンクの間で分割される可能性があります
- 途中で迷った場合: LLM は、コンテキストの最初と最後のチャンクに重点を置き、中心のチャンクを無視する傾向があります。
- シングルホップの制限: 複数の文書からの要約が必要な質問には回答できません
11.2 高度な RAG テクニック
素朴な RAG から高度な RAG への進化
| 技術 | 問題は解決しました | 仕組み |
|---|---|---|
| クエリのリライト | あいまいな質問、または言葉遣いが不十分な質問 | LLM はクエリを検索により適した形式に書き換えます。 |
| ハイデ | クエリとドキュメントの不一致 | クエリから仮説的なドキュメントを生成し、類似したドキュメントを検索します。 |
| 再ランキング | 結果が最適に並べ替えられていない | クロスエンコーダーモデルは、関連性によって結果を並べ替えます |
| マルチクエリ | 単一の研究の視点 | クエリ バリアントを生成して対象範囲を拡大する |
| セルフRAG | 取り出しが不要な場合 | モデルは自律的に取得するかどうか、いつ取得するかを決定します。 |
| マルチホップ RAG | 複雑な複数のステップからなる質問 | 複合推論を構築するための反復検索の連鎖 |
| ハイブリッド検索 | セマンティック検索だけの限界 | セマンティック (ベクトル) 検索とキーワードを組み合わせる (BM25) |
| グラフRAG | エンティティ間の複雑な関係 | ナレッジ グラフを使用して構造化された関係とコンテキストをナビゲートする |
NAIVE RAG:
Query ──> Embedding ──> Search ──> Top-K ──> LLM ──> Risposta
ADVANCED RAG:
Query ──> [Query Analysis]
│
├──> Query Rewriting ──> Embedding ──> Search ─┐
├──> HyDE Generation ──> Embedding ──> Search ─┤
└──> Multi-Query ──────> Embedding ──> Search ─┘
│
[Merge + Deduplica]
│
[Reranker Model]
│
[Context Compression]
│
[LLM + Citazioni]
│
[Risposta Verificata]
これらの各テクニックについては、シリーズの後続の記事でさらに詳しく説明します。 特に次の記事では ハイブリッド検索と再ランキング.
12. RAG をいつ使用するか: 意思決定フレームワーク
RAG はすべての問題に対する答えではありません。大きく分けて3つのアプローチがあり、 LLM の動作をカスタマイズします。それぞれに明確な利点と制限があります。 選択は特定の使用例によって異なります。
RAG vs 微調整 vs 迅速なエンジニアリング
| 基準 | 迅速なエンジニアリング | ラグ | 微調整 |
|---|---|---|---|
| 初期費用 | 最小 | 中くらい | 高い |
| 必要なデータ | 誰でもない | 知識ベース | トレーニングデータセット |
| アップデート | 即時(即時変更) | 速い(文書を更新する) | 遅い (再トレーニング) |
| レイテンシ | 低い | メディア (検索 + 生成) | 低い |
| 事実の正確さ | モデルによって異なります | 高(文書ベース) | 平均(トレーニングによって異なります) |
| 引用可能 | なし | 高 (トラックソース) | なし |
| 複雑 | 低い | 平均 | 高い |
12.1 実際的なデシジョンツリー
Hai bisogno di personalizzare un LLM?
│
├── I dati cambiano frequentemente? (documenti, policy, catalogo)
│ └── SI ──> RAG
│ (I dati si aggiornano senza re-training)
│
├── Serve citare le fonti?
│ └── SI ──> RAG
│ (Tracciabilita delle risposte)
│
├── Il dominio è stabile e ben definito?
│ ├── Hai un grande dataset di training?
│ │ └── SI ──> Fine-Tuning
│ │ (Personalizzazione profonda del comportamento)
│ └── NO ──> RAG oppure Prompt Engineering
│
├── Serve solo cambiare tono/formato/stile?
│ └── SI ──> Prompt Engineering
│ (Nessuna infrastruttura aggiuntiva)
│
└── Serve ragionamento complesso su dati proprietari?
└── SI ──> RAG + Fine-Tuning (Approccio Ibrido)
(Il meglio di entrambi i mondi)
黄金律
AI エンジニアリング コミュニティによって推奨されるアプローチは、複雑さのスケールに従います 昇順: エンジニアリングプロンプトから始める、次に進みます ラグ 外部データや引用が必要な場合は、 微調整 そのときだけ 最初の 2 つのアプローチでは不十分です。この進歩によりコストが最小限に抑えられます 複雑性を高め、ROI を最大化します。
12.2 RAG の理想的な使用例
- ビジネスチャットボット: 彼らは内部文書に基づいて対応します
- セマンティック検索: キーワードだけでなく意味に関連するドキュメントを検索する
- ナレッジベースのQ&A: ドキュメントに応じて更新される動的な FAQ
- 法務アシスタント: 規制や判例に基づいた回答
- テクニカルサポート: 以前のチケットと手動チケットに基づく解決策
- ドキュメンタリー分析: レポート、契約書、科学論文から洞察を抽出する
12.3 RAG を使用してはいけない場合
- クリエイティブなタスク: クリエイティブ ライティング、ブレインストーミング、アイデア生成 (テンプレートは無料である必要があります)
- 一般的な会話: 特定のデータを必要としないソーシャル チャットボット
- データが少ないタスク: ドキュメントが少数しかない場合は、迅速なエンジニアリングで十分な場合があります
- 厳密なリアルタイム応答: 取得遅延が許容できない場合 (50ms 未満)
13. RAG市場: 数字と傾向
RAG はもはや学術的な概念ではなく、運用アーキテクチャとして採用されています。 大規模に。市場の数字はその戦略的重要性を裏付けています。
数字で見る RAG (2024-2030)
| メトリック | 与えられた |
|---|---|
| 世界のRAG市場(2024年) | 約12億ドル |
| 市場予測(2030年) | ~110億ドル |
| 年間成長率 (CAGR) | 49.1% (2025-2030) |
| エンタープライズでの導入 | LLM ユースケースの 30 ~ 60% が RAG を使用 |
| 幻覚の軽減 | 適切に実装された RAG により最大 71% |
| 主要なフレームワーク | 80.5% が FAISS または Elasticsearch を使用 |
導入を促進する業界は法律、医療、カスタマー サポートおよびサービスです 財務、つまり事実の正確性と引用可能性が求められるすべての分野 ソースの数は交渉の余地のない要件です。 2025年から2026年にかけてトレンドは切り替わる 実験から大規模生産まで、ますます重点が置かれています。 コンプライアンス、モニタリング、データ品質。
14. 結論と次のステップ
この記事では、問題から RAG について包括的に理解しました。 これは、(LLM の幻覚を)エンドツーエンドのアーキテクチャに解決し、 パイプラインのすべてのコンポーネント。実際に動作する実装を見てきました そして、RAG を代替手段 (微調整、迅速なエンジニアリング) と比較しました。
主要な概念の概要
- ラグ 検索と生成を組み合わせて実際のデータに基づいた回答を生成します
- La インデックス作成パイプライン ドキュメントをベクトルに変換: ロード、チャンク化、埋め込み、ストレージ
- La クエリパイプライン 関連ドキュメントの検索と使用: 埋め込み、検索、アセンブリ、生成
- Il チャンク化 これは最も重要な決定の 1 つであり、検索の品質に直接影響します。
- Gli 埋め込み テキストの意味論的な意味を数値ベクトルで捉えます。
- I ベクトルストア 数百万のドキュメントで類似性検索が可能になります
- 高度な RAG Naive RAG の制限を克服するために、再ランキング、HyDE、マルチホップなどの技術を導入します。
- RAG は必要なときに最適です 更新され、検証可能で引用可能な回答
次の記事: 埋め込みとセマンティック検索
シリーズの次の記事では、RAG の最も魅力的なコンポーネントをさらに詳しく掘り下げます。 彼 埋め込み。それらが内部でどのように機能するのか、どのように選択するのかを見ていきます。 適切なモデル、その品質を評価する方法、セマンティック検索を最適化する方法。 また、評価指標と測定のためのベンチマーク手法についても調査します。 検索システムのパフォーマンス。
AIエンジニアリングシリーズとAdvanced RAG
| アイテム | 主題 |
|---|---|
| 01 - あなたはここにいます | RAG: 検索拡張生成の説明 |
| 02 - 次へ | 埋め込みと深度セマンティック検索 |
| 03 | Vector データベース: アーキテクチャとベスト プラクティス |
| 04 | LangChain と Python を使用した RAG システムの構築 |
| 05 | ハイブリッド検索: キーワード + セマンティクス + 再ランキング |
| 06 | RAG のコンテキスト ウィンドウとプロンプト エンジニアリング |
| 07 | 本番環境の RAG: モニタリング、評価、スケーリング |
| 08 | ナレッジグラフと構造化検索 |
| 09 | マルチエージェント システムとオーケストレーションされた RAG |
| 10 | RAG の将来: トレンドと研究 |







