44
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

生成AIに関する記事を書こう!
Qiita Engineer Festa20242024年7月17日まで開催中!

プロキシ環境下のローカルPCに"Dify"と"Ollama"を導入して、インターネットを通らない「完全ローカルRAGアプリ」を作る

Last updated at Posted at 2024-06-15

はじめに

お疲れ様です。yuki_inkです。

「生成AIでRAGやりたい!」と言われると、反射神経で「S3!Kendra!Bedrock!」などと言ってしまうのですが、いざRAGで扱うドキュメントが自社やお客様の機密文書レベルになってくると、途端にその声のトーンは小さくなってしまいます。

え、そもそもこのドキュメント、クラウドに上げられます、、?

なるほど、ローカルPCで全部完結すれば万事解決ですわ!!
というモチベーションで色々やってみたという記事です。

前提条件

以下2点を前提条件とさせていただきます。

  • 固定IPがPCに割り当てられていること
  • PC(Windows)の管理者権限が利用できること

なお、この記事では、プロキシの IP アドレスを 192.168.11.9、プロキシのポートを 3128 として説明します。
この記事を参考にされる際は、実際のプロキシの情報に置き換えて設定してください。

以下の手順は、PC(Windows)の管理者権限を持つローカルユーザで操作を行ってください。
ドメインユーザの場合、ドメインポリシーによる制限がかかり、想定通りの操作ができない場合があります。
※特にOllamaが謎のエラーを吐く場合があります。

事前準備

Difyの導入までは、以下の記事を参照してください!!
(ついでに「いいね」と「ストック」もお願いしますw)

参照いただきたい箇所は以下の通りです。

以下に記載する手順は、Dify導入までが完了していることを前提としています。

やったこと

  1. 環境変数の設定
  2. Ollama のインストール
  3. Dify の設定(モデルの追加)
  4. Dify でRAGアプリを作成
  5. PC起動時にWSLが自動起動するようにしておく

本題は #1〜#4 。#5 はついでです。

(1) 環境変数の設定

こちらの記事を参考に、PCの環境変数を設定します。

設定する環境変数は以下の通り。
image.png

変数
HTTP_PROXY http://192.168.11.9:3128
HTTPS_PROXY http://192.168.11.9:3128
NO_PROXY 0.0.0.0
OLLAMA_HOST 0.0.0.0

ユーザ環境変数の設定が終わったら、設定反映のためOS再起動をしておきます。

【参考にした記事】

(2) Ollama のインストール

(1) 環境変数の設定 で作業したユーザと同じユーザで作業してください。

こちらのWebページからOllamaのインストーラを入手します。

Download for Windows (Preview) ボタンをクリックして、インストーラ OllamaSetup.exe を取得。
image.png

インストーラ OllamaSetup.exe を起動し、Install ボタンをクリック。
image.png

「完了しました」的な画面は表示されませんでしたが、インストールは完了した模様。
スタート画面のアイコンがかわいい。
image.png

続いてモデルをダウンロード。
今回はphi3を利用します。

コマンドプロンプトを立ち上げて、以下のコマンドを打鍵。
※カレントディレクトリはどこでも大丈夫です(カレントディレクトリにモデルの各種ファイルがダウンロードされるということはなかった)

ollama run phi3

初回はモデルのダウンロードに少し時間がかかります。
モデルのダウンロードが完了したら、自動でチャットセッションが開始されます。
image.png

「大規模言語モデルについて簡潔に教えて」と聞いてみます。
日本語で回答を返してくれました。
image.png

ブラウザを起動し、http://(PCのIPアドレス):11434/ にアクセスします。
Ollama is runnning と表示されればOK!
image.png

なお、PCのIPアドレスは、コマンドプロンプトで ipconfig コマンドを実行して確認できます。
以下の例だと 172.19.11.1 がPCのIPアドレスになります。
※WSLと書いてある方ではないことに注意

> ipconfig

