このドキュメントでは、Extensionタイプのプラグインを迅速に開発し、プラグイン開発の基本的な流れを理解するのに役立つように解説します。
事前準備
プラグイン開発の足場ツールの準備方法については、開発ツールの初期化を参照してください。
新規プロジェクトの作成
現在のパスで、足場コマンドラインツールを実行し、新しいDifyプラグインプロジェクトを作成します。
./dify-plugin-darwin-arm64 plugin init
このバイナリファイルをdify
にリネームし、/usr/local/bin
パスにコピーした場合、以下のコマンドを実行して新しいプラグインプロジェクトを作成できます。
プラグイン情報の入力
表示される指示に従って、プラグイン名、作者情報、プラグインの説明を設定してください。チームで共同作業する場合は、作者を組織名にすることも可能です。
プラグイン名の長さは1〜128文字で、文字、数字、ダッシュ、アンダースコアのみを使用できます。
入力が完了したら、プラグイン開発言語の選択でPythonを選択してください。
3. プラグインタイプの選択とプロジェクトテンプレートの初期化
足場ツール内のすべてのテンプレートには、完全なコードプロジェクトが用意されています。このドキュメントでは、例としてExtension
タイプのプラグインテンプレートを使用します。プラグインに精通している開発者であれば、テンプレートを使用せずに、APIドキュメントを参照して様々なタイプのプラグイン開発を進めることができます。
プラグイン権限の設定
プラグインがDifyメインプラットフォームに正常に接続するためには、Difyメインプラットフォームの権限を読み取る必要があります。このサンプルプラグインには、以下の権限を付与してください。
永続ストレージを有効にし、デフォルトサイズのストレージを割り当てる
ターミナル内で方向キーを使って権限を選択し、「Tab」キーで権限を付与します。
すべての権限項目をチェックした後、Enterキーを押してプラグインの作成を完了します。システムが自動的にプラグインのプロジェクトコードを生成します。
プラグインの基本ファイル構造は以下の通りです。
.
├── GUIDE.md
├── README.md
├── _assets
│ └── icon.svg
├── endpoints
│ ├── your-project.py
│ └── your-project.yaml
├── group
│ └── your-project.yaml
├── main.py
├── manifest.yaml
└── requirements.txt
GUIDE.md
: プラグインの作成プロセスを説明する簡単なチュートリアルです。
README.md
: 現在のプラグインに関する情報です。このプラグインの概要や使用方法をこのファイルに記述する必要があります。
_assets
: 現在のプラグインに関連するすべてのマルチメディアファイルを保存します。
endpoints
: CLIのガイドに従って作成されるExtension
タイプのプラグインテンプレートです。このディレクトリには、すべてのエンドポイントの機能実装コードが格納されています。
group
: 秘密鍵のタイプ、多言語設定、API定義ファイルのパスを指定します。
main.py
: プロジェクト全体のエントリポイントとなるファイルです。
manifest.yaml
: プラグインの基本設定ファイルです。このプラグインに必要な権限、拡張機能の種類などの設定情報が含まれています。
requirements.txt
: Python環境の依存関係を記述します。
プラグインの開発
1. プラグインのリクエストエンドポイントの定義
endpoints/test_plugin.yaml
を編集し、以下のコードを参考に変更してください。
path: "/neko"
method: "GET"
extra:
python:
source: "endpoints/test_plugin.py"
このコードは、プラグインのエントリパスを/neko
、リクエストメソッドをGETタイプとして定義するものです。プラグインの機能実装コードは、endpoints/test_plugin.py
ファイルに記述します。
2. プラグイン機能の作成
プラグインの機能:プラグインサービスをリクエストし、猫の情報を出力します。
プラグインの機能実装コードをendpoints/test_plugin.py
ファイルに記述します。以下のサンプルコードを参考にしてください。
from typing import Mapping
from werkzeug import Request, Response
from flask import Flask, render_template_string
from dify_plugin import Endpoint
app = Flask(__name__)
class NekoEndpoint(Endpoint):
def _invoke(self, r: Request, values: Mapping, settings: Mapping) -> Response:
ascii_art = '''
⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛⬛️⬜️⬜️⬜️⬜️⬜⬜️⬜️️
🟥🟥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🟥🟥🟥🟥🟥🟥🟥🟥⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬛🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧⬛️⬜️⬜️⬜️⬜️⬜⬜️️
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥⬛️🥧🥧🥧💟💟💟💟💟💟💟💟💟💟💟💟💟🥧🥧🥧⬛️⬜️⬜️⬜️⬜⬜️️
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥⬛️🥧🥧💟💟💟💟💟💟🍓💟💟🍓💟💟💟💟💟🥧🥧⬛️⬜️⬜️⬜️⬜️⬜️️
🟧🟧🟥🟥🟥🟥🟥🟥🟥🟥🟧🟧🟧🟧🟧🟧🟧🟧🟥🟥🟥🟥🟥🟥🟥⬛🥧💟💟🍓💟💟💟💟💟💟💟💟💟💟💟💟💟💟🥧⬛️⬜️⬜️⬜️⬜⬜️️
🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧⬛️🥧💟💟💟💟💟💟💟💟💟💟⬛️⬛️💟💟🍓💟💟🥧⬛️⬜️⬛️️⬛️️⬜⬜️️
🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧🟧⬛️🥧💟💟💟💟💟💟💟💟💟⬛️🌫🌫⬛💟💟💟💟🥧⬛️⬛️🌫🌫⬛⬜️️
🟨🟨🟧🟧🟧🟧🟧🟧🟧🟧🟨🟨🟨🟨🟨🟨🟨🟨🟧⬛️⬛️⬛️⬛️🟧🟧⬛️🥧💟💟💟💟💟💟🍓💟💟⬛️🌫🌫🌫⬛💟💟💟🥧⬛️🌫🌫🌫⬛⬜️️
🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨⬛️🌫🌫⬛️⬛️🟧⬛️🥧💟💟💟💟💟💟💟💟💟⬛️🌫🌫🌫🌫⬛️⬛️⬛️⬛️🌫🌫🌫🌫⬛⬜️️
🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨⬛️⬛️🌫🌫⬛️⬛️⬛️🥧💟💟💟🍓💟💟💟💟💟⬛️🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫⬛⬜️️
🟩🟩🟨🟨🟨🟨🟨🟨🟨🟨🟩🟩🟩🟩🟩🟩🟩🟩🟨🟨⬛⬛️🌫🌫⬛️⬛️🥧💟💟💟💟💟💟💟🍓⬛️🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫⬛️
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩⬛️⬛️🌫🌫⬛️🥧💟🍓💟💟💟💟💟💟⬛️🌫🌫🌫⬜️⬛️🌫🌫🌫🌫🌫⬜️⬛️🌫🌫⬛️
️🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩⬛️⬛️⬛️⬛️🥧💟💟💟💟💟💟💟💟⬛️🌫🌫🌫⬛️⬛️🌫🌫🌫⬛️🌫⬛️⬛️🌫🌫⬛️
🟦🟦🟩🟩🟩🟩🟩🟩🟩🟩🟦🟦🟦🟦🟦🟦🟦🟦🟩🟩🟩🟩🟩🟩⬛️⬛️🥧💟💟💟💟💟🍓💟💟⬛🌫🟥🟥🌫🌫🌫🌫🌫🌫🌫🌫🌫🟥🟥⬛️
🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦⬛️🥧🥧💟🍓💟💟💟💟💟⬛️🌫🟥🟥🌫⬛️🌫🌫⬛️🌫🌫⬛️🌫🟥🟥⬛️
🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦⬛️🥧🥧🥧💟💟💟💟💟💟💟⬛️🌫🌫🌫⬛️⬛️⬛️⬛️⬛️⬛️⬛️🌫🌫⬛️⬜️
🟪🟪🟦🟦🟦🟦🟦🟦🟦🟦🟪🟪🟪🟪🟪🟪🟪🟪🟦🟦🟦🟦🟦🟦⬛️⬛️⬛️🥧🥧🥧🥧🥧🥧🥧🥧🥧🥧⬛️🌫🌫🌫🌫🌫🌫🌫🌫🌫🌫⬛️⬜️⬜️
🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪⬛️🌫🌫🌫⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬛️⬜️⬜️⬜️
🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪🟪⬛️🌫🌫⬛️⬛️⬜️⬛️🌫🌫⬛️⬜️⬜️⬜️⬜️⬜️⬛️🌫🌫⬛️⬜️⬛️🌫🌫⬛️⬜️⬜️⬜️⬜️
⬜️⬜️🟪🟪🟪🟪🟪🟪🟪🟪⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬜️🟪🟪🟪🟪🟪⬛️⬛️⬛️⬛⬜️⬜️⬛️⬛️⬛️⬜️⬜️⬜️⬜️⬜️⬜️⬜️⬛️⬛️⬛️⬜️⬜️⬛️⬛️⬜️⬜️⬜️⬜️⬜️️
'''
ascii_art_lines = ascii_art.strip().split('\n')
with app.app_context():
return Response(render_template_string('''
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-color: black;
color: white;
overflow: hidden;
margin: 0;
padding: 0;
}
#ascii-art {
font-family: monospace;
white-space: pre;
position: absolute;
top: 50%;
transform: translateY(-50%);
display: inline-block;
font-size: 16px;
line-height: 1;
}
</style>
</head>
<body>
<div id="ascii-art"></div>
<script>
var asciiArtLines = {{ ascii_art_lines | tojson }};
var asciiArtDiv = document.getElementById("ascii-art");
var index = 0;
function displayNextLine() {
if (index < asciiArtLines.length) {
var line = asciiArtLines[index];
var lineElement = document.createElement("div");
lineElement.innerHTML = line;
asciiArtDiv.appendChild(lineElement);
index++;
setTimeout(displayNextLine, 100);
} else {
animateCat();
}
}
function animateCat() {
var pos = 0;
var screenWidth = window.innerWidth;
var catWidth = asciiArtDiv.offsetWidth;
function move() {
asciiArtDiv.style.left = pos + "px";
pos += 2;
if (pos > screenWidth) {
pos = -catWidth;
}
requestAnimationFrame(move);
}
move();
}
displayNextLine();
</script>
</body>
</html>
''', ascii_art_lines=ascii_art_lines), status=200, content_type="text/html")
このコードを実行する前に、まず以下のPythonの依存パッケージをインストールする必要があります。
pip install werkzeug
pip install flask
pip install dify-plugin
プラグインのデバッグ
次に、プラグインが正常に動作するかどうかをテストします。Difyはリモートデバッグ機能を提供しており、「プラグイン管理」ページでデバッグキーとリモートサーバーのアドレスを取得できます。
プラグインのプロジェクトに戻り、.env.example
ファイルをコピーして.env
にリネームします。そして、取得したリモートサーバーのアドレスやデバッグキーなどの情報を.env
ファイルに記入してください。
.env
ファイルの内容:
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=remote-url
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****
python -m main
コマンドを実行してプラグインを起動します。プラグインページで、このプラグインがワークスペースにインストールされたことを確認できます。他のチームメンバーもこのプラグインにアクセス可能です。
プラグイン内に新しいエンドポイントを追加し、名前やapi_key
などの情報を任意で入力します。自動生成されたURLにアクセスすると、プラグインが提供するウェブサービスが表示されます。
プラグインのパッケージ化
プラグインが正常に動作することを確認したら、以下のコマンドラインツールを使用してプラグインをパッケージ化し、名前を付けることができます。実行後、現在のフォルダにneko.difypkg
というファイルが生成されます。このファイルが最終的なプラグインパッケージです。
dify-plugin package ./neko
おめでとうございます!これで、プラグインの開発、テスト、パッケージ化の全工程が完了しました。
プラグインの公開
作成したプラグインは、Dify Plugins コードリポジトリにアップロードして公開できます。アップロードする前に、プラグインがプラグイン公開仕様に準拠していることを確認してください。審査に合格すると、コードはメインブランチにマージされ、Dify Marketplaceに自動的に公開されます。
さらに詳しく
クイックスタート:
プラグインインターフェースドキュメント:
ベストプラクティス:
Telegram Botプラグインの開発