0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Dify ボットUI を探そう - 2(dify2openai 導入)

Posted at

記事一覧
 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

localhost127.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 への接続が試行されます。接続に成功すると 画面右上に 緑色の「接続成功」を示すポップアップが表示されます。

最後に [保存] ボタンをクリックして、接続情報を登録してください。

「OpenAI API接続の管理」の一覧では「URL」しか確認できません。
複数のDifyアプリへの接続情報を登録すると すべて同じ「URL」表記となり、どの接続がどのDifyアプリに対応しているかを判別しづらくなります

そのため、Prefix ID を工夫して、モデル選択時にどのDifyアプリのモデルか分かりやすくすることをおすすめします。

③ モデル情報の確認

[設定] - [モデル] を選択すると、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(パイプライン)機能による拡張なども含め、このまま試行錯誤を続けるべきか、あるいは別の解決策を模索すべきか、思案のしどころです。

0
0
0

Register as a new user and use Qiita more conveniently

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?