WindowsでDifyを使いこなす!
ゴール
- 社内のWindows PCにDify環境を立てる
- Difyで生成AIアプリを作る
このスクラップへのリンク
-
Dify環境を作る #1
- 社内PCでDifyを起動させるためにdocker-compose.yamlを修正した
-
Dify環境を作る #2
- 別のPCでは、wsl2データを全削除したらエラー解消した
-
Difyを0.6.10にアップデートする
- やはり公式のdocker-compose.yamlを修正した
-
Dify+Ollamaでチャットボットを作る
- 英語で回答しがちなLlama3にぜったい日本語で回答させることに成功
-
Dify+OllamaでRAGチャットボットを作る(未完)
- Ollmaで使える埋め込みモデルでは日本語埋め込みできないと分かった。。
-
Difyと一緒にOllamaもDockerで動かしてみる
- OllamaがCPUだけで動くので遅くなった。(対処方法はある)
-
DifyアプリにAPIアクセスする
- 公式docを参考にしてできた
-
Dify+OllamaでRAGチャットボットを作る#2
- 多言語対応埋め込みモデルを使って成功。ただし精度は悪く、実用には堪えない
-
Difyを0.6.10から0.6.12fix1にアップデートする
- データ引継ぎは断念。。
-
FireCrawlをセルフホストして、Difyで使う#1
- 簡単にできた。社内SPOサイトはクロールできなかった。。
-
API経由でナレッジを操作する
- Pythonのrequestsライブラリを使う
-
Dify0.6.12fix1から0.6.14にアップデートする
- データ継承も問題なくできた。
-
DifyコンテナのPostgresデータベースにSQLツールから接続する
- A5:SQL Mk-2から接続する。
-
ベクトルデータベースとの接続トラブル対処記録
- weaviateデータベースに接続できなくなったが、middlewareを再起動したら解決した。
-
Dify0.6.15から0.7.0にアップデートする
- データ継承も問題なくできた。
-
Firecrawlをセルフホストして、Difyで使う #2
- Dify0.7.0にアップデートしてからツールがtextでなくjsonを出力するようになったので対応した。
-
Difyを0.8.3にアップデートする
- アップデートは問題なくできた。LLMモデルのロードバランサー機能もONにした。
- ただローカルホストしているFirecrawlのツールが使えなくなった。Firecrawlによるナレッジ取得はできるので、Firecrawlコンテナとの通信はできている、、続く。
-
セルフホストしているFirecrawlをv0からv1にアップデートする
- Dify0.8.3にしたらツールが使えなくなったのでFirecrawlもv0からv1アップデートしたが解決せず、、続く。
-
Dify0.9.0でRAG検索できないエラー発生
- 0.9.1にアップデートしたら直りました。
-
Difyを0.10.0にアップデートする
- ファイルアップロード機能が追加された。
Dify公式リンク
- Dify公式サイト ※日本語版があった
- Difyリポジトリ
- Dify公式Xアカウント
- Dify公式YouTubeチャンネル
-
Dify公式Discordサーバ
- Chrome拡張機能「Chromeの右クリックを有効にする」 ※これを入れておくとページ翻訳ができて便利
Dify関連記事を探す
Dify関連の良かった記事
その他リンク
Dify環境を作る #1
ゴール
- DifyをWindows PCにインストールして起動する
まとめ
- 公式ドキュメントとか巷にあふれるブログ記事のように簡単に起動できなかった
- 情報がなく苦労したこと
- Docker Desktop for Windows: バイパスproxy設定
- docker-compose.yaml: エラー回避のためのコード修正
関連リンク
- Dify公式doc Docker Compose Deployment
- wsl2の有効化
- MS Learn WSLの基本的なコマンド
- MS Learn WSL を使用して Windows に Linux をインストールする方法
- Docker Desktop for Windows
大まかな手順
- Docker Desktop for Windowsを導入する
- Docker環境でDifyを起動する
もう少し詳しい手順
- gitをインストールする(割愛)
- WSL2を有効化する
- 「Windowsの機能の有効化または無効化」を開いて「Linux用Windowsサブシステム」と「仮想マシンプラットフォーム」にチェックを入れて保存、PCを再起動する
設定画面
- PowerShellを管理者モードで立ち上げてubuntuをインストールする
以下のコマンドを順番に実行する。
wsl --status #バージョン2になっていることを確認
wsl --install -d ubuntu #ubuntuをインストール
wsl --update #wslの更新
wsl --status #ubuntuがインストールできたか確認
- Docker Desktop for Windowsをインストールする(割愛)
- Docker Desktop for Windowsの設定をする
Docker Desktop for WindowsのResources設定画面
- wsl2との連携をONにする
- Dockerのデフォルトネットワークサブネット。Dockerコンテナ同士の通信や、ホストマシンとDockerコンテナの間の通信用(いじらない)
- プロキシ設定画面 大事!!
- バイパスproxy設定の方法が分からない場合は、
ipconfig /all
の結果をChatGPTに貼り付けて、「Docker Desktop fow Windowsのバイパスproxy設定を教えて」と言って教えてもらう! - /22 とか /24の意味は「IPv4アドレス32ビット長のうち、ネットワーク部分が何ビットかを指すか」ということ。/22だとネットワークが22ビット、ホストが10ビット(=1024)なので、1024個のIPアドレス範囲を指すことになる。(、、、とChatGPTが教えてくれた)
- Difyのコードを公式リポジトリからダウンロードする
git clone https://github.com/langgenius/dify.git
- cloneしたdifyフォルダの中のdockerフォルダでPowerShellを起動して、DifyのDockerコンテナを起動する ⇒エラーが出る
docker compose up -d
⇒port80は別のアプリですでに使われているというエラーが出る
port80を使っているのはsystem
⇒netstat -nano
コマンドでPID4のプロセスと分かる
⇒タスクマネージャーでSystemが使っていると分かる
⇒port80を使うのは諦める。
- port80でなく8080を使うように、
docker-compose.yaml
を修正する
docker-compose.yamlの修正部分
nginx:
image: nginx:latest
restart: always
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/proxy.conf:/etc/nginx/proxy.conf
- ./nginx/conf.d:/etc/nginx/conf.d
#- ./nginx/ssl:/etc/ssl
depends_on:
- api
- web
ports:
# - "80:80" #元の設定
- "8080:80" #変更後の設定
#- "443:443"
- あらためて
docker-compose up -d
する ⇒まだ駄目
⇒langgenius/dify-web:0.6.9
とpostgres:15-alpine
のコンテナが停止、再起動を繰り返す。。
該当するコード
web:
image: langgenius/dify-web:0.6.9
restart: always
environment:
CONSOLE_API_URL: ''
APP_API_URL: ''
SENTRY_DSN: ''
db:
image: postgres:15-alpine
restart: always
environment:
PGUSER: postgres
POSTGRES_PASSWORD: difyai123456
POSTGRES_DB: dify
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- ./volumes/db/data:/var/lib/postgresql/data
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
-
ChatGPTに助けてもらいながら、docker-compose.yamlをあちこち修正する。
「エラーlogを渡す⇒yamlファイルの修正案をもらう⇒トライ」を繰り返した。。
⇒最終的にできたyamlファイルはこれ
ようやく完成したdocke-compose.yamlファイル
version: '3'
# ===========================================================
services:
# -----------------------------------------------------------
api:
image: langgenius/dify-api:0.6.9
restart: always
environment:
MODE: api
LOG_LEVEL: INFO
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
CONSOLE_WEB_URL: ''
INIT_PASSWORD: ''
CONSOLE_API_URL: ''
SERVICE_API_URL: ''
APP_WEB_URL: ''
FILES_URL: ''
FILES_ACCESS_TIMEOUT: 300
MIGRATION_ENABLED: 'true'
DB_USERNAME: postgres
DB_PASSWORD: difyai123456
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: dify
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_USERNAME: ''
REDIS_PASSWORD: difyai123456
REDIS_USE_SSL: 'false'
REDIS_DB: 0
CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
WEB_API_CORS_ALLOW_ORIGINS: '*'
CONSOLE_CORS_ALLOW_ORIGINS: '*'
STORAGE_TYPE: local
STORAGE_LOCAL_PATH: storage
S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
S3_BUCKET_NAME: 'difyai'
S3_ACCESS_KEY: 'ak-difyai'
S3_SECRET_KEY: 'sk-difyai'
S3_REGION: 'us-east-1'
AZURE_BLOB_ACCOUNT_NAME: 'difyai'
AZURE_BLOB_ACCOUNT_KEY: 'difyai'
AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
VECTOR_STORE: weaviate
WEAVIATE_ENDPOINT: http://weaviate:8080
WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
QDRANT_URL: http://qdrant:6333
QDRANT_API_KEY: difyai123456
QDRANT_CLIENT_TIMEOUT: 20
QDRANT_GRPC_ENABLED: 'false'
QDRANT_GRPC_PORT: 6334
MILVUS_HOST: 127.0.0.1
MILVUS_PORT: 19530
MILVUS_USER: root
MILVUS_PASSWORD: Milvus
MILVUS_SECURE: 'false'
RELYT_HOST: db
RELYT_PORT: 5432
RELYT_USER: postgres
RELYT_PASSWORD: difyai123456
RELYT_DATABASE: postgres
PGVECTOR_HOST: pgvector
PGVECTOR_PORT: 5432
PGVECTOR_USER: postgres
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
MAIL_TYPE: ''
MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
SMTP_SERVER: ''
SMTP_PORT: 465
SMTP_USERNAME: ''
SMTP_PASSWORD: ''
SMTP_USE_TLS: 'true'
SMTP_OPPORTUNISTIC_TLS: 'false'
RESEND_API_KEY: ''
RESEND_API_URL: https://api.resend.com
SENTRY_DSN: ''
SENTRY_TRACES_SAMPLE_RATE: 1.0
SENTRY_PROFILES_SAMPLE_RATE: 1.0
NOTION_INTEGRATION_TYPE: public
NOTION_CLIENT_SECRET: you-client-secret
NOTION_CLIENT_ID: you-client-id
NOTION_INTERNAL_SECRET: you-internal-secret
CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
CODE_EXECUTION_API_KEY: dify-sandbox
CODE_MAX_NUMBER: 9223372036854775807
CODE_MIN_NUMBER: -9223372036854775808
CODE_MAX_STRING_LENGTH: 80000
TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
CODE_MAX_STRING_ARRAY_LENGTH: 30
CODE_MAX_OBJECT_ARRAY_LENGTH: 30
CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
depends_on:
- db
- redis
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
# -----------------------------------------------------------
worker:
image: langgenius/dify-api:0.6.9
restart: always
environment:
CONSOLE_WEB_URL: ''
MODE: worker
LOG_LEVEL: INFO
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
DB_USERNAME: postgres
DB_PASSWORD: difyai123456
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: dify
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_USERNAME: ''
REDIS_PASSWORD: difyai123456
REDIS_DB: 0
REDIS_USE_SSL: 'false'
CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
STORAGE_TYPE: local
STORAGE_LOCAL_PATH: storage
S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
S3_BUCKET_NAME: 'difyai'
S3_ACCESS_KEY: 'ak-difyai'
S3 SECRET_KEY: 'sk-difyai'
S3_REGION: 'us-east-1'
AZURE_BLOB_ACCOUNT_NAME: 'difyai'
AZURE_BLOB_ACCOUNT_KEY: 'difyai'
AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
VECTOR_STORE: weaviate
WEAVIATE_ENDPOINT: http://weaviate:8080
WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
QDRANT_URL: http://qdrant:6333
QDRANT_API_KEY: difyai123456
QDRANT_CLIENT_TIMEOUT: 20
QDRANT_GRPC_ENABLED: 'false'
QDRANT_GRPC_PORT: 6334
MILVUS_HOST: 127.0.0.1
MILVUS_PORT: 19530
MILVUS_USER: root
MILVUS_PASSWORD: Milvus
MILVUS_SECURE: 'false'
MAIL_TYPE: ''
MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
SMTP_SERVER: ''
SMTP_PORT: 465
SMTP_USERNAME: ''
SMTP_PASSWORD: ''
SMTP_USE_TLS: 'true'
SMTP_OPPORTUNISTIC_TLS: 'false'
RESEND_API_KEY: ''
RESEND_API_URL: https://api.resend.com
RELYT_HOST: db
RELYT_PORT: 5432
RELYT_USER: postgres
RELYT_PASSWORD: difyai123456
RELYT_DATABASE: postgres
PGVECTOR_HOST: pgvector
PGVECTOR_PORT: 5432
PGVECTOR_USER: postgres
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
NOTION_INTEGRATION_TYPE: public
NOTION_CLIENT_SECRET: you-client-secret
NOTION_CLIENT_ID: you-client-id
NOTION_INTERNAL_SECRET: you-internal-secret
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
depends_on:
- db
- redis
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
# -----------------------------------------------------------
web:
image: langgenius/dify-web:0.6.9
restart: always
environment:
CONSOLE_API_URL: ''
APP_API_URL: ''
SENTRY_DSN: ''
networks:
- ssrf_proxy_network # 修正: defaultネットワークにssrf_proxy_networkを追加
- default
# -----------------------------------------------------------
db:
image: postgres:15-alpine
restart: always
environment:
PGUSER: postgres
POSTGRES_PASSWORD: difyai123456
POSTGRES_DB: dify
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres_data:/var/lib/postgresql/data # 修正: ./volumes/db/dataからpostgres_dataに変更
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
networks:
- default
# -----------------------------------------------------------
redis:
image: redis:6-alpine
restart: always
volumes:
# - redis_data:/data # 修正: ./volumes/redis/dataからredis_dataに変更
- ./volumes/redis/data:/data
command: redis-server --requirepass difyai123456
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
networks:
- default
# -----------------------------------------------------------
weaviate:
image: semitechnologies/weaviate:1.19.0
restart: always
volumes:
- ./volumes/weaviate:/var/lib/weaviate
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'none'
CLUSTER_HOSTNAME: 'node1'
AUTHENTICATION_APIKEY_ENABLED: 'true'
AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
AUTHORIZATION_ADMINLIST_ENABLED: 'true'
AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
networks:
- default
# -----------------------------------------------------------
sandbox:
image: langgenius/dify-sandbox:0.2.0
restart: always
environment:
API_KEY: dify-sandbox
GIN_MODE: 'release'
WORKER_TIMEOUT: 15
ENABLE_NETWORK: 'true'
HTTP_PROXY: 'http://ssrf_proxy:3128'
HTTPS_PROXY: 'http://ssrf_proxy:3128'
volumes:
- ./volumes/sandbox/dependencies:/dependencies
networks:
- ssrf_proxy_network
# -----------------------------------------------------------
ssrf_proxy:
image: ubuntu/squid:latest
restart: always
volumes:
- ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
networks:
- ssrf_proxy_network
- default
# -----------------------------------------------------------
nginx:
image: nginx:latest
restart: always
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/proxy.conf:/etc/nginx/proxy.conf
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- api
- web
ports:
- "8080:80"
networks:
- default # 修正: defaultネットワークを追加
# ===========================================================
networks:
ssrf_proxy_network:
driver: bridge
internal: true
default: # 修正: defaultネットワークを追加
driver: bridge
# ===========================================================
volumes:
postgres_data: # 追加: 新しいボリュームを定義
# redis_data: # 追加: 新しいボリュームを定義```
オリジナルと最終的なdocker-compose.yamlを可視化して比較
※graphvizで可視化してみた。
オリジナル
最終版
- ようやくDifyが起動!
Dify環境を作る#2
ゴール
- DIfyを別のWindows PCにインストールして起動する
まとめ
- Docker Desktopでwsl2データを全削除したらエラーが解消した
関連リンク
- エラー対処方法で参考にした記事
- [docker-compose up で failed to mkdir]((https://zenn.dev/nw/scraps/6e8ef6361f8369)
手順
※ 同じ社内ネットワークにある別のPCなので、途中までは [前回](https://zenn.dev/link/comments/59a67f0070ba23) と同じで、手順6で出たエラーだけが違う
- gitをインストール(割愛)
- wsl2を有効化(割愛)
- Docker Desktop for Windowsを導入(割愛)
- Difyのコードを公式リポジトリからgit cloneする(割愛)
- cloneしたdifyフォルダの中の
docker-compose.yaml
を書き替える
ファイルのパスはE:\dify\docker\docker-compose.yaml
書き替えたあとのdocker-compose.yaml
version: '3'
# ===========================================================
services:
# -----------------------------------------------------------
api:
image: langgenius/dify-api:0.6.9
restart: always
environment:
MODE: api
LOG_LEVEL: INFO
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
CONSOLE_WEB_URL: ''
INIT_PASSWORD: ''
CONSOLE_API_URL: ''
SERVICE_API_URL: ''
APP_WEB_URL: ''
FILES_URL: ''
FILES_ACCESS_TIMEOUT: 300
MIGRATION_ENABLED: 'true'
DB_USERNAME: postgres
DB_PASSWORD: difyai123456
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: dify
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_USERNAME: ''
REDIS_PASSWORD: difyai123456
REDIS_USE_SSL: 'false'
REDIS_DB: 0
CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
WEB_API_CORS_ALLOW_ORIGINS: '*'
CONSOLE_CORS_ALLOW_ORIGINS: '*'
STORAGE_TYPE: local
STORAGE_LOCAL_PATH: storage
S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
S3_BUCKET_NAME: 'difyai'
S3_ACCESS_KEY: 'ak-difyai'
S3_SECRET_KEY: 'sk-difyai'
S3_REGION: 'us-east-1'
AZURE_BLOB_ACCOUNT_NAME: 'difyai'
AZURE_BLOB_ACCOUNT_KEY: 'difyai'
AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
VECTOR_STORE: weaviate
WEAVIATE_ENDPOINT: http://weaviate:8080
WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
QDRANT_URL: http://qdrant:6333
QDRANT_API_KEY: difyai123456
QDRANT_CLIENT_TIMEOUT: 20
QDRANT_GRPC_ENABLED: 'false'
QDRANT_GRPC_PORT: 6334
MILVUS_HOST: 127.0.0.1
MILVUS_PORT: 19530
MILVUS_USER: root
MILVUS_PASSWORD: Milvus
MILVUS_SECURE: 'false'
RELYT_HOST: db
RELYT_PORT: 5432
RELYT_USER: postgres
RELYT_PASSWORD: difyai123456
RELYT_DATABASE: postgres
PGVECTOR_HOST: pgvector
PGVECTOR_PORT: 5432
PGVECTOR_USER: postgres
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
MAIL_TYPE: ''
MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
SMTP_SERVER: ''
SMTP_PORT: 465
SMTP_USERNAME: ''
SMTP_PASSWORD: ''
SMTP_USE_TLS: 'true'
SMTP_OPPORTUNISTIC_TLS: 'false'
RESEND_API_KEY: ''
RESEND_API_URL: https://api.resend.com
SENTRY_DSN: ''
SENTRY_TRACES_SAMPLE_RATE: 1.0
SENTRY_PROFILES_SAMPLE_RATE: 1.0
NOTION_INTEGRATION_TYPE: public
NOTION_CLIENT_SECRET: you-client-secret
NOTION_CLIENT_ID: you-client-id
NOTION_INTERNAL_SECRET: you-internal-secret
CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
CODE_EXECUTION_API_KEY: dify-sandbox
CODE_MAX_NUMBER: 9223372036854775807
CODE_MIN_NUMBER: -9223372036854775808
CODE_MAX_STRING_LENGTH: 80000
TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
CODE_MAX_STRING_ARRAY_LENGTH: 30
CODE_MAX_OBJECT_ARRAY_LENGTH: 30
CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
depends_on:
- db
- redis
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
# -----------------------------------------------------------
worker:
image: langgenius/dify-api:0.6.9
restart: always
environment:
CONSOLE_WEB_URL: ''
MODE: worker
LOG_LEVEL: INFO
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
DB_USERNAME: postgres
DB_PASSWORD: difyai123456
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: dify
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_USERNAME: ''
REDIS_PASSWORD: difyai123456
REDIS_DB: 0
REDIS_USE_SSL: 'false'
CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
STORAGE_TYPE: local
STORAGE_LOCAL_PATH: storage
S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
S3_BUCKET_NAME: 'difyai'
S3_ACCESS_KEY: 'ak-difyai'
S3 SECRET_KEY: 'sk-difyai'
S3_REGION: 'us-east-1'
AZURE_BLOB_ACCOUNT_NAME: 'difyai'
AZURE_BLOB_ACCOUNT_KEY: 'difyai'
AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
VECTOR_STORE: weaviate
WEAVIATE_ENDPOINT: http://weaviate:8080
WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
QDRANT_URL: http://qdrant:6333
QDRANT_API_KEY: difyai123456
QDRANT_CLIENT_TIMEOUT: 20
QDRANT_GRPC_ENABLED: 'false'
QDRANT_GRPC_PORT: 6334
MILVUS_HOST: 127.0.0.1
MILVUS_PORT: 19530
MILVUS_USER: root
MILVUS_PASSWORD: Milvus
MILVUS_SECURE: 'false'
MAIL_TYPE: ''
MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
SMTP_SERVER: ''
SMTP_PORT: 465
SMTP_USERNAME: ''
SMTP_PASSWORD: ''
SMTP_USE_TLS: 'true'
SMTP_OPPORTUNISTIC_TLS: 'false'
RESEND_API_KEY: ''
RESEND_API_URL: https://api.resend.com
RELYT_HOST: db
RELYT_PORT: 5432
RELYT_USER: postgres
RELYT_PASSWORD: difyai123456
RELYT_DATABASE: postgres
PGVECTOR_HOST: pgvector
PGVECTOR_PORT: 5432
PGVECTOR_USER: postgres
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
NOTION_INTEGRATION_TYPE: public
NOTION_CLIENT_SECRET: you-client-secret
NOTION_CLIENT_ID: you-client-id
NOTION_INTERNAL_SECRET: you-internal-secret
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
depends_on:
- db
- redis
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
# -----------------------------------------------------------
web:
image: langgenius/dify-web:0.6.9
restart: always
environment:
CONSOLE_API_URL: ''
APP_API_URL: ''
SENTRY_DSN: ''
networks:
- ssrf_proxy_network # 修正: defaultネットワークにssrf_proxy_networkを追加
- default
# -----------------------------------------------------------
db:
image: postgres:15-alpine
restart: always
environment:
PGUSER: postgres
POSTGRES_PASSWORD: difyai123456
POSTGRES_DB: dify
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres_data:/var/lib/postgresql/data # 修正: ./volumes/db/dataからpostgres_dataに変更
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
networks:
- default
# -----------------------------------------------------------
redis:
image: redis:6-alpine
restart: always
volumes:
# - redis_data:/data # 修正: ./volumes/redis/dataからredis_dataに変更
- ./volumes/redis/data:/data
command: redis-server --requirepass difyai123456
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
networks:
- default
# -----------------------------------------------------------
weaviate:
image: semitechnologies/weaviate:1.19.0
restart: always
volumes:
- ./volumes/weaviate:/var/lib/weaviate
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'none'
CLUSTER_HOSTNAME: 'node1'
AUTHENTICATION_APIKEY_ENABLED: 'true'
AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
AUTHORIZATION_ADMINLIST_ENABLED: 'true'
AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
networks:
- default
# -----------------------------------------------------------
sandbox:
image: langgenius/dify-sandbox:0.2.0
restart: always
environment:
API_KEY: dify-sandbox
GIN_MODE: 'release'
WORKER_TIMEOUT: 15
ENABLE_NETWORK: 'true'
HTTP_PROXY: 'http://ssrf_proxy:3128'
HTTPS_PROXY: 'http://ssrf_proxy:3128'
volumes:
- ./volumes/sandbox/dependencies:/dependencies
networks:
- ssrf_proxy_network
# -----------------------------------------------------------
ssrf_proxy:
image: ubuntu/squid:latest
restart: always
volumes:
- ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
networks:
- ssrf_proxy_network
- default
# -----------------------------------------------------------
nginx:
image: nginx:latest
restart: always
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/proxy.conf:/etc/nginx/proxy.conf
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- api
- web
ports:
- "8080:80"
networks:
- default # 修正: defaultネットワークを追加
# ===========================================================
networks:
ssrf_proxy_network:
driver: bridge
internal: true
default: # 修正: defaultネットワークを追加
driver: bridge
# ===========================================================
volumes:
postgres_data: # 追加: 新しいボリュームを定義
# redis_data: # 追加: 新しいボリュームを定義 ```
オリジナルと最終的なdocker-compose.yamlを可視化して比較
※graphvizで可視化してみた。
オリジナル
最終版
- dockerフォルダでPoserShellを立ち上げて
docker-compose up -d
コマンドを打つ ⇒エラーが出る
Error response from daemon: error while creating mount source path '/run/desktop/mnt/host/e/dify/docker/volumes/sandbox/dependencies': mkdir /run/desktop/mnt/host/e: file exists
- データをいったん全削除する
GhatGPTに聞きながら対応しても解決しない
⇒ググって、この記事を見つける!
⇒同じようにやってみる
Docker Desktop for Windows操作の画面キャプチャ
Troubleshootを開く
Clean / Purge data をクリック
WSL 2を選択して delete をクリック
images も containers も全部消えた。。
- あらためて
docker-compose up -d
する - ようやくDifyが起動!
Difyを0.6.10にアップデートする
ゴール
- Dify0.6.9 から Dify0.6.10 にアップデートする
まとめ
- Dify0.6.9をインストールしたときに作ったdocker-compose.yamlファイルを流用した
関連リンク
- Dify公式リポジトリ
- Dify公式doc
手順
- いまの
docker
フォルダにあるdocker-compose.yaml
の名称をdocker-compose_069backup.yaml
みたいな名前にしておいて、公式docどおりに進める。
# dockerフォルダに移動
cd dify/docker
# リモートリポジトリのmainブランチから最新バージョンをダウンロード
git pull origin main
# 現在のdockerコンテナを停止
docker compose down
# docker-compose.ymlで定義された最新のイメージを取得
docker compose pull
# ------ ここから先はまだしない! --------------
# dockerコンテナを再構築して起動
# docker compose up -d
- 0.6.10バージョンのdocker-compose.yamlを以下のように書き換える。
docker-compose.yamlの中身
services:
api:
image: langgenius/dify-api:0.6.10
restart: always
environment:
MODE: api
LOG_LEVEL: INFO
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
CONSOLE_WEB_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
INIT_PASSWORD: ''
CONSOLE_API_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
SERVICE_API_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
APP_WEB_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
FILES_URL: 'http://161.93.***.***:8080' #追加(PCの静的IPを入れる)
FILES_ACCESS_TIMEOUT: 300
MIGRATION_ENABLED: 'true'
DB_USERNAME: postgres
DB_PASSWORD: difyai123456
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: dify
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_USERNAME: ''
REDIS_PASSWORD: difyai123456
REDIS_USE_SSL: 'false'
REDIS_DB: 0
CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
WEB_API_CORS_ALLOW_ORIGINS: '*'
CONSOLE_CORS_ALLOW_ORIGINS: '*'
STORAGE_TYPE: local
STORAGE_LOCAL_PATH: storage
S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
S3_BUCKET_NAME: 'difyai'
S3_ACCESS_KEY: 'ak-difyai'
S3_SECRET_KEY: 'sk-difyai'
S3_REGION: 'us-east-1'
AZURE_BLOB_ACCOUNT_NAME: 'difyai'
AZURE_BLOB_ACCOUNT_KEY: 'difyai'
AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
VECTOR_STORE: weaviate
WEAVIATE_ENDPOINT: http://weaviate:8080
WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
QDRANT_URL: http://qdrant:6333
QDRANT_API_KEY: difyai123456
QDRANT_CLIENT_TIMEOUT: 20
QDRANT_GRPC_ENABLED: 'false'
QDRANT_GRPC_PORT: 6334
MILVUS_HOST: 127.0.0.1
MILVUS_PORT: 19530
MILVUS_USER: root
MILVUS_PASSWORD: Milvus
MILVUS_SECURE: 'false'
RELYT_HOST: db
RELYT_PORT: 5432
RELYT_USER: postgres
RELYT_PASSWORD: difyai123456
RELYT_DATABASE: postgres
PGVECTOR_HOST: pgvector
PGVECTOR_PORT: 5432
PGVECTOR_USER: postgres
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
MAIL_TYPE: ''
MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
SMTP_SERVER: ''
SMTP_PORT: 465
SMTP_USERNAME: ''
SMTP_PASSWORD: ''
SMTP_USE_TLS: 'true'
SMTP_OPPORTUNISTIC_TLS: 'false'
RESEND_API_KEY: ''
RESEND_API_URL: https://api.resend.com
SENTRY_DSN: ''
SENTRY_TRACES_SAMPLE_RATE: 1.0
SENTRY_PROFILES_SAMPLE_RATE: 1.0
NOTION_INTEGRATION_TYPE: public
NOTION_CLIENT_SECRET: you-client-secret
NOTION_CLIENT_ID: you-client-id
NOTION_INTERNAL_SECRET: you-internal-secret
CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
CODE_EXECUTION_API_KEY: dify-sandbox
CODE_MAX_NUMBER: 9223372036854775807
CODE_MIN_NUMBER: -9223372036854775808
CODE_MAX_STRING_LENGTH: 80000
TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
CODE_MAX_STRING_ARRAY_LENGTH: 30
CODE_MAX_OBJECT_ARRAY_LENGTH: 30
CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
depends_on:
- db
- redis
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
worker:
image: langgenius/dify-api:0.6.10
restart: always
environment:
CONSOLE_WEB_URL: ''
MODE: worker
LOG_LEVEL: INFO
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
DB_USERNAME: postgres
DB_PASSWORD: difyai123456
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: dify
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_USERNAME: ''
REDIS_PASSWORD: difyai123456
REDIS_DB: 0
REDIS_USE_SSL: 'false'
CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
STORAGE_TYPE: local
STORAGE_LOCAL_PATH: storage
S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
S3_BUCKET_NAME: 'difyai'
S3_ACCESS_KEY: 'ak-difyai'
S3_SECRET_KEY: 'sk-difyai'
S3_REGION: 'us-east-1'
AZURE_BLOB_ACCOUNT_NAME: 'difyai'
AZURE_BLOB_ACCOUNT_KEY: 'difyai'
AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
VECTOR_STORE: weaviate
WEAVIATE_ENDPOINT: http://weaviate:8080
WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
QDRANT_URL: http://qdrant:6333
QDRANT_API_KEY: difyai123456
QDRANT_CLIENT_TIMEOUT: 20
QDRANT_GRPC_ENABLED: 'false'
QDRANT_GRPC_PORT: 6334
MILVUS_HOST: 127.0.0.1
MILVUS_PORT: 19530
MILVUS_USER: root
MILVUS_PASSWORD: Milvus
MILVUS_SECURE: 'false'
MAIL_TYPE: ''
MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
SMTP_SERVER: ''
SMTP_PORT: 465
SMTP_USERNAME: ''
SMTP_PASSWORD: ''
SMTP_USE_TLS: 'true'
SMTP_OPPORTUNISTIC_TLS: 'false'
RESEND_API_KEY: ''
RESEND_API_URL: https://api.resend.com
RELYT_HOST: db
RELYT_PORT: 5432
RELYT_USER: postgres
RELYT_PASSWORD: difyai123456
RELYT_DATABASE: postgres
PGVECTOR_HOST: pgvector
PGVECTOR_PORT: 5432
PGVECTOR_USER: postgres
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
NOTION_INTEGRATION_TYPE: public
NOTION_CLIENT_SECRET: you-client-secret
NOTION_CLIENT_ID: you-client-id
NOTION_INTERNAL_SECRET: you-internal-secret
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
depends_on:
- db
- redis
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
web:
image: langgenius/dify-web:0.6.10
restart: always
environment:
CONSOLE_API_URL: ''
APP_API_URL: ''
SENTRY_DSN: ''
networks: #追加
- ssrf_proxy_network #追加
- default #追加
db:
image: postgres:15-alpine
restart: always
environment:
PGUSER: postgres
POSTGRES_PASSWORD: difyai123456
POSTGRES_DB: dify
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
#- ./volumes/db/data:/var/lib/postgresql/data
- postgres_data:/var/lib/postgresql/data #変更
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
networks: #追加
- default #追加
redis:
image: redis:6-alpine
restart: always
volumes:
- ./volumes/redis/data:/data
command: redis-server --requirepass difyai123456
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
networks: #追加
- default #追加
weaviate:
image: semitechnologies/weaviate:1.19.0
restart: always
volumes:
- ./volumes/weaviate:/var/lib/weaviate
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'none'
CLUSTER_HOSTNAME: 'node1'
AUTHENTICATION_APIKEY_ENABLED: 'true'
AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
AUTHORIZATION_ADMINLIST_ENABLED: 'true'
AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
networks: #追加
- default #追加
sandbox:
image: langgenius/dify-sandbox:0.2.1
restart: always
environment:
API_KEY: dify-sandbox
GIN_MODE: 'release'
WORKER_TIMEOUT: 15
ENABLE_NETWORK: 'true'
HTTP_PROXY: 'http://ssrf_proxy:3128'
HTTPS_PROXY: 'http://ssrf_proxy:3128'
SANDBOX_PORT: 8194
volumes:
- ./volumes/sandbox/dependencies:/dependencies
networks:
- ssrf_proxy_network
ssrf_proxy:
image: ubuntu/squid:latest
restart: always
volumes:
- ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
networks:
- ssrf_proxy_network
- default
nginx:
image: nginx:latest
restart: always
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/proxy.conf:/etc/nginx/proxy.conf
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- api
- web
ports:
- "8080:80" #80:80から変更
networks: #追加
- default #追加
networks:
ssrf_proxy_network:
driver: bridge
internal: true
default: #追加
driver: bridge
volumes: #追加
postgres_data: #追加
docker-compose.yamlの中身を可視化
※streamlit+graphvizで可視化してみた。
- あたらめて起動
# dockerコンテナを再構築して起動
# docker compose up -d
- 無事起動!
Dify+Ollamaでチャットボットを作る
ゴール
- Ollamaで動くLlama3と連携したチャットボットを作る
まとめ
- Difyはすごい!
- ノーコードでLLMアプリを作れる
- 作ったアプリをホストしてくれる
- デバッグがしやすい
- ログ管理やセッション管理までできる
- LLMブロックを3段階重ねて、なんとかLlama3で日本語チャットができるようになった
参考リンク
- Dify公式doc Quickstart
- Ollama公式doc
手順
まず、DifyにOllamaで動くLlama3を登録する
- Ollamaを以下のbatファイルから起動する
※ 前提:ollamaにllama3がインストールされている
※ OLLAM_HOSTをシステム環境変数として登録してもよい
@echo off
set OLLAMA_HOST=0.0.0.0:11434
ollama serve
- Difyを起動して、アクセスする。(私の場合は
http://localhost:8080/apps
) - LLMモデルを登録する
つぎに、Difyでチャットボットを作る
- 下図のようにはじめる
スタジオ
→最初から作成
→チャットボット
→Chatflow
→アプリ名はLlama3チャットボット
- ブロックを追加、連結、編集していく。
完成したフロー
全体フロー
日→英翻訳:ユーザー入力を英語に変換する
- システムプロンプト
# INSTRUCTIONS
- Translate only the Japanese parts of the "USER INPUT" sentences into English.
- Output only the translated text.
- Do not include "Here is the translation of the Japanese part: " at the beginning of the output text.
- Ensure the translation captures the full meaning of the Japanese text without adding unnecessary context.
# GOOD SAMPLE
- USER INPUT: "moonshot meanってどういう意味?"
- YOUR OUTPUT: "What does moonshot mean?"
# BAD SAMPLE
- USER INPUT: "テニスのルールを教えて"
- YOUR OUTPUT: "Translation of Japanese text to English\nThe translation of the Japanese text is as follows:\n\n\"Teaching tennis rules\"
# USER INPUT
{{#context#}}
メインブロック:回答を生成する
英→日翻訳:LLM出力を日本語に翻訳する
システムプロンプト
以下の文章を、忠実に日本語に翻訳して出力してください。
(ただし以下は日本語に変換しないこと:固有名詞、技術用語、プログラミングコード、製品名やブランド名、特定の業界用語や略語(例えば、IT業界の「API」や「SQL」など)、ファイル名やディレクトリ名、設定や構成項目の名前、ログメッセージやエラーメッセージ、数値や特定の単位(例えば、「GB」や「Hz」など)、メールアドレスやURL )
# 翻訳する文章
{{#context#}}
出力:出力するだけ
- デバッグしながら、プロンプトやLLM設定(tempretureなど)を調整する
デバッグの様子
- アプリとして「公開する」
アプリを公開
アプリを実行
を選択すると、webアプリページが開く。
Chrome拡張機能を使って、ウェブサイトに埋め込むこともできる
※動かないサイトも多い
- アプリ管理機能もある
アプリ管理機能
ログ&アナウンス
概要
メッセージ数、アクティブユーザー数、セッション数、トークン出力速度、トークン使用量など
- (追加)最初のメッセージを設定する
最初のメッセージを設定
Dify+OllamaでRAGチャットボットを作る#1
ゴール
- OllamaのモデルだけでRAGチャットボットを作れるようになる
まとめ
- Ollamaで使える埋め込みモデルの日本語処理性能が悪い!→使えないので中止
関連リンク
埋め込みモデルの設定方法
- Dify公式: Ollamaとの連携方法
Ollamaで使える埋め込みモデル一覧(2024-6-9時点)
-
Ollamaモデル一覧
- nomic-embed-text:埋め込み可能な最大コンテキストサイズは8192トークン
- mxbai-embed-large:同512トークン
- all-minilm:同256トークン
- snowflake-arctic-embed:同4096トークン
- Ollamaブログ:埋め込みモデル
mxbai-embed-largeモデルについて
-
Ollamaでのモデル紹介
2024 年 3 月現在、このモデルは MTEB 上の Bert の大規模モデルで SOTA パフォーマンスを達成しています。OpenAI のtext-embedding-3-largeモデルなどの商用モデルよりも優れており、その 20 倍のサイズのモデルのパフォーマンスに匹敵します。 - mixedbread.aiのブログ記事
- Hugging Faceのリポジトリ
サンプルFAQデータセット
手順
Difyにmxbai-embe-largeを登録する
- ollamaにモデルをpullする。
ollama pull mxbai-embed-large
- ollamaを起動する
@echo off
set OLLAMA_HOST=0.0.0.0:11434
ollama serve
- Difyでモデルを設定する
画面右上のアカウント名
をクリック →モデルプロバイダー
→Ollama
→Add model
モデル設定画面
※ model context sizeは公式サイト(下図)を参考に、512に設定した。
埋め込むデータを準備する
- LINEヤフーが公開している「子育てAIチャットボット用FAQデータセット」を利用する
- このサイトからZIPファイルをダウンロードして展開する
解凍したデータ
エクセル(xlsx)ファイルで、レコード数は981。
質問項目は以下のとおり。
- 母子手帳・妊婦健診
- 子どもの健診
- 予防接種
- 引っ越し手続き
- 児童手当
- 療育医療・育成医療・養育医療
- 保育園・延長保育・一時保育
- 子育て支援・イベント
- その他の手続き(住民票、婚姻届など)
データを埋め込む
-
システムモデル設定
で、埋め込みモデルをmxdbai-embed-large
に設定しておく。
-
Difyに取り込む
画面上部のナレッジ
→知識を作成
→テキストファイルからインポート
→回答したエクセルファイルをアップロードと進む(詳細は下記)
ファイルアップロードから埋め込みまでの流れ
ファイルをアップロード
テキストの前処理とクリーニング
すべて自動でおまかせする。
埋め込みの実行
1分くらいで終わる。
- 検索テストをしてみる
画面上部→ナレッジ
→埋め込み完了したデータセットを選択→サイドバーの検索テスト
をクリック
検索テストの結果
※top-Kは10に再設定した
- 「母子手帳」で検索 →ダメ
- 「児童手当」で検索 →ダメ
- 「保育園に入れたい」で検索 →ダメ
→全然ダメだ。。
比較:azure-openai text-embedding-3-largeで埋め込んだときの検索テスト結果
検索テスト結果
※top-Kは6に再設定した
- 「母子手帳」で検索 →合格
- 「児童手当」で検索 →合格
- 「保育園に入れたい」で検索 →合格
→非常に優秀
別のモデル(nomic-embe-text、snowflake-arctic-embed)も導入する
- Ollamaを停止
- 二つのモデルをpull
ollama pull nomic-embed-text
ollama pull snowflake-arctic-embed
- Ollmaを再起動
- Difyと連携
-
Model context size
はnomic-embed-text
は8192
、snowflake-arctic-embed
は4096
に設定した。
- データを埋め込む
- 検証テストをする
検証テスト結果(nomic-embed-text)
- 「母子手帳」で検索 →ダメ
- 「児童手当」で検索 →ダメ
- 「保育園に入れたい」で検索 →ギリギリ合格
- 「金属ごみの出し方を知りたい」で検索 →ダメ
- 「粗大ごみの出し方」で検索 →ダメ
→**nomic-embed-text
もダメ**
検証テスト結果(snowflake-arctic-embed)
- 「母子手帳」で検索 →ダメ
- 「児童手当」で検索 →ダメ
- 「保育園に入れたい」で検索 →ダメ
- 「金属ごみの出し方を知りたい」で検索 →ダメ
- 「粗大ごみの出し方」で検索 →ギリギリ合格
→**snowflake-arctic-embed
もダメ**
Difyと一緒にOllamaもDockerで動かしてみる
ゴール
- Difyのdocker-compose.yamlにOllamaも追記して、Docker上でOllamaを稼働させる
※現状はwindowsアプリとして起動させている
まとめ
- 問題なく動いたが、現状CPUしか使えていない
- ⇒GPUで動くようにするのはまた今度
関連リンク
- 参考ブログ:「DifyとOllamaでオープンなRAG型チャットボットを構築してみた。」
※参考にさせていただきました。 - Docker Hub Ollama導入手順
※GPUを使う場合の手順はここに書いてある。
手順
コンテナの再構築
- dify/dockerフォルダでPowerShellを起動して、Difyを停止する。
docker-compose down
※Docker Desktopの停止ボタンを押しても良い。
2. docker-compose.yamlを次のように書き替える
修正したdocker-compose.yaml
version: '3'
services:
api:
image: langgenius/dify-api:0.6.10
restart: always
environment:
MODE: api
LOG_LEVEL: INFO
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
CONSOLE_WEB_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
INIT_PASSWORD: ''
CONSOLE_API_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
SERVICE_API_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
APP_WEB_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
FILES_URL: 'http://(DifyをホストするPCの静的IPを記載):8080' #追加
FILES_ACCESS_TIMEOUT: 300
MIGRATION_ENABLED: 'true'
DB_USERNAME: postgres
DB_PASSWORD: difyai123456
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: dify
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_USERNAME: ''
REDIS_PASSWORD: difyai123456
REDIS_USE_SSL: 'false'
REDIS_DB: 0
CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
WEB_API_CORS_ALLOW_ORIGINS: '*'
CONSOLE_CORS_ALLOW_ORIGINS: '*'
STORAGE_TYPE: local
STORAGE_LOCAL_PATH: storage
S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
S3_BUCKET_NAME: 'difyai'
S3_ACCESS_KEY: 'ak-difyai'
S3_SECRET_KEY: 'sk-difyai'
S3_REGION: 'us-east-1'
AZURE_BLOB_ACCOUNT_NAME: 'difyai'
AZURE_BLOB_ACCOUNT_KEY: 'difyai'
AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
VECTOR_STORE: weaviate
WEAVIATE_ENDPOINT: http://weaviate:8080
WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
QDRANT_URL: http://qdrant:6333
QDRANT_API_KEY: difyai123456
QDRANT_CLIENT_TIMEOUT: 20
QDRANT_GRPC_ENABLED: 'false'
QDRANT_GRPC_PORT: 6334
MILVUS_HOST: 127.0.0.1
MILVUS_PORT: 19530
MILVUS_USER: root
MILVUS_PASSWORD: Milvus
MILVUS_SECURE: 'false'
RELYT_HOST: db
RELYT_PORT: 5432
RELYT_USER: postgres
RELYT_PASSWORD: difyai123456
RELYT_DATABASE: postgres
PGVECTOR_HOST: pgvector
PGVECTOR_PORT: 5432
PGVECTOR_USER: postgres
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
MAIL_TYPE: ''
MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
SMTP_SERVER: ''
SMTP_PORT: 465
SMTP_USERNAME: ''
SMTP_PASSWORD: ''
SMTP_USE_TLS: 'true'
SMTP_OPPORTUNISTIC_TLS: 'false'
RESEND_API_KEY: ''
RESEND_API_URL: https://api.resend.com
SENTRY_DSN: ''
SENTRY_TRACES_SAMPLE_RATE: 1.0
SENTRY_PROFILES_SAMPLE_RATE: 1.0
NOTION_INTEGRATION_TYPE: public
NOTION_CLIENT_SECRET: you-client-secret
NOTION_CLIENT_ID: you-client-id
NOTION_INTERNAL_SECRET: you-internal-secret
CODE_EXECUTION_ENDPOINT: "http://sandbox:8194"
CODE_EXECUTION_API_KEY: dify-sandbox
CODE_MAX_NUMBER: 9223372036854775807
CODE_MIN_NUMBER: -9223372036854775808
CODE_MAX_STRING_LENGTH: 80000
TEMPLATE_TRANSFORM_MAX_LENGTH: 80000
CODE_MAX_STRING_ARRAY_LENGTH: 30
CODE_MAX_OBJECT_ARRAY_LENGTH: 30
CODE_MAX_NUMBER_ARRAY_LENGTH: 1000
SSRF_PROXY_HTTP_URL: 'http://ssrf_proxy:3128'
SSRF_PROXY_HTTPS_URL: 'http://ssrf_proxy:3128'
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
depends_on:
- db
- redis
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
worker:
image: langgenius/dify-api:0.6.10
restart: always
environment:
CONSOLE_WEB_URL: ''
MODE: worker
LOG_LEVEL: INFO
SECRET_KEY: sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
DB_USERNAME: postgres
DB_PASSWORD: difyai123456
DB_HOST: db
DB_PORT: 5432
DB_DATABASE: dify
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_USERNAME: ''
REDIS_PASSWORD: difyai123456
REDIS_DB: 0
REDIS_USE_SSL: 'false'
CELERY_BROKER_URL: redis://:difyai123456@redis:6379/1
STORAGE_TYPE: local
STORAGE_LOCAL_PATH: storage
S3_ENDPOINT: 'https://xxx.r2.cloudflarestorage.com'
S3_BUCKET_NAME: 'difyai'
S3_ACCESS_KEY: 'ak-difyai'
S3_SECRET_KEY: 'sk-difyai'
S3_REGION: 'us-east-1'
AZURE_BLOB_ACCOUNT_NAME: 'difyai'
AZURE_BLOB_ACCOUNT_KEY: 'difyai'
AZURE_BLOB_CONTAINER_NAME: 'difyai-container'
AZURE_BLOB_ACCOUNT_URL: 'https://<your_account_name>.blob.core.windows.net'
GOOGLE_STORAGE_BUCKET_NAME: 'yout-bucket-name'
GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: 'your-google-service-account-json-base64-string'
VECTOR_STORE: weaviate
WEAVIATE_ENDPOINT: http://weaviate:8080
WEAVIATE_API_KEY: WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
QDRANT_URL: http://qdrant:6333
QDRANT_API_KEY: difyai123456
QDRANT_CLIENT_TIMEOUT: 20
QDRANT_GRPC_ENABLED: 'false'
QDRANT_GRPC_PORT: 6334
MILVUS_HOST: 127.0.0.1
MILVUS_PORT: 19530
MILVUS_USER: root
MILVUS_PASSWORD: Milvus
MILVUS_SECURE: 'false'
MAIL_TYPE: ''
MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
SMTP_SERVER: ''
SMTP_PORT: 465
SMTP_USERNAME: ''
SMTP_PASSWORD: ''
SMTP_USE_TLS: 'true'
SMTP_OPPORTUNISTIC_TLS: 'false'
RESEND_API_KEY: ''
RESEND_API_URL: https://api.resend.com
RELYT_HOST: db
RELYT_PORT: 5432
RELYT_USER: postgres
RELYT_PASSWORD: difyai123456
RELYT_DATABASE: postgres
PGVECTOR_HOST: pgvector
PGVECTOR_PORT: 5432
PGVECTOR_USER: postgres
PGVECTOR_PASSWORD: difyai123456
PGVECTOR_DATABASE: dify
NOTION_INTEGRATION_TYPE: public
NOTION_CLIENT_SECRET: you-client-secret
NOTION_CLIENT_ID: you-client-id
NOTION_INTERNAL_SECRET: you-internal-secret
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: 1000
depends_on:
- db
- redis
volumes:
- ./volumes/app/storage:/app/api/storage
networks:
- ssrf_proxy_network
- default
web:
image: langgenius/dify-web:0.6.10
restart: always
environment:
CONSOLE_API_URL: ''
APP_API_URL: ''
SENTRY_DSN: ''
networks: #追加
- ssrf_proxy_network #追加
- default #追加
db:
image: postgres:15-alpine
restart: always
environment:
PGUSER: postgres
POSTGRES_PASSWORD: difyai123456
POSTGRES_DB: dify
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
#- ./volumes/db/data:/var/lib/postgresql/data
- postgres_data:/var/lib/postgresql/data #変更
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
networks: #追加
- default #追加
redis:
image: redis:6-alpine
restart: always
volumes:
- ./volumes/redis/data:/data
command: redis-server --requirepass difyai123456
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
networks: #追加
- default #追加
weaviate:
image: semitechnologies/weaviate:1.19.0
restart: always
volumes:
- ./volumes/weaviate:/var/lib/weaviate
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'false'
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
DEFAULT_VECTORIZER_MODULE: 'none'
CLUSTER_HOSTNAME: 'node1'
AUTHENTICATION_APIKEY_ENABLED: 'true'
AUTHENTICATION_APIKEY_ALLOWED_KEYS: 'WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih'
AUTHENTICATION_APIKEY_USERS: 'hello@dify.ai'
AUTHORIZATION_ADMINLIST_ENABLED: 'true'
AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
networks: #追加
- default #追加
sandbox:
image: langgenius/dify-sandbox:0.2.1
restart: always
environment:
API_KEY: dify-sandbox
GIN_MODE: 'release'
WORKER_TIMEOUT: 15
ENABLE_NETWORK: 'true'
HTTP_PROXY: 'http://ssrf_proxy:3128'
HTTPS_PROXY: 'http://ssrf_proxy:3128'
SANDBOX_PORT: 8194
volumes:
- ./volumes/sandbox/dependencies:/dependencies
networks:
- ssrf_proxy_network
ssrf_proxy:
image: ubuntu/squid:latest
restart: always
volumes:
- ./volumes/ssrf_proxy/squid.conf:/etc/squid/squid.conf
networks:
- ssrf_proxy_network
- default
nginx:
image: nginx:latest
restart: always
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/proxy.conf:/etc/nginx/proxy.conf
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- api
- web
ports:
- "8080:80" #80:80から変更
networks: #追加
- default #追加
# ----------------------------------------
# 240609: Ollamaを追加
# ----------------------------------------
ollama: #追加
image: ollama/ollama
restart: always
container_name: ollama
ports:
- "11434:11434"
volumes:
- ollama:/root/.ollama
networks:
ssrf_proxy_network:
driver: bridge
internal: true
default: #追加
driver: bridge
volumes: #追加
postgres_data: #追加
ollama: #追加
コンテナの関係を可視化
- Difyを再起動
# ollamaイメージをダウンロード
docker-compose pull ollama
# difyを再起動。
docker-compose up -d
OllamaにLlama3導入
- Docker上のollamaにllama3を導入
ollamaコンテナに入る
docker exec -it ollama /bin/sh
ollamaコンテナでコマンドを実行
ollama pull llama3
Docker Desktopから簡単にアクセスできる
- Chrome拡張機能のollama-uiでLlama3が稼働していることを確認する
確認方法
- ollama-uiを導入
- 問題なければ
llama3
モデルが選択できる
- チャットもできた
DifyとOllama(Llama3)を連携
- Diryにアクセス
- 画面右上のアカウントをクリック⇒
モデルプロバイダー
⇒Ollama
⇒Add Model
⇒下図のように設定
Difyで動作検証
- 既存チャットボットのモデルをOllmaのLlama3に切り替えて動かしてみた(割愛)
- やはりCPUしか使っていないのでレスポンスが遅い。。
タスクマネージャーの画面
DifyアプリにAPIアクセスする
ゴール
- Dify APIエンドポイントにAPIリクエストを送信する
まとめ
- Chrome拡張機能のTalend API TesterからのPOSTリクエストが成功した
関連リンク
- Dify公式doc API利用方法
- Chrome拡張機能 Talend API Tester - Free Edition
手順
DifyチャットアプリのAPIキーを取得する
- Difyでチャットアプリを作る
- 概要からAPIキーを取得する
- Chromeブラウザに
Talend API Tester
拡張機能を導入する - Dify公式docなどを参考に、下図のように設定する
参考にしたもの
Dify公式doc
import requests
import json
url = 'https://api.dify.ai/v1/chat-messages'
headers = {
'Authorization': 'Bearer ENTER-YOUR-SECRET-KEY',
'Content-Type': 'application/json',
}
data = {
"inputs": {},
"query": "eh",
"response_mode": "streaming",
"conversation_id": "1c7e55fb-1ba2-4e10-81b5-30addcea2276",
"user": "abc-123"
}
response = requests.post(url, headers=headers, data=json.dumps(data))
print(response.json())
アプリのAPIアクセスページ
curl -X POST 'http://161.93.110.41:8080/v1/chat-messages' \
--header 'Authorization: Bearer {api_key}' \
--header 'Content-Type: application/json' \
--data-raw '{
"inputs": {},
"query": "What are the specs of the iPhone 13 Pro Max?",
"response_mode": "streaming",
"conversation_id": "",
"user": "abc-123",
"files": [
{
"type": "image",
"transfer_method": "remote_url",
"url": "https://cloud.dify.ai/logo/logo-site.png"
}
]
}'
BODYは次のとおり
※会話IDは空欄
※テキストチャットなら"files"は不要
{
"query": "こんにちは",
"response_mode": "streaming",
"conversation_id": "",
"user": "abc-123",
"inputs": {},
"files": [
{
"type": "image",
"transfer_method": "remote_url",
"url": "https://cloud.dify.ai/logo/logo-site.png"
}
]
}
- SENDを押す⇒成功!
Dify+OllamaでRAGチャットボットを作る#2
ゴール
- ローカルだけで完結するRAG検索チャットボットを作る
まとめ
- ollama pullできる多言語対応埋め込みモデルがあったので作れたが、精度は悪く、実用には堪えない。
関連リンク
- Ollama pullできる多言語対応埋め込みモデル
手順
- Ollamaトップページの検索窓で
embedding multi
みたいなキーワードを入力して検索する - ヒットしたモデルのなかで、多言語対応の埋め込みモデルの
paraphrase-multilingual-minilm
と日本語LLMのFugaku-llm
をollama pullする
ollama pull nextfire/paraphrase-multilingual-minilm
ollama run nebel/fugaku-llm:13b-instruct
- ollamaを起動する
- Difyに2つのモデルを登録する
Dify登録画面
paraphrase-multilingual-minilmを登録
Fugaku-llmの登録
- Difyでまずナレッジを埋め込む
- 元データはLINEの公開している子育てAIチャットボット用のサンプルFAQデータセットを使う
- チャンク設定は
自動
、インデックスモードは高品質
、top-Kは8
- 埋め込みが完了したら、検索テストをしてみる
頑張ってはいるが精度はいまいち。。
検索テストの結果
- RAGアプリを作る
下図のようにつくった
アプリ作成画面
アプリ全体のアーキテクチャ
Fugaku-llmの詳細設定
- デバッグとプレビュー機能を使って検索してみる
検索結果
→うーむ、使えたものじゃない。。
Difyを0.6.10から0.6.12fix1にアップデートする
ゴール
- Dify0.6.12fix1にバージョンアップする
- 0.6.10環境のデータを引き継ぐ
まとめ
- 0.6.12fix1は起動できたが、0.6.10環境のデータの引継ぎはできず。。
- これまでのようにdocker-compose.yamlの内容をあれこれ触らなくても起動した。
- ただしPostgresDBのデータ保管場所だけは従来と同じく変えた(後述)
関連リンク
- Difyリリースノート ※更新方法もある
手順
(背景)
- 別のPCのDify0.6.10環境にDify0.6.12fixを上書きするインストールしたが、データ継承されなかった。
- このPCのDify0.6.10環境は絶対壊したくないので、既存のDify0.6.10環境を残して、新たにDify0.6.12fix1環境を作った。以下はその手順。
PowerShellで実行するコマンド
# difyフォルダをコピー
cp dify dify_latest
# コピー先のdockerディレクトリに移動
cd dify_latest\docker\
# 手元のフォルダのタグを確認
git tag
# ⇒0.6.10までだった
# リモートのタグ情報を取得
git fetch --tags
# 再度タグを確認
git tag
# ⇒0.6.12fix1までになった
# mainブランチに切り替え
git checkout main
# リモートのmainブランチの最新内容を取得(=fetch+merge)
git pull origin main
# ⇒手元のdocker-compose.yamlをコミットしていないのでダメとエラーが出た
# docker-compose.yamlの変更を破棄
git checkout -- docker-compose.yaml
# ⇒docker-compose.yamlが上書きされるので、
# docker-compose_0.6.10stable.yamlという名前にして、別のフォルダに保存する
# 改めてmainブランチの最新内容を取得
git pull origin main
# →今度はできた
# 手動でdocker-compose.yamlの中身を書き換える(後述)
# .env.sampleファイルを.envという名前に変えて、中身を書き換える(後述)
# コンテナをdify0_6_12という名前で起動
docker-compose -p dify0_6_12 up -d
# ⇒無事起動!
-
GitHubリポジトリにあるファイルへのリンク:
-
docker-compose.yamlと.envファイルの変更点:
db:
volumes:
# 変更後
- postgres_data:/var/lib/postgresql/data #追加
# 変更前
# - ./volumes/db/data:/var/lib/postgresql/data
volumes:
oradata:
postgres_data: #追加
# ------------------------------
# Common Variables
# ------------------------------
# ホストマシンのIPに変更
CONSOLE_API_URL=http://161.93.***.**:8880 #追加
CONSOLE_WEB_URL=http://161.93.***.**:8880 #追加
SERVICE_API_URL=http://161.93.***.**:8880 #追加
APP_API_URL=http://161.93.***.**:8880 #追加
APP_WEB_URL=http://161.93.***.**:8880 #追加
FILES_URL=http://161.93.***.**:8880 #追加
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8880 #80から変更
EXPOSE_NGINX_SSL_PORT=8443 #443から変更
Firecrawlをセルフホストして、Difyで使う
ゴール
- Firecrawlをセルフホストして、Difyと連携する
- Firecrawlはサイトをクロールしてマークダウンに変換するツール
- FirecrawlをDifyと連携させると、サイトデータをナレッジとして簡単に埋め込めるようになる
まとめ
- Firecrawlをセルフホストできた
- Difyと連携して、外部サイトデータ(githubリポジトリ)をナレッジにできた
- しかし、社内サイト(SharePointOnlineサイト、OneDriveなど)はできなかった
関連リンク
手順
- FirecrawlをDockerから起動するまで
-
公式サイトとこちらのZenn記事を参考にすすめた。
-
difyフォルダのあるフォルダでPowerShellを立ち上げて、以下を実行する。
# リポジトリをクローン
git clone https://github.com/mendableai/firecrawl.git
# ディレクトリに移動
cd firecrawl
# 深い階層にある.env.sampleを現在のディレクトリに.envとしてコピー
cp ./apps/api/.env.example .env
# .envの中身を書き換える(後述)
# dockerコンテナを立てる
docker-compose build
#⇒かなり時間かかるが、待てば処理が終わる。
docker-compose up -d
#⇒かなり時間かかるが、無事起動!
- GitHubリポジトリへのリンク
- docker-compose.yaml ※このまま使う
- .env.sample ※名前を.envに変えてから、下記のように修正
.env
# ===== Required ENVS ======
NUM_WORKERS_PER_QUEUE=8
PORT=3002
HOST=0.0.0.0
# 変更前
# REDIS_URL=redis://localhost:6379
# 変更後
REDIS_URL=redis://redis:6379
PLAYWRIGHT_MICROSERVICE_URL=http://playwright-service:3000/html
## To turn on DB authentication, you need to set up supabase.
# trueから変更
USE_DB_AUTHENTICATION=false
# ===== Optional ENVS ======
# Supabase Setup (used to support DB authentication, advanced logging, etc.)
# 変更後
SUPABASE_ANON_TOKEN=dummy_token
SUPABASE_URL=http://dummy_url
SUPABASE_SERVICE_TOKEN=dummy_service_token
# Other Optionals
# 変更前
# TEST_API_KEY= # use if you've set up authentication and want to test with a real API key
# 変更後
TEST_API_KEY=fc-test
RATE_LIMIT_TEST_API_KEY_SCRAPE= # set if you'd like to test the scraping rate limit
RATE_LIMIT_TEST_API_KEY_CRAWL= # set if you'd like to test the crawling rate limit
SCRAPING_BEE_API_KEY= #Set if you'd like to use scraping Be to handle JS blocking
OPENAI_API_KEY= # add for LLM dependednt features (image alt generation, etc.)
BULL_AUTH_KEY= @
LOGTAIL_KEY= # Use if you're configuring basic logging with logtail
LLAMAPARSE_API_KEY= #Set if you have a llamaparse key you'd like to use to parse pdfs
SERPER_API_KEY= #Set if you have a serper key you'd like to use as a search api
SLACK_WEBHOOK_URL= # set if you'd like to send slack server health status messages
POSTHOG_API_KEY= # set if you'd like to send posthog events like job logs
POSTHOG_HOST= # set if you'd like to send posthog events like job logs
STRIPE_PRICE_ID_STANDARD=
STRIPE_PRICE_ID_SCALE=
STRIPE_PRICE_ID_STARTER=
STRIPE_PRICE_ID_HOBBY=
STRIPE_PRICE_ID_HOBBY_YEARLY=
STRIPE_PRICE_ID_STANDARD_NEW=
STRIPE_PRICE_ID_STANDARD_NEW_YEARLY=
STRIPE_PRICE_ID_GROWTH=
STRIPE_PRICE_ID_GROWTH_YEARLY=
HYPERDX_API_KEY=
HDX_NODE_BETA_MODE=1
FIRE_ENGINE_BETA_URL= # set if you'd like to use the fire engine closed beta
# Proxy Settings for Playwright (Alternative you can can use a proxy service like oxylabs, which rotates IPs for you on every request)
PROXY_SERVER=
PROXY_USERNAME=
PROXY_PASSWORD=
# set if you'd like to block media requests to save proxy bandwidth
BLOCK_MEDIA=
# Set this to the URL of your webhook when using the self-hosted version of FireCrawl
SELF_HOSTED_WEBHOOK_URL=
# Resend API Key for transactional emails
RESEND_API_KEY=
- ブラウザから起動を確認する
-
http://localhost:3002/
⇒SCRAPERS-JS: Hello, world! Fly.io
と表示される -
http://host.docker.internal:3002/
⇒SCRAPERS-JS: Hello, world! Fly.io
と表示される -
http://localhost:3002/test
⇒Hello, world!
が表示される -
http://host.docker.internal:3002/test
⇒Hello, world!
が表示される
-
- Difyと連携する
- 設定項目
- API Key:
fc-test
- Base URL:
http://host.docker.internal:3002
- API Key:
画面キャプチャ
- Difyトップ画面 ⇒ナレッジ ⇒ウェブサイトから同期 ⇒設定:データベース ⇒ FireCrawlのConfigureを選択
- 以下のように設定
- 成功!
- ウェブサイトをナレッジにしてみる
- GitHubリポジトリはできた
- 社内サイト(SharePointOnlineサイト、OneNoteなど)はクロールできず。。
画面キャプチャ
- Difyリポジトリをナレッジにしてみる
※以下割愛
Langfuseをセルフホストして、Difyで使う #1
ゴール
- Langfuseをセルフホストする
- LangfuseとDifyを連携して、DifyアプリをLangfuseでトレースする
まとめ
- セルフホストは簡単にできた(http://localhost:3000)
- ただしDifyはhttps通信でないと連携できない!⇒ 次回に続く
関連リンク
手順
- Langfuseを起動する
# Langfuseリポジトリをcloneする
git clone https://github.com/langfuse/langfuse.git
# langufuseフォルダに移動
cd langfuse
# docker-compose.yamlをすこし書き換える(後述)
# langfuseを起動
docker-compose up -d
# ⇒特に問題なく起動!
docker-compose.yml
- オリジナルの docker-compose.yml
- 修正後(変更箇所は1か所だけ)
services:
langfuse-server:
image: langfuse/langfuse:2
depends_on:
db:
condition: service_healthy
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/postgres
- NEXTAUTH_SECRET=mysecret
- SALT=mysalt
# 変更前
# - NEXTAUTH_URL=http://localhost:3000
# 変更後(ホストするPCのIPアドレスに書き換える)
- NEXTAUTH_URL=http://161.93.***.**:3000
- TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-true}
- LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=${LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES:-false}
db:
image: postgres
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 3s
timeout: 3s
retries: 10
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=postgres
ports:
- 5432:5432
volumes:
- database_data:/var/lib/postgresql/data
volumes:
database_data:
driver: local
- Langfuseにサインアップする
画面キャプチャ
- ブラウザで
localhost:3000
にアクセスすると、サインイン画面になる。
- まずはサインアップする
- あらためてサインインすると、初期画面になった。
- Difyと連携する
- セルフホストしているhttpサーバを指定するとエラーになる。。(今回はここまで)
API経由でナレッジを操作する
ゴール
- APIを使ってナレッジを操作できるようになる。
まとめ
- 簡単にできた。これを使えば、ファイルの更新や追加があるたびに埋め込み処理を実行したり、自作のwebアプリ経由でナレッジを追加したりできる。
- ただし、ナレッジ削除も簡単にできてしまうので注意が必要。
参考リンク
- Dify公式doc APIによるデータセットの維持
手順
- 公式docはcURLコマンドのサンプルがあるので、これをPythonコードに書き換えて実行してみる。
- いずれも問題なく実行できた。
ナレッジ一覧の取得
import requests
import json
# -------------------------------
# ユーザー設定
api_key = "dataset-**********" # APIキー
endpoint = "http://161.93.***:**:8880/v1/datasets?page=1&limit=20" # エンドポイント
# -------------------------------
headers = {"Authorization": f"Bearer {api_key}"}
# GETリクエストを送信
response = requests.get(endpoint, headers=headers)
response = response.json() # JSON形式に変換
# dataから、ナレッジのnameとidだけを取得して表示
for knowledge in response["data"]:
print("="*100)
print(f"Name: {knowledge['name']}")
print(f"ID: {knowledge['id']}")
新規ナレッジの作成
import requests
import json
# -------------------------------
# ユーザー設定
api_key = "dataset-**********"
endpoint = "http://161.93.***:**:8880/v1/datasets"
new_knowledge_name = "API-Knowledge 5" # 新しいナレッジの名前
# -------------------------------
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {"name": new_knowledge_name}
# POSTリクエストを送信して新しいナレッジを作成
response = requests.post(endpoint, headers=headers, data=json.dumps(payload))
response = response.json()
# dataにstatusコードが含まれていないときだけ実行する
if "status" not in response:
# dataから、ナレッジのnameとidだけを取得して表示
print("="*100)
print(f"Name: {response['name']}")
print(f"ID: {response['id']}")
else:
# data全体を見やすく表示
print(json.dumps(response, indent=4))
既存ナレッジの削除
import requests
import json
# -------------------------------
# ユーザー設定
api_key = "dataset-**********" # APIキー
dataset_id = "******************" # 削除するナレッジのID
# -------------------------------
endpoint = f"http://161.93.***:**:8880/v1/datasets/{dataset_id}"
headers = {"Authorization": f"Bearer {api_key}"}
# DELETEリクエストを送信してナレッジを削除
response = requests.delete(endpoint, headers=headers)
# レスポンスを表示
if response.status_code == 204:
print("Knowledge deleted successfully.")
else:
print(f"Failed to delete knowledge. Status code: {response.status_code}")
ファイルからドキュメントを作成
import requests
import json
# -------------------------------
# ユーザー設定
api_key = "dataset-**********" # APIキー
dataset_id = "******************" # ドキュメントを追加するナレッジのID
file_path = r"ファイルパス" # ドキュメントとして追加するファイルのパス
# -------------------------------
endpoint = f"http://161.93.***:**:8880/v1/datasets/{dataset_id}/document/create_by_file"
headers = {"Authorization": f"Bearer {api_key}"}
# 処理方法
# 自動埋め込みならこれだけ
process_rule = {"mode": "automatic"}
# カスタム埋め込みならこちらを使う
# process_rule = {
# "mode": "custom"
# "rules": {
# "pre_processing_rules": [
# {"id": "remove_extra_spaces", "enabled": True}, # 余分なスペースを削除
# {"id": "remove_urls_emails", "enabled": False} # URLとメールアドレスを削除
# ],
# "segmentation": {"separator": "###", "max_tokens": 1000} # セグメントの設定
# }
# }
data = {
"indexing_technique": "high_quality", # インデックス技術
"process_rule": process_rule # プロセスルール
}
files = {
'file': open(file_path, 'rb'),
'data': (None, json.dumps(data), 'application/json')
}
# POSTリクエストを送信して新しいドキュメントを作成
response = requests.post(endpoint, headers=headers, files=files)
response = response.json()
# 結果を見やすく表示
print(json.dumps(response, indent=4))
テキストからドキュメントを作成
import requests
import json
# -------------------------------
# ユーザー設定
api_key = "dataset-**********"
dataset_id = "******************" # ドキュメントを追加するナレッジのID
document_name = "Sample Document"
document_text = """生成AIの業務利用には以下の点に注意が必要です。
まず、生成AIが提供する情報の正確性や信頼性を常に確認してください。
生成AIは誤った情報を生成する可能性があるため、重要な決定に使用する前に専門家によるレビューが必要です。
次に、データのプライバシーとセキュリティを確保するため、適切なアクセス制御とデータ保護対策を講じてください。
また、生成AIの利用が法令や規制に準拠していることを確認することも重要です。
最後に、生成AIが生成するコンテンツの著作権や倫理的側面についても注意し、適切な利用範囲を守るようにしてください。
これらのポイントを遵守することで、生成AIの業務利用が効果的かつ安全になります。
"""
# -------------------------------
# APIエンドポイントURL
endpoint = f"http://161.93.***:**:8880/v1/datasets/{dataset_id}/document/create_by_text"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
# POSTデータを作成
payload = {
"name": document_name,
"text": document_text,
"indexing_technique": "high_quality",
"process_rule": {"mode": "automatic"}
}
# POSTリクエストを送信して新しいドキュメントを作成
response = requests.post(endpoint, headers=headers, data=json.dumps(payload))
response = response.json()
# 結果を見やすく表示
print(json.dumps(response, indent=4))
ナレッジのドキュメント一覧を取得
import requests
import json
# APIキーとdataset_idを設定
api_key = "dataset-ydCFZztP4M**************"
dataset_id = "9d93bf86-0354-4211-af2**********"
headers = {"Authorization": f"Bearer {api_key}"}
url_get_documents = f"http://161.93.+++.+++:8880/v1/datasets/{dataset_id}/documents"
response_get_documents = requests.get(url_get_documents, headers=headers)
if response_get_documents.status_code == 200:
documents = response_get_documents.json()
# print("Documents:", documents) # そのまま出力
# print(json.dumps(documents, indent=4)) # 見やすく表示
# "id"と"name"だけ出力
print("Document ID and Name")
for d in documents["data"]:
print(d["id"], d["name"])
else:
print(f"Failed to retrieve documents. Status code: {response_get_documents.status_code}")
ナレッジのドキュメントを削除
import requests
api_key = "dataset-ydCFZztP4MSgwa**********"
dataset_id = "9d93bf86-0354-4211-af20-89**********"
document_id = "****************" # 削除するドキュメントのID
url_delete_document = f"http://161.93.+++.+++:8880/v1/datasets/{dataset_id}/documents/{document_id}"
headers = {"Authorization": f"Bearer {api_key}"}
response_delete_document = requests.delete(url_delete_document, headers=headers)
if response_delete_document.status_code == 204:
print("Document deleted successfully.")
else:
print(f"Failed to delete document. Status code: {response_delete_document.status_code}")
Dify0.6.12fix1から0.6.14にアップデートする
ゴール
- Dify0.6.14にアップデートする
- Dify0.6.12fix1のデータを引き継ぐ
まとめ
- スムーズにアップデートできた。データ引き継ぎも問題なし。
関連リンク
- [Dify0.6.14リリースノート] (https://github.com/langgenius/dify/releases/tag/0.6.14) ※更新方法もある
手順
PowerShellで実行するコマンド
# difyのdockerフォルダに移動して
docker-compose down
# ダウンロード済みのタグを確認
git tag
# ⇒0.6.13までだった
# リモートのタグ情報を取得
git fetch --tags
# 再度タグ確認
git tag
# ⇒0.6.14までになった
# mainブランチに切り替え
git checkout main
# リモートのmainブランチの最新内容をpull(=fetch+merge)
# ※git checkput main しているので git pull でもよい
git pull origin main
# ⇒手元のdocker-compose.yamlなどの更新がコミットされていないというエラーが出る
# ⇒docker-compose.yamlと.envファイルだけ「バックアップ」フォルダを作ってコピーしておく
# スタッシュする
git stash
# あらためてpull
# ※これもgit pullでよい
git pull origin main
# docker-compose.yamlと.envファイルを書き替える(後述)
# コンテナを起動
docker-compose up -d
# ※docker-compose -p dify0_6_14 up -dのようにコンテナ名を変えるとデータ継承されない
# ⇒無事起動!データも継承されている。
- docker-compose.yamlと.envファイルの変更点:
###############
# 変更1箇所目
###############
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 #オリジナル
- postgres_data:/var/lib/postgresql/data #追加
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
ports: #追加(SQLツールからアクセスできるように)
- "5432:5432" #追加
###############
# 変更2箇所目
###############
volumes:
oradata:
postgres_data: #追加
# ホストマシンのIPに変更
# ------------------------------
# Common Variables
# ------------------------------
CONSOLE_API_URL=http://161.93.+++.+++:8080
CONSOLE_WEB_URL=http://161.93.+++.+++:8080
SERVICE_API_URL=http://161.93.+++.+++:8080
APP_API_URL=http://161.93.+++.+++:8080
APP_WEB_URL=http://161.93.+++.+++:8080
FILES_URL=http://161.93.+++.+++:8080
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8080 #80から変更
EXPOSE_NGINX_SSL_PORT=8443 #443から変更
DifyコンテナのPostgresデータベースにSQLツールから接続する
ゴール
- DifyのPostgresデータベースにSQLツールのA5:SQL Mk2から接続する
まとめ
- 簡単にできた。
- DBに格納されているデータに簡単にアクセスできるようになった。
参考リンク
Difyが動かしている3つのデータベースについて
Postgresデータベースには、Difyアプリケーションに関連する多くの永続的なデータが格納されます。
具体的には以下のような情報が含まれます。
- ユーザーデータ: ユーザーアカウント、プロフィール情報、認証情報など。
- アプリケーションデータ: アプリケーション設定、構成情報、使用状況ログなど。
- メッセージデータ: チャットや会話のログ、メッセージの履歴など。
- APIトークン: 外部サービスとの連携に使用されるAPIトークン。
- アノテーションデータ: アノテーションに関連する設定や履歴。
- ワークフローデータ: ワークフローの定義や実行履歴。
Redisはインメモリデータベースで、高速アクセスが必要なデータのキャッシュやセッション情報の格納に使用されます。具体的には以下のような情報が含まれます。
- セッションデータ: ユーザーのセッション情報、ログイン状態など。
- キャッシュデータ: 頻繁にアクセスされるデータのキャッシュ(例: ユーザー設定やアプリケーション設定)。
- キュー: ジョブキューやタスクキュー(Celeryなどのバックエンドタスク処理で使用)。
Weaviateはベクトル検索エンジンで、ベクトルデータや意味的検索に関連する情報を格納します。具体的には以下のような情報が含まれます。
- ベクトルデータ: テキストやその他のデータのベクトル表現。
- メタデータ: 各ベクトルに関連するメタデータ(例: ドキュメントIDやその他の関連情報)。
- 検索インデックス: 効率的なベクトル検索をサポートするためのインデックス。
手順
- docker-compose.yamlに外部ポート開放設定を追加
# 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:
# 変更後
# 名前付きボリューム postgres_data をコンテナ内のディレクトリ /var/lib/postgresql/data にマウントします。
- postgres_data:/var/lib/postgresql/data #追加
# オリジナルは下記
# ./volumes/db/data をコンテナ内のディレクトリ /var/lib/postgresql/data にマウントします。
# - ./volumes/db/data:/var/lib/postgresql/data
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
ports: #追加
- "5433:5432" #追加 5432でなく5433を使います!
- コンテナを
docker-compose up -d
などで起動。 - A5:SQL Mk2を起動して、以下のように設定する。
.env設定を変えていないならば、
- データベース名:
dify
- ユーザーID:
postgres
- パスワード:
difyai123456
⇒設定が正しいかは、「テスト接続」ですぐ確認できる。
- 接続すると、
public
スキーマにあるテーブルに各種データが格納されていることがわかる。
-
accounts
テーブル- Difyアカウント情報(id、登録名、メールアドレス、登録日など)
-
apps
テーブル- アプリ情報(アプリid、アプリ名、テナントid、作成日など)
-
datasets
テーブル- ナレッジのデータセット情報(id、ファイル名、埋め込み方法など)
-
documents
テーブル- ナレッジに格納しているドキュメント情報
-
end_users
テーブル- Difyアプリを使ったユーザー情報(利用したアプリid、登録日など)
-
messages
テーブル- チャット履歴(id、アプリid、会話id、クエリ、トークン数、ユーザーid(from_end_user_id、from_account_idのいずれか)、作成日など)
ベクトルデータベースとの接続トラブル対処記録
ゴール
- ベクトルデータベース(weaviate)とDify本体(sandbox)が通信できない不具合を解消する。
まとめ
- middlewareコンテナを停止、再起動したら解消した。
- ⇒ middlewareの何が悪かったのかは未解明。
手順
- 前日まで問題なく動いていたが、朝から次の症状が出た
- ナレッジの埋め込みはできるが、データベースに登録できない
- RAGアプリでナレッジ検索ブロックでデータベースに接続できない
- 確認したこと
- ログ ⇒問題ない
- ストレージ ⇒十分余裕がある
- ファイル ⇒壊れていない
- Dify本体コンテナの停止、再起動 ⇒症状改善しない
- Dify本体をバージョンアップ(0.6.14⇒0.6.15)⇒症状改善しない
- Dify-middlewareを停止、再起動 ⇒ 症状改善した
Dify0.6.15から0.7.0にアップデートする
ゴール
- Dify0.7.0にアップデートする
まとめ
- スムーズにアップデートできた。データ引き継ぎも問題なし。
- middlewareは変化なしだったのでそのまま稼働中。
関連リンク
- Dify0.7.0リリースノート ※更新方法もある
手順
- gitから最新版をpullするまでは 0.6.15へのアップデートと同じ
# difyのdockerフォルダに移動して、起動中の環境を落とす
docker-compose down
# いまのdocker-compose.yamlとか.envファイルを別フォルダにコピー(バックアップ)する
# データバックアップはしない
# 最新バージョンをpullするために、現在のフォルダ状態をスタッシュ
git stash
# mainブランチに切り替え
git checkout main
# リモートのタグ情報を取得
git fetch --tags
# タグ確認
git tag
# ⇒0.7.0まであることを確認
# 最新バージョンをpull
git pull origin main
# docker-compose.yamlと.envファイルを書き換える(後述)
# コンテナを起動
docker-compose up -d
- docker-compose.yamlと.envファイルの変更点:
### 変更1箇所目 #################################
# 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}
command: >
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
-c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
volumes:
# - ./volumes/db/data:/var/lib/postgresql/data #オリジナル
- postgres_data:/var/lib/postgresql/data #追加
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
### 変更2箇所目 #################################
volumes:
oradata:
dify_es01_data:
postgres_data: #追加
# ホストマシンのIPに変更
# ------------------------------
# Common Variables
# ------------------------------
CONSOLE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
CONSOLE_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
SERVICE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
FILES_URL=http://161.93.+++.++:8880 #オリジナルは空欄
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8880 #オリジナルは80
EXPOSE_NGINX_SSL_PORT=8443 #オリジナルは443
Firecrawlをセルフホストして、Difyで使う #2
ゴール
- Dify0.7.0にバージョンアップしたら動かなくなったFirecrawlを使ったチャットボットを再び動かす
まとめ
- 次のブロックに渡すFirecrawlの出力をtextからjsonに変更して復活させた
- textだと空データが出力されてしまう
関連リンク
- Firecrawlをセルフホストして、Difyで使う #1
-
Web Clipperを作ってみた - Dify,Chrome拡張,Firecrawl,GPT-4o mini,Notionを活用
- 後述するテンプレートブロック作成の参考にした。
- ちなみにこれまではコードブロックを使っていた。
手順
- CRAWLブロックの次のブロックに渡す変数を
text
からjson
に変更した。
- また次のテンプレートブロックで、最大1万文字でカットオフする。
{{ json[0].data|map(attribute='content')|join(' ')|truncate(10000, true, '') }}
- 無事復活した。
Difyを0.8.3にアップデートする
ゴール
- APIキーのロードバランシングもできるようにする 参考記事
まとめ
- スムーズにアップデートできた。データ引き継ぎも問題なし。
- ロードバランシング機能も有効化できた。(まだ有効にはしていない)
関連リンク
手順
- gitから最新版をpullするまでは 0.7.0へのアップデート と同じ
# difyのdockerフォルダに移動して、起動中の環境を落とす
docker-compose down
# いまのdocker-compose.yamlとか.envファイルを別フォルダにコピー(バックアップ)する
# データバックアップはしない
# 最新バージョンをpullするために、現在のフォルダ状態をスタッシュ
git stash
# mainブランチに切り替え
git checkout main
# リモートのタグ情報を取得
git fetch --tags
# タグ確認
git tag
# ⇒0.8.3まであることを確認
# 最新バージョンをpull
git pull origin main
# docker-compose.yamlと.envファイルを書き換える(後述)
# コンテナを起動
docker-compose up -d
- docker-compose.yamlと.envファイルの変更点:
### 変更1箇所目 #################################
# ロードバランシングを有効化するため
x-shared-env: &shared-api-worker-env
LOG_LEVEL: ${LOG_LEVEL:-INFO}
LOG_FILE: ${LOG_FILE:-}
## 途中省略 ##
SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
MODEL_LB_ENABLED: "true" # 追加(ロードバランシングを有効化)
### 変更2,3箇所目 #################################
# 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}
command: >
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
-c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
volumes:
# - ./volumes/db/data:/var/lib/postgresql/data #オリジナル
- postgres_data:/var/lib/postgresql/data #追加(こうしないとエラーになるから)
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
ports: #追加
- "5432:5432" #追加(SQLツールからの接続用)
### 変更4箇所目 #################################
volumes:
oradata:
dify_es01_data:
postgres_data: #追加
# ホストマシンのIPに変更
# ------------------------------
# Common Variables
# ------------------------------
CONSOLE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
CONSOLE_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
SERVICE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
FILES_URL=http://161.93.+++.++:8880 #オリジナルは空欄
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8880 #オリジナルは80
EXPOSE_NGINX_SSL_PORT=8443 #オリジナルは443
セルフホストしているFirecrawlをv0からv1にアップデートする#1
ゴール
- ローカルPCでセルフホストしているFirecrawlをv0からv1にアップグレードする
- Difyを0.8.3にアップデートしたらFirecrawlツールが使えなくなったため、とりあえずやってみる。
まとめ
- v0のときと症状は変わらず。Difyでナレッジ作成はできるが、ツールが使えない。
- (11/9追記)再構築したら治った
ナレッジ作成画面(問題なし)
改善前の症状
ツール(4種類)でエラーが出るのは解消せず。
認証はされているようだが、、
⇒認証を再設定しようとするとエラーが出る
関連リンク
手順
- 最新バージョンをgithubからpull
- .envファイルを書き換えて、コンテナをbuild&up
# firecrawlフォルダに移動して、起動中の環境を落とす
docker-compose down
# いまのdocker-compose.yamlと.envファイルを別フォルダにコピー(バックアップ)する
# データバックアップはしない
# 最新バージョンをpullするために、現在のフォルダ状態をスタッシュ
git stash
# mainブランチに切り替え
git checkout main
# リモートのタグ情報を取得
git fetch --tags
# タグ確認
git tag
# ⇒v1まであることを確認
# 最新バージョンをpull
git pull origin main
# .envファイルを書き換える(後述)
# docker-compose.yamlは書き換えるところなし
# buildする
docker-compose build
# ⇒時間かかる。待つ。
# コンテナを起動する
docker-compose up -d
無事起動
.envファイル(変更あり)
.env
# ===== Required ENVS ======
NUM_WORKERS_PER_QUEUE=8
PORT=3002
HOST=0.0.0.0
REDIS_URL=redis://redis:6379 #for self-hosting using docker, use redis://redis:6379. For running locally, use redis://localhost:6379
REDIS_RATE_LIMIT_URL=redis://redis:6379 #for self-hosting using docker, use redis://redis:6379. For running locally, use redis://localhost:6379
PLAYWRIGHT_MICROSERVICE_URL=http://playwright-service:3000/html
## To turn on DB authentication, you need to set up supabase.
# USE_DB_AUTHENTICATION=true #オリジナル
USE_DB_AUTHENTICATION=false #変更後
# ===== Optional ENVS ======
# SearchApi key. Head to https://searchapi.com/ to get your API key
SEARCHAPI_API_KEY=
# SearchApi engine, defaults to google. Available options: google, bing, baidu, google_news, etc. Head to https://searchapi.com/ to explore more engines
SEARCHAPI_ENGINE=
# Supabase Setup (used to support DB authentication, advanced logging, etc.)
SUPABASE_ANON_TOKEN=
SUPABASE_URL=
SUPABASE_SERVICE_TOKEN=
# Other Optionals
# use if you've set up authentication and want to test with a real API key
TEST_API_KEY=fc-test #追加
# set if you'd like to test the scraping rate limit
RATE_LIMIT_TEST_API_KEY_SCRAPE=
# set if you'd like to test the crawling rate limit
RATE_LIMIT_TEST_API_KEY_CRAWL=
# set if you'd like to use scraping Be to handle JS blocking
SCRAPING_BEE_API_KEY=
# add for LLM dependednt features (image alt generation, etc.)
OPENAI_API_KEY=
BULL_AUTH_KEY=@
# set if you have a llamaparse key you'd like to use to parse pdfs
LLAMAPARSE_API_KEY=
# set if you'd like to send slack server health status messages
SLACK_WEBHOOK_URL=
# set if you'd like to send posthog events like job logs
POSTHOG_API_KEY=
# set if you'd like to send posthog events like job logs
POSTHOG_HOST=
STRIPE_PRICE_ID_STANDARD=
STRIPE_PRICE_ID_SCALE=
STRIPE_PRICE_ID_STARTER=
STRIPE_PRICE_ID_HOBBY=
STRIPE_PRICE_ID_HOBBY_YEARLY=
STRIPE_PRICE_ID_STANDARD_NEW=
STRIPE_PRICE_ID_STANDARD_NEW_YEARLY=
STRIPE_PRICE_ID_GROWTH=
STRIPE_PRICE_ID_GROWTH_YEARLY=
# set if you'd like to use the fire engine closed beta
FIRE_ENGINE_BETA_URL=
# Proxy Settings for Playwright (Alternative you can can use a proxy service like oxylabs, which rotates IPs for you on every request)
PROXY_SERVER=
PROXY_USERNAME=
PROXY_PASSWORD=
# set if you'd like to block media requests to save proxy bandwidth
BLOCK_MEDIA=
# Set this to the URL of your webhook when using the self-hosted version of FireCrawl
SELF_HOSTED_WEBHOOK_URL=
# Resend API Key for transactional emails
RESEND_API_KEY=
# LOGGING_LEVEL determines the verbosity of logs that the system will output.
# Available levels are:
# NONE - No logs will be output.
# ERROR - For logging error messages that indicate a failure in a specific operation.
# WARN - For logging potentially harmful situations that are not necessarily errors.
# INFO - For logging informational messages that highlight the progress of the application.
# DEBUG - For logging detailed information on the flow through the system, primarily used for debugging.
# TRACE - For logging more detailed information than the DEBUG level.
# Set LOGGING_LEVEL to one of the above options to control logging output.
LOGGING_LEVEL=INFO
docker-compose.yamlファイル(変更していません)
docker-compose.yaml
name: firecrawl
x-common-service: &common-service
build: apps/api
networks:
- backend
extra_hosts:
- "host.docker.internal:host-gateway"
services:
playwright-service:
build: apps/playwright-service
environment:
- PORT=3000
- PROXY_SERVER=${PROXY_SERVER}
- PROXY_USERNAME=${PROXY_USERNAME}
- PROXY_PASSWORD=${PROXY_PASSWORD}
- BLOCK_MEDIA=${BLOCK_MEDIA}
networks:
- backend
api:
<<: *common-service
environment:
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
REDIS_RATE_LIMIT_URL: ${REDIS_URL:-redis://redis:6379}
PLAYWRIGHT_MICROSERVICE_URL: ${PLAYWRIGHT_MICROSERVICE_URL:-http://playwright-service:3000}
USE_DB_AUTHENTICATION: ${USE_DB_AUTHENTICATION}
PORT: ${PORT:-3002}
NUM_WORKERS_PER_QUEUE: ${NUM_WORKERS_PER_QUEUE}
OPENAI_API_KEY: ${OPENAI_API_KEY}
OPENAI_BASE_URL: ${OPENAI_BASE_URL}
MODEL_NAME: ${MODEL_NAME:-gpt-4o}
SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL}
LLAMAPARSE_API_KEY: ${LLAMAPARSE_API_KEY}
LOGTAIL_KEY: ${LOGTAIL_KEY}
BULL_AUTH_KEY: ${BULL_AUTH_KEY}
TEST_API_KEY: ${TEST_API_KEY}
POSTHOG_API_KEY: ${POSTHOG_API_KEY}
POSTHOG_HOST: ${POSTHOG_HOST}
SUPABASE_ANON_TOKEN: ${SUPABASE_ANON_TOKEN}
SUPABASE_URL: ${SUPABASE_URL}
SUPABASE_SERVICE_TOKEN: ${SUPABASE_SERVICE_TOKEN}
SCRAPING_BEE_API_KEY: ${SCRAPING_BEE_API_KEY}
HOST: ${HOST:-0.0.0.0}
SELF_HOSTED_WEBHOOK_URL: ${SELF_HOSTED_WEBHOOK_URL}
LOGGING_LEVEL: ${LOGGING_LEVEL}
FLY_PROCESS_GROUP: app
depends_on:
- redis
- playwright-service
ports:
- "3002:3002"
command: [ "pnpm", "run", "start:production" ]
worker:
<<: *common-service
environment:
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
REDIS_RATE_LIMIT_URL: ${REDIS_URL:-redis://redis:6379}
PLAYWRIGHT_MICROSERVICE_URL: ${PLAYWRIGHT_MICROSERVICE_URL:-http://playwright-service:3000}
USE_DB_AUTHENTICATION: ${USE_DB_AUTHENTICATION}
PORT: ${PORT:-3002}
NUM_WORKERS_PER_QUEUE: ${NUM_WORKERS_PER_QUEUE}
OPENAI_API_KEY: ${OPENAI_API_KEY}
OPENAI_BASE_URL: ${OPENAI_BASE_URL}
MODEL_NAME: ${MODEL_NAME:-gpt-4o}
SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL}
LLAMAPARSE_API_KEY: ${LLAMAPARSE_API_KEY}
LOGTAIL_KEY: ${LOGTAIL_KEY}
BULL_AUTH_KEY: ${BULL_AUTH_KEY}
TEST_API_KEY: ${TEST_API_KEY}
POSTHOG_API_KEY: ${POSTHOG_API_KEY}
POSTHOG_HOST: ${POSTHOG_HOST}
SUPABASE_ANON_TOKEN: ${SUPABASE_ANON_TOKEN}
SUPABASE_URL: ${SUPABASE_URL}
SUPABASE_SERVICE_TOKEN: ${SUPABASE_SERVICE_TOKEN}
SCRAPING_BEE_API_KEY: ${SCRAPING_BEE_API_KEY}
HOST: ${HOST:-0.0.0.0}
SELF_HOSTED_WEBHOOK_URL: ${SELF_HOSTED_WEBHOOK_URL}
LOGGING_LEVEL: ${LOGGING_LEVEL}
FLY_PROCESS_GROUP: worker
depends_on:
- redis
- playwright-service
- api
command: [ "pnpm", "run", "workers" ]
redis:
image: redis:alpine
networks:
- backend
command: redis-server --bind 0.0.0.0
networks:
backend:
driver: bridge
Dify0.9.0でRAG検索できないエラー発生
ゴール
- 0.8.3から0.9.0にアップデートしたら知識獲得ツールでエラーが出るようになったのを対処する。
Run failed: '<' not supported between instances of 'NoneType' and 'NoneType'
まとめ
- 0.9.0から0.9.1にアップデートしたら治った。
参考リンク
- 公式リポジトリのIssueで見つけた同じ不具合
手順
- 0.8.3へのアップデート方法と同じなので割愛
Dify0.10.0にアップデートする
ゴール
- 0.10.0にアップデートする
まとめ
- スムーズにアップデートできた。データ引き継ぎも問題なし。
参考リンク
- 公式リポジトリのリリースノート
- 公式Doc: ファイルアップロード
- 公式Doc: ファイルアップロードを使用した記事理解アシスタントの構築方法
- 公式Blog: 新機能を利用してNotebookLMのようなAIポッドキャストアプリを作成する方法
手順
- いつもは単なる最新版へのupdateだが、今回は0.10.0bata2から0.10.0にする
# firecrawlフォルダに移動して、起動中の環境を落とす
docker-compose down
# いまのdocker-compose.yamlと.envファイルを別フォルダにコピー(バックアップ)する
# データバックアップはしない
# 最新バージョンをpullするために、現在のフォルダ状態をスタッシュ
git stash
# mainブランチに切り替え
git checkout main
# リモートのタグ情報を取得
git fetch --tags
# タグ確認
git tag
# ⇒0.10.0まであることを確認
# 最新バージョンまでpull
git pull origin main
# ===最新版にするだけなら不要(ここから)===
# 0.10.0タグに切り替え
git checkout tags/0.10.0
# ===最新版にするだけなら不要(ここまで)===
# docker-compose.yamlと.envファイルを書き換える(後述)
# コンテナを起動する
docker-compose up -d
⇒無事起動。
- docker-compose.yamlと.envファイルの変更点:
### 変更1箇所目 #################################
# ロードバランシングを有効化するため
x-shared-env: &shared-api-worker-env
LOG_LEVEL: ${LOG_LEVEL:-INFO}
LOG_FILE: ${LOG_FILE:-}
## 途中省略 ##
SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128}
SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128}
MODEL_LB_ENABLED: "true" # 追加(ロードバランシングを有効化)
### 変更2,3箇所目 #################################
# 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}
command: >
postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}'
-c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}'
-c 'work_mem=${POSTGRES_WORK_MEM:-4MB}'
-c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}'
-c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}'
volumes:
# - ./volumes/db/data:/var/lib/postgresql/data #オリジナル
- postgres_data:/var/lib/postgresql/data #追加(こうしないとエラーになるから)
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 1s
timeout: 3s
retries: 30
ports: #追加
- "5432:5432" #追加(SQLツールからの接続用)
### 変更4箇所目 #################################
volumes:
oradata:
dify_es01_data:
postgres_data: #追加
# ホストマシンのIPに変更
# ------------------------------
# Common Variables
# ------------------------------
CONSOLE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
CONSOLE_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
SERVICE_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_API_URL=http://161.93.+++.++:8880 #オリジナルは空欄
APP_WEB_URL=http://161.93.+++.++:8880 #オリジナルは空欄
FILES_URL=http://161.93.+++.++:8880 #オリジナルは空欄
# ------------------------------
# Docker Compose Service Expose Host Port Configurations
# ------------------------------
EXPOSE_NGINX_PORT=8880 #オリジナルは80
EXPOSE_NGINX_SSL_PORT=8443 #オリジナルは443
Dify0.11.0にアップデートする
ゴール
- 0.11.0にアップデートする
まとめ
- middlewareを稼働させたままアップデートしたら、ナレッジのドキュメント取り込みができなくなった。(過去にもあった現象)
- ⇒ middlewareを停止して、Difyを再起動したら治った。
- 並列イテレーションが実装されて、アプリが高速化した!
参考リンク
手順
- 0.10.0にアップデートしたときと同じなので割愛