Baldwin
© Copyright Andy Stephenson and licensed for reuse under this Creative Commons Licence.

 

 

前回は、MoAアプリに利用する生成AI選びから横道に逸れて、ChatGPT、Gemini、Copilotの「疑似RAGアプローチ」の内情確認にたどり着いてしまいました。

 

  • あらかじめLLMでは学習していない情報を、RAG情報としていくつかの塊(チャンク)に分け、組込み技術(Embeddings)を使ってベクトル形式に変換して外部データベースに保持しておき、質問を受けた段階で、質問文のキーワードベースでRAG情報を検索するのではなく、質問文全体をベクトル形式にしたものに意味的に近いRAG情報を「セマンティック検索」するというのが、一般的なRAGの定義となっているようなので、事前にRAG情報を用意するのではなく、質問を受ける都度、関連する外部情報から補填して回答を作成するChatGPT、Gemini、Copilotの処理を「疑似RAGアプローチ」と呼んでいます。

 

なお、時として、生成AI本体の振舞いと、生成AIを呼び出すチャットボット(あるいは生成AIアシスタント)の振舞を混同してしまうのですが、

  • OpenAIの場合は、チャットボット:ChatGPT、内部的に呼び出される生成AI:5、GPT4
  • Microsoftの場合、チャットボット:Copilot、内部的に呼び出される生成AI:GPT4
  • Googleの場合、チャットボット:Gemini、内部的に呼び出される生成AI:5Pro

 

ということで、生成AIの学習に使用されたトレーニングデータよりも最新の情報を質問された場合、RAG情報あるいは疑似RAGアプローチでの質問中に含まれるキーワード検索が、実はハルシネーションが起きるかどうかの分かれ目で、どの生成AIを使ったところで、知らない情報のみから真実の情報を提供できないということですね。

考えてみれば、当たり前ですが。

 

ということは、最新情報検索でハルシネーションを防ぐには、質問に関連する最新情報に関して複数の検索エンジンを利用して、正しい最新情報を見定め、その内容を、質問内容とともに生成AIに渡して回答を作成してもらえばよいということになり、複数の生成AIの「いいとこどり」を狙うMoAアプローチではなく、複数検索エンジンを利用する「疑似RAGアプローチ」でよかったことになります。

 

前回、ブログの最後に、『次回からは、Difyがメインではなく、MoAアプリの構築をメインにするので、「MoAについて」と改題して、ブログを続けようと思います』と書いたのですが、以上のとおり、「疑似RAGアプローチ」でも良いことが分かったので、今回、ブログのタイトルを「Difyについてーその10 (疑似RAGアプローチに再度変更)」とした次第です。

 

繰り返しになりますが、最新情報の検索においてもハルシネーションの発生を少なくするには、複数の生成AIの出力を評価するのではなく、OpenAIが、ChatGPTで採用しているように、生成AIを呼び出す前に、質問に関連する最新情報を複数のサーチエンジンから入手して、そのサーチ結果としてもっともらしいものを、当初の質問内容とともに生成AIに渡して回答を作成すればよさそうです。

 

そこで、Difyで作成する場合のフローを次のように変更しようと考えました。

 

ステップ1:【開始】質問を受け付ける

ステップ2:【LLM1】質問中のキーワードを3つ選ぶ

ステップ3-1:【Search Tool1】質問中のキーワード3つを使って検索した結果をtext出力

ステップ3-2:【Search Tool2】質問中のキーワード3つを使って検索した結果をtext出力

ステップ3-3:【Search Tool3】質問中のキーワード3つを使って検索した結果をtext出力

ステップ4:【LLM2】ステップ3の3つのサーチツールの回答に整合性があるかどうかチェックし、整合性があれば、3つの回答を束ねてサーチツールから得た最新情報とする。整合性のない場合は、「サーチツール情報間に矛盾がある」ことを出力で示す

ステップ5:【質問分類器】ステップ4の出力が、「サーチツール情報間に矛盾がある」の場合は、3つのサーチツールの検索結果と、「サーチツール情報間に矛盾があった」ことを出力として、回答ノードを呼び、その旨を回答として出力し、終了する。一方、ステップ4の出力で、サーチツール情報間に矛盾がないことが分かった場合は、ステップ4の出力と、ステップ1の質問自体を入力として、ステップ6のLLM3を呼ぶ

