記事一覧
Dify ボットUI を探そう - 1(Open WebUI 導入)
Dify ボットUI を探そう - 2(dify2openai 導入)
------------------------------------------------
前回、チャットボットの UI として Open WebUI を導入しました。
この Open WebUI は OpenAI 互換の API クライアントとして動作しますが、そのままでは Dify チャットボットに接続できません。
そこで、Dify の独自 API にアクセスするための API プロキシサーバーである dify2openai を導入し、問題なく運用できるかどうかを簡単に検証してみます。
dify2openai
dify2openai は、Open WebUI から Dify チャットボットを利用できるようにするための仲介者です。
具体的には、以下の3つの役割を担います。
-
リクエスト データ形式の変換(OpenAI互換API仕様 ---> Dify独自API仕様)
Open WebUI からの OpenAI 互換 API リクエストを、Dify 独自の API リクエスト形式に変換します。
-
レスポンス データ形式の変換(Dify独自API仕様 ---> OpenAI互換API仕様)
Dify 独自の API からのレスポンスを、OpenAI 互換 API のレスポンス形式に変換します。
-
Dify未サポートの OpenAI互換API(/v1/models など)への応答
Dify がまだ対応していない OpenAI 互換 API (例: /v1/models) へのリクエストにも応答します。
Dify アプリは、様々な機能を「エンドポイント」と呼ばれる API で提供しています。dify2openai は、そのうちのいくつかのエンドポイントに対応しており、Open WebUI からチャットボットに接続して会話を行うことができます。
サポートしている API(エンドポイント)は下表のとおりです。
アプリ種別 | エンドポイント | 説明 |
---|---|---|
チャット or チャットフロー |
/chat-messages | メッセージ送信のリクエスト。 |
テキスト ジェネレーター |
/completion-messages | テキスト生成のリクエスト。 |
ワークフロー | /workflows/run | ワークフロー実行のリクエスト。 |
その他の情報については、下記のサイトを参照してください。
インストール
dify2openai は Dify や Open WebUI と同様に Dockerコンテナ で動作します。
① Git リポジトリのクローン
まず、dify2openai のソースコードをダウンロードします。
~/docker
フォルダへ移動してから、git clone
コマンドを実行してください。
$ ~/docker
$ git clone https://github.com/fatwang2/dify2openai.git
Cloning into 'dify2openai'...
remote: Enumerating objects: 270, done.
remote: Counting objects: 100% (70/70), done.
remote: Compressing objects: 100% (23/23), done.
remote: Total 270 (delta 57), reused 47 (delta 47), pack-reused 200 (from 2)
Receiving objects: 100% (270/270), 2.06 MiB | 3.13 MiB/s, done.
Resolving deltas: 100% (159/159), done.
実行すると、~/docker
フォルダ内にdify2openai
というフォルダが作成されます。
~/docker
├── dify
├── dify2openai <-- 作成されるフォルダ
└── open-webui-project
② コンテナイメージの作成(ビルド)
クローンしたソースコードから、Docker コンテナ用のイメージを作成します。
dify2openai
フォルダへ移動してから、docker build
コマンドを実行してください。
$ cd dify2openai
$ docker build -t dify2openai:latest .
[+] Building 2.3s (10/10) FINISHED docker:default
:(省略)
=> => naming to docker.io/library/dify2openai:latest 0.0s
ビルドが成功すると、dify2openai
というイメージが作成されます。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dify2openai latest 886a04c47d82 36 seconds ago 134MB
:(省略)
③ 環境設定ファイル .env
の作成
dify2openai の動作に必要な情報を設定する .env
ファイルを作成します。
$ cp .env.template .env
$ nano .env
変数名 | 必須 | 説明 |
---|---|---|
DIFY_API_URL | 〇 | 自分でホストする場合のDify API (例. https://api.dify.ai/v1 ) |
BOT_TYPE | 〇 | Difyボットの種類 (例. Chat ,Completion ,Workflow ) |
INPUT_VARIABLE | ワークフローの入力変数の名前 (例. query ,text ) |
|
OUTPUT_VARIABLE | ワークフローの出力変数の名前 (例. text ) |
|
MODELS_NAME |
/v1/models で出力するモデル名(省略時は dify ) |
上表の内容に従い、.env
ファイルの内容を修正します。
DIFY_API_URL=http://192.168.0.200:20080/v1
BOT_TYPE=Chat
INPUT_VARIABLE=
OUTPUT_VARIABLE=
MODELS_NAME=My Dify
-
DIFY_API_URL
Dify アプリの API にアクセスするための URL を設定します。
この URL は、dify2openai コンテナから Dify API が見えるアドレスを指定してください。
書式: {Dify API の URL}:{ポート番号}/v1
localhost や 127.0.0.1 は指定しないでください。
これらのアドレスは、dify2openai コンテナ自身を指します。そのため、Dify API が別のコンテナやホスト上で動作している場合、dify2openai コンテナは自分自身に接続しようとしてしまい、「接続先が見つからない」といったエラーが発生します。
代わりに、以下のいずれかを指定してください。
-
Dify が動作しているサーバーの IP アドレスまたはホスト名
例:Dify が 192.168.1.100 の 8080 ポートで公開されている場合:
http://192.168.1.100:8080/v1
-
Dify コンテナのサービス名(Dify コンテナが dify2openai と同じ Docker ネットワーク上にいる場合)
例:Dify コンテナのサービス名が dify で、内部ポートが
80 の場合 (Docker Composeなどで同じネットワークにいる場合):
http://dify:80/v1
-
BOT_TYPE
Dify アプリケーションの種別を指定します。
「チャットボット」や「チャットフロー」のときは Chat と記述します。
-
MODELS_NAME
OpenAI 互換 API の/v1/models
エンドポイントで返却されるモデル名を指定します。
複数のモデル名を記述することはできません。
④ docker-compose.yml の修正
docker compose
コマンドで使用する設定ファイル docker-compose.yml
を準備します。
クローンしたソースコードに含まれる docker-compose.yml
を、以下の内容に修正して使用します。
$ nano docker-compose.yml
修正前
version: '3.5'
services:
dify2openai:
container_name: dify2openai
build:
context: .
dockerfile: Dockerfile
network_mode: bridge
ports:
- "3000:3000"
restart: always
environment:
- DIFY_API_URL=https://api.dify.ai/v1
- BOT_TYPE=Chat
修正後
services:
dify2openai:
container_name: dify2openai
build:
context: .
dockerfile: Dockerfile
ports:
- "20001:3000"
restart: always
env_file: .env
-
version: '3.5' の削除
最近のdocker compose
コマンドでは、version
指定は必須ではなく、省略されることが一般的です。
-
network_mode: bridge の削除
network_mode: bridge
は、Dockerコンテナのデフォルトのネットワークモードです。
明示的に記述する必要がなく、設定を簡潔にするため削除します。
-
ports の変更
ports: - "20001:3000"
は、ホストOSのポート20001
を、コンテナ内部のポート3000
にマッピングすることを意味します。
dify2openai アプリケーションはコンテナ内で3000
番ポートを使用しますが、20001
番のような別のポートを割り当てることが推奨されます。
-
environment から env_file: .env への変更
environment
で直接環境変数を記述する代わりに、.env
という外部ファイルから環境変数を読み込むように変更します。
⑤ Dockerコンテナの起動
修正した docker-compose.yml
を使って、dify2openai
コンテナを起動します。
docker compose up -d
コマンドを実行してください。
$ docker compose up -d
Compose can now delegate builds to bake for better performance.
To do so, set COMPOSE_BAKE=true.
[+] Building 1.8s (11/11) FINISHED docker:default
:(省略)
=> [dify2openai] resolving provenance for metadata file 0.0s
[+] Running 3/3
✔ dify2openai Built 0.0s
✔ Network dify2openai_default Created 0.1s
✔ Container dify2openai Started 0.2s
docker ps コマンドで、現在稼働中のDockerコンテナを確認できます。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f11f8b89d251 dify2openai-dify2openai "docker-entrypoint.s…" 20 seconds ago Up 20 seconds 0.0.0.0:20001->3000/tcp, [::]:20001->3000/tcp dify2openai
:(省略)
接続テスト
dify2openai のコンテナ起動が完了したら、Difyで作成したチャットフローアプリケーションとOpen WebUIの接続テストを行います。
Difyアプリの準備
まず、Dify画面で接続確認用のチャットフローアプリケーションを作成します。
① 回答ブロック
Open WebUIへの応答がこのDifyアプリからのものであることを明確にするため、回答ブロックの「応答」欄の1行目に「★テスト2(チャットフロー)★」という固定文字列を追記します。

② API キーの作成
Open WebUIからこのDifyアプリのAPIへアクセスするために、APIキーを作成します。
Dify 画面の左ペインから「APIアクセス」を選択し、画面右上に表示される [APIキー] をクリックします。

[新しいシークレットキーを作成] ボタンをクリックします。

表示されたAPIシークレットキーをコピーし、安全な場所に控えておいてください。
このキーは後ほどOpen WebUIの設定画面で入力します。

「OK」ボタンをクリックしてダイアログを閉じます。作成したAPIシークレットキーは、「APIアクセス」ページでいつでも確認できます。
右側の「メモ帳」アイコンをクリックすると、再度コピーすることが可能です。
(必要に応じて複数のキーを作成することもできます。)

Open WebUI での設定
Open WebUI の「接続(Connection)」機能では、大規模言語モデル(LLM)や外部サービス(例: Difyアプリ)と連携するための情報を登録します。登録された接続は「接続可能なモデル」として扱われ、チャット画面のモデル選択リストに表示され、利用できるようになります。
登録する内容は下表のとおりです。
項目名 | 設定値 | 説明 |
---|---|---|
URL | http://192.168.0.200:20001/v1 | dify2openai へ接続するための URL。 |
キー | 発行したAPIシークレットキー | 接続先Difyアプリで発行したキー。 |
Prefix ID | 任意の識別文字列 | 接続先Difyアプリを識別するための接頭辞。 モデル選択リストの項目名に使用される。 |
① 接続情報の追加
管理者パネルを開き、[設定] - [接続] を選択。
「OpenAI API接続の管理」の右側の [+] をクリックします。

② 接続情報の編集・保存
「URL」「キー」「Prefix ID」に、Difyアプリへの接続情報を入力します。
「キー」には DifyアプリのAPIシークレットキー を入力します。

入力後、緑のスライドスイッチ 左横の テスト接続アイコン(矢印アイコン)をクリックします。

クリックと同時に dify2openai への接続が試行されます。接続に成功すると 画面右上に 緑色の「接続成功」を示すポップアップが表示されます。

最後に [保存] ボタンをクリックして、接続情報を登録してください。
③ モデル情報の確認
[設定] - [モデル] を選択すると、Open WebUI から利用可能なモデルが表示されます。
下図では二つのモデルが表示されていますが、その名前は次の書式で表示されています。
表示されるモデルの名前は、以下の書式で構成されています。
書式: {接続情報の Prefix ID}
.{.env に記述した MODELS_NAME}

この例では、「Test1」と「Test2」が、先ほど接続情報で設定した Prefix ID にあたります。これにより、異なるDifyアプリ(または異なる設定のDifyアプリ)からのモデルを区別できます。
「.My Dify」の部分は、.env
ファイル)で定義されているモデルの識別名です。
ユーザーは、この一覧から利用したいモデルを選択して、AIとの会話(チャット)を開始できます。
メッセージの送信
Open WebUI 画面左上の「新しいチャット」をクリックします。
チャット画面に切り替わったら、画面上部の「モデル選択リスト」をクリックしてください。

