【RAG Fusion】LLMのハルシネーションを防ぐRAGの進化版!その効果を徹底検証

RAG-Fusion LLM ハルシネーション 防ぐ RAG 進化版 効果 徹底検証

WEELメディア事業部AIライターの2scです。

ITエンジニアのみなさん!生成AIに学習範囲外の知識を与える「RAG Fusion」はご存知ですか?

RAG Fusionは、AIチャットボットに用いられるRAGの進化形。従来型RAGよりも深く知識が反映できて……

このように、質問の意図をよく理解するAIチャットボットが作れちゃうんです!

当記事では、そんなRAG Fusionの仕組みやRAGからの改善点を解説。加えて記事の最後に、Pythonを使ったRAG Fusionの実演も載せております。

完読いただくと、かしこいAIチャットボットが作れちゃう……かもです!

ぜひ最後までお読みくださいね。

目次

RAG Fusionの概要

「RAG Fusion」はLLM(大規模言語モデル)のハルシネーションを防ぐ方法の一種。学習範囲外の事実をプロンプトに挿入するRAG(Retrieval Augmented Generation)の進化版にあたります。

そもそもRAGのしくみは、

  1. ユーザーが質問を入力
  2. 質問に関連する事実をベクトルデータベースから検索
  3. 検索結果をプロンプト経由でLLMに提示(Few-shot Learning)
  4. LLMが事実を踏まえた回答を生成

というものでした。対してその進化版・RAG Fusionでは……

参考:https://blog.langchain.dev/query-transformations/
  1. ユーザーがオリジナルの質問を入力
  2. LLMが質問に関連する新たな質問を複数生成
  3. オリジナルの質問・新たな質問それぞれで、ベクトルデータベースから事実を検索
  4. 複数の質問で得られた検索結果をまとめて順位付け(リランキング)
  5. 上位の検索結果をプロンプト経由でLLMに提示(Few-shot Learning)
  6. LLMが事実を踏まえた回答を生成

以上のとおり、「LLMによる追加質問の生成」と「リランキング」の手順が加わっています。(※1、2)その効果のほどは、次項で詳しくみていきましょう!

なお、RAGの基本「Embedding」について詳しく知りたい方は、下記の記事をあわせてお読みください。

従来型RAG比でのRAG Fusionの長所

ユーザーの質問のみで検索を行っていた従来型RAGと異なり、RAG Fusionは「ユーザーの質問+LLMによる追加質問」でベクトルデータベースを検索します。そんなRAG Fusionには……

専門分野でも、深い回答が得られる:質問の不足箇所を追加質問で補うため
質問ミスがフォローできる:質問中のあいまいな表現やタイプミスを追加質問で補うため

といった長所があります。つまりは従来比で、より正確かつ包括的な回答が得られるということです。

RAG Fusionの短所

RAGの進化形・RAG Fusionも完璧ではありません。一度、「LLMに追加質問を生成させる工程」がはさまるため……

従来型RAG比で、トークン数の消費が増える
従来型RAG比で、回答速度が落ちる
意図から外れた回答や冗長な回答が返ってくることもある

という短所があるんです。

さて次項からは実際にPythonを使って、このRAG Fusionの効果を検証していきます。AIチャットボットの自社開発を目指すエンジニアのみなさんはぜひ、続きをご覧ください!

なお、トークン数を節約するテクニックについて詳しく知りたい方は、下記の記事をあわせてお読みください。

PythonでのRAG Fusion実践編

ここからは、Google Colaboratory(Google Colab)とPythonを駆使して、RAG Fusionの効果を検証していきます。その処理の流れは……

今回作るRAG Fusion(by Langchain)
  1. ユーザーがオリジナルの質問を入力
  2. GPT-3.5が質問に関連する新たな質問を複数生成
  3. オリジナルの質問・追加質問それぞれで、Pineconeのベクトルデータベースから事実を検索
  4. 複数の質問で得られた検索結果をまとめて順位付け
  5. 上位の検索結果をプロンプト経由でGPT-3.5に提示
  6. GPT-3.5が事実を踏まえた回答を生成