ステップ6:【LLM3】ステップ5から渡された2つの情報を基に、回答を作成する。

ステップ7:【終了】ステップ5あるいはステップ6で作成された出力を回答として表示する。

 

※「質問分類器」は、Difyが用意しているフロー制御ノードに1つで、入力の内容によって条件分岐させることができます。

※ご覧いただければわかるように、ハルシネーションのない情報検索を全自動で行うのではなく、提供できる情報に自信がない場合は、人間側に判断を委ねる感じにしました。

 

この方針のもと、アプリの制作に取り掛かろうと思って、Difyに戻り、まず、どんなサーチツールが良いか検討を始めました。

Difyの「ツール」メニューを表示させ、左下に「Search」とあるツールを探すと、上図にあるように、ザッとこれだけの使えそうなサーチツールがありました。

まず、「Google」をクリックして、このツールを試したのですが、LLM1から渡されたキーワードによる検索結果がJson形式で出力されるため、そのままでは、検索結果の情報を後続のLLM2のノードに渡せませんでした。

次にMicrosoft「Bing」をクリックして、その「BingWebSearch」というツールを試してみると、質問内容から抽出したキーワードをもとに検索した結果をtext出力し、LLM2ノードに渡されるのが確認できました。

その次の「DuckDuckGo」が提供する「DuckDuckGo Search」というツールは全く知らないツールなので、Perplexity AIで調べてみました。

Perplexity.AI:

DuckDuckGo(ダックダックゴー)は、プライバシー保護を重視したインターネット検索エンジンです。2008年9月25日にガブリエル・ワインバーグによって設立され、現在も運営されています。

特徴と機能

1. プライバシー保護: DuckDuckGoはユーザーの個人情報や検索履歴を保存しません。IPアドレスの保存やクッキーの使用も最小限に抑えています。検索結果のパーソナライズを行わないため、ユーザーは「フィルターバブル」に陥ることがありません。

2. 検索結果のソース: DuckDuckGoの検索結果は、Yahoo! Search BOSS、ウィキペディア、Wolfram Alpha、Microsoft Bing、Yandex、そして自身のウェブクローラーであるDuckDuckBotを含む400種以上のソースから生成されます。

3. !Bang コマンド: 「!Bang」コマンドを使用することで、特定のウェブサイトに直接リダイレクトして検索を行うことができます。例えば、「!w DuckDuckGo」と入力すると、Wikipedia内で「DuckDuckGo」を検索することができます。

4. ユーザーインターフェース: 検索結果は1ページにスクロールして表示され、複数のページに分割されることはありません。

利用状況と採用

l  DuckDuckGoは、VivaldiやTor Browserの標準検索エンジンとして採用されています。

l  2022年3月には、ロシアのウクライナ侵攻を受けて、Yandex Searchとの提携を一時停止しました。

メリットとデメリット

メリット: プライバシーが強化され、個人情報の収集やプロファイリングが行われないため、安心して利用できます。

デメリット: 他の検索エンジンと比較して追加機能が少ないため、シンプルな検索体験に限定されます。

DuckDuckGoは、プライバシー保護を重視するユーザーにとって魅力的な選択肢となる検索エンジンです。

Difyで試しに使ってみたのですが、こちらでも、キーワードに基づく検索結果の情報がLLM2のノードに渡されました。

 

次の「SearchApi」はどのような検索エンジンなのか?と思ってクリックしてみたところ、下図の通り、この中に4種類のGoogle検索に対応する検索機能があるようです。

Google検索API:Google検索エンジンで、アンサーボックス(Google検索した際、Webページの結果とは別に検索結果の上部にその検索キーワードに関して表示される簡潔な答え)、ナレッジグラフ(Google検索でも散られる知識ベースの情報)、スニペット(Webページの要約文)、Webページを取得するツール。

Google Jobs API:Google Jobsエンジンで、求人情報(職種、会社名、仕事内容等)を取得するツール。