事前に設定したモデル名が表示されるので、その中から「Test2.My Dify」を選択します。
選択したら、"こんにちは" と入力してみましょう。

次の3行が表示されました。
★テスト2(チャットフロー)★
こんにちは。
[どのようなお手伝いをしましょうか?] (What can I help you with?)
回答ブロックの「応答」欄の1行目に設定した 「★テスト2(チャットフロー)★」が含まれていますので、Dify アプリ(チャットフロー)と正常にやり取りできているようです。
業務運用が可能か否か
以下は、現時点(2025年7月14日)での私自身の独断に基づく所感 です。
Open WebUI の機能をより深く理解することで、ここで挙げた課題が改善される可能性もあります。
Q1. テキストメッセージのやり取りは可能?
A1. 基本的には可能です。
Open WebUIと連携するモデルのデフォルト設定や、Open WebUIのシステムプロンプトが英語である場合、回答やチャット履歴のタイトルが英語になることがあります。これは、Open WebUIの設定画面から日本語のカスタムプロンプトを登録することで改善可能です。
Q2. ファイルを添付することは可能?
A2. ファイルによっては失敗する場合があります
Open WebUIのチャット画面からファイルをアップロードする操作は可能ですが、その内容をDifyアプリへ適切に連携できていません。
Open WebUIはファイルを読み込み、その内容を文字列としてメッセージに含めて送信しようとしているようです。しかし、Difyにはファイルアップロード専用のAPIが存在するため、この連携がうまくいっていません。
ファイルを正しく文字列化してDifyが処理できるようにするか、DifyのファイルアップロードAPIをOpen WebUI側から呼び出すように改修することで、実現できる可能性があります。
Q3. 会話ログは Dify で確認できる?
A3. Difyで会話ログを確認することは可能ですが、以下の2点において課題が見られます。
① ユーザー名がすべて「apiuser」と表示される
Difyのログでは、すべてのユーザーが「apiuser」として記録されます。これは、実際のユーザーを特定できないという運用上の課題となります。