というふうになっています。以下、途中経過のスクリーンショットや使用したソースコードも掲載しておりますので、エンジニアのみなさんは必見です!

RAG Fusionに使用した環境・準備物

RAG Fusionの実践にあたって、今回使用した環境・準備物は以下の4点です。

● Python 3(Python 3.7.1以上)
● OpenAI Pythonライブラリ(openai)
ChatGPTの有料アカウント
● Pineconeのアカウント(無料版も可)

あわせてPythonコードを実行するための場として、

  • Google Colaboratory(Google Colab)
  • Visual Studio Code
  • Jupyter Notebook

以上のいずれかがあると、RAG Fusionが簡単に試せます。こちらについてはGoogle Colabを使用しました。

Pythonライブラリの用意

RAG Fusionを構築するにあたっては、LLMとベクトルデータベース、そして両者をつなぐフレームワークが必須。今回は……

  • LLM:GPT-3.5
  • ベクトルデータベース:Pinecone
  • 連結用のフレームワーク:Langchain

を、以下のソースコードを使って用意しました。

#ライブラリインストール
!pip install openai langchain chromadb tiktoken langchain-pinecone langchain-openai langchainhub

こちらのコードをGoogle Colabで実行すると……

以上のとおり、必要なPythonライブラリがインストールされます。

APIとモジュールの下準備

続けてChatGPT APIとPineconeのそれぞれで、APIキーを発行して実行環境に反映します。

まず、PineconeのAPIキーについては、Pinecone Consoleから発行できます。同時に、後で使用するインデックスについても……

  • インデックス名:rag-fusion
  • 次元数:1536

という条件で作成しておきましょう。

次にChatGPT APIに関しては、こちらのAPIキー作成画面から発行が可能。それぞれ発行後は、以下のコードにペーストしてください。(※3)

#APIキー入力
import os
os.environ["OPENAI_API_KEY"] = "ChatGPT APIのAPIキー"
os.environ["PINECONE_API_KEY"] = "PineconeconeのAPIキー"

あわせてRAG Fusionに使用するモジュールも、以下のコードを使ってインポートします。

#モジュールインポート
from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.text_splitter import CharacterTextSplitter
from langchain_pinecone import PineconeVectorStore

from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough, RunnableLambda
from langchain.prompts import ChatPromptTemplate
from langchain.prompts.chat import (
   AIMessagePromptTemplate,
   HumanMessagePromptTemplate,
)

以上2つのコードをそれぞれGoogle Colabで実行すると……

というふうに、APIとモジュールの準備が完了します。

記事の分割とエンベディング

ここからは、RAG Fusionの組み立て作業に移ります。

まずはRAG Fusionで示したい知識を用意する工程から、なのですが……

今回は当メディアの生成AIずかん全記事をスクレイピングして、テキストファイル「WEEL_Zenkiji.txt」にまとめました。まとめたテキストファイルは……

このように、ディレクトリ「sample_data」に収めています。

続けて生成AIずかん全記事を……

  1. チャンクに分ける(長文を細切れにする)
  2. Embeddingする(ベクトルに変換する)
  3. Pineconeのインデックスに格納する(先ほどのrag-fusionを使用)

という手順で加工して、ベクトルデータベースを作成します。うち、チャンク分けとEmbeddingについては……

%cd sample_data
#テキストをチャンクに分けて埋め込む
loader = TextLoader("WEEL_Zenkiji.txt",encoding="utf-8")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings(disallowed_special=())

こちらのコードで可能。(※4、5)実行すると……

このように記事全文が加工されます。

続けて、加工した記事全文を……

index_name = "rag-fusion"

vectorstore = PineconeVectorStore.from_documents(docs, embeddings, index_name=index_name)