Google News API:Google Newsエンジンでオーガニック検索結果(検索結果画面の広告枠を除いた部分)のスニペットやリンクを取得するツール。

YouTube Transcripts API

特定のYouTube動画からトランスクリプトを取得するツール。

 

ということは、ステップ3で、種類の異なるベンダーのSearch Toolを使うのではなく、ステップ2で質問内容を「質問分類器」にかけて、

  • 職種、会社名、仕事内容等の求人に関する質問なら「Google Jobs API」を、
  • ニュース関連の質問なら「Google News API」を、
  • その他の場合は「Google検索API」を

呼び出して得られた検索結果と元の質問から、後段のLLMに回答を作成させるという手も考えられます。

 

とにかく、これで

  • Search Tool1:BingWebSearch またはGoogle Jobs API
  • Search Tool2:DuckDuckGo SearchまたはGoogle News API
  • Search Tool3:Google Search API

とすれば、アプリが組めそうです。

以下は、Difyのsearch ApツールのGoogle Jobs API、Google News API、Google Search APIを使ったアプリ「Google Search APIに訊いてみよう」のフロー図です。

また、以下は、このアプリの実行例です。

ChatGPT-4oに同じ質問をすると、最近はChatGPT4も疑似RAGアプローチをとっているので、むしろこちらの方が、残念ながら良質な回答が得られました。

※ただし、7/14のニュースにトランプ前大統領の狙撃事件が入っていないのが気になりましたが。。。

同じ質問をChatGPT3.5にした場合の回答よりはずいぶんマシですが。。。

 

 

もう1つのDifyで利用できるSearXNGという検索ツールも気になったのでPerplexity.AIで調べてみました。

:SearXNGについて教えてください

 

Perplexity.AI

SearXNGは、プライバシーを重視した無料のインターネットメタ検索エンジンです。以下にSearXNGの主な特徴と情報をまとめます:

主な特徴

  • 70以上の検索サービスから結果を集約します。
  • ユーザーの追跡やプロファイリングを行いません。
  • オープンソースで、GNU Affero General Public License version 3の下で提供されています。
  • ネットワーク経由で使用可能で、オンラインの匿名性を高めることができます。

SearXとの違い

  • SearXNGはSearXのフォークプロジェクトで、以下のような改善が行われています:
  • ユーザーエクスペリエンスの向上(デスクトップ、タブレット、モバイル対応)
  • ライトモードとダークモードの提供
  • 右から左に読む言語のサポート
  • 翻訳の更新(Weblateで貢献可能)
  • 設定ページの改善

使用方法

1.     公開インスタンスの利用:https://searx.space/ で公開されているインスタンスを使用できます。

2.     自身でホスティング:Dockerやインストールスクリプトを使用して、自分のサーバーにSearXNGをセットアップできます。

プライバシーと信頼性

  • 公開インスタンスを使用する場合、そのインスタンスの管理者を信頼する必要があります。
  • 自分でインスタンスをホストすることで、プライバシーとコントロールを最大限に確保できます。

注意点

  • 公開インスタンスは、トラフィックが多いため検索プロバイダーにブロックされる可能性が高くなります。
  • 自分でホストする場合、設定によってはログを最小限に抑えることができます。

SearXNGは、プライバシーを重視しつつ、多様な検索サービスの結果を一度に利用できる強力なツールです。自身のニーズに合わせて、公開インスタンスの利用か自身でのホスティングを選択できます。

SearXNG Searchというツールも使ったことがないので、回答にあった「SearXNGの公開インスタンスのサイト」から、唯一日本でホストされているもの(https://searx.juancord.xyz/)を使ってみると、なかなかよさそうです。

そこで、Difyで利用しようとしたのですが、注意点に記載されているように、DifyからのSearXNGを呼び出す際の「認証の設定」で「SearXNG base URL」にSearXNGの公開インスタンスのURLを設定しようとすると、「Error 429:Too many Requests」が出て使えませんでした。

ローカルPC側にSearXNGをインストールし、ローカルのDifyからアクセスすれば問題なく使えそうなのですが、それだとAIアプリとして一般公開できないので、とりあえず今回は見送ることにしました。

 

長くなってきたので、今回はここまでとします。

 

 

 

終わり