Difyでナレッジベースを連携！実践チャットフロー作成チュートリアル

# 🌟実践！DifyでRAGを活用したAIアプリ作成ガイド🌟

本記事では、DifyのRAG機能を使って、AIチャットボットアプリを構築する手順を解説します！

## 1. Difyアカウントの作成＆設定🔧

- **アカウント登録**：Difyの公式サイトでアカウントを作成。📝  
- **APIキー設定**：OpenAIやCohereなど、外部APIのキーを「設定」→「モデルプロバイダー」で入力！🔑  
- **ナレッジベースの設定**：ナレッジベースは、ユーザーのクエリに対してナレッジベースから最適な情報チャンクを検索し、LLMに渡して回答を生成する仕組み(RAG)です。🤖

ここまでは前提として準備しておきましょう！

💡ナレッジベースの設定は下記の記事でも紹介しています。

https://qiita.com/Casineria/items/1d9227b9fd8a2cc5d723

## 2. RAGアプリの構築🔨

まず、サンプルとして、Difyが提供している、ライブラリ（探索）から、「Question Classifier + Knowledge + Chatbot 」を取得してみてみましょう。

![スクリーンショット 2025-02-20 15.06.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/a87328b6-ed54-4dff-82c7-5a8a03e73530.png)

開くと以下のようなチャットフローが表示されると思います。

![スクリーンショット 2025-02-20 20.46.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/f98b496a-522f-48ab-9f4c-d73c2ee96ac7.png)

- **開始ブロック**
各ブロックを一つずつ確認していきます。開始ブロックは、入力を単純なテキストにする場合には特に修正はありません。独自の選択肢、文書、画像を入力にしたい場合は「入力フィールド」にそれぞれの変数を追加してください。

![スクリーンショット 2025-02-20 15.12.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/9dd5cfbe-5cf2-4485-a572-17a5071c11fe.png)

- **質問分類器ブロック**
質問の分類にも、クラスの部分に分類わけしたい条件を記載するだけです。特に解説は必要ないでしょう。


![スクリーンショット 2025-02-20 15.13.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/d2ea0298-fe86-4460-a477-39744955e64c.png)

- **知識習得ブロック**
続いてナレッジの説明に入ります。クエリ変数には、検索する際の入力になりますが、ここではsys.queryとします。先ほど開始ブロックで設定したユーザーのテキスト入力を格納した変数がsys.queryです。次にナレッジの右上にあるプラスボタンを押して、あらかじめ自分で設定しておいたナレッジを連携させてください。ここでは例として”MentalHealth”というドキュメントを連携させています。ドキュメントの設定方法に関してわからない人は下記の記事を参照してください。

https://qiita.com/Casineria/items/1d9227b9fd8a2cc5d723

次に、プラスの横の「検索設定」を押してください。「RERANK設定」「Rerankモデル」「トップK」「スコア閾値」などの項目があります。これらはRAGの検索精度を向上させるためのパラメータです。自由に設定して問題ありません。設定方法は下記の通りです。参考にしてください。

> #### RERANK設定とは？🤔
> - **一言で言うと**：検索結果の候補（チャンク）の中から、最も関連性の高いものを選ぶ設定のこと。RE：RANK 再び順位づけ
> - 最初に、ベクトル検索や全文検索で候補となる結果を取得しますが、そのままでは順位が完全ではない場合があります。  
> - 外部のRerankモデルを使って、取得した候補を再度評価し、上位に最適なものをランク付けを行います。 
> - ここで使用するのがCohere(コーヒア)の「rerank-v3.5」など、外部APIを利用するモデルです。現在Cohereが強みを持つ領域ですが、このモデルを利用すると、外部API利用料（トークン消費など）が発生するため、コストとのバランスも考慮してください。
> #### トップKって何？🔝
> - **一言で言うと**：検索結果から最も関連性が高い上位K個のチャンクを選択する設定。  
> - トップK=3と設定すると、検索候補の中から上位3件だけをLLMに渡す、という意味です。
> - 候補の数を絞ることで、LLMに渡す情報のノイズが減って、回答の精度が向上します。  
> - アプリのユースケースやナレッジベースの規模に応じて、最適な値に設定しましょう。🎯
> #### スコア閾値って何？📏
> - **一言で言うと**：検索候補を採用するための最低限必要な関連性スコアを設定するパラメータです。  
> - *候補のスコアがこの閾値以上でなければ、その候補は採用されません。  
> - スコア閾値0.5と設定すれば、0.5未満のスコアの候補は除外されます。使ってみればわかりますが、Difyでは検索するときにログ見るとスコアが表示されます。この値のことかと後でわかると思います。 
> - 低い関連性の候補を排除することで、LLMに渡す情報の質を保って、誤った情報が混入するリスクを低減できます。🔒