Windows IP 構成

イーサネット アダプター イーサネット 2:
   接続固有の DNS サフィックス . . . . .:
   IPv4 アドレス . . . . . . . . . . . .: 172.19.11.1
   サブネット マスク . . . . . . . . . .: 255.255.xx.xx
   デフォルト ゲートウェイ . . . . . . .: 172.19.xx.xx

イーサネット アダプター vEthernet (WSL):
   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: 1234:567:890a::bcde:f1a2:b3c4
   IPv4 アドレス . . . . . . . . . . . .: 172.20.22.2
   サブネット マスク . . . . . . . . . .: 255.255.xx.xx
   デフォルト ゲートウェイ . . . . . . .:

Ollamaインストール後、このような画面が表示された場合、アクセスを許可する ボタンをクリックします。
image.png
私の場合、Ollamaインストール後の初回OS再起動後にこの画面が表示されました。
まだこの画面が表示されていない場合、念のためOS再起動しておくといいかも。

【参考にした記事】

Windows WSL2 dockerでOllamaを起動し検証をしたが最初の読み込みの時間が遅く、使い勝手が悪かったので、docker抜きで検証することにした。結論、ロードのスピードが早くなり、レスポンスも向上した。
プロダクションでOllamaを使う場合は、Dockerは使わないほうがよいかなといった印象。そもそも、Docker使う場合、色々とケアする項目(Dockerの設定など)増えるので、プロダクションでのOllama利用は、サーバーに直接Ollamaをインストールして扱うほうが無難かも。

WSL上のDockerを使ってOllamaを導入するという手段もありましたが、この記事を読んで、PCに直接インストールしようと思い至りました。

【余談】

おお!!確かに!!

(3) Dify の設定(モデルの追加)

Difyへのログインがまだの場合、ブラウザから http://localhost/signin にアクセスし、Difyにログインします。

画面右上のユーザー名をクリックし、表示されるメニューから 設定 を選択。
左のメニューから モデルプロバイダー を選択します。

Ollamaがいました。
image.png

セットアップ画面を開き、パラメータを入れていきます。
Base URL には、先ほどの手順でブラウザに入れたURL http://(PCのIPアドレス):11434/ を入れます。

> Model Name
phi3

> Base URL
http://(PCのIPアドレス):11434/

※他はひとまずデフォルト値

image.png

各パラメータの詳細はこちらの記事に詳しく記載されていました。
是非参照してください。

【余談】
今回の検証で一番詰まったところがここの手順でした、、
最後の章「苦労したこと」にまとめていますので、よかったらお目通しください。
特に、「なんでIPアドレスで通信させとん?」と思った方は是非!w

(4) Dify でRAGアプリを作成

前回は「ワークフロー」を利用したので、今回は「チャットボット」を使ってみたいなと!!

▼「チャットボット」を触ってみたかった!!
image.png

今回は以下の記事を参考に、RAGを活用したチャットボットを作っていきます。

ナレッジにするドキュメントの用意

ナレッジにするドキュメントとして、今回はQiita CLIの README を利用します。
Qiita CLIのリポジトリから README.md をダウンロード。

一応、拡張子を txt に変えておきます。
ファイル名を README.txt として、一応文字化けがないか確認します。
image.png

ナレッジの準備

まずは、ナレッジを準備しましょう。
上部のナビゲーションに「ナレッジ」があるのでクリックします。
「知識を作成」をクリックします。
ナレッジにするドキュメントをアップロードして、「次へ」をクリックします。

先ほど用意した README.txt をアップロードします。
image.png

TXT, MARKDOWN, PDF, HTML, XLSX, XLS, DOCX, CSVをサポートしています。1つあたりの最大サイズは15MBです。 とのことで、PDFに加え、Excel、Wordファイルにも対応しているようです。
素敵!ついでにPowerPointも対応してほしいw

次へ ボタンをクリックすると、「テキストの前処理とクリーニング」画面に遷移します。
今回はデフォルト値を維持します。
右横のプレビュー画面で、どんな感じでチャンクが切られているか確認できます。
image.png

Ollama経由でphi3のみを利用する環境では、インデックスモード高品質 は選べないようです。

以下の記事では 高品質 or 経済的 による動作の違いが分かりやすく記載されていましたので、参考までに。
【参考】Dify やってみた

保存して処理 ボタンをクリックすると、「ナレッジが作成されました」と表示されます。
image.png

チャットボットの作成

上部のナビゲーションの「スタジオ」をクリックします。
「最初から作成」をクリックします。
「チャットボット」を選択して「作成する」をクリックします。

今回アプリ名は「RAGチャットくん」にしました。
image.png

「コンテキスト」の「追加」をクリックします。
先ほど追加したナレッジを選択して、「追加」をクリックします。

README.md をコンテキストに追加しました。
image.png

下の方にある「機能を追加」をクリックします。
「引用と帰属」をOnにします。
Onにすることで、チャットボットの回答に引用元が表示されるようになります。

今回は「引用と帰属」に加えて「フォローアップ」もOnにしてみました。
image.png

仕上げに、「手順」のところに以下の "おまじない" を書いておきます。

あなたはQiitaの専門家です。
ルール(<rules>)に基づいて、質問に答えてください。

<rules>
必ず日本語で回答すること。
誤字・脱字がなく、日本語の文法として正しい文章であること。
答えを知っているか、あるいは十分な推測ができる場合のみ、質問に回答すること。
</rules>

ここまでの手順で、こんな感じの画面になっているはず。
image.png

最後に、画面右上に表示されているモデルが、(3) Dify の設定 で追加したものになっていることを確認します。
image.png

ここでBedrockなどが指定されていると、ドキュメントに記載された機密情報がインターネットを通ってしまう可能性があります。
注意!!!

▼例:Bedrockの Claude 3 Sonnet が指定されている場合
image.png

問題なければ、右上の 公開する ボタンをクリックし、続いて 更新 ボタンをクリックして、設定を保存しておきます。
image.png

動かしてみる

まずは、スタジオ画面右横の「デバックとプレビュー」ですぐに動かしてみます!
「Qiita CLI の導入条件は?」と聞いてみます。
image.png
お~、よさげ!
プレビュー段階では大丈夫そうですね!

続いて、先ほどクリックした 更新 ボタンの下にある アプリを実行 ボタンをクリックして、専用のチャット画面を開いてみます。
image.png

開いたチャットで「Qiitaで新しい記事を作成する際のコマンドを教えてください。」と聞いてみます。
image.png
お~~~~!!!よさげ~~~~!!!
次の質問のリコメンドもちゃんと出してくれました(ちょっと微妙ですがw)

【参考にした記事】

(5) PC起動時にWSLが自動起動するようにしておく

本題は以上なんですが、ここからはちょっと横道にそれて、ついでに作業しておきたい内容です。

作業中にWindows Updateが走ってしまったので、PCを再起動して、Difyに再度接続しようとしたら、接続できませんでした。
どうやら、WSLはPCを起動しただけでは起動しないらしい。
PCを起動し、ログイン後、WSLのターミナルを立ち上げて初めて起動するとのこと。

……面倒くさ!
ということで、以下の記事を参考に、PC起動時にWSLが自動起動するようにしておきます。

WSLの場所
WSLを起動する実行ファイルは %userprofile%\AppData\Local\Microsoft\WindowsApps の中に "ubuntu2204.exe" のようなファイルで存在します。

スタートアップへの設置
起動したいWSLのディストリビューションのショートカットをスタートアップに置きます。

スタートアップフォルダーは、ファイルを指定して実行 (Windows + R キー)で開いて、以下を入力します。
shell:common startup

ショートカットを設置したら、プロパティの「実行時の大きさ」を「最小化」にしておけばあまり邪魔になりません。
これで、WSLのターミナルが自動起動するようになりました。

環境の都合で、shell:common startup で開いたフォルダ上にショートカットを配置できなかった場合、shell:startup で開いたフォルダで代替します。

【参考にした記事】

苦労したこと

以下の記述は今回の構築には役に立ちませんが、色々試行錯誤した結果を供養します。。

DNSエラーとの遭遇

DifyにOllamaをモデルとして追加する際、Base URL には http://host.docker.internal:11434 という値を入れるんですよ、と案内されている記事が多く見られました。
(例1) ノーコードLLM統合アプリのdifyでollamaと連携してみた
(例2) 🐢Dify | インストール

いざその通りにモデルを追加しようとすると、DNSエラーが発生し、モデルの追加ができませんでした。
image.png

docker exec -it (コンテナID) bash で起動しているコンテナに入り、/etc/hosts を見てみると、うーん、確かにダメそう。
※例として docker-nginx-1 のコンテナ

# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.xx.xx      a24698b8a393

docker-compose.yaml をいじってみる(うまくいかなかった)

色々調べて、以下の情報にたどり着きました。

Ollamaと同じマシンで動かしているため、OllamaのBASE URLをDifyに設定しやすいように、Difyのdocker-compose.yamlにhost側を見る様に設定する。
docker-compose.yamlのservices:api:以下にextra_hostsを加える。

   extra_hosts:
     - host.docker.internal:host-gateway

ということで、docker-compose.yaml の各サービス配下に、上記の通り extra_hosts を追加していった。
コンテナを再作成した後、再び /etc/hosts を確認すると、それらしきエントリを確認。
※例として docker-nginx-1 のコンテナ

    # cat /etc/hosts
    127.0.0.1       localhost
    ::1     localhost ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
+   172.17.0.1      host.docker.internal
    172.18.xx.xx      75d51a410196

しかし、改めて Base URLhttp://host.docker.internal:11434 を入れてリトライしても、エラーが再発し、DifyからOllamaの連携はうまくいかなかった。。

原因と対応

さらに調査を進めると、どうやら今回作った環境がイケてないことが分かりました。
WSL上で稼働しているDocker(Docker CE)では、"host.docker.internal" はWindows PC(ホスト)ではなく、WSLインスタンスを指すらしい。

理解のために、こちらの図が大変分かりやすかったです。
image.png
(出典)WSLとは?「WSL1とWSL2の違い」などをわかりやすく解説!

図の上にイメージを補記させていただきました。
image.png

こりゃ "host.docker.internal" にこだわって頑張るのは大変そう!
ポートフォワーディングとか頑張ればどうにかなるのかもですが、、
面倒くさいしローカルPC内の通信だし、IPベースでやったらええかw

という経緯で (3) Dify の設定(モデルの追加)で記載した手順に至りました。
以上、供養でした🙏

こんな設定いれたら"host.docker.internal" でもいけるよ、というご指摘があれば、コメントいただけるととても嬉しいです!!

【参考にした記事】

色々調べる中で、「そもそもDocker Composeって何だっけ、、?」となり、以下の記事に助けられました。

終わりに

以上、プロキシ環境下のローカルPCに "Dify" と "Ollama" を導入して、インターネットを通らない「完全ローカルRAGアプリ」を作ってみました!

今回の検証に着手する前は、「Ollama入れて、Difyのモデルに追加するだけやろ?楽勝~~」と思っていましたが、思わぬ沼にはまり、結局今回も大変でしたw
が、沼から得られた知識も結構あり、この学びこそが「やってみた」の良いところだなと思ったりもします。

今回の検証のなかで、インデックスモードで 高品質 が選べないという発見もありました。
どうにかローカルLLMで 高品質 を利用する方法がないか、探ってみたいと思います!

最後までお目通しいただき、ありがとうございました。

44
22
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
44
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?