
こんにちは、CCCMKホールディングスAIエンジニアの三浦です。
最近DifyというAIアプリケーション開発プラットフォームについて調べていました。社内の有志のメンバーでDifyについて発表しあう会があり、そこに向けて自分も発表の準備をしていたからです。
テーマは何にしようかな・・・と考え、最終的にDifyで組むことが多いRAG(Retrieval-Augmented Generation)の性能をDifyで出来るちょっとした工夫で改善する方法を調べてみることにしました。
RAGのSurvey論文
RAGに関するさまざまな手法を調べるに当たり、最初に目を通したのが以下のRAGのSurvey論文です。
- Title: Retrieval-Augmented Generation for Large Language Models: A Survey
- Authors: Yunfan Gao, Yun Xiong, Xinyu Gao, Kangxiang Jia, Jinliu Pan, Yuxi Bi, Yi Dai, Jiawei Sun, Meng Wang, Haofen Wang
- Submitted: 18 Dec 2023 (v1), last revised 27 Mar 2024
- arXiv: https://arxiv.org/abs/2312.10997
この論文では従来のRAGをNaive RAGと呼び、Naive RAGのうち情報検索の前後に追加の処理を加えて性能を向上させたRAGをAdvanced RAGと呼んでいます。

情報検索の前(Pre-Retrieval)では主に検索に使用するクエリの最適化を行います。Naive RAGではユーザーの入力をそのまま情報検索クエリとして使用しますが、ユーザーの入力は検索クエリとして最適なものとは限りません。情報が少なかったり、反対に複数の意味が複雑に含まれていることもあります。ユーザーの入力に対して最適なVectorDBにルーティングするQuery Routing, ユーザーの入力を検索クエリに適した形に書き換えるQuery Rewriting, 複雑なユーザーの入力を複数のクエリに分割するQuery Expansionといったテクニックが存在します。
情報検索の後(Post-Retrieval)では検索した情報の最適化を行います。LLMは上位にある情報ほど優先して見に行く傾向があるため、ユーザーの質問に対する関連度などで情報を並べなおすRerank, 情報を要約したり集約することで内部に含まれるノイズを除いたり、与える情報を圧縮するSummaryやFusionといったテクニックが存在します。
Pre-RetrievalとPost-Retrievalのうち、今回はPre-Retrievalに注目をしてみることにしました。特にユーザーの入力を検索に適したクエリに書き換えるQuery Rewritingの中でHypothetical Document Embeddings(HyDE)というテクニックが面白そうだったので実際に試してみました。
HyDE
HyDEが提案されているのはこちらの論文です。
- Title: Precise Zero-Shot Dense Retrieval without Relevance Labels
- Authors: Luyu Gao, Xueguang Ma, Jimmy Lin, Jamie Callan
- Submitted: 20 Dec 2022
- arXiv: https://arxiv.org/abs/2212.10496
結構前の論文でした。2022年の末はChatGPTがリリースされたころでまだそれほどRAGは注目されていなかったと思います。実際この論文の中でも"RAG"というワードは出てこず、埋め込みベクトルを使った情報検索の精度向上という観点でHyDEが提案されています。
HyDE以前はユーザークエリと該当文章のマッチング向上のために"Contrastive Learning"のような学習ステップを必要とする手法がよく取られていたようです。それに対しHyDEは一切追加の学習を必要としない点が当時とてもユニークだったのでは、と思いました。
HyDEのアイデアはとても明瞭です。ユーザーのクエリを一度LLMを使って仮の回答に変換をし、その仮の回答を使って情報検索を行います。もちろん仮の回答は正確な内容とは限りませんが、埋め込み空間においてはユーザーのクエリよりも検索対象の文章により近い場所に存在する可能性が高くなります。

この論文で述べられているHyDEではユーザーのクエリに対し複数個の仮の回答の生成を行わせています。HyDEの実装コードを見ると、デフォルトで8個の回答を生成させているようでした。仮の回答達に対する埋め込みベクトルと元のユーザークエリに対する埋め込みベクトルの平均ベクトルを検索用の埋め込みベクトルとして使用しています。
DifyでHyDEを試す
HyDEの主なポイントはLLMで生成させたユーザーの質問に対する仮の回答をKnowledge Baseの検索クエリとして使用する点です。生成する仮の回答は1つとし、Difyで実装してみました。
まずベースとなるNaive RAGのフローを以下のように作成してみました。

このフローにHyDEを適用する場合はKnowledge Retrievalノードの前にLLMノードを挟み、仮の回答を生成させた後に仮の回答をKnowledge Retrievalノードに入力します。

仮の回答を生成させるLLMノードには以下のようなプロンプトを設定しました。

