1.はじめに
生成AIを複数のサービス(OpenAI、Azure OpenAI、Google Gemini、Anthropicなど)で利用していると、APIの契約管理が煩雑になります。
LLMは従量課金制で利用しており、月額5,000円以内に抑えたいのですが、契約が分散していると使用状況を把握しづらく、使いすぎてしまう傾向があります。
また、Azure OpenAIではTier不足で最新のAIモデルを使えないことも多々あります。
そこで、APIプロバイダーをOpenRouterで一元管理し、月々の費用管理と最新モデルの検証を容易にするため、ローコードチャットボットプラットフォームのDifyとそのOpenRouterプラグインを活用することにしました。
OpenRouterには2025年4月28日(土)時点で398個のLLMが存在します。プラグインは厳選された主要モデルのみを提供していますが、導入すれば手作業での追加なしに一括利用が可能です。もちろん、新しいモデルを手動で追加することもできます。
私はOpenRouterをRoo Code(VSCodeの拡張機能)、Dify、LibreChatから利用していますが、主にClaude-3.7-sonnetを使用しています。特にDifyはモデルの機能検証に非常に便利なツールです。
ただし、DifyのOpenRouterプラグインにはClaude-3.7-sonnetモデルがデフォルトで含まれていないため、手動設定が必要で少々面倒でした。そこで、Difyのプラグイン開発を調査し、
OpenRouterプラグインをClaude-3.7-sonnetにデフォルト対応させる作業に取り組んでみました。
2.OpenRouterプラグインとは
OpenRouterプラグインはDifyのAIモデル統合システムの一部で、2025年1月9日(木)にベータ版が公開され2025年2月に正式リリースされたDify v1.0.0以降のプラグインアーキテクチャに対応したプラグインです。このプラグインを使用することで、OpenRouterが提供する様々なAIモデル(GPT-4、Claude、Llama、Mistralなど)にアクセスできるようになります。
OpenRouterは複数のAIモデルへの統一的なAPIアクセスを提供するプラットフォームで、DifyのOpenRouterプラグインを利用することで1つのAPIプロバイダーに集約して利用できることから私の最近のお気に入りです。
- 単一のAPIキーで多様なAIモデルにアクセス可能
- モデル間のコスト比較や性能比較が容易
- 新しいAIモデルが追加された際の即時利用が可能
- 複数のモデルプロバイダーを統一的なインターフェースで操作可能
このプラグインはDifyのプラグインシステムの特徴である拡張性と柔軟性を活かし、新しいモデルの追加や既存モデルの更新を容易に行うことができる設計となっています。
3.エンハンス手順
DifyのOpenRouterプラグインのエンハンスの全体の流れは以下のとおりです。
GitHubでの公式プラグインのフォークから始まり、WSL環境での開発、ファイルの修正、そしてデバッグまでの流れで実施していきます。
項番 | 作業内容 | 説明 |
---|---|---|
1 | dify-official-pluginsのフォーク | GitHubでDifyの公式プラグインリポジトリ(dify-official-plugins)を自分のリポジトリにフォークし、開発用の作業コピーを作成します。 |
2 | Ubuntu(WSL)にクローン | フォークしたリポジトリをWindows Subsystem for Linux (WSL)上のUbuntuにクローンします。Windows環境ではエラーが発生するため、WSLでの作業が必要です。 |
3 | 開発ブランチの作成 | 機能追加用の新しい開発ブランチを作成し、メインブランチと分離して安全に開発を進められる環境を整えます。 |
4 | VSCodeの起動 | WSLにリモート接続したVSCodeを起動し、開発環境を整備します。作成した開発ブランチで作業することを確認します。 |
5 | ファイル修正計画 | 既存のPull requestsを参考に、どのファイルを修正・追加する必要があるか計画を立てます。必要な変更箇所を特定します。 |
6 | ファイルの追加・変更 | 計画に基づいて、必要なファイルの追加や既存ファイルの変更を実施します。新しいモデルの設定やパラメータを追加します。 |
7 | デバッグ | Difyのリモートデバッグ機能を使用して、追加・変更したプラグインの動作確認を行います。WSL環境で実施することが重要です。 |
3.1. dify-official-pluginsのフォーク
langgenius/dify-official-pluginsをGitHubの自分のリポジトリにフォークします。
フォークは自身のGitHubアカウントでサインインした後にlanggenius/dify-official-pluginsのトップページで「Fork」ボタンを押すだけです。
オリジナルのリポジトリ
https://github.com/langgenius/dify-official-plugins
フォークしたリポジトリ
https://github.com/potofo/dify-official-plugins
3.2.Ubuntu(WSL)にクローン
フォークしたpotofo/dify-official-pluginsをWindows11上のWSLで構築したUbuntuにクローンします。
この例では~/workspaceフォルダにpotofo/dify-official-plugins.gitからクローンしてdify-official-pluginsワークスペースを作成しています。
Windows11環境で開発すると、プラグインは接続できるのですが、LLMを利用するときに「Failed to read data from localhost:5003」エラーとなり操作できないためWSL上のUbuntuで作業する必要があります。
※git cloneはWSLにリモート接続したVSCodeで実施しても大丈夫です。画像を貼ると記事が読みにくくなるため、コマンドラインで説明します。
root@Ardbeg:~/workspace# git clone https://github.com/potofo/dify-official-plugins.git
Cloning into 'dify-official-plugins'...
remote: Enumerating objects: 8543, done.
remote: Counting objects: 100% (323/323), done.
remote: Compressing objects: 100% (207/207), done.
remote: Total 8543 (delta 222), reused 126 (delta 115), pack-reused 8220 (from 4)
Receiving objects: 100% (8543/8543), 55.76 MiB | 22.95 MiB/s, done.
Resolving deltas: 100% (4387/4387), done.
root@Ardbeg:~/workspace#
3.3.開発ブランチの作成
開発用のブランチ「Added-claude-3.7-sonnet-model-to-openrouter」をGitコマンドで作成します。
git checkout -b Added-claude-3.7-sonnet-model-to-openrouter
root@Ardbeg:~/workspace# cd dify-official-plugins
root@Ardbeg:~/workspace/dify-official-plugins# git branch -a
* main
remotes/origin/HEAD -> origin/main
remotes/origin/main
root@Ardbeg:~/workspace/dify-official-plugins# git checkout -b Added-claude-3.7-sonnet-model-to-openrouter
Switched to a new branch 'Added-claude-3.7-sonnet-model-to-openrouter'
root@Ardbeg:~/workspace/dify-official-plugins# git branch -a
* Added-claude-3.7-sonnet-model-to-openrouter
main
remotes/origin/HEAD -> origin/main
remotes/origin/main
root@Ardbeg:~/workspace/dify-official-plugins#
3.4. VSCodeの起動
Windows11にWSL拡張機能をインストールしておくと、WSL上でcodeと入力すると、WSL用のラッパーがダウンロードされ、Windows11環境で、WSLにリモート接続したVSCodeが開きます。
ここでWindows11でVSCodeが左下部分の接続先がWSLのUbuntu(例:WSL:Ubuntu-22.04)になっていることと、先ほど3.3で作成した「Added-claude-3.7-sonnet-model-to-openrouter」になっていることを確認します。
なっていない場合はアイコンをクリックすれば切り替えられます。
3.5. ファイル修正計画
残念なことにDifyのlanggenius/dify-official-plugins関係の仕様は全くありません。そこでlanggenius/dify-official-pluginsのPull requestsからモデルを追加する場合のファイル変更点を調べます。
openrouterのプラグインでは「#321 feat(openrouter): update openrouter models and version to 0.0.4」というopenai/o3-miniとopenai/o3-mini-2025-01-31を追加したときのPull requestを発見できました。
モデルを追加するには、どうやらmanifest.yamlと_position.yaml、モデルのパラメタを変更or追加すれば良さそうです。
No | Pull requestsされていたファイル | 変化点からの推測 |
---|---|---|
1 | models/openrouter/manifest.yaml | versionがどうやらプライグインバージョンのようです。 この例では0.0.3から0.0.4にバージョンアップしていました。 - version: 0.0.3 + version: 0.0.4 |
2 | models/openrouter/models/llm/_position.yaml | _position.yamlに管理しているモデルの名前が列挙されているようです このPull requestではo3-miniとo3-mini-2025-01-31が追加されていました。 + - openai/o3-mini + - openai/o3-mini-2025-01-31 - openai/o1-preview - openai/o1-mini - openai/gpt-4o |
3 | models/openrouter/models/llm/o3-mini-2025-01-31.yaml | _position.yamlに追加したo3-miniファイルのパラメタのようです |
4 | models/openrouter/models/llm/o3-mini.yaml | _position.yamlに追加したo3-mini-2025-01-31ファイルのパラメタのようです |
3.6. ファイルの追加・変更
上記の調査に基づいて今回は2つのファイルの変更と1つのファイルの追加を行います。
作業はAdded-claude-3.7-sonnet-model-to-openrouterブランチ上で行います。
No | Pull requestsされていたファイル | 変化点からの推測 |
---|---|---|
1 | models/openrouter/manifest.yaml | フォークした時のバージョンは0.0.7でしたので、0.0.8に変更しました。 - version: 0.0.7 + version: 0.0.8 |
2 | models/openrouter/models/llm/_position.yaml | _position.yamlに管理しているモデルの名前が列挙されているようです anthropic/claude-3.7-sonnetを追加しました。 + - anthropic/claude-3.7-sonnet - anthropic/claude-3.5-sonnet - anthropic/claude-3-haiku - anthropic/claude-3-opus - anthropic/claude-3-sonnet |
3 | models/openrouter/models/llm/claude-3.7-sonnet.yaml | claude-3.5-sonnetをベースにAnthropicのプラグインを参考にthinkingやthinking_budgetを追加して、3.5のトークンサイズを3.7用に書き換えました。 |
3.7. デバッグ
このデバッグは必ずUbuntu(WSL)から実施しないとWindows11では接続後にConnection Error となりました。
私はWindows11で最初やっていて4時間ほど沼りました。
デバッグはDifyのリモートデバッグ機能を使うのが簡単です。
リモートデバッグとはDifyのプラグインの開発環境とコミュニティ版、クラウド版のDifyを接続してデバッグする方法です。
流れは以下のとおりです。
①Difyのプラグイン画面を表示
Difyのトップ画面の「プラグイン」をクリックして、プラグイン画面を表示します。
②リモートサーバのアドレスとデバッグキーの取得
プラグイン画面の「プラグインをインストールする」の右側にあるプラグインのアイコンをクリックするとリモートサーバのアドレスとデバッグキーを表示します。
No | 項目 | 値 | 説明 |
---|---|---|---|
1 | リモートサーバのアドレス | localhost | Difyの.envファイルでEXPOSE_PLUGIN_DEBUGGING_HOSTとして定義されているDifyが動作するホスト名同一ホストではない場合は.envを変更する必要があります。 |
2 | リモートサーバのポート | 5003 | Difyの.envファイルでEXPOSE_PLUGIN_DEBUGGING_PORTとして定義されているplugin-daemon-1がデバッグ用として開いているTCPポート番号 |
3 | デバッグキー | bfafac9e-907e-4d73-8659-79b56bdcce3a | Difyに接続するためのデバッグキー |
③環境変数の設定
Ubuntu(WSL)にリモート接続しているVSCodeのターミナル画面でPython3.12の仮想環境を作成(python -m venv venv)して、仮想環境をアクティベート(source ./venv/bin/activate)して依存関係パッケージを導入します。
一般的にはrequirements.txtだけをインストールすればよいのですが、どういうわけかdify-pluginというパッケージが記述してないため、pipコマンドで手動でインストール(pip install dify-plugin)します。
root@Ardbeg:~/workspace/dify-official-plugins# python -m venv venv
root@Ardbeg:~/workspace/dify-official-plugins# source ./venv/bin/activate
((venv) ) root@Ardbeg:~/workspace/dify-official-plugins# pip install dify-plugin
Collecting dify-plugin
Using cached dify_plugin-0.2.1-py3-none-any.whl.metadata (1.4 kB)
Collecting Flask~=3.0.3 (from dify-plugin)
Using cached flask-3.0.3-py3-none-any.whl.metadata (3.2 kB)
Collecting Werkzeug~=3.0.3 (from dify-plugin)
Using cached werkzeug-3.0.6-py3-none-any.whl.metadata (3.7 kB)
... 省略 ...
Using cached h11-0.16.0-py3-none-any.whl (37 kB)
Using cached setuptools-79.0.1-py3-none-any.whl (1.3 MB)
Installing collected packages: pydub, dpkt, urllib3, typing-extensions, socksio, sniffio, setuptools, regex, pyyaml, python-dotenv, propcache, multidict, MarkupSafe, itsdangerous, idna, h11, greenlet, click, charset-normalizer, certifi, blinker, annotated-types, zope.interface, zope.event, yarl, Werkzeug, typing-inspection, requests, pydantic-core, Jinja2, httpcore, anyio, tiktoken, pydantic, httpx, gevent, Flask, pydantic_settings, dify-plugin
Successfully installed Flask-3.0.3 Jinja2-3.1.6 MarkupSafe-3.0.2 Werkzeug-3.0.6 annotated-types-0.7.0 anyio-4.9.0 blinker-1.9.0 certifi-2025.4.26 charset-normalizer-3.4.1 click-8.1.8 dify-plugin-0.2.1 dpkt-1.9.8 gevent-24.11.1 greenlet-3.2.1 h11-0.16.0 httpcore-1.0.9 httpx-0.27.2 idna-3.10 itsdangerous-2.2.0 multidict-6.4.3 propcache-0.3.1 pydantic-2.11.3 pydantic-core-2.33.1 pydantic_settings-2.9.1 pydub-0.25.1 python-dotenv-1.1.0 pyyaml-6.0.2 regex-2024.11.6 requests-2.32.3 setuptools-79.0.1 sniffio-1.3.1 socksio-1.0.0 tiktoken-0.8.0 typing-extensions-4.13.2 typing-inspection-0.4.0 urllib3-2.4.0 yarl-1.20.0 zope.event-5.0 zope.interface-7.2
((venv) ) root@Ardbeg:~/workspace/dify-official-plugins#
dify-official-pluginsは公式プラグインが一つのリポジトリで一緒に管理されているため、今回の目的のmodelのopenrouterプラグインのフォルダに移動し、ここで再度Pythonの依存関係パッケージを
インストールします(pip install -r requirements.txt)
((venv) ) root@Ardbeg:~/workspace/dify-official-plugins# cd models/openrouter
((venv) ) root@Ardbeg:~/workspace/dify-official-plugins/models/openrouter# pip install -r requirements.txt
Collecting dify_plugin~=0.0.1b76 (from -r requirements.txt (line 1))
Using cached dify_plugin-0.0.1b77-py3-none-any.whl.metadata (715 bytes)
Requirement already satisfied: Flask~=3.0.3 in /root/workspace/dify-official-plugins/venv/lib/python3.12/site-packages (from dify_plugin~=0.0.1b76->-r requirements.txt (line 1)) (3.0.3)
Requirement already satisfied: Werkzeug~=3.0.3 in /root/workspace/dify-official-plugins/venv/lib/python3.12/site-packages (from dify_plugin~=0.0.1b76->-r requirements.txt (line 1)) (3.0.6)
... 省略 ...
Requirement already satisfied: multidict>=4.0 in /root/workspace/dify-official-plugins/venv/lib/python3.12/site-packages (from yarl<2.0,>=1.9.4->dify_plugin~=0.0.1b76->-r requirements.txt (line 1)) (6.4.3)
Requirement already satisfied: propcache>=0.2.1 in /root/workspace/dify-official-plugins/venv/lib/python3.12/site-packages (from yarl<2.0,>=1.9.4->dify_plugin~=0.0.1b76->-r requirements.txt (line 1)) (0.3.1)
Requirement already satisfied: setuptools in /root/workspace/dify-official-plugins/venv/lib/python3.12/site-packages (from zope.event->gevent~=24.11.1->dify_plugin~=0.0.1b76->-r requirements.txt (line 1)) (79.0.1)
Using cached dify_plugin-0.0.1b77-py3-none-any.whl (303 kB)
Installing collected packages: dify_plugin
Attempting uninstall: dify_plugin
Found existing installation: dify_plugin 0.2.1
Uninstalling dify_plugin-0.2.1:
Successfully uninstalled dify_plugin-0.2.1
Successfully installed dify_plugin-0.0.1b77
((venv) ) root@Ardbeg:~/workspace/dify-official-plugins/models/openrouter#
次に/models/openrouterにある環境変数ファイル設定ファイルのサンプル(.env.exampleから.envファイルを作成します
((venv) ) root@Ardbeg:~/workspace/dify-official-plugins/models/openrouter# cp .env.example .env
最後に先ほど控えておいたリモートサーバのホスト名、ポート番号、デバッグキーを.envファイルの環境変数に設定します。
No | 環境変数 | 設定値 | 説明 |
---|---|---|---|
1 | INSTALL_METHOD | remote | インストール方法をリモートに設定 |
2 | REMOTE_INSTALL_HOST | localhost (*1) | Difyが起動しているリモートサーバーのホスト名 |
3 | REMOTE_INSTALL_PORT | 5003 | Difyが起動しているリモートサーバーのポート番号 |
4 | REMOTE_INSTALL_KEY | bfafac9e-907e-4d73-8659-79b56bdcce3a | デバッグ用の認証キー |
(*1)DifyとVSCodeが同一ホストの場合はlocalhostでも良いですが、クラウド版のDifyや別ホストのDifyと接続する場合はDifyの.envファイルでEXPOSE_PLUGIN_DEBUGGING_HOSTなどで設定しDifyの
「プラグインをインストールする」の右側にあるプラグインのアイコンで確認したホスト名を指定する必要があります。
④プラグインの起動
プラグインの起動はVSCodeのコンソールでpython -m mainコマンドを実行します。
「{"event": "log", "data": {"level": "INFO", "message": "Installed model: openrouter", "timestamp": 1745673981.8292854}}」と表示されてば起動成功です
(venv) PS Q:\OneDrive\Python\dify-official-plugins\models\openrouter> python -m main
{"event": "log", "data": {"level": "INFO", "message": "Installed model: openrouter", "timestamp": 1745654631.861939}}
※「During handling of the above exception, another exception occurred:」エラーが出て場合はデバッグキーが変わってしまっていますので、.envファイルのREMOTE_INSTALL_KEYを再設定してください
⑤Difyのプラグイン確認
リモートデバッグのDifyのプラグインが接続されたかはDifyのプラグイン画面で確認します。
プラグインを認識した後(DEBUGGING PLUGIN)という朱色の文字が目印です。
※同じ名前のプラグインがインストール済みの場合、どちらのプラグインが動作するのか挙動があやしくなるので、必ず、アンインストールしてから接続しましょう。
プラグイン画面で接続している「OpenRouter」プラグインをダブルクリックするとデフォルトで設定されるモデルが表示されます。
今回、追加したClaude-3.7-sonnetが表示されていれば正しく認識されています。
⑥プラグインを使ってみる
プラグインがリモートデバッグモードで認識されたら、[設定]⇒[モデルプロバイダー]からOpenRouterのAPIキーを設定し、シンプルなチャットフローを作成して、今回追加したモデルを選び使ってみます。
4.まとめ
今回は、DifyのOpenRouterプラグインを活用を通じて複数のAIモデルを効率的に管理する方法について考えてみました。
• OpenAI、Azure OpenAI、Google Gemini、Anthropicなど複数のAPIを一元管理することで、契約管理の煩雑さを解消
• 月額利用料の管理を容易にし、予算内(5,000円以内)での運用を実現
• Azure OpenAIのTier不足による最新モデル利用制限の課題を解決
• Claude-3.7-sonnetモデルをデフォルトで追加するための具体的な手順を提供
• 開発環境の整備から、デバッグ方法、実際の運用確認まで、段階的な実装手順を詳述
今後、プラグインで新しいモデルが存在しなかったときは、この手順でエンハンスしてみたいと考えています。
今回の変更内容は採用されるかは分かりませんが、#800でPull requestしたところ翌日には承認されマージされました。
5.参考URL