モジュール 04 · 第 1 回

なぜ RAG が必要なのか

同じ質問でも、資料を与えなければモデルは間違え、関係するドキュメントの一節をプロンプトに入れれば正解します。RAG の基本的な流れ、何を解決するのか、そして向いていない場面を説明します。

  • 約 25 分
  • 難易度:中級
  • 検証:2026-09-14 deepseek-flash

コードと実行結果は実際に動かしたときのまま載せているため、コメントと出力は中国語です。

前の課の RepoBot v1 は「httpx は既定でリダイレクトに従うか」という質問に間違え、辻褄を合わせるためにバージョンの経緯までこしらえました。プロンプトを変えたり思考をオンにしたりしても、この種の誤りは減らせるだけで、なくすことはできません。モデルは記憶に頼って答えるしかなく、その記憶の中では httpx と requests が混ざっているからです。

こういう質問に、人ならどうするでしょうか。ドキュメントを調べます。この課では、モデルにも「ドキュメントを調べ」させます。

実験:ドキュメントの一節を与える

httpx のドキュメントには、requests との違いを専門に扱う compatibility.md というページがあり、その中に「Redirects」という節があります。まず第 2 課で扱う分割関数でこの節を見つけ出し、同じ質問を 2 回します。1 回は資料を何も与えずに、もう 1 回はこの節をプロンプトに入れて。

section = next(c for c in split_by_heading(load_docs()["compatibility.md"]) if c.startswith("## Redirects"))

answer, tokens = ask([{"role": "user", "content": QUESTION + "用两三句话回答。"}])

prompt = f"""根据下面的 httpx 文档片段回答问题。文档里没有提到的,就说文档里没有。

<doc>
{section}
</doc>

问题:{QUESTION}用两三句话回答。"""
answer, tokens = ask([{"role": "user", "content": prompt}])

見つかったドキュメントの断片は次のとおりです。

## Redirects

Unlike `requests`, HTTPX does **not follow redirects by default**.

