[Dify]CRAGをDifyで作成してみた


## はじめに


今回は練習がてらDifyでCRAGのフローを組んでみました。
CRAGのフローをLangChainブログの簡略化版ではなく、論文で提示されている版を組むとなかなか大変です。
みなさんも一度これを読んでCRAGの構築実践してみましょう！
これができたらDify中級者なんじゃないでしょうか？
では始めます。

## CRAGとは

![](https://storage.googleapis.com/zenn-user-upload/be8c6ac2a79d-20240212.png)
(Referenced by https://arxiv.org/pdf/2401.15884.pdf)

プロセスとしては、
1. 持っているドキュメントに検索しに行く
2. 検索したドキュメントから取得した内容が、関連しているか、してないかを判定する。
3. 知識をより洗練する。
    - **取得した内容が関連していない**　→　文脈を補足するためにウェブベースの文書検索を実行する。そのために質問をWeb検索用に最適化＋Webで検索して知識を補強！
    - **取得した内容が関連している** →　取得してきたドキュメントを分割して、各分割に対して評価して無関係なものは除去！
    - **取得した内容が関連してるか微妙**　→　知識の洗練とWebでの情報取得の両方を行う。

4. 回答を生成する。
    - **取得した内容が関連していない**　→　**質問**＋**Webで検索して知識**で回答を生成
    - **取得した内容が関連している**　→　 **質問**＋**洗練した知識**で回答を生成
    - **取得した内容が関連してるか微妙**　→　**質問**＋**Webで検索して知識**＋**洗練した知識**で回答を生成

簡単にいうと、
**RAGに指定した文書に関連する内容があったら、知識を洗練する！なかったらWeb検索しに行けばいいんやん、関連してるかわからんやったらどっちもやろ！**
ってことです。

具体的には以下のブログを見てみてください。︎（私が書いた記事で恐縮です。）
https://zenn.dev/yamada_quantum/articles/ab41b431581eba


## 全体像
ではDifyで構築するとの全体像は以下です。
上記に記載したCRAGの図のようなknowledge　refineはDifyで現状難しそうなのでLLMにRefineさせるようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/810c1028-b88e-10ba-e972-4bb055e68711.png)

では各モジュールを見ていきましょう。



## 知識の取得から分類まで
まず知識の取得から分類までの全体像です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/8c838d7f-a0aa-ade8-8018-bbda86ff72a5.png)

知識取得してから、質問分類できるように文字列にします。
そして検索がいい感じかをCorrect, Incorrect, Ambiguousの３つに分類します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/dc0e9676-fe1c-1335-7f15-dc5d52236f7f.png)

## Correctの場合
Correctの全体像は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/ca377723-06da-e712-7be4-92d9cb5718a6.png)

具体的な内容は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/f354de5f-ba00-4e32-8dc2-cdd3d879c1b3.png)


## Incorrectの場合
Incorrectの全体像は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/0bf5947d-0a6e-c3a2-6cb6-248855cf522d.png)

具体的な内容は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/942a4f2c-dc9e-a708-49ee-fad5891c4142.png)


## Ambiguousの場合
Ambiguousの全体像は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/40b12df5-4bce-cf7e-e4f3-d69502876dbe.png)

具体的な内容は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376115/6b5ae1cf-6fe2-748e-46e9-1dac16ef07c7.png)

ここまでできたら終了です。

## プロンプト

では実際に使用しているプロンプトを記載します。

### KnowledgeRefineのプロンプト

```
Please organize your information so that you can properly answer the questions.

{{#context#}}
```

### 質問変換のプロンプト

```
You are generating questions that is well optimized for retrieval. \n 
    Look at the input and try to reason about the underlying sematic intent / meaning. \n 
    Here is the initial question:
    \n ------- \n
    {{#sys.query#}}
    \n ------- \n
    Formulate an improved question: 
```

### 回答生成のプロンプト


```
Please answer the following questions according to the instructions on the following information.
{{#context#}}
    Question: {{#sys.query#}}

```

Ambiguousの場合はコンテキストにtavilyの出力も入れておきましょう。

## 最後に

CRAGのDifyでの構築はいかがでしたでしょうか？
今回は少し長めのフロー組んでみました。みなさんのDifyの練習になれば嬉しいです。

Xやってるので気になる方はフォローお願いします。
https://x.com/hudebakonosoto