では、実際のデータを使って、それぞれの動作を見てみます。使用したデータは私が書いたこちらのブログの内容をテキスト化したものです。
それぞれ、「インタビューによって人格設定することのメリットは?」という入力をしてみました。まずNaive RAGの場合、次のようなデータが検索されました。
========== では1,000人にも及ぶ参加者に2時間ものインタビューをどのように実施しているのでしょうか?Generative Agentの面白いのが、インタビューを行うインタビュアーもまたAIで構築しているという点です。 ========== ========== インタビューによって人の行動をシミュレーションする"Generative Agent Simulations of 1,000 People"について調べました。 ========== ========== 参加者はシステムにログインし、自身の情報(アバター作成など)を登録した後に以下のようなインターフェースでAIによるインタビューを受けることになります。 ==========
"インタビュー"という単語への関連は強いのですが、回答するための情報としては内容が薄いように感じました。一方HyDEの場合は次のようなデータが検索されました。
========== では1,000人にも及ぶ参加者に2時間ものインタビューをどのように実施しているのでしょうか?Generative Agentの面白いのが、インタビューを行うインタビュアーもまたAIで構築しているという点です。 ========== ========== 比較対象のシミュレーション構築手法 実在する人物をAIでシミュレーションする方法は他にも考えることが出来ます。たとえばその人物の人口統計情報をプロンプトに与える方法や、その人物のプロフィールをプロンプトに与える方法です。人口統計ベースの方法をDemographic-Based, プロフィールベースの方法をPersona-Based、そしてGenerative Agentで使われているインタビューベースの方法をInterview-Basedとしてそれぞれの手法でどれだけ人物を再現できるのかが比較検証されています。 ========== ========== 参照元】Generative Agent Simulations of 1,000 People, Supplementary Materials, Figure 4 インタビューはどうやって実現しているのか? Generative Agentのベースは、米国の代表的なサンプルになるように年齢・性別・人種・地域・教育水準・政治的イデオロギーといった要素を考慮した層化抽出法によって募集された1,000人以上の実在する人物に対して行ったインタビューのトランスクリプトです。インタビュー項目は社会科学の観点でとくに関心がもたれている個人の人生史から現代社会の問題に対する意見まで幅広いトピックに及んでいて、American Voices Projectの一環として社会学者によって開発されたインタビューを元に構築しています。さらに時間が許す限り状況に応じてフォローアップの質問も実施されています。 ==========
こちらの方がより内容が濃い情報が検索出来ています。また、3つ目のデータはインタビューの内容そのものに言及したものなので、「インタビューによって人格設定することのメリットは?」という問いにも活用できるものといえます。
それぞれが生成した回答は以下のようになりました。
【Naive RAG】
インタビューによって人格設定を行うことには以下のようなメリットがあります: 1. **リアルな行動シミュレーションが可能** インタビューで得られた情報を元に個々の人格を設定することで、Generative Agentがよりリアルで自然な行動をシミュレーションできます。これにより、仮想空間やシステム内での人間らしい振る舞いや意思決定を再現できます。 2. **多様性の反映** 参加者の個々の情報や背景を取り込むことで、1000人の異なる性格や特性を持つ代理人を生成できます。これにより、シミュレーション環境で多様な視点や反応を観察することが可能になります。 3. **効率的なデータ収集** AIによるインタビューを通じて効率的に情報を収集し、それを基に個々の人格を設定することで、大規模なシミュレーションを迅速かつ正確に準備することができます。 4. **カスタマイズ性の向上** システムが各参加者の情報に基づいてアバターや人格を設定することで、仮想環境がよりパーソナライズされ、参加者や研究者が特定の条件でのシミュレーションを柔軟に行えるようになります。 5. **研究や分析の精度向上** 個別の人格設定を行うことで、特定の行動パターンや意思決定プロセスを深く理解するためのデータを得ることが可能です。これにより、社会的行動や心理学的研究の質が向上します。 このようなメリットにより、Generative Agentを活用したシミュレーションは、現実に近い仮想空間での人間行動の研究や応用に役立つ仕組みとなっています。
【HyDE採用】
インタビューによって人格設定することのメリットは、以下の点にあります: 1. **個別性の高い人格の再現**: インタビューを通じて得られる情報は個々の人物の人生史や意見など、非常に具体的で詳細な内容を含んでいます。そのため、Generative Agentが個々の特徴を反映したリアルな人格を構築できるという利点があります。 2. **幅広い視点を取り込む**: インタビュー項目が現代社会の問題や個人の人生史など幅広いトピックを網羅しているため、Generative Agentは多様な視点や意見を持つ人格を構築することが可能です。これにより、シミュレーションの結果がより包括的で価値のあるものになります。 3. **リアリズムの向上**: 実在する人物へのインタビューを基にしているため、Generative Agentが生成する人格は実世界の人々の言動や思考に近いものとなります。これにより、人物のリアリズムや信頼性が高まります。 4. **状況に応じた柔軟性**: インタビュー中にフォローアップの質問を実施することで、個々の回答の背景やニュアンスを深掘りすることができます。この情報はGenerative Agentにとってより精密な人格設定に役立つため、状況に応じた柔軟性が備わります。 5. **社会科学の知見を活用**: インタビュー設計が社会科学者によって開発されているため、学術的に裏付けられた手法を用いて人格設定が行われます。これにより、シミュレーションの信頼性や精度がさらに向上します。 これらのメリットにより、インタビューを基にした人格設定は、リアルで多様性に富みながらも信頼性の高いGenerative Agentを構築するうえで非常に効果的な手法となっています。
よりデータに基づいた回答が出来ているのは、やはりHyDEを採用したほうだと感じました。
まとめ
ということで、今回はDifyでも活用がしやすいRAGの性能向上のテクニックHyDEを実際にDifyで試してみた話をご紹介しました。はじめHyDEのアプローチを知った時は「仮の回答で検索して大丈夫なのかな」と思ったのですが、元のユーザーの入力をより検索したい情報に近づける変換処理だ、という風に見ればとても理にかなった方法だと思いました。実装はそれほど難しくないと思うので、ぜひ試してみてください。