We differ in behaviour here [because auto-redirects can easily mask unnecessary network
calls being made](https://github.com/encode/httpx/discussions/1785).

You can still enable behaviour to automatically follow redirects, but you need to
do so explicitly...

```python
response = client.get(url, follow_redirects=True)
```

Or else instantiate a client, with redirect following enabled by default...

```python
client = httpx.Client(follow_redirects=True)
```

2 回の回答です(完全なコードは code/04-rag/why_rag.py。あなたの言い回しは違うはずです)。

== 不给资料(输入 19 词元):
会,httpx 默认会自动跟随重定向(最多 20 次)。可以在请求中用 `follow_redirects=False` 关闭,或用 `max_redirects` 调整次数。

== 给了文档片段(输入 169 词元):
不会。文档明确说明 httpx 与 `requests` 不同,**默认不跟随重定向**。如果想自动跟随,必须显式设置,例如在请求中用 `follow_redirects=True`,或在创建客户端时用 `httpx.Client(follow_redirects=True)`。

資料なしでは間違え、RepoBot v1 と同じ誤りを犯しています。150 トークンのドキュメントを与えると、すぐに正解し、理由と有効にする方法まで説明しています。余分にかかったのは入力 150 トークン分で、モジュール 01 第 4 課の料金で約 0.00005 ドルです。

これが RAG の考え方のすべてです。まず関係する資料を見つけ、それからモデルに資料に沿って答えさせる

RAG とは

RAG は Retrieval-Augmented Generation の略で、日本語では検索拡張生成と呼ばれます。名前は長いですが、分解すれば三つのステップです。検索(retrieval)、拡張(augmented、見つけた資料をプロンプトに加える)、生成(generation)。

上の実験では、「Redirects の節を見つける」ことは私が手作業でしました。答えがどこにあるかを前もって知っていたからです。本物の RAG システムは、このステップを自動でこなさなければなりません。ユーザーがどんな質問をしても、大量のドキュメントの中から最も関係のある数か所をプログラムが見つけ出すのです。流れ全体は二つの部分に分かれます。

提前准备(只做一次,文档更新时再做):

  文档 ──▶ 切成小块 ──▶ 为每块建立索引(向量、关键词)──▶ 存起来
          (第 2 课)     (第 3、4 课)

每次提问时:

  用户问题 ──▶ 检索:找出最相关的几块 ──▶ 把这几块和问题一起放进提示词 ──▶ 模型回答
                (第 3、4 课)              (第 5 课:要求它注明引用)

このモジュールの残りの課で、この図の各ボックスを作っていきます。第 2 課で分割、第 3 課でベクトル検索、第 4 課でキーワード検索と両者の融合、第 5 課でモデルに引用つきで答えさせ、第 6 課でシステム全体の良し悪しを評価し、第 7 課でそれらを RepoBot に組み込みます。

RAG が解決するもの

モデルが知らないこと。あなたの会社の社内ドキュメント、あなたのプロジェクトのコード、先週出たばかりの新バージョンのリリースノート。どれもモデルは学習のときに見ていません。RAG はそれらをその場でモデルに渡します。

モデルが記憶違いしていること。httpx のリダイレクトの例がそうです。モデルは httpx を「知って」いますが、混同しています。原文があれば、記憶に頼る必要はありません。

追跡できること。回答がどの資料をもとに出されたのかをプログラムは知っていて、それをユーザーに見せられます。ユーザーは原文を開いて確認でき、誤りがあれば検索の誤りなのか、モデルの読み違いなのかを調べられます。

更新が安い。ドキュメントが変わったら、変わったページだけを処理し直せば済みます。それに比べて、学習によって新しい知識をモデルに「教え込む」のはずっと費用がかかり、効果も当てになりません(ファインチューニングが知識を注入するのに向かない理由は、第 10 モジュール第 1 課で説明します)。

なぜすべてのドキュメントを詰め込まないのか

モジュール 01 第 4 課でこの実験をしました。httpx のドキュメント全体は約 2.9 万トークンで、全部入れてもモデルは正解できます。それなら、なぜわざわざ検索するのでしょうか。

毎回 2.9 万トークンを詰め込むと、関係する数百トークンだけを入れる場合より数十倍高く、ずっと遅くなるのに、ユーザーが毎回必要とするのはそのごく一部だけだからです。httpx のドキュメントはまだ小さいほうで、あなたの会社のナレッジベースは数千万トークンあるかもしれず、そもそもコンテキストに入りません。さらに、無関係な内容を多く入れるほど、モデルが惑わされて見当違いの場所を探す可能性も高くなります。

ですから、二つのやり方にはそれぞれ適した範囲があります。

資料の規模 やり方
数千から数万トークンで、呼び出しが多くない 全部入れる。簡単で確実で、キャッシュにもヒットする
それより大きい、または呼び出しが非常に多い RAG。関係する部分だけを入れる

まず全部入れられるかを考えましょう。入れられるならそうして、RAG に飛びつかないことです。

RAG が向いていない場面

  • 質問が資料全体を必要とする。「このドキュメントを要約して」「ドキュメントでパラメータはいくつ出てくるか」といった質問は全文を見る必要があり、数か所を検索しただけでは足りません。
  • 資料そのものの質が悪い。ドキュメントが古い、互いに矛盾している、書き方があいまいなら、RAG はモデルに誤った資料に沿って答えさせるだけで、しかも「出典」があるぶん、より信頼できそうに見えてしまいます。
  • 答えがどのドキュメントにもない。たとえば httpx のあるふるまいがソースコードにしかなく、ドキュメントに書かれていない場合です。そのときはモデルにソースコードを読ませる必要があり、それはモジュール 05 のエージェントの仕事です。
  • 検索ではなく推論が必要。「私のこのコードはなぜエラーになるのか」は、ドキュメントを探すだけでは足りず、ユーザーのコードを理解する必要があります。RAG は関係するドキュメントを補助として提供できますが、主にモデル自身の能力が頼りです。

練習問題

  1. code/04-rag/why_rag.py を実行して、あなたが得た二つの回答がどんなものか見てください。
  2. 別の質問に替えてみてください。たとえば「httpx の Response には ok という属性がありますか」。compatibility.md の中で関係する節を手作業で見つけ(ヒント:「Checking for success」で検索)、why_rag.py を修正して同じ比較をします。
  3. why_rag.py でプロンプトに入れるドキュメントを、無関係な内容(たとえば timeouts.md のある節)に置き換えて、リダイレクトの質問をもう一度してください。モデルはどう答えるでしょうか。「ドキュメントには書かれていない」と言うでしょうか。

確認テスト

1. RAG の三文字はそれぞれ何を表していますか?三つのステップはそれぞれ何をしますか?

Retrieval(検索):質問をもとに最も関係のある資料を見つける。Augmented(拡張):見つけた資料をプロンプトに加える。Generation(生成):モデルが資料をもとに回答を生成する。

2. 資料はわずか 2 万トークンで、1 日に数十回質問されます。RAG を使いますか?

ふつうは使いません。資料が小さく呼び出しが多くないなら、資料全体をプロンプトに入れるほうが簡単で確実で、固定の資料を先頭に置けばキャッシュにもヒットし、費用も高くありません。RAG が向いているのは、資料が大きすぎてコンテキストに入らない場合や、呼び出しが多く全部入れると高くつきすぎる場合です。

3. 資料の質が悪いと、RAG で状況がかえって悪くなりうるのはなぜですか?

モデルは検索された資料に沿って答えます。資料が間違っていれば回答も間違い、しかも「出典」が付いているので、ユーザーはかえって信じやすくなります。RAG の効果は資料そのものの質に縛られるのです。

質問と議論

このレッスンでつまずいたところは、ここで質問してください。他の人の質問に答えるのも歓迎です。

質問で 3 ポイント、回答で 6 ポイント。審査を通過すると公開されます。

議論を読み込んでいます…