![スクリーンショット 2025-02-20 15.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/0a30f549-b1ad-40d6-9b01-92c916c185f7.png)

また、sys.queryを入力として、情報が見つかった場合、その結果が変数resultに格納されます。この変数のデータ構造には、セグメント内容、タイトル、リンク、アイコン、メタデータ情報が含まれます。

>#### 概要
>- **result (Array[Object])**：検索で見つかった複数のセグメントの集合（オブジェクトの配列）  
>- **content**：実際のテキストコンテンツ(テキストそのもの)
>- **title**：各セグメントのタイトル情報(各セグメントの概要や、ドキュメント名、章のタイトルなど、内容を把握しやすくするための情報) 
>- **url**：元データへのリンク情報(Webページやドキュメントのリンク先を、参照元の確認や詳細情報をここに保持)
>- **icon**：視覚的な識別用アイコン(ビジュアル面での補助情報として、データの種類やカテゴリを視覚的に識別できるようにしている)
>- **metadata**：その他の詳細情報（日時、スコア、位置など）
 
![スクリーンショット 2025-02-25 17.35.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/aacb6ce5-3812-4154-84e6-985a50eb485e.png)

続いてLLMの設定です。「コンテキスト」「SYSTEM」「USER」『ASSISTANT」とあります。「コンテキスト変数」にはナレッジ検索の「result」を格納してください。

> #### コンテキスト変数
> - **一言で言うと**：ナレッジ検索で得た「result」を格納できる変数
>  ナレッジ検索で得た「result」をコンテキストに設定しておけば、プロンプトの中で変数として「result」を使うことができます。
>

![スクリーンショット 2025-02-20 16.17.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/e2d8aae5-c4b4-4d00-94c7-935866c85273.png)


> #### SYSTEM プロンプト
> - LLMに与える全体の会話やタスクに対する「高レベルな命令」
> - LLMの「全体の方針」や「ルール」を定めます 
> - **例**：  
  ```
  SYSTEM:
      1. 文章を読み、内容を理解します。
      2. 文章を以下の5つのセクションに分けて要約します：
         - 背景
         - 問題
         - 課題
         - 施策
         - 結論
      3. 各セクションは明確に区別し、適切な見出しを付けてください。
      4. 出力はXMLタグを含めず、テキストのみで構成してください。
      5. 各セクションは簡潔でありながら、必要な情報を含むようにしてください。
  ```
  → ここでは、全体のタスクのやり方やルールが指示されています。  

> ここについては、Difyには「プロンプト生成機」が用意されているため、基本的にこれを使えば問題ないでしょう。特に複雑な設定をしなくても、スムーズに進められるはずです。

![スクリーンショット 2025-02-20 16.05.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/549de369-0f22-4193-a3ca-25ce8fa81fba.png)


> #### USER プロンプト 💬
>
> - ユーザーが指示したいことを記載する欄。つまりシステムに渡す入力を記載する欄です。
> - USERの指示に従ってSYSTEMが動くと理解してください。
>
> よって基本はsys.queryを記載します。
>
- **下記のような使い方もできます**：  
  ```
  USER:
      変数I（入力でユーザーが設定した値）を利用して、関連する文章を探し、表してください。
  ```
  → こんな風に、ユーザーが任意の変数を『開始』ブロックを設定しておけば、その値に基づいた入力処理も指定できます。


![スクリーンショット 2025-02-20 16.24.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/d6521956-8290-495f-92ed-88e0e647829d.png)


> #### ASSISTANT プロンプト 🤖
> - 「応答」の定義を記載する欄です。
> - USERの指示に基づいて、SYSTEMが実行されて、ASSISTANTの定義に沿って回答する。というイメージを持ってください。
- **例**：  
  ```
  ASSISTANT:
      日本語以外の文章は全て通訳してください。
  ```
  
![スクリーンショット 2025-02-20 16.31.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/0ecdd89e-2b84-40ee-8ea7-169c69893107.png)


最後に、LLMは”text string”で回答されるため、出力は、"text"として終了です。


![スクリーンショット 2025-02-20 16.33.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3867059/cd267481-5d5d-4190-a31f-d7f089cb2fa7.png)


## 3. まとめ✨

- ここまでで、「開始」→「知識取得」→「LLM」→「回答」の各ノードを組み合わせ、実用的なRAGアプリを迅速に構築できるようになったでしょうか。

ぜひ、この記事の手順に沿って実際に手を動かし、あなた自身のRAGアプリ作成にチャレンジしてみてください！💪🌟