# 生成AI・LLM時代必須のRAG(検索拡張生成)について解説！Pythonで実装してみよう！

> 当サイト【スタビジ】の本記事では、生成系AI・LLM時代におさえておきたいRAGについて解説していきます！社内用チャットボットなどを作る際によく利用されるアプローチです。どんなアプローチなのか理解した後は実際にPythonで簡単な実装をしていきます！

- URL: https://toukei-lab.com/llm-rag
- 公開: 2024.04.20 / 更新: 2025.04.01
- サイト: スタビジ（https://toukei-lab.com）

:::talk{who="umatan"}
当サイト【スタビジ】の本記事では、生成系AI・LLM時代におさえておきたいRAG(検索拡張生成)について解説していきます！社内用チャットボットなどを作る際によく利用されるアプローチです。どんなアプローチなのか理解した後は実際にPythonで簡単な実装をしていきます！
:::

こんにちは！データサイエンティストのウマたん([@statistics1012](https://twitter.com/statistics1012?lang=ja))です！

この記事では、最近流行りの生成AI・[大規模言語モデル](/llm)においてよく登場するRAG(検索拡張生成)について分かりやすく解説していきます！

RAGを理解して使えるようになっておくと重宝されます！

それでは見ていきましょう！

ちなみにRAGに関して詳しく学びたい方は以下のUdemyコースにて詳しく解説していますのでぜひチェックしてみてください！

:::box
[**【初心者向け】大規模言語モデルにおけるRAGを実装できるようになろう！Webページの情報を元に回答できるAIを作ろう！**](https://www.udemy.com/course/rag-deploy/?couponCode=P3YK6VU8)

[![Udemy- RAG](/wp-content/uploads/2024/05/Rag-3.jpg)](https://www.udemy.com/course/rag-deploy/?couponCode=P3YK6VU8)

<table class="table">
<tbody>
<tr>
<th>【時間】</th>
<td><span>3.5時間</span></td>
</tr>
<tr>
<th>【レベル】</th>
<td><span>初級</span></td>
</tr>
</tbody>
</table>

大規模言語モデルを使って社内向けチャットボットなどを実装したいのであればRAGをこのコースで！今なら購入時に「NZWCLGF4BTZENY6E」という講師クーポンコードを入れると90%オフ以上の割引価格になりますのでぜひご受講ください！

＼30日以内なら返金無料／

::button[このコースを見てみる]{href="https://www.udemy.com/course/rag-deploy/?couponCode=P3YK6VU8"}
:::

RAGに関して以下のYoutube動画でも解説していますので合わせてチェックしてみてください！

::youtube{#NoM2JdOnYsA}

## RAG(検索拡張生成)とは？

RAGとはRetrieval-Augmented Generationの略であり、直訳すると検索拡張生成になります。

構造自体は非常に単純で

:::box
**特定のデータベースに情報を検索しに行って、その検索結果を大規模言語モデル（LLM）にインプットした上で質問を投げかける**
:::

というアプローチ。

![RAG](/wp-content/uploads/2024/04/RAG-1.jpg)

基本的に[大規模言語モデル（LLM）](/llm)は広く公開されている一般的な内容を学習して作られていますので、クローズドな情報に関する質問は答えられません。

よくあるのが

「社内に大量に貯まっているクローズドなデータに対して質問をして返してくれるようなチャットボットを作りたい！」

といった事例。

:::talk{who="umatan"}
あの情報ってどっかのフォルダにあったはずなんだけど、どこにあったっけ・・・といった経験をしているはず！
:::

そういう時に役立つのがRAGというアプローチなのです！

例えば、「2023年の第1事業部の売上ってどのくらいだっけ？」という質問をしたいとします。

その時に以下のように情報が格納されているデータベースがあるとします。

<table class="table">
<tbody>
<tr>
<td>情報</td>
</tr>
<tr>
<td>・・・</td>
</tr>
<tr>
<td>2023年上期売上200億円、下期売上300億円</td>
</tr>
<tr>
<td>2023年第1事業部売上300億円、第2事業部売上150億円、第3事業部売上50億円</td>
</tr>
<tr>
<td>2024年は全社で1000億円の売上を目指す</td>
</tr>
<tr>
<td>・・・</td>
</tr>
</tbody>
</table>

そうするとまず、このデータベースに検索をかけて質問と近い情報を引っ張ってきます。

それをコンテキストとして大規模言語モデルにインプットしてあげるのです。

プロンプトとしては以下のようなイメージです。

> 以下の質問に以下の情報をベースにして答えてください。\
> \[ユーザーの質問]\
> XXXXX
>
> \[情報]\
> XXXXX

今回のケースだと、以下のようになります。

> 以下の質問に以下の情報をベースにして答えてください。\
> \[ユーザーの質問]\
> 2023年の第1事業部の売上ってどのくらい？
>
> \[情報]\
> 2023年第1事業部売上300億円、第2事業部売上150億円、第3事業部売上50億円

![RAG](/wp-content/uploads/2024/04/716086010b9f001d5bec5ff5abb8c344.png)

今回は検索で引っ張ってきた情報が欲しい情報とピッタリ合致していますが、以下のようにいくつか近しい情報を引っ張ってきてコンテキストとして与えても問題ありません。

> 以下の質問に以下の情報をベースにして答えてください。\
> \[ユーザーの質問]\
> 2023年の第1事業部の売上ってどのくらい？
>
> \[情報]\
> ・2023年上期売上200億円、下期売上300億円\
> ・2023年第1事業部売上300億円、第2事業部売上150億円、第3事業部売上50億円

![RAG](/wp-content/uploads/2024/04/62f3ae4c28dfc665f1f232631169a227.png)

ここまで見てきて勘の良い方はお気づきかもしれませんが、RAGにおいては<mark>情報の整理そして検索ロジックの正確さが肝になってきます。</mark>

後ほど実際にどうやってデータベースから質問と近い情報を検索して引っ張ってくるか、見ていきます。

## RAGとファインチューニングの違い

ではRAGとファインチューニングの違いはなんでしょうか？

:::talk{who="umatan"}
ファインチューニングも色んなところでよく聞くよね！
:::

ファインチューニングとはザックリ言うと

:::box
**事前に学習されたモデルに対して手元のデータセットを元に再学習させてモデルのパラメータを調整して特定のタスクに適用させるようなモデルを生成する**
:::

アプローチを指します。

つまりファインチューニングでは、<mark>事前に学習された大規模言語モデルに新しい独自データセットを投入して再学習しなくてはいけないのです。</mark>

その分リソースがかかります。

しかも、<mark>新しい強い汎用モデルが登場した時にそのモデルをベースにするとなると、もう一度そのモデルで再学習しないといけなかったりするので面倒ですよね・・・</mark>

一方で、RAGでは外部リソースを検索して、それを大規模言語モデルにコンテキストとしてインプットするだけなのでモデルを再学習する必要はありません。

実際に独自のチャットボットを作るようなケースではRAGが用いられるケースが多く、以下のMicrosoftが発表した論文でもRAGの方が精度が高いと結論付けられています。

:::box
[Fine-Tuning or Retrieval? Comparing Knowledge Injection in LLMs](https://arxiv.org/pdf/2312.05934.pdf)
:::

ただ必ずしも全ての状況でRAGがよい！というわけではないので、ファインチューニングについても理解して状況に応じて使えるようになっておくとよいと思います。

ファインチューニングに関しては以下の記事で詳しく解説しているのでそちらも合わせてチェックしてみてください！

<https://toukei-lab.com/fine-tuning>

## RAGをPythonで実装してみよう！

では、早速RAGをPythonで実装してみたいと思います！

冒頭でもお話しましたが、RAGでは必要な情報をデータベースから検索してくる部分が肝になってきます。

そして情報検索において一般的なのは、

:::box
**情報をあらかじめベクトル化しておきデータベースに格納しておき、質問内容をベクトル化したものとデータベースのベクトル同士で類似度を計算し近いものを引っ張ってくるというアプローチ**
:::

です。

このような検索方法をベクトル検索（セマンティック検索）と呼びます。

以下の記事で詳しく解説していますので、あわせて参考にしてみてください！

<https://toukei-lab.com/vector-search>

ベクトル化の方法としては色々あるのですが、今回は簡易的に実装できるOpenAIの[EmbeddingsAPI](https://platform.openai.com/docs/guides/embeddings/embedding-models)を利用していきたいと思います。

![Embedding](/wp-content/uploads/2023/07/b9d7560d4dcc4a97de3a1c7fb1802af5.png)

OpenAIのEmbeddingsAPIを利用したベクトル化に関しては以下の記事で詳しく解説しているのでチェックしてみてください！

<https://toukei-lab.com/embedding-api>

それでは実際にコードを書いていきましょう！

:::warn
OpenAIのAPIを利用する上で若干費用がかかりますので注意してください
:::

あらかじめ[OpenAI](https://openai.com/)のアカウントを作成してAPIキーを取得しておいてください。

実装環境としては[Google Colab](/google-colaboratory)を利用していきます。

まずはOpenAIのライブラリをインストールしていきましょう！

```python
!pip install openai
```

続いて必要なライブラリをインストールしてAPIキーをセットして準備を整えていきましょう！

```python
from openai import OpenAI
import numpy as np
import pandas as pd
import os

# OpenAI APIキーの設定
os.environ["OPENAI_API_KEY"] = '自分のAPIのキー'

client = OpenAI()
```

続いてベクトル化する関数を作っていきます。

```python
def vectorize_texts(text):
    """ 文書リストをベクトル化して返します """
    response = client.embeddings.create(
        input=text,
        model="text-embedding-3-small"
    )
    return np.array(response.data[0].embedding).reshape(1, -1)
```

ここでは、OpenAIのEmbeddingsAPIを使ってテキストをベクトル化しています。返り値を返すところで後で計算しやすいように2次元配列に直しています。

続いて類似度を算出して最適な情報を引っ張ってくる関数を作っていきます。

```python
def find_most_similar(question_vector, vectors, documents):
    """ 類似度が最も高い文書を見つけます """
    vectors = np.vstack(vectors)  # ドキュメントベクトルを垂直に積み重ねて2次元配列にする
    similarities = np.dot(vectors, question_vector.T).flatten() / (np.linalg.norm(vectors, axis=1) * np.linalg.norm(question_vector))
    print("similarities", similarities)
    most_similar_index = np.argmax(similarities)
    return documents[most_similar_index]
```

COS類似度はそれぞれのベクトルの内積を分子としてそれぞれのベクトルのL2ノルム（大きさ）をかけ合わせたものを分母として計算します。

詳しくは以下の記事を見てみてください。

<https://toukei-lab.com/python-mecab>

そして最もCOS類似度が高い情報（文書）を抽出しています。

ここでは、各文書との類似度をprint文で出力しています。

続いてユーザーの質問と検索データベースから引っ張ってきた情報を大規模言語モデルに投入する関数を作っていきます。

```python
def ask_question(question, context):
    """ GPTを使って質問に答えます """
    prompt = f'''以下の質問に以下の情報をベースにして答えてください。
            [ユーザーの質問]
            {question}

            [情報]
            {context}
            '''
    print("prompt", prompt)
    response = client.completions.create(
        model="gpt-3.5-turbo-instruct",
        prompt=prompt,
        max_tokens=200
    )
    return response.choices[0].text
```

そして最後にこの記事で取り上げた例と共に文書と質問を投入していきます。

```python
# 情報
documents = [
    "2023年上期売上200億円、下期売上300億円",
    "2023年第1事業部売上300億円、第2事業部売上150億円、第3事業部売上50億円",
    "2024年は全社で1000億円の売上を目指す"
]

# 文書をベクトル化
vectors = [vectorize_texts(doc) for doc in documents]

# 質問
question = "2023年の第1事業部の売上ってどのくらい？"

# 質問をベクトル化
question_vector = vectorize_texts(question)

# 最も類似した文書を見つける
similar_document = find_most_similar(question_vector, vectors, documents)

# GPTモデルに質問
answer = ask_question(question, similar_document)
print(answer)
```

結果はどうなるでしょう・・・？

COS類似度は以下のようになり、ちゃんと2番目の文書が最も高くなっていることがわかります。

:::box
**similarities \[0.6021774 0.85588556 0.62325224]**
:::

最終的な結果は以下のようになりました。

:::box
**prompt 以下の質問に以下の情報をベースにして答えてください。**\
**\[ユーザーの質問]**\
**2023年の第1事業部の売上ってどのくらい？**

**\[情報]**\
**2023年第1事業部売上300億円、第2事業部売上150億円、第3事業部売上50億円**

**\[ユーザーの質問]**\
**2023年の第1事業部の売上ってどのくらい？**

**\[AIの回答]**\
**2023年第1事業部売上は300億円です。**
:::

ちゃんと想定通りの答えが返ってきていることがわかりますね！

## RAG　まとめ

ここまででRAGについてまとめてきました。

もし社内ChatBotなどを作ろうとしていて、どうすればよいか分からない・・・という方はぜひ参考にしてみてください！

RAGの実装についてもっと詳しく知りたい方は以下のUdemy講座でまとめていますので是非チェックしてみてください！

:::box
[**【初心者向け】大規模言語モデルにおけるRAGを実装できるようになろう！Webページの情報を元に回答できるAIを作ろう！**](https://www.udemy.com/course/rag-deploy/?couponCode=P3YK6VU8)

[![Udemy- RAG](/wp-content/uploads/2024/05/Rag-3.jpg)](https://www.udemy.com/course/rag-deploy/?couponCode=P3YK6VU8)

<table class="table">
<tbody>
<tr>
<th>【時間】</th>
<td><span>3.5時間</span></td>
</tr>
<tr>
<th>【レベル】</th>
<td><span>初級</span></td>
</tr>
</tbody>
</table>

大規模言語モデルを使って社内向けチャットボットなどを実装したいのであればRAGをこのコースで学ぼう！

＼30日以内なら返金無料／

::button[このコースを見てみる]{href="https://www.udemy.com/course/rag-deploy/?couponCode=P3YK6VU8"}
:::

ディープラーニング系、その他のAI用語を一挙にまとめた以下の記事も合わせて要チェックです！

<https://toukei-lab.com/ai-term>

また、当メディアが運営するスタアカの以下のコースでも大規模言語モデル(LLM)について詳しく解説していますので是非チェックしてみてください！

:::box
**[スタアカ「13.大規模言語モデル（LLM）・生成系AIコース」](https://toukei-lab.com/achademy/?sfwd-courses=llm)**
:::

スタアカは業界最安級のAIデータサイエンススクールです。

![スタアカトップ](/wp-content/uploads/2021/11/2bc9f22d0f8dfe24080b83884b7a5ec6-1024x576.jpg)

<table class="table">
<tbody>
<tr>
<th>【価格】</th>
<td>ライトプラン：1280円/月<br>
プレミアムプラン：149,800円</td>
</tr>
<tr>
<th>【オススメ度】</th>
<td><span class="stars" role="img" aria-label="5点中5点" data-value="5"></span></td>
</tr>
<tr>
<th>【サポート体制】</th>
<td><span class="stars" role="img" aria-label="5点中4点" data-value="4"></span></td>
</tr>
<tr>
<th>【受講形式】</th>
<td>オンライン形式</td>
</tr>
<tr>
<th>【学習範囲】</th>
<td>データサイエンスを網羅的に学ぶ<br>
実践的なビジネスフレームワークを学ぶ<br>
SQLとPythonを組みあわせて実データを使った様々なワークを行う<br>
マーケティングの実行プラン策定<br>
マーケティングとデータ分析の掛け合わせで集客マネタイズ</td>
</tr>
</tbody>
</table>

:::box
**・BigQuery上でSQL、Google Colab上でPythonを使い野球の投球分析**\
**・世界最大手小売企業のウォルマートの実データを用いた需要予測**\
**・ビジネス・マーケティングの基礎を学んで実際の企業を題材にしたマーケティングプランの策定\
・Webサイト構築してデータ基盤構築してWebマーケ×データ分析実践して稼ぐ**
:::

＼今すぐ試す／

::button[スタアカの受講はこちら]{href="https://toukei-lab.com/achademy/"}

<mark>**AIデータサイエンスを学んで市場価値の高い人材になりましょう！**</mark>

データサイエンスやAIの勉強方法は以下の記事でまとめています。

<https://toukei-lab.com/data-scientist>

<https://toukei-lab.com/ai-learning>