以上のコードで、先ほどのPineconeインデックス「rag-fusion」へ格納します。実行すると……

このように、生成AIずかん全記事を格納したベクトルデータベースが完成しました。

Chainの作成

最後に……

  • GPT-3.5で追加質問を生成する工程
  • 得られた複数の検索結果に順位をつける工程
  • 上位の検索結果をもとにGPT-3.5に回答させる工程

をコーディングして、RAG Fusionを完成させます。今回は各工程を一連で実行できるLangchainの機能「Chain」を活用して、下記のコードを用意しました。(※4、5)

#複数クエリの生成
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
from langchain import hub

prompt = hub.pull("langchain-ai/rag-fusion-query-generation")
generate_queries = (
    prompt | ChatOpenAI(temperature=0) | StrOutputParser() | (lambda x: x.split("\n"))
)

#関連度の高い順にドキュメントを返すようにする
from langchain.load import dumps, loads


def reciprocal_rank_fusion(results: list[list], k=60):
    fused_scores = {}
    for docs in results:
        for rank, doc in enumerate(docs):
            doc_str = dumps(doc)
            if doc_str not in fused_scores:
                fused_scores[doc_str] = 0
            previous_score = fused_scores[doc_str]
            fused_scores[doc_str] += 1 / (rank + k)

    reranked_results = [
        (loads(doc), score)
        for doc, score in sorted(fused_scores.items(), key=lambda x: x[1], reverse=True)
    ]
    return reranked_results

# 10個の関連文書を取ってくるようにする
retriever = vectorstore.as_retriever(search_kwargs={'k': 10})

#関連する質問を生成させるためのプロンプト
template = """You are an expert of world knowledge. I am going to ask you a question. Your response should be comprehensive and not contradicted with the following context if they are relevant. Otherwise, ignore them if they are not relevant.
{context}

Question: {question}
"""
prompt2 = ChatPromptTemplate.from_messages(
   [
       HumanMessagePromptTemplate.from_template(template),
       AIMessagePromptTemplate.from_template(""),
   ]
)

retrieve_chain = (
   {"original_query": lambda x: x}
   | generate_queries
   | retriever.map()
   | reciprocal_rank_fusion
)

chain = (
   {
       "context": retrieve_chain,
       "question": lambda x: x,
   }
   | prompt2
   | ChatOpenAI(temperature=0)
   | StrOutputParser()
)

こちらをGoogle Colabで実行すると……

以上のとおり、RAG Fusionの流れが完成しました。ではさっそく、次項からRAG Fusionの効果を試していきましょう!

RAG Fusionの効果検証

LangChainで構築したRAG Fusionを使ってGPT-3.5に質問する際は……

for s in chain.stream("任意の質問"):
    print(s, end="", flush=True)

以上のコードを実行するだけでOK。まずは下記の質問について、RAG Fusion経由でGPT-3.5から回答を得てみましょう!

オンプレミスで使えるおすすめの小型LLMについて、具体的なモデル名を教えて

するとこのように、学習範囲外の具体的なツール名(2021年9月以降登場)が回答に反映されています。従来型RAGの回答と比較してみると……

RAG Fusionでの回答

オンプレミスで使えるおすすめの小型LLMとして、以下のモデル名をおすすめします:

  1. OpenELM-270M
  2. Phi-3-mini
  3. Stable LM 2 12B
  4. TinyLlama
  5. OpenHermes 2.5

これらのモデルは、小型でありながら高性能であり、オンプレミス環境での利用に適しています。それぞれのモデルについて詳細な情報や使い方は各モデルの公式サイトやリソースを参照してください。

従来型RAGでの回答

申し訳ありませんが、具体的なモデル名については情報が得られませんでした。お探しの情報を提供できず申し訳ありません。

以上のとおり、違いは一目瞭然。RAG Fusionは元記事に一句もない表現「オンプレミス」を理解して、具体的なツール名を引用してくれているんです!

ちなみに以下の質問についても、RAG Fusionと従来型RAGでGPT-3.5の回答を比較してみると……

GPT-4を無料で使えるツールって知ってる?日本語で教えて。
RAG Fusionでの回答

GPT-4を無料で利用できるツールとして、GPT EngineerとGPT4FREEが挙げられます。GPT Engineerはオープンソースであり、誰でも無料で利用することができます。具体的な使い方として、まずgptengineer.appにアクセスし、登録を完了させることで、テキストボックスにアプリの説明を入力し、「Create」をクリックすることでアプリを開発することができます。また、ChatGPTを利用したい場合は、GPT EngineerのGPTsを利用することができます。ただし、ChatGPTの有料ユーザー向けであることに留意してください。

もう一つの無料ツールであるGPT4FREEは、GPT-4などの言語モデルにアクセスを提供するプロジェクトです。テキスト生成、チャットボット作成、言語生成、翻訳、コード支援など、多様な用途で利用可能であり、Pythonパッケージを介してインストールすることができます。ただし、GPT4FREEはアクセス制御と利用規約を回避することにより、倫理的及び法的問題が議論されている点に留意する必要があります。

これらのツールを利用することで、GPT-4を無料で活用することが可能です。ただし、利用する際には各ツールの利用規約や倫理的な観点に留意することが重要です。

従来型RAGでの回答

はい、GPT-4を無料で使えるツールにはGPT4FREEやGPT Engineerなどがあります。これらはオープンソースのプロジェクトで、テキスト生成やチャットボット作成など多様な用途で利用可能です。ただし、正規のGPT-4を利用するよりも安全性が低いため、利用には注意が必要です。

このようにRAG Fusionのほうで、より具体的な回答が返ってきています。

なお、従来型RAGのPythonコードについて詳しく知りたい方は、下記の記事をあわせてお読みください。

RAG Fusionなら深い回答が得られる!

当記事ではRAGの進化版「RAG Fusion」について解説を行いました。RAGと比べたときのRAG Fusionの強みは……

専門分野でも、深い回答が得られる:質問の不足箇所を追加質問で補うため
質問ミスがフォローできる:質問中のあいまいな表現やタイプミスを追加質問で補うため

以上のとおり。実践編でも、引用元にない「オンプレミス」の意味まで踏まえた回答が返ってきていました。チャットボットで高度な知識を扱いたい場合はぜひ、このRAG Fusionをお試しください!

サービス紹介資料

生成系AIの業務活用なら!

・生成系AIを活用したPoC開発

・生成系AIのコンサルティング

・システム間API連携

最後に

いかがだったでしょうか?

弊社では

・マーケティングやエンジニアリングなどの専門知識を学習させたAI社員の開発
・要件定義・業務フロー作成を80%自動化できる自律型AIエージェントの開発
・生成AIとRPAを組み合わせた業務自動化ツールの開発
・社内人事業務を99%自動化できるAIツールの開発
ハルシネーション対策AIツールの開発
自社専用のAIチャットボットの開発

などの開発実績がございます。

まずは、「無料相談」にてご相談を承っておりますので、ご興味がある方はぜひご連絡ください。

➡︎生成AIを使った業務効率化、生成AIツールの開発について相談をしてみる。

生成AIを社内で活用していきたい方へ

「生成AIを社内で活用したい」「生成AIの事業をやっていきたい」という方に向けて、生成AI社内セミナー・勉強会をさせていただいております。

セミナー内容や料金については、ご相談ください。

また、弊社紹介資料もご用意しておりますので、併せてご確認ください。

投稿者

  • 2sc

    テクニカルライター 大学時代はアリの生態を研究。 ラボで唯一、Pythonを使ってデータ分析を効率化していた。 現在はライターとして、オウンドメディアや学術記事の執筆に当たっている。

  • URLをコピーしました!
  • URLをコピーしました!
目次