この原因は、Open WebUIとDifyを連携させるためのプロキシツールであるdify2openaiのソースコード(app.js
ファイル)にあります。DifyのAPIを呼び出す際のリクエストボディに、ユーザー名としてapiuserがハードコーディングされているためです。

本来であればOpen WebUIのログインユーザー名がDifyに連携されることが望ましいですが、これを実現するにはdify2openaiの改修が必要です。
また、Open WebUIからdify2openaiへログインユーザー名が渡されているかどうかの確認や、Open WebUI側のリクエストボディの構造も検証する必要があるでしょう。この問題の解決には、ある程度の開発工数が見込まれます。
② 一つの会話が4分割される
Difyの「ログ&アナウンス」画面では、DifyアプリのWeb UIから行われたチャットのやり取りは「一つの会話(チャット)」としてグループ化され、メッセージ数が加算されて表示されます。

しかし、Open WebUIからDifyへメッセージを送信した場合、Open WebUIの画面上では連続した会話として表示されていても、Difyのログではそれぞれのメッセージが独立した「1個のメッセージ」として記録されます。

これは、Difyが内部で管理する「会話(チャット)グループ」とOpen WebUIが管理する会話のコンテキストが連携されていないためです。
Open WebUIはメッセージ送信時に会話履歴をDifyに渡していますが、Dify側ではこれを既存の会話グループに紐づけず、個別のメッセージとして処理していると考えられます。
この状態では、Difyのフロー処理において会話の連続性が正しく認識されず、文脈に基づいた適切な応答や後続処理に影響を与える可能性があります。
Difyの会話グループとOpen WebUIの会話コンテキストを連携させるには、相応の改修作業が必要となるでしょう。
終わりに
テキストメッセージの送受信は問題なく行えるようです。
しかし、添付ファイルの内容が正しく認識されない点は、機能面で大きな課題となります。この問題を解決するためには、ファイルを正確にテキストデータに変換する専用ツール(例: Apache Tika)の導入を検討する必要があるかもしれません。
また、Dify内で一連の会話(チャット)が適切にグループ化されないことも、Difyアプリケーションのフロー設計において制約が生じる可能性があります。
open WebUIのFunctions(パイプライン)機能による拡張なども含め、このまま試行錯誤を続けるべきか、あるいは別の解決策を模索すべきか、思案のしどころです。