ノーコード/ローコードでAIアプリを構築できるオープンソースプラットフォーム「Dify」を活用して、AIワークフローを構築する本連載。第4回は、プラグインを自作して、Dify内で利用する方法を紹介します。前回までの内容を踏まえ、ユーザー入力からURLを抽出するツールを自作し、チャットフローに組み込んでみましょう。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
連載:生成AI×ノーコードでつくる!Difyワークフロー構築入門
本連載のサンプルコード(DSLのYAMLファイル)はGitHubで公開しています。必要な場合はこちらからダウンロードしてみてください。
第1回ではWebページやPDFのスクレイピングと要約、第2回ではワークフローをツール化しチャットフローで活用する方法を紹介しました。前回(第3回)は質問分類器やイテレーションなどのブロックを活用し、複数のWebページの要約結果をまとめてユーザー指定の形式(PDF、Wordなど)で返す自動化フローを作成しました。
第4回となる今回は、プラグインを自作して、Dify内で利用する方法を紹介します。これまでLLM(大規模言語モデル)で抽出していたURLを、正規表現で抽出するツールを自作してみましょう。
なお、本連載で作成したフローのDify構成ファイル(DSLのYAMLファイル)は、GitHubリポジトリで公開していますので、参考にしてください。また、今回作成するURL抽出ツールのコードは、こちらのGitHubリポジトリで公開しています。
Difyのプラグインは、Difyの機能を拡張するためのモジュールです。ツールやデータソース、AI(人工知能)モデルプロバイダーなどを自作することで、Dify単体や公式プラグイン単体ではできない高度な処理が可能になります。今回は、ツールタイプのプラグインを自作してみましょう。
本稿では以下の環境を想定します。
Difyのプラグイン開発には、Dify Plugin Daemonというツールが必要です。Dify Plugin DaemonのGitHubリポジトリから、OSとアーキテクチャに合ったバイナリをダウンロードしてインストールしてください。今回はWSL2のUbuntu環境のためLinux AMD64版「dify-plugin-linux-amd64」を使用します。
ここではDify Plugin Daemonをグローバルインストールしています。ダウンロードしたバイナリを直接実行しても問題ありませんが、個人の開発環境では"dify"だけでコマンドが実行できた方が便利でしょう。
# Dify Plugin Daemonのバイナリダウンロード ~$ curl -o dify -L https://github.com/langgenius/dify-plugin-daemon/releases/download/0.5.3/dify-plugin-linux-amd64 # バイナリに実行権限を付与して/usr/local/binに移動 ~$ chmod +x dify ~$ sudo mv dify /usr/local/bin/ # バージョン確認 ~$ dify version v0.5.3
dify plugin initコマンドを実行して、プラグインのテンプレートを作成します。必要事項を入力してEnterを押して進めます(少しインタフェースが分かりづらいので、間違えたら[Ctrl]+[C]キーで中止して、やり直してください)。ここでは以下のように入力しました。
テンプレートの選択で「tool」を選ぶと、ツールタイプのプラグインのテンプレートが作成されます。プラグインの権限設定については幾つかの選択肢が表示されますが、今回はツールタイプのプラグインを作成するので、Tools/Enabledのみを選択してください。Difyの最小バージョン要件は、特に指定がなければ指定なしで問題ありません。
plugin created successfullyと表示されたら、完了です。url_extractorというディレクトリが作成され、その中にプラグインのコードや設定ファイルが入っています(図1)。実装したときに差分が追えるよう、url_extractorディレクトリで初期状態のGitコミットを作成しておくとよいでしょう。
次にPythonの仮想環境を作成し、依存関係をインストールします。今回はPython 3.12を使用します(Dify公式手順で3.12が使用されているため)。Pythonがインストールされていない場合は、aptや公式サイトからインストールしてください。
なお、dify plugin initコマンドを実行するとデフォルトでrequirements.txtが生成されます。本稿ではvenvで作成した仮想環境内でpipを使用して依存関係をインストールしますが、お好みの方法で構いません。
# 仮想環境を作成して有効化(python3.12コマンドは環境によって適切なものを使用してください) ~/url_extractor$ python3.12 -m venv .venv ~/url_extractor$ source .venv/bin/activate # 以下は仮想環境が有効になった状態(プロンプトの先頭に(.venv)が表示されている) (.venv) ~/url_extractor$ python --version Python 3.12.3 (.venv) ~/url_extractor$ pip install --upgrade pip 〜中略〜 Successfully installed Flask-3.0.3 Jinja2-3.1.6 MarkupSafe-3.0.3 Werkzeug-3.0.6 annotated-types-0.7.0 〜省略〜
さて、いよいよツールを開発しましょう。今回はツールのインタフェース(入出力)の仕様を以下のようにします。
Difyのツール定義では、インタフェース仕様をYAMLファイルに記述します。テンプレートで作成されたtools/url_extractor.yamlファイルを開いて、リスト3のように編集してください。
〜省略〜
parameters:
- name: input
type: string
required: true
label:
en_US: Input string
zh_Hans: 输入字符串
ja_JP: 入力文字列
form: llm
output_schema:
type: object
properties:
urls:
type: array
description: "抽出されたURLのリスト"
items:
type: string
count:
type: integer
description: "抽出されたURLの数"
〜省略〜
parametersセクションで、ツールの入力パラメーターのスキーマを記述します。先述の仕様通り、inputという名前の文字列型の必須パラメーターを定義しています。パラメーターの詳細は公式ドキュメントを参照してください。
出力のスキーマはoutput_schemaセクションで記述します。今回のツールでは、urlsという名前の文字列の配列と、countという整数を定義しています。
次に、ツールの実装を行います。tools/url_extractor.pyファイルを開いて、サンプルコードの内容に変更してください。
class UrlExtractorTool(Tool):
# 〜〜〜省略〜〜〜
# ツールが呼び出されたときの実装
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
# ツールの入力パラメーターからテキストを取得
input_text = str(tool_parameters.get("input") or "")
# テキストから URL を抽出
urls = self._extract_urls(input_text)
count = len(urls)
# 抽出された URL とその数をツールの出力として返す
yield self.create_variable_message("urls", urls)
yield self.create_variable_message("count", count)
リスト4はツールが呼び出されたときのコア処理の実装(_invokeメソッド)です。_invokeメソッドの引数tool_parametersは、ツールの入力パラメーターが格納されたディクショナリです。ここからinputパラメーターを取得します。URL抽出処理を経て、最後にyieldでツールの出力を返します。出力(戻り値)を返すメソッド(公式ドキュメント参照)は幾つかありますが、ここではcreate_variable_messageを使用して、ツールの出力変数としてurlsとcountを返すようにしています。これにより後続のノードでツールの出力を変数として参照しやすくなります。
なお、今回のコードはあくまでサンプルですが、正規表現で抽出したURLを重複排除してリストにまとめ、ツールの出力として返すようにしています。
作成したツール(プラグイン)を使用するためには、Difyにインストールする必要があります。インストール方法としては、以下の3つがあります。
どの方法が適しているかは公式ドキュメントに推奨事項が記載されているので、参考にしてください。今回は、ローカルファイルからのインストール方法を紹介します。
次に、作成したプラグインをDifyにインストールするためのパッケージを作成します。プラグインディレクトリの上位ディレクトリでdify plugin packageコマンドを実行してください。
~$ dify plugin package ./url_extractor/ 2026/03/02 17:36:02 package.go:35: [INFO]plugin packaged successfully, output path: url_extractor.difypkg ~$ ll url_extractor.difypkg -rw-r--r-- 1 hogehoge hogehoge 11190 Mar 14 17:36 url_extractor.difypkg
上記のようにplugin packaged successfullyと表示されれば、*.difypkgというインストール用のパッケージファイルが作成されています。
作成したパッケージファイル(*.difypkgファイル)をDifyにインストールします。Difyのプラグイン画面を開き、「プラグインをインストールする」→「ローカルパッケージファイル」をクリックし、生成されたurl_extractor.difypkgファイルを選択します(図2)。
インストール画面が表示されるので、内容を確認して、「インストール」ボタンをクリックします(図3)。
インストールには数分かかることがあります。インストールが完了すると、進捗表示が「installed」になり、プラグイン一覧にも「LOCAL PLUGIN」として表示されます(図4)。
さて、早速自作ツールをフローに組み込んでみましょう。前回作成したチャットフロー「Webページ要約ボット v2」を開いて、空いたスペースで右クリックし、「ブロックを追加」→「ツール」→「プラグイン」とたどると、url_extractorが表示されるはずです。これを選択してURL抽出ツールを追加してください(図5)。
URL抽出のLLMノードを削除し、代わりにURL抽出ツールを配置します(図6)。
URL抽出ツールの「入力文字列(inputパラメーター)」にユーザー入力ノードのqueryを指定します。「出力変数」のところにツール定義に記載したcountとurlsが表示されていることが確認できます(図7)。
また、後続の「IF/ELSE」ノードのIF条件と「イテレーション」の入力を、URL抽出ツールの出力であるurlsを参照するように変更します(図8)。
その他の部分を変更する必要はないので、プレビュー実行で動作を確認してみましょう。
ユーザー入力にURLを含むテキストを入力すると、URL抽出ツールがURLを抽出し、その後の処理が正しく実行されます。
リスト6のようなMarkdown形式の文字列を入力してみたところ、無事URLが抽出され、2記事の要約がPDFとして出力されました(図9)。
要約してPDFにして - [ノーコードで実現! DifyでカスタマーサポートAIチャットbotを作成する:「生成AI」×ノーコードツール「Dify」で学ぶ、チャットbot構築のいろは(1) - @IT](https://atmarkit.itmedia.co.jp/ait/articles/2506/19/news001.html) - [こんなに簡単 DifyでカスタマーサポートAIチャットbotをWebサイトに組み込む方法:「生成AI」×ノーコードツール「Dify」で学ぶ、チャットbot構築のいろは(2) - @IT](https://atmarkit.itmedia.co.jp/ait/articles/2507/17/news001.html)
フローの実行結果を詳しく見ると、URL抽出ツールが入力テキストから2つのURLを抽出していることが分かります。また、実行時間が100ミリ秒程度になっており、LLMノードでは数秒かかっていた処理が高速化されたことが分かります(図10)。
開発中は、Dify Plugin Daemonを起動しておくことで、Dify上でツールの変更を反映させながら動作確認ができます。.envに設定するデバッグ実行用のキーは、Difyのプラグイン画面のデバッグ(虫)ボタンをクリックすると表示されるUUIDです(図11)。
# .env ファイルの作成
(.venv) ~/url_extractor$ cp -a .env.example .env
# vi などで .env ファイルを開いて、REMOTE_INSTALL_KEYを設定
# 開発環境を起動
(.venv) ~/url_extractor$ python -m main
{"event": "log", "data": {"level": "INFO", "message": "Installed tool: url_extractor", "timestamp": 1773467998.3825657}}
INFO:dify_plugin.plugin:Installed tool: url_extractor
正しく起動できれば、Difyのプラグイン画面にDEBUGGING PLUGINとして表示され、パッケージからインストールしたときと同様に、ツール選択画面に表示されるようになります。
ただし、本稿執筆時にデバッグ実行を試みたところ、Dify側で「no available node, plugin runtime not found」というエラーが発生して動作が停止してしまい、正常に開発を進めることができませんでした。コミュニティーにも同様の報告があるものの、筆者が以前試した際には問題なく動作していました。そのため、筆者固有の環境に起因する問題か、あるいは何らかの一時的な不具合である可能性があります。
今回はDifyのプラグインを自作して、チャットフローに組み込む方法を紹介しました。YAMLファイルでインタフェースを定義し、Pythonで実装するだけで、Difyから簡単に呼び出せるカスタムツールを作成できます。
今回のURL抽出のような簡単な処理であれば、「コード実行」ブロックでも実現可能です。しかし、繰り返し利用するような処理をツール化することで、再利用性が高まるだけでなく、入出力が明確になるためフローの設計もシンプルになります。また、カスタムツールはフローに配置できるだけでなく、AIエージェントから呼び出すこともできるため、より柔軟な活用が可能です。
本稿では「ツール」のみを取り上げましたが、Difyのプラグインには「データソース」や「AIモデルプロバイダー」などのタイプもあり、これらも同様に自作してDifyに組み込むことができます。
本連載では、実践的なフローを構築する上で必要となるさまざまなブロックやツールを組み合わせ、チャットフローを作り上げてきました。マーケットプレイスで公開されているプラグインや今回のような自作プラグインを活用することで、さらに多彩な処理をフローに組み込むことが可能です。Difyや生成AIは急速に進化しているため、今後も可能性を広げる新機能やプラグインが続々と登場するでしょう。実際のユースケースに応用しやすい内容を中心に取り上げてきましたので、ぜひご自身のアイデアを踏まえてさまざまな効率化に活用してみてください。
WINGSプロジェクト 山田研二(ヤマダ ケンジ)
株式会社MSEN CTO(https://msen.jp/)。高校卒業後、大阪大学の研究所で働きながらプログラミングやWebデザインをはじめ、以後20年以上、Webサイト制作や業務システムの構築を手掛けている。フリーソフトも幾つか公開している。好きな言語はC#とTypeScript、趣味は旅行。
・GitHubアカウント(https://github.com/kenzauros)
WINGSプロジェクト
有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティー(代表山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手掛ける。2021年10月時点での登録メンバーは55人で、現在も執筆メンバーを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。
・サーバーサイド技術の学び舎 - WINGS(https://wings.msn.to/)
・RSS(https://wings.msn.to/contents/rss.php)
・X: @WingsPro_info(https://x.com/WingsPro_info)
・Facebook(https://www.facebook.com/WINGSProject)
Copyright © ITmedia, Inc. All Rights Reserved.
編集部からのお知らせ