はじめに
Open SourceのLLMアプリ開発プラットフォームを活用して、自分のオリジナルRAG環境を構築してみることとする
自身のWindows端末上のPodman DesktopにContainer版のDifyをデプロイし、合わせてFirecrawlもデプロイして、WEBクローリングでRAGのナレッジを収集する
また、自身が所属しているプロジェクトはRedmineを使ってタスク管理を行ってノウハウを集約しているため、Redmineチケットの内容もRAGのナレッジに登録してみる
環境情報
- OS: Windows 11 Pro 23H2
- RAM: 16.0GB
- SSD: 256GB
- Podman Desktop: v1.11.1
- Podman: v5.1.1
Difyのインストール(Dify関連コンテナの起動)
Difyのデプロイ
GithubのGithub Dify のリポジトリをクローンする
PS C:\WINDOWS\system32> git clone https://github.com/langgenius/dify.git
次に、ローカルで起動するために.envファイルを用意します
# ディレクトリに移動
PS C:\WINDOWS\system32> cd dify
# サンプルの環境変数をコピー
PS C:\WINDOWS\system32> cp ./docker/.env.example ./docker/.env
DifyのListen Portを変更したかったため .env
の以下部分を編集
.env
...
EXPOSE_NGINX_PORT=80 -> EXPOSE_NGINX_PORT=11080
EXPOSE_NGINX_SSL_PORT=443 -> EXPOSE_NGINX_SSL_PORT=11443
...
podman machine上でpodman-composeコマンドを利用するので、Windows PowerShell(管理者)にてWSLでpodman-machine-defaultに接続する
PS C:\WINDOWS\system32> wsl -d podman-machine-default
You will be automatically entered into a nested process namespace where
systemd is running. If you need to access the parent namespace, hit ctrl-d
or type exit. This also means to log out you need to exit twice.
[user@hostname ~]$
docker-compose
をpodman-compose
に読み替えて実行したところ、以下エラーで失敗
[user@hostname ~]$ podman-compose up -d
podman-compose version: 1.1.0
['podman', '--version', '']
using podman version: 5.1.1
Traceback (most recent call last):
File "/usr/bin/podman-compose", line 33, in <module>
sys.exit(load_entry_point('podman-compose==1.0.6', 'console_scripts', 'podman-compose')())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/podman_compose.py", line 2940, in main
podman_compose.run()
File "/usr/lib/python3.11/site-packages/podman_compose.py", line 1420, in run
self._parse_compose_file()
File "/usr/lib/python3.11/site-packages/podman_compose.py", line 1567, in _parse_compose_file
raise RuntimeError(f"missing networks: {missing_nets_str}")
RuntimeError: missing networks: default
issue を参考にdocker-compose.yaml
を一部修正
docker-compose.yaml
...
networks:
# create a network between sandbox, api and ssrf_proxy, and can not access outside.
ssrf_proxy_network:
driver: bridge
internal: true
milvus:
driver: bridge
opensearch-net:
driver: bridge
internal: true
default: <- 追加
driver: bridge <- 追加
podman-compose
を再実行。エラーで失敗したときはpodman-compose down
で念のためコンテナを削除してから再実行してみる
[user@hostname ~]$ podman-compose down
[user@hostname ~]$ podman-compose up -d
次はdocker_db_1コンテナが起動/停止を繰り返す事象
以下コマンドでログ確認したところ、同じメッセージが出続けている
[user@hostname ~]$ podman logs docker_db_1
...
fixing permissions on existing directory /var/lib/postgresql/data/pgdata ... The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
Dify on WSL2の起動時にpostgresがエラーを出力する を参考にdocker-compose.yaml
を編集
postgresql用のデータ領域としてvolume
を作成して、そちらを利用するように書き換える
...
# The postgres database.
db:
image: postgres:15-alpine
restart: always
environment:
PGUSER: ${PGUSER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456}
POSTGRES_DB: ${POSTGRES_DB:-dify}
PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata}
volumes:
- ./volumes/db/data:/var/lib/postgresql/data -> db_data:/var/lib/postgresql/data
...
volumes:
oradata:
db_data: <- 追加
再度podman-compose
を実行
[user@hostname ~]$ podman-compose up -d
コンテナのステータスを確認する
[user@hostname ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
cf78ff1321ad docker.io/langgenius/dify-web:0.6.13 About a minute ago Up About a minute 3000/tcp docker_web_1
1050c5515fec docker.io/library/postgres:15-alpine postgres About a minute ago Up About a minute (healthy) 5432/tcp docker_db_1
d792d2821884 docker.io/library/redis:6-alpine redis-server --re... About a minute ago Up About a minute (healthy) 6379/tcp docker_redis_1
ed29715b3809 docker.io/langgenius/dify-sandbox:0.2.1 About a minute ago Up About a minute docker_sandbox_1
3d1ec8fb577f docker.io/ubuntu/squid:latest About a minute ago Up About a minute 3128/tcp docker_ssrf_proxy_1
faf6e1e7c36b docker.io/langgenius/dify-api:0.6.13 About a minute ago Up About a minute 5001/tcp docker_api_1
1b32ebb48a5e docker.io/langgenius/dify-api:0.6.13 About a minute ago Up About a minute 5001/tcp docker_worker_1
1007d6723ea1 docker.io/library/nginx:latest About a minute ago Up About a minute 0.0.0.0:11080->80/tcp, 0.0.0.0:11443->443/tcp, 80/tcp docker_nginx_1
.env
ファイルでCOMPOSE_PROFILES=${VECTOR_STORE:-weaviate}
にてCOMPOSE_PROFILE
環境変数にてベクターDBを設定し、docker-compose.yaml
内のprofile
にてデプロイするベクターDBのコンテナを選択している
なぜかCOMPOSE_PROFILES
環境変数が効かずに、weaviate
コンテナがデプロイされないので、podman-compose
実行時にprofile
を指定して実行した
podman-compose -f docker-compose.yaml --profile weaviate up -d
再度コンテナのステータスを確認するとweaviate
コンテナが起動している
[user@hostname ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
55403e1e4c6b docker.io/langgenius/dify-web:0.6.13 27 minutes ago Up 27 minutes
3000/tcp docker_web_1
eca999d7c3d2 docker.io/library/postgres:15-alpine postgres 27 minutes ago Up 27 minutes (healthy) 5432/tcp docker_db_1
4e19335435a7 docker.io/library/redis:6-alpine redis-server --re... 27 minutes ago Up 27 minutes (healthy) 6379/tcp docker_redis_1
c25b168f7991 docker.io/langgenius/dify-sandbox:0.2.1 27 minutes ago Up 27 minutes
docker_sandbox_1
1003b5bdd142 docker.io/ubuntu/squid:latest 27 minutes ago Up 27 minutes
3128/tcp docker_ssrf_proxy_1
a3ec3e6eeaf9 docker.io/semitechnologies/weaviate:1.19.0 --host 0.0.0.0 --... 27 minutes ago Up 27 minutes
docker_weaviate_1
061db32e8ed2 docker.io/langgenius/dify-api:0.6.13 27 minutes ago Up 27 minutes
5001/tcp docker_api_1
d4b662460cf2 docker.io/langgenius/dify-api:0.6.13 27 minutes ago Up 27 minutes
5001/tcp docker_worker_1
d127b93ed7c5 docker.io/library/nginx:latest 27 minutes ago Up 27 minutes
0.0.0.0:11080->80/tcp, 0.0.0.0:11443->443/tcp, 80/tcp docker_nginx_1
Difyへのアクセス
プラウザからhttp://localhost:11080/install
へアクセスするとDifyのページが表示されるためユーザを作成する
以下ログインページが表示されたら先ほど設定したユーザでログインする
Difyのデプロイはいったん完了
モデルの設定
利用するLLMを設定する
今回はOpenAI
を利用してみる
OpenAIのAPIキー取得
OpenAI APIにログインする
OpenAIがFree trial
だとエラーとなってしまうため、支払情報を登録した上でDashboard
をクリックする
Name
を入力してCreate secret key
をクリックする
Difyのモデルの追加
Difyの右上隅のアカウントアイコンをクリックし、設定
-> モデルプロバイダー
を選択する
OpenAI
-> セットアップ
を選択する
【24年最新版】ChatGPT(OpenAI)のAPI料金体系まとめを参考になるべくコストがかからないものを選択して保存
をクリックした
OpenAIでテストボットを作る
動作確認のためにテストボットを作ってみる
アプリの作成
チャットボット
を選択してアプリの名前
と説明
を入力して作成する
をクリックする
右上のモデルでgpt 3.5-turbo
を選択して公開する
をクリックの上で更新
をクリックする
Firecrawlのインストール(コンテナ起動)
RAGデータをWebサイトのクローリングで登録するためにFirecrawlを利用する
FirecrawlはSaaS版もあるが、今回はOSS版をローカルにコンテナで起動する構成とする
Firecrawlのデプロイ
GithubのGithub Firecrawlのリポジトリをクローンする
PS C:\WINDOWS\system32> git clone https://github.com/mendableai/firecrawl.git
次に、ローカルで起動するために.envファイルを用意します
# ディレクトリに移動
PS C:\WINDOWS\system32> cd firecrawl
# サンプルの環境変数をコピー
PS C:\WINDOWS\system32> cp ./apps/api/.env.example ./.env
コピーした .envファイルをエディタで開いて以下のようにREDIS_URL
, USE_DB_AUTHENTICATION
, TEST_API_KEY
に変更を加える
-
REDIS_URL
は、立ち上がったRedisコンテナに向き先を変更 -
USE_DB_AUTHENTICATION
は無効とする -
TEST_API_KEY
はAPI Keyを意味している。この値は、fc-xxxxの形式であれば何でもOK。今回は「fc-test」を設定した
.env
...
REDIS_URL=redis://localhost:6379 -> REDIS_URL=redis://redis:6379
...
USE_DB_AUTHENTICATION=true -> USE_DB_AUTHENTICATION=false
...
TEST_API_KEY= -> TEST_API_KEY=fc-test
...
podman machine上でpodman-composeコマンドを利用するので、Windows PowerShell(管理者)にてWSLでpodman-machine-defaultに接続する
PS C:\WINDOWS\system32> wsl -d podman-machine-default
You will be automatically entered into a nested process namespace where
systemd is running. If you need to access the parent namespace, hit ctrl-d
or type exit. This also means to log out you need to exit twice.
[user@hostname ~]$
podman-compose
を実行してコンテナを起動
[user@hostname ~]$ cd firecrawl/.
[user@hostname ~]$ podman-compose up -d
以下コマンドを実行してHello, World!
が出たらデプロイ成功
[user@hostname ~]$ curl -X GET http://localhost:3002/test
Hello, world!
ローカルのDifyとの繋ぎこみ
次に、ローカルのDifyと繋ぎ込みを行う
Difyのナレッジ
-> 知識を作成
-> Configure
を選択する
Firecrawlの設定モーダルが表示されるので、先程環境変数で設定した TEST_API_KEY
の値(fc-test
)とBase URLにhttp://host.docker.internal:3002
を入力して保存
をクリックする
Webサイトのナレッジ登録
動作確認として、Red Hat Openstackの公式ドキュメントをナレッジとして登録してみる
対象のリンクとしてhttps://docs.redhat.com/ja/documentation/red_hat_openstack_platform/16.2
を設定してRun
を選択
Limit
は読み込む最大ページ数を指定する
Max depth
はサブページを何階層まで読み込むかを指定する
問題なければ下記のようにクローリングした結果が表示される
ナレッジ登録するページにチェックすればOK
今回はReset All
にチェックして全選択して次へ
を選択する
前処理画面が出てくるので必要に応じて設定して保存して処理
を選択すればナレッジ登録が始まる
Redmineチケットのナレッジ登録
Redmineにはチケットをcsvエクスポートする機能がある
これを利用してチケットデータをナレッジとして登録する
Redmineチケットのエクスポート
一度にエクスポート可能なチケットの件数はデフォルトでは最大500となっているため必要に応じて上限を変更しておく
変更は管理
-> 設定
-> チケットトラッキング
からエクスポートするチケット数の上限
を変更して保存
をクリックする
すべての項目
を選択し、説明
,最新のコメント
にチェックを入れてエクスポート
をクリックする
csvファイルを適切なフォルダに保存する
Difyのナレッジ登録
出力したcsvファイルをナレッジとして登録する
ナレッジ
-> 知識を作成
の+
をクリックする
テキストファイルからインポート
を選択し、ファイルをドラッグ&ドロップするか 参照
のところにcsvファイルをドラッグ&ドロップして次へ
をクリックする
テキストファイル
とあるが、TXT
,MARKDOWN
,PDF
,HTML
,XLSX
,XLS
,DOCX
,CSV
がサポートされている
RAGのチャットボットの作成
今まで登録したナレッジをRAGとして利用するチャットボットを作成する
RAGの機能を持ったチャットボットの作成
テンプレート一覧が表示されるのでKnowledge Retrieval + Chatbot
を選択する
Knowledge Retrieval
をクリックし、右側の知識
の右側の+
をクリックする
Red Hat Openstack 16公式ページのナレッジを選択して追加
をクリックする
ナレッジは複数追加することもできる
LLM
をクリックし、右側のモデル
で gpt-3.5-turbo
を選択する
Knowledge Retrieval
の回答をGPT
の入力に設定する
LLM
ブロックをクリック後のパネルのコンテキスト
よりKnowledge Retrieval > result Array[Object]
を選択する
これにより直前のKnowledge Retrieval
の回答をそのまま LLM の入力として設定できる
SYSTEM
の部分にはプロンプトを入力する
テンプレートからアプリを作成しているのでもともと英語でプロンプトが入力済みだが、日本語のコンテンツに対して日本語で質問するので日本語でプロンプトを入力してみた
入力したプロンプトは以下の通り
あなたはRed Hat Openstack 16に関する質問をサポートするアシスタントです
`コンテキスト`の情報を元に回答してください
`コンテキスト`の情報は以下の<context></context>というXML タグの中にあります
<context>
{{#context#}}
</context>
`コンテキスト`の情報から回答できない場合は`わかりません`と答えてください
回答で使用する各事実には必ず出典名(`コンテキスト`のURL。例だと`http://index1.html`や`https://index2.html`など)を行の末尾に記載します
出典名は必ず一つずつブラケット[]で囲んでください。例えば、`http://index1.html`なら、`[http://index1.html]`です。
ちなみに、`http://index1.html`や`http://index2.html`は架空の資料なので使用しないでください
質問者の言語に応じて回答してください
アプリを公開
お試し利用
おわりに
以上でDify+Firecrawlをデプロイして自分用のRAGアプリを構築できる環境を作ることができた
個人のローカル環境で手軽に利用できる生成AIを活用したアプリ開発のテストベッドとして有効活用していきたい
参考ページ
- Github Dify
- Dify | インストール
- 初心者でもできた Dify環境構築メモ(Windows+Anaconda+Docker Desktop)
- Podman deployment issues: RuntimeError: missing networks: default and socket.gaierror: [Errno -3] Temporary failure in name resolution #4773
- Dify on WSL2の起動時にpostgresがエラーを出力する
- DifyでLLMを使えるようにする(OpenAI GPT-4o)
- Github Firecrawl
- Firecrawlをローカルで動かしDifyと繋げてみる
- 5分でわかるRedmineのインポート・エクスポート機能
- Dockerで構築したDifyを利用しノーコードでRAGのチャットボットを作る
- 【24年最新版】ChatGPT(OpenAI)のAPI料金体系まとめ