ローカルSLMでRAG

# はじめに
前回の記事で構築したOllama + Difyの環境でRAGの修行です。

https://qiita.com/Y-Shikase/items/f3d1486073412cd2d221

# モデル
モデルは次のものを追加しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/0ca522e2-9bf3-d10e-a370-7d8c63792c29.png)

# ナレッジ
アウトドアウェアでお世話になってるフルマークスストアの製品情報をテキストファイルでまとめてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/38a790df-4195-928f-4d14-03d370cf690c.png)

ナレッジの作成で、テキストファイルからインポートします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/71eb2e81-94e1-3dc0-bc1b-2db96ea6a01b.png)

自動で高品質のベクトル検索にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/d405b3f7-e7a5-eedf-a393-bd2627580eea.png)

「保存して処理」をクリックするとナレッジの作成が完了します。
埋め込みの完了もすぐ100%で完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/ed55f6e8-d60f-cc3f-27e9-a9c10e2eaaee.png)


# アプリ
上部の「スタジオ」を開き、アプリを作成する画面で「最初から作成」をクリックします。
「BETA」がなかなか取れないですが、「ワークフロー」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/54c3897c-c610-38aa-2b6c-79b994ef0ba8.png)

## RAGのテンプレフロー

よく見るRAGのテンプレフローです。Difyに慣れてくると、1分で作れると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/e2814810-d520-7aa4-59ac-bae280d42a50.png)

有名なフローですが、精度が出ないテンプレなのであまり使い物になりません。
試しに「暑い日でも涼しいウェアとパンツを列挙してください。」と質問してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/5e4b8877-a115-1664-88d3-90c96c1789e2.png)

結果は以下です。パンツを無視しちゃってますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/8d8c00cd-a8c3-70c5-2962-8ffea3f2c492.png)

原因は、ベクトル検索でのクエリを見れば分かると思います。このクエリの類似文を1回検索しているだけという事になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/7aa448df-6865-733c-e895-19ad0cd1f315.png)

## 少し改良したフロー
ベクトル検索を細かく複数回に分けて実行した結果をまとめれば、大体のものはコンテキストに入るはずなので、少しフローを改良したものを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/6031e5fc-d145-3ad2-8a9d-2ac1110974d6.png)

最初に「LLM」を仕込んで、複数回の単語検索をする事を想定とした場合の情報をJSON形式で出力してもらいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/3f9fdace-84cd-ffa4-dfca-fa678f5af8d7.png)

検索語をJSON文字列で出してもらったら、次に「コード」でオブジェクトに変換します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/8bf57d98-0f6b-f68b-e6c4-61a7d349eff3.png)

コードの次は「イテレーション」を配置します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/1bf44350-15c3-9fd2-d128-86d2091f38db.png)

入力は「コード」で変換したオブジェクトです。
※出力変数はイテレーションの作成が終わってから設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/f6c83b79-9f5e-ad1b-ebe5-cb56b02673c3.png)

イテレーション内に「コード」を配置してオブジェクトから検索語を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/6620534b-33a3-fdc5-3cc0-1e532fe75b67.png)

「知識取得」でコードの検索語を使って検索させます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/d1867308-24e3-36fe-e7bd-a6927c4a0a60.png)

検索結果だけを「コード」で抜き取ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/2a09502a-10af-2ae8-3b80-7f5846405bf4.png)

最後に「コード」の結果を「イテレーション」の出力変数に設定しておきます。

「イテレーション」に続けて「LLM」を配置します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/231c2ca0-fc11-3ada-63d0-874dc5dc4236.png)

内容は通常のRAGで良いと思いますが、コンテキストにイテレーションの出力変数を指定しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/9191ad18-83d4-68d3-cb7c-770d7b7f70e1.png)

再度同じ質問をすると、今度はパンツも回答しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/44e5dcfb-ceea-c5f2-2338-687fd50dbcd8.png)

トレースを見ると、知識取得を2回実施しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/3ee49801-6ef2-13c0-3284-38a34dcbb5b3.png)

知識取得の内容を見ると、単語検索LLMが「夏 涼しい ウェア」と「夏 涼しい パンツ」に分けてくれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/4b2d0c1e-ae60-290c-3840-b325621658f9.png)

パンツもウェアなのですが、「ウェア」と「パンツ」で分けているのは、単に私が類似検索を意識しているだけかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/0af4244d-bd24-b8b1-e8e2-42368559614f.png)

ともあれ、若干精度の良くなったRAGができました。
フローやプロンプトを改良していけばもっと精度が良くなりそうですね。

# おわりに

イテレーションで「知識取得」を使ってますが、GoogleなどのWeb検索や社内の検索システムに変えても面白そうですね。