Kings Ash Road, Paignton
© Copyright Crispin Purdye and licensed for reuse under this Creative Commons Licence.
「Difyについてーその2」では、DifyのサーバをローカルなWindows PC上で起動してDifyを呼び出すところまでをご覧いただきました。
本日は、DifyでのRAG構築の仕方を試してみましたので、ご紹介します。
はじめに、Claude3に、RAGについて尋ねてみましょう。
私#1: RAGについて説明してください。 Claude3#1: RAG (Retrieval-Augmented Generation) は、大規模な言語モデルと外部知識ソースを組み合わせた自然言語処理のアプローチです。具体的には、次の2ステップからなります。 1. 情報検索 (Retrieval): 入力テキストに関連する文書や文章を、外部の大規模なコーパス(ウェブページ、ウィキペディア、企業内文書など)から検索します。 2. 生成 (Generation): 言語モデルが、入力テキストと検索された関連情報を組み合わせて、最終的な出力を生成します。
RAGの長所は、大規模な言語モデルの高い生成能力と、外部知識ソースの豊富な情報を組み合わせることで、より正確で豊富な応答を生成できる点にあります。一方で、検索の品質や関連する情報の扱いなど、課題も残されています。 RAGは質問回答や対話システム、要約、データ対データ変換など、様々なNLPタスクに応用が期待されています。DPRやRAG-Sequence、FiDなどのRAGモデルが提案されており、研究が活発に行われている分野です。
私#2: DPR、RAG-Sequence、FiDというのは、何がどう違うのでしょうか? Claude3#2: DPR、RAG-Sequence、FiDはいずれもRAGアプローチを採用した代表的なモデルですが、以下のような違いがあります。 DPR (Dense Passage Retriever):
RAG-Sequence:
FiD (Fusion-in-Decoder):
いずれも情報検索と生成を組み合わせるRAGの枠組みは同じですが、具体的な検索・生成のアーキテクチャや、関連情報の利用方法が異なります。モデルの性能や特性を踏まえ、用途に合わせて使い分ける必要があります。
私#3: 違いが良くわからないので、それぞれについて例で示してもらえますか? Claude3#3: 分かりました。DPR、RAG-Sequence、FiDそれぞれのモデルの動作例を挙げて説明します。 【DPR】 質問: プラハの旧市街広場にはどのような建造物があるますか? 1. 情報検索部分で、質問に関連する文書を以下のようにランキング付けして取得:①プラハ旧市街広場にはティーン教会、旧市庁舎などの中世の建造物が立ち並んでいる。②チェコの首都プラハは美しい街並みで知られ、中世の教会や時計台が残されている。… 2. ただし、この段階では関連情報を活用して生成する機能はない。
【RAG-Sequence】 質問: 第二次世界大戦中のチャーチルの主な役割は何でしたか? 1. 情報検索部分でDPRと同様に関連文書を取得する。 2. そして、言語モデル部分で質問と関連文書を参照して以下のように生成: ウィンストン・チャーチルは第二次世界大戦中、イギリス首相として主導的役割を果たした。ナチス・ドイツに対する物心両面の戦争指導に当たり、……(関連情報を参照しながら詳細を生成)
【FiD】 質問: オリンピックで陸上競技に含まれる種目を教えてください。 1. 情報検索部分で関連文書を取得。 2. 言語モデル部分では、デコーダ内で関連情報を柔軟に参照しながら以下のように生成: オリンピックの陸上競技には、[走種目]: 100m、200m、400m…、[跳躍種目]: 走高跳、棒高跳、…[投てき種目]: 砲丸投げ、ハンマー投げ…などの種目があります。(関連情報を自然に参照・挿入)
このように、DPRは検索のみ、RAG-Sequenceは検索と生成を直列的に行うのに対し、FiDは関連情報を生成時に柔軟に活用できる点に特徴があります。
私#4: DPRの補足説明1の「情報検索部分で、質問に関連する文書を以下のようにランキング付けして取得」の意味が良くわかりませんでした。①と②のランク分けについて、この例題に沿ってもう少し詳しく説明してください。 Claude3#4: 分かりました。DPRの情報検索部分の具体的な動作を、この例を使ってさらに説明します。 質問: 「プラハの旧市街広場にはどのような建造物があるますか?」 DPRのエンコーダは、この質問文とコーパス内の各文書(もしくは文書の一部のパッセージ)をベクトル化して、ベクトル空間内での類似度を計算します。 具体的には、 1. 質問文 「プラハの旧市街広場にはどのような建造物があるますか?」をベクトル化 2. コーパス内の各文書(例えば①と②)もそれぞれベクトル化 3. 質問ベクトルと各文書ベクトルの類似度(コサイン類似度など)を計算 4. 類似度が高い順に文書をランキング付け
この例では、
つまり、DPRは質問に関連する程度が高い文書を上位に検索してくるという仕組みになっています。この検索結果を次のRAG-Sequenceなどの生成モデルに入力して、関連情報を参照しながら最終的な応答を生成します。
私#5: なるほど。質問文自体をベクトル化したものに対して、生成AIが学習したデータではなくRAGとして用意した外部コーパス内のいくつかの文章(チャンクと呼ばれているものですね)のベクトル化したものを、類似度(ベクトルの方向性の一致度)の高い順にランキング付けするということですね。 Claude3#5: はい、その理解で正しいです。 要約すると: 1. 質問文をベクトル化する 2. 別途用意した外部コーパスから、文書やパッセージ(チャンク)ごとにベクトル化したものを複数用意する 3. 質問ベクトルと各チャンクベクトルの類似度(コサイン類似度など)を計算する 4. 類似度が高い順にチャンクをランキングする 5. 上位のランキングチャンクを次の生成モデルに入力として渡す
このようにして、質問に関連する外部知識(チャンク)を効率的に検索し、生成モデルに提供するのがDPRの役割になります。
私#6: ところで、DRPのDenseとは、どういう意味なのでしょうか? Claude3#6: Dense Passage Retriever(密なパッセージ検索器)の”Dense”は、質問文とパッセージ(チャンク)をベクトル空間の密ベクトル表現で扱うことを指しています。 DPRではトランスフォーマーベースの双方向エンコーダを使い、質問文とパッセージを密なベクトル表現に変換します。 そして、このベクトル空間内での類似度計算によって、質問に関連するパッセージを効率的に検索することができます。密なベクトル表現を用いることで、単なるキーワードの一致ではなく、意味的な関連性を捉えられるようになりました。 このようにDPRは、RAGアプローチにおける情報検索の高性能化に大きく貢献したモデルであり、名称の由来にもなっています。
私#7: どうもありがとう。よくわかりました。次のRAG-SequenceとFiDの違いは、類似度の高いコーパス情報ベースで回答を作成するか、類似度の高いコーパス情報ベースにしながら、生成AIがすでに学習している内容を盛り込んでさらに詳細な情報提供を行うかどうかの違いと考えて良いですか? Claude3#7: はい、その理解で概ね正しいと言えます。 RAG-SequenceとFiDの主な違いは、以下の点にあります。 【RAG-Sequence】
【FiD (Fusion-in-Decoder)】
つまり、RAG-Sequenceは生成モデルが外部知識を参照するのに対し、FiDは外部知識と生成モデル自身の知識を融合して出力を生成する、という違いがあります。FiDの方が、より詳細で豊富な出力を生成できる可能性があります。 ご理解の通り、どちらも外部知識を活用しつつ、その活用方法が異なるモデルだと捉えられます。
私#8: これまで、RAGは使っていませんでしたが、生成AIのハルシネーション対策として、1つの生成AIの回答を別の生成AIに与えて内容を評価し加筆訂正してもらうというアプローチをとっていました。DifyでRAGを構築する際は、RAG-Sequenceに近い形になると思いますが、LLM1の回答をLLM2で評価し、必要に応じて加筆訂正させることで、FiD相当のことができそうですね。 Claude3#8: はい、その理解で正しいと思います。 従来のアプローチでは、1つの生成AIの出力を別の生成AIで評価・加筆訂正することで、ハルシネーションなどの誤りを減らそうとしていたわけですね。 RAGを導入する場合、まずはRAG-Sequenceのようなアプローチで、1つ目の生成AI(LLM1)が外部知識を参照しながら回答を生成し、2つ目のAI(LLM2)がその回答を評価・加筆訂正するという方法が考えられます。 さらに、FiDのような発展形として、LLM2のデコーダ内で、LLM1の出力と外部知識を融合させながら評価・加筆を行うことも可能でしょう。つまり、LLM2が単に評価・修正するだけでなく、LLM1の知識と外部知識を掛け合わせて、よりレベルの高い回答を生成することになります。 このようなマルチステップのRAGアプローチを取ることで、単一の生成AIに比べて、より正確で詳細な回答を導出できる可能性が高まると考えられます。ハルシネーション対策に加え、回答の充実化が期待できそうですね。
私#9: なるほど。ただ、LLM1の回答にハルシネーションが含まれていた場合、それと類似度の高いコーパスを選んでLLM2に渡してしまうと、回答の品質が劣化する場合もありそうですね。 Claude3#9: その指摘は非常に重要な点を捉えています。確かに、以下のようなリスクがあります。
このケースでは、外部知識の活用が逆効果となり、回答の品質が劣化してしまう恐れがあります。 この問題を回避するには、いくつかの対策が考えられます。 1. LLM1の回答に対して別の評価モデルで事前に誤り検知を行い、ハルシネーションが含まれていそうな場合は情報検索自体を見送る 2. 情報検索時に、質問文のみでなくLLM1の回答も考慮に入れて、より適切なチャンクを検索する 3. LLM2の加筆・評価時に、コーパスチャンクだけでなく、LLM1の学習済み知識とも照らし合わせる
など、ハルシネーションの伝搬リスクに対する追加の制御が必要になると思われます。 RAGのメリットを最大限に活かしつつ、このようなリスクを最小化できる設計が重要になってくるでしょう。貴重な指摘をありがとうございました。
私#10: 対策1(LLM1の回答に対して別の評価モデルで事前に誤り検知を行い、ハルシネーションが含まれていそうな場合は情報検索自体を見送る)に関してですが、現在は、LLM1の回答をLLM2が否定した場合は、LLM3にLLM1とLLM2の回答のどちらが正しいか、「第三者」に判定させています。 例えば、Gemini1.5Proの回答をClaude3に見てもらって、この2つの回答に矛盾があればCopilotにどちらが正しいか確認してもらっています。(ChatGPTは自分の回答の参照情報を出してくれないので、第3者判定には不向きです) Claude3#10: なるほど、興味深い対応策ですね。LLM同士で相互に評価しあい、矛盾が生じた場合に第3のLLMに最終判断を仰ぐという手法を取られているようです。 この方式のメリットは、以下のような点が考えられます。
一方で、留意点としては:
などが考えられます。 このように、複数のLLMを掛け合わせる手法には一長一短があります。RAGにおいても、このようなアプローチで外部知識検索の可否を判断することは検討に値すると思われます。ただし、上記の留意点を考慮した上で、本当に効果的な手段かどうかを見極める必要があるでしょう。 いずれにしろ、ご提案の対応策はユニークな発想で、RAGの課題解決に役立つ可能性があると感じました。ありがとうございます。 |
以上、Claude3との対話で、RAGに関する知識の整理を実施するとともに、RAG-Sequenceの改良版(FiDもどき)の姿が見えてきたので、実際にDifyで試してみたいと思います。
なお、DifyでRAGを活用したチャットボットを構築する方法はすでにネット上で出回っていますので、RAG構築手順そのものに関しては、例えば以下のサイト/YouTube動画を参考にしてください。
■DifyでRAGを使う方法を解説したサイト
① Zenn:DifyでRAGを活用したチャットボットを構築する(簡易編)
② Note:Dify で RAG を試す|npaka
③ うさラボ:【Dify】RAGを使った簡単なアプリを作る – うさラボ
■DifyでRAGを使う方法を解説したYouTube動画
④ にゃんた:仕事で使えそう?DifyでRAGを行う時の設定について解説してみた
①は、Difyが使える環境が整っていることを前提として、とりあえずDifyへのRAGの情報の登録の仕方と、チャットボット側で登録したRAG情報を参照するようにする仕方が説明されています。
②は、簡単にRAGの説明をした後、Dify自身は生成AIではないので、モデルプロバイダーとしてどこの生成AIを使うかの設定の説明があり、RAGの情報をDifyに登録する手順を詳しく説明したのち、ChatflowというDifyの機能を使ってグラフィカルにRAGを利用したチャットボットの作成方法が説明されていました。
③でも、②同様、ChatflowというDifyの機能を使ってグラフィカルにRAGを利用したチャットボットの作成方法が説明されているのですが、RAGの情報登録段階でのデバッグとプレビューの仕方や、ワークフローの設定等が詳しく図付きで紹介されていました。
④は、DifyでどのようにRAG機能が実装され、どのように使えばよいかが、非常にわかりやすく解説されていました。RAGの原理まで説明されていて、おすすめです。
ということで、ここからは、実際にDifyを使って、Difyのサイトで提供しているドキュメントをRAG情報として、RAG-Sequence+FiDもどきのチャットボット「Difyのことなら何でも聞いてください」を作成しましたので、出来上がるまでをご紹介したいと思います。
■Difyのことは、Dify.AIに訊こう!
Difyのサイトを呼び出すと、下図のように「ドキュメント」というメニューがあるのは、ご存じだと思います。
この「ドキュメント」をクリックして表示されるのが、下の画面です。
日本語表示に切り替わることを期待して、「English」というメニューをクリックしてみた方は多いのではないでしょうか?
残念ながら、英語と中国語の2択です。
そこで、この「Welcome to Dify!」のページから始めて、Dify.AIが「ドキュメント」として用意してくれている内容を一旦PDFにしてRAGの情報として用意し、英語や中国語以外で入力されたDifyに関する質問に対して、入力された言語で回答するRAGアプリを作ってみようというわけです。
#もう少し待てば、PDF化しなくても、「ドキュメント」の各ページのURLをDifyの「ナレッジ」➡「知識を作成」➡「データソースの選択」で「ウエブサイトからの同期」の機能を使えば、もっと簡単にRAG情報として用意できるのですが。。。
ただ、「Coming soon」が、どれほど「soon」なのかわからないのと、Difyの「ドキュメント」を1ページずつPDF化するのも、面倒なので、下図の緑の枠で囲った単位でPDF化を行いました。
それでも、下図の通り、24個のPDFを「ナレッジ」としてDifyに登録しなければなりませんでした。
最後まで書き進めようと思っていたのですが、長くなってきたので、このよう用意したナレッジを使うチャットボットアプリ「Difyのことなら何でも聞いてください」の構築のご紹介は、次回に回したいと思います。
終わり
Pingback: Difyについてーその7(FiDもどきのRAGアプリ構築を目指したのですが。。。) – インターテックリサーチ株式会社