feat: plugin_dev init

This commit is contained in:
Alter-xyz
2025-05-16 19:28:58 +08:00
parent 78095626e3
commit d3874efad6
36 changed files with 8289 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
---
dimensions:
type:
primary: conceptual
detail: introduction
level: beginner
standard_title: Getting Started Dify Plugin
language: ja
title: Dify プラグイン開発へようこそ
description: Difyプラグインの概念、機能、開発価値を紹介し、プラグインタイプモデル、ツール、エージェント戦略、エクステンション、バンドルの簡単な説明と、開発者ドキュメントの内容概覧を含みます。
---
こんにちはDify プラグインの構築にご興味をお持ちいただき、大変嬉しく思います。この開発者ドキュメントセンターは、Dify プラグインの学習、作成、デバッグ、公開、管理を支援するための中心的なリソースです。
**Dify プラグインとは?**
Dify プラグインは、AI アプリケーションに**強化された認識能力と実行能力**を与えるモジュール式コンポーネントと考えることができます。これらにより、外部サービス、カスタム機能、専用ツールを「プラグアンドプレイ」のシンプルな方法で Dify ベースの AI アプリケーションに統合することが可能になります。プラグインを通じて、AI アプリケーションはより良く「見る」、「聞く」、「話す」、「描く」、「計算する」、「推論する」ことができ、外部 API に接続したり、さらには実世界の操作を実行したりすることができます。
**プラグイン開発者**として、ご自身の Dify アプリケーション専用の機能拡張を構築したり、あなたのイノベーションを Dify エコシステム全体に貢献して、より多くのユーザーに利益をもたらしたりすることができます。
**この開発者ドキュメントでは、以下の内容を見つけることができます:**
このドキュメントは、プラグイン開発者が初めて試す場合でも、高度なカスタマイズを求める場合でも、明確なガイダンスを提供することを目的としています:
- **[クイックスタート](/plugin_dev_ja/0211-getting-started-dify-tool.ja):** Dify プラグインシステムの基本概念を学び、そのコアアーキテクチャを理解し、開発環境を迅速にセットアップして、最初の「Hello World」プラグインを構築します。
- **[コアコンセプト](/plugin_dev_ja/0131-cheatsheet.ja):** プラグインのライフサイクル、セキュリティモデル、エンドポイント統合 (Endpoint Integration)、リバースコール (Reverse Call)、永続ストレージなどの主要な原理を深く理解します。
- **さまざまなタイプのプラグイン開発:** 各プラグインタイプに対して、専用の開発ガイドを提供します:
- **[モデル (Models)](/plugin_dev_ja/0211-getting-started-new-model.ja):** さまざまな AI モデルをパッケージ化、設定し、プラグインとして管理する方法を学びます。
- **[ツール (Tools)](/plugin_dev_ja/0211-getting-started-dify-tool.ja):** データ分析、コンテンツ処理、カスタム統合など、エージェントおよびワークフロー向けの専門的な機能を構築します。
- **[エージェント戦略 (Agent Strategies)](/plugin_dev_ja/9433-agent-strategy-plugin.ja):** Dify の自律エージェントを強化するために、カスタムの推論戦略ReAct, CoT, ToT など)を作成します。
- **[エクステンション (Extensions)](/plugin_dev_ja/9231-extension-plugin.ja):** HTTP Webhook を介して外部サービスとの統合を実現し、複雑なロジックを処理します。
- **[バンドル (Bundles)](/plugin_dev_ja/9241-bundle.ja):** 複数のプラグインを組み合わせてパッケージ化し、配布とデプロイを容易にする方法を学びます。
- **[開発とデバッグ](/plugin_dev_ja/0411-remote-debug-a-plugin.ja):** SDK の使用、使いやすいリモートデバッグ機能の活用、プラグインのテスト方法など、効率的なプラグイン開発のためのツールとテクニックを習得します。
- **[公開とマーケットプレイス](/plugin_dev_ja/0321-release-overview.ja):** プラグインをパッケージ化し、公式の Dify Marketplace に提出したり、GitHub などのチャネルを通じてコミュニティと共有したりする方法を学びます。
- **[API & SDK リファレンス](/plugin_dev_ja/0411-general-specifications.ja):** API、SDK メソッド、マニフェストファイル形式、および必要なスキーマの詳細な技術仕様を検索します。
- **[コミュニティと貢献](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja):** 他の開発者と交流し、助けを求め、Dify プラグインエコシステムとこのドキュメントに貢献する方法を学びます。
**なぜ Dify プラグインを開発するのか?**
- **AI 能力の拡張:** Dify ベースのアプリケーションに専門ツール、マルチモーダル処理、実世界サービスへの接続など、無限の可能性を与えます。
- **Dify 体験のカスタマイズ:** 専用プラグインを構築することで、特定のビジネスシナリオやワークフローのニーズを正確に満たします。
- **インテリジェントプロセスの再構築:** カスタムツールとエージェント戦略を利用して、RAG プロセスを最適化し、エージェントの推論能力を強化します。
- **モジュール化と分離の実現:** 機能を独立したプラグインとして開発および管理し、コードの保守性と柔軟性を向上させます。
- **Dify ユーザーへのリーチ:** Dify Marketplace を通じて、あなたのイノベーションを広大な Dify ユーザー層と共有します。
- **開発者フレンドリーな体験の享受:** 強力な SDK、便利なリモートデバッグツール、明確なドキュメントを提供し、効率的な開発を支援します。
**構築を始める準備はできましたか?**
以下は、開始に役立つクイックエントリです:
- **[クイックスタートガイドを読む](/plugin_dev_ja/0211-getting-started-dify-tool.ja)** - 簡単なツールプラグインの構築から始めましょう
- **[プラグイン開発チートシートを見る](/plugin_dev_ja/0131-cheatsheet.ja)** - コアコンセプトとよく使われるコマンドを理解する
- **[開発環境の初期化](/plugin_dev_ja/0221-initialize-development-tools.ja)** - 開発環境をセットアップする
- **[よくある質問を見る](/plugin_dev_ja/0331-faq.ja)** - よくある疑問を解決する
## 関連リソース
- **[モデルプラグイン紹介](/plugin_dev_ja/0131-model-plugin-introduction.ja)** - モデルプラグインの基本構造を理解する
- **[開発実践例](/plugin_dev_ja/0432-develop-a-slack-bot-plugin.ja)** - 実際のプラグイン開発事例を見る
Dify プラグインを使用して素晴らしいアプリケーションや機能を作成されることを楽しみにしています!

View File

@@ -0,0 +1,143 @@
---
dimensions:
type:
primary: conceptual
detail: architecture
level: beginner
standard_title: Cheatsheet
language: ja
title: Difyプラグイン開発チートシート
description: 環境要件、インストール方法、開発フロー、プラグインの分類と種類、よく使われるコードスニペット、よくある問題の解決策など、Difyプラグイン開発に関する包括的なリファレンスガイドです。開発者が素早く参照するのに適しています。
---
### 環境要件
- Python バージョン ≥ 3.12
- Dify プラグインスケルトンツール (dify-plugin-daemon)
> 詳細はこちら:[開発ツールの初期化](/plugin_dev_ja/0221-initialize-development-tools.ja)
### Dify Plugin 開発パッケージの入手
[Dify Plugin CLI](https://github.com/langgenius/dify-plugin-daemon/releases)
#### プラットフォーム別のインストール方法
**macOS [Brew](https://github.com/langgenius/homebrew-dify)(グローバルインストール):**
```bash
brew tap langgenius/dify
brew install dify
```
インストール完了後、任意のターミナルウィンドウを新規作成し、`dify version` コマンドを実行します。バージョン情報が出力されれば、インストールは成功です。
**macOS ARM (Mシリーズチップ):**
```bash
# dify-plugin-darwin-arm64 をダウンロード
chmod +x dify-plugin-darwin-arm64
./dify-plugin-darwin-arm64 version
```
**macOS Intel:**
```bash
# dify-plugin-darwin-amd64 をダウンロード
chmod +x dify-plugin-darwin-amd64
./dify-plugin-darwin-amd64 version
```
**Linux:**
```bash
# dify-plugin-linux-amd64 をダウンロード
chmod +x dify-plugin-linux-amd64
./dify-plugin-linux-amd64 version
```
**グローバルインストール (推奨):**
```bash
# 名前を変更してシステムパスに移動
# 例 (macOS ARM)
mv dify-plugin-darwin-arm64 dify
sudo mv dify /usr/local/bin/
dify version
```
### 開発パッケージの実行
ここでは `dify` を例とします。ローカルインストール方式を使用している場合は、状況に応じてコマンドを置き換えてください。例:`./dify-plugin-darwin-arm64 plugin init`。
### プラグイン開発フロー
#### 1. 新規プラグイン作成
```bash
./dify plugin init
```
プロンプトに従ってプラグインの基本情報を設定します
> 詳細はこちら:[Dify プラグイン開発Hello World ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja)
#### 2. 開発モードでの実行
`.env` ファイルを設定し、プラグインディレクトリで以下のコマンドを実行します:
```bash
python -m main
```
> 詳細はこちら:[プラグインのリモートデバッグ](/plugin_dev_ja/0411-remote-debug-a-plugin.ja)
#### 4. パッケージ化とデプロイ
プラグインのパッケージ化:
```bash
cd ..
dify plugin package ./yourapp
```
> 詳細はこちら:[リリース概要](/plugin_dev_ja/0321-release-overview.ja)
### プラグインの分類
#### ツールラベル
分類 `tag` [class ToolLabelEnum(Enum)](https://github.com/langgenius/dify-plugin-sdks/blob/main/python/dify_plugin/entities/tool.py)
```python
class ToolLabelEnum(Enum):
SEARCH = "search"
IMAGE = "image"
VIDEOS = "videos"
WEATHER = "weather"
FINANCE = "finance"
DESIGN = "design"
TRAVEL = "travel"
SOCIAL = "social"
NEWS = "news"
MEDICAL = "medical"
PRODUCTIVITY = "productivity"
EDUCATION = "education"
BUSINESS = "business"
ENTERTAINMENT = "entertainment"
UTILITIES = "utilities"
OTHER = "other"
```
### プラグインタイプの参照
Dify は複数のタイプのプラグイン開発をサポートしています:
- **ツールプラグイン**: サードパーティ API およびサービスを統合
> 詳細はこちら:[ツールプラグイン開発](/plugin_dev_ja/0211-getting-started-dify-tool.ja)
- **モデルプラグイン**: AI モデルを統合
> 詳細はこちら:[モデルプラグイン紹介](/plugin_dev_ja/0131-model-plugin-introduction.ja)、[新しいモデルの迅速な統合](/plugin_dev_ja/0211-getting-started-new-model.ja)
- **Agent 戦略プラグイン**: Agent の思考および意思決定戦略をカスタマイズ
> 詳細はこちら:[Agent 戦略プラグイン](/plugin_dev_ja/9433-agent-strategy-plugin.ja)
- **拡張プラグイン**: Dify プラットフォーム機能を拡張Endpoint および WebAPP
> 詳細はこちら:[拡張プラグイン](/plugin_dev_ja/9231-extension-plugin.ja)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,541 @@
---
dimensions:
type:
primary: implementation
detail: basic
level: beginner
standard_title: Getting Started Dify Tool
language: ja
title: Dify プラグイン開発Hello World ガイド
description: このドキュメントでは、Telegraph公開プラグインの作成を例に、ゼロからのDifyプラグイン開発に関する詳細なチュートリアルを提供します。環境準備、プロジェクト初期化、仮想環境設定、プラグインコアロジック開発、ローカル実行デバッグ、プラグインメタ情報整備、パッケージ化と公開といった手順が含まれます。
---
Dify プラグイン開発入門ガイドへようこそ!このチュートリアルは、基本的なプログラミング知識と Dify プラットフォームの使用経験があることを前提としています。このチュートリアルを完了すると、簡単な Dify プラグインを作成するための基本的な流れを習得し、Dify ユーザーからプラグイン貢献者へとステップアップできます。
Telegraph 公開プラグインを例に、簡単なプラグインの開発方法をステップバイステップで示します。このチュートリアルでは、主にコマンドライン操作を使用し、VSCode をコードエディタとして使用する場合の例も示します。**まず全体的な流れを理解するために一度ざっと目を通し、その後、手順に従って実際に操作することをお勧めします。**
> **LLM 向けの説明:** ここで私たちが作成したプロンプトを使用して、プラグイン開発を支援することもできます:[Dify プラグイン開発:プロンプト](/plugin_dev_ja/0211-getting-started-by-prompt.ja)
始める前に、いつでも私たちが提供する [**開発者向けチートシート (Cheatsheet)**](/plugin_dev_ja/0131-cheatsheet.ja) でよく使われるコマンドや情報を確認したり、より複雑な問題に遭遇した場合には完全な開発者ドキュメントを参照したりすることができます。
## 1. 開発環境の準備
Dify プラグインの開発を始める前に、お使いの環境に以下のツールが準備されていることを確認してください:
- **Dify プラグイン開発 CLI (CLI):** これはプラグインの開発、デバッグ、パッケージ化を行うための中核となるツールで、`dify-plugin-daemon` または「プラグイン開発SDK」とも呼ばれます。
- **Python 環境:** Python 3.12 以降が必要です。
### 1.1 Dify プラグイン開発 CLI のインストール
> より詳細な開発環境準備ガイドについては、[開発ツールの初期化](/plugin_dev_ja/0221-initialize-development-tools.ja) を参照してください。
1. **ダウンロード:** [Dify Plugin CLI Releases](https://github.com/langgenius/dify-plugin-daemon/releases) ページにアクセスします。お使いのオペレーティングシステムWindows, macOS Intel/ARM, Linuxに対応する最新バージョンのバイナリファイルをダウンロードします。
2. **実行権限の設定 (macOS / Linux):**
- **以下の手順は macOS (Apple Silicon / M シリーズチップ) を例としています**。ダウンロードしたファイル名を `dify-plugin-darwin-arm64` と仮定します。ターミナルで、ファイルが存在するディレクトリに移動し、以下のコマンドを実行して実行権限を付与します:
```bash
chmod +x dify-plugin-darwin-arm64
```
- Linux ユーザーの場合は、対応する Linux バージョンのファイルをダウンロードし、同様の `chmod +x <downloaded_filename>` コマンドを実行してください。
- Windows ユーザーの場合は、`.exe` ファイルをダウンロードした後、通常は直接実行できます。
3. **インストールの確認:**
- ターミナルで、以下のコマンドを実行してツールが正常に動作するか確認します(`./dify-plugin-darwin-arm64` をダウンロードした実際のファイル名またはパスに置き換えてください):
```bash
./dify-plugin-darwin-arm64 version
```
- ターミナルにバージョン情報(例:`v0.0.1-beta.15`)が正常に出力されれば、インストールは成功です。
> **ヒント (Tips):**
>
> - **macOS のセキュリティ警告:** macOS で初めて実行する際に「Apple は検証できません」または「開けません」と表示された場合は、「システム設定」→「プライバシーとセキュリティ」→「セキュリティ」セクションに移動し、関連するメッセージを見つけて「それでも開く」または「許可」をクリックしてください。
> - **コマンドの簡略化:** ダウンロードしたバイナリファイル名を短い名前(例:`dify` や `dify-plugin`)に変更すると、後の使用が便利になります。例:`mv dify-plugin-darwin-arm64 dify`、その後は `./dify version` で使用できます。
> - **グローバルインストール(オプション):** システムのどのパスからでも直接コマンドを実行できるようにしたい場合(例:`./dify` ではなく直接 `dify` と入力する)、名前変更後のファイルをシステムの `PATH` 環境変数に含まれるディレクトリ(例:`/usr/local/bin` (macOS/Linux)に移動するか、Windows の環境変数に追加します。
> - 例 (macOS/Linux): `sudo mv dify /usr/local/bin/`
> - 設定完了後、ターミナルで直接 `dify version` と入力すると、バージョン番号が正常に出力されるはずです。
**便宜上、このドキュメントでは以降、Dify プラグイン開発 CLI コマンドの例として `./dify` を使用します。ご自身の実際の状況に合わせてコマンドを置き換えてください。**
## 2. プラグインプロジェクトの初期化
それでは、CLI ツールを使用して新しいプラグインプロジェクトを作成しましょう。
1. ターミナルを開き、初期化コマンドを実行します:
```bash
./dify plugin init
```
2. プロンプトに従って、プラグインの基本情報を順に入力します:
- **Plugin name:** プラグインの一意の識別子。例:`telegraph`
- _制約: 長さ 1128 文字、小文字の英数字、ハイフン(-)、アンダースコア(_)のみ使用可能。_
- **Author:** プラグイン作者の識別子。例:`alterxyz`
- _制約: 長さ 164 文字、小文字の英数字、ハイフン(-)、アンダースコア(_)のみ使用可能。_
- **Description:** プラグイン機能の簡単な説明。例:`A Telegraph plugin that allows you to publish your content easily`
3. **開発言語の選択:** `Select language` と表示されたら、`python` を選択してください。
4. **プラグインタイプの選択:** `Select plugin type` と表示されたら、このチュートリアルでは `tool` を選択してください。
5. **追加機能の選択:** 次に、プロバイダー認証、永続ストレージなどの追加機能が必要かどうか尋ねられます。この簡単な Hello World プラグインでは、これらは一時的に不要なので、成功メッセージが表示されるまで **Enter キー** を押してすべてのオプションをスキップできます。
6. **作成成功の確認:** ターミナルに以下のような情報が出力されたら、プラグインプロジェクトは正常に作成されています:
```bash
[INFO] plugin telegraph created successfully, you can refer to `telegraph/GUIDE.md` for more information about how to develop it
```
これで、現在のディレクトリに `telegraph`(または指定したプラグイン名)という名前の新しいフォルダが表示され、これがプラグインプロジェクトになります。
## 3. Python 仮想環境と依存関係の設定
プロジェクトの依存関係を分離するために、Python 仮想環境の使用を推奨します。
### 3.1 仮想環境の作成とアクティベート(コマンドライン方式)
これは**推奨される一般的な**方法で、特定の IDE に依存しません:
1. **プロジェクトディレクトリへの移動:**
```bash
cd telegraph
```
2. **仮想環境の作成:** (名前を `venv` にすることを推奨します)
```bash
python -m venv venv
```
3. **仮想環境のアクティベート:**
- **macOS / Linux:**
```bash
source venv/bin/activate
```
- **Windows (cmd.exe):**
```bash
venv\Scripts\activate.bat
```
- **Windows (PowerShell):**
```bash
venv\Scripts\Activate.ps1
```
- アクティベートに成功すると、通常、ターミナルのプロンプトの前に `(venv)` と表示されます。
### 3.2 基本的な依存関係のインストール
プロジェクト初期化時に生成された `requirements.txt` ファイルには、プラグイン開発に必要な基本ライブラリ `dify_plugin` が含まれています。仮想環境をアクティベートした後、以下のコマンドを実行してインストールします:
```bash
pip install -r requirements.txt
```
### 3.3 (オプション) VSCode 統合環境設定
VSCode をコードエディタとして使用している場合、その統合機能を利用して Python 環境を管理できます:
1. **プロジェクトフォルダを開く:** 作成した `telegraph` フォルダを VSCode で開きます。
2. **Python インタープリタの選択:**
- コマンドパレットを開きます (macOS: `Cmd+Shift+P`, Windows/Linux: `Ctrl+Shift+P`)。
- `Python: Select Interpreter` と入力して選択します。
- 表示されたリストから、先ほど作成した仮想環境内の Python インタープリタを選択します(通常、パスには `.venv/bin/python` または `venv\Scripts\python.exe` が含まれます)。リストに自動的に表示されない場合は、`Enter interpreter path...` を選択して手動で検索できます。
- _(ローカルの対応するスクリーンショットを参照してください。インタープリタ選択画面が表示されています)_
3. **依存関係のインストール (VSCode が提示した場合):** VSCode が `requirements.txt` ファイルを検出し、その中の依存関係をインストールするよう促すことがあります。プロンプトが表示されたら、インストールを確認してください。
- _(ローカルの対応するスクリーンショットを参照してください。依存関係のインストール確認画面が表示されています)_
**以降のすべての `pip install` コマンドと `python -m main` の実行操作は、アクティベートされた仮想環境で実行してください。**
## 4. プラグインコアロジックの開発
それでは、プラグインのコードを記述していきましょう。この例では、指定されたコンテンツを Telegraph に公開するための簡単なツールを実装します。
### 4.1 サンプル依存ライブラリ: `your-telegraph`
`your-telegraph` という名前の Python ライブラリを使用して Telegraph API とやり取りします。_これは仮のライブラリ名です。実際に使用するライブラリが有効であることを確認してください_
> `your-telegraph` は、Telegraph API の操作を簡略化する Python ラッパーで、数行のコードで簡単にコンテンツを公開できます。
その基本的な使い方は以下のようになるかもしれません:
```python
# サンプルコードであり、プラグイン内のコードではありません
from ytelegraph import TelegraphAPI
# access_token が必要です
ph = TelegraphAPI(access_token="your_telegraph_access_token")
# ページを作成してリンクを取得
ph_link = ph.create_page_md("My First Page", "# Hello, Telegraph!\n\nThis is my first Telegraph page.")
print(ph_link)
```
私たちの目標は、Dify プラグインで同様の機能を実現することです。
### 4.2 プロジェクト依存関係の追加と設定
1. **依存ライブラリのインストール:** 仮想環境がアクティベートされていることを確認し、ターミナルで以下を実行します:
```bash
pip install your-telegraph
```
2. **`requirements.txt` の更新:** プロジェクトルートディレクトリにある `telegraph/requirements.txt` ファイルを開き、`dify_plugin` の下に、先ほどインストールしたライブラリ名を一行追加します:
```plaintext
dify_plugin
your-telegraph
```
これにより、他の開発者やデプロイ環境がすべての必要な依存関係を簡単にインストールできるようになります。
### 4.3 プロバイダー認証情報の設定
この例では `telegraph_access_token` が必要です。プロバイダー設定でこの認証情報を定義し、ユーザーがプラグインを使用する際に入力できるようにする必要があります。プロバイダー設定の詳細については、[一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) を参照してください。
1. **プロバイダー YAML の編集:** `telegraph/provider/telegraph.yaml` ファイルを開きます。
2. **`credentials_for_provider` の追加:** ファイルの末尾(または適切な場所)に以下の内容を追加します:
```yaml
# ... (ファイルに既にある identity, name, label, description, icon などは変更しません) ...
credentials_for_provider:
telegraph_access_token: # これは認証情報の内部名で、Python コードで使用されます
type: secret-input # 入力タイプはパスワードフィールド
required: true # この認証情報は必須です
label: # Dify UI に表示されるラベル (多言語対応)
en_US: Telegraph Access Token
ja: Telegraph アクセストークン
# ... (その他の言語)
placeholder: # 入力フィールドのプレースホルダーテキスト (多言語対応)
en_US: Enter your Telegraph access token
ja: Telegraph アクセストークンを入力してください
# ... (その他の言語)
help: # ヘルプヒント情報 (多言語対応)
en_US: How to get your Telegraph access token
ja: Telegraph アクセストークンの取得方法
# ... (その他の言語)
url: https://telegra.ph/api#createAccount # ヘルプヒントをクリックしたときにジャンプする URL
```
- **フィールドの説明:**
- `telegraph_access_token`: 認証情報の一意の識別子。コード内では `self.runtime.credentials["telegraph_access_token"]` を介してユーザーが入力した値にアクセスします。
- `type: secret-input`: Dify UI 上でパスワード入力フィールドとして表示されます。
- `required: true`: ユーザーがこのプラグイン提供のツールを使用するには、この認証情報を入力する必要があります。
- `label`, `placeholder`, `help`: 多言語対応の UI テキストを提供します。
- `url`: (オプション) 認証情報取得のためのヘルプリンクを提供します。
### 4.4 ツール (Tool) ロジックの実装
それでは、実際に公開操作を実行するツールのコードを記述しましょう。
1. **ツール Python ファイルの編集:** `telegraph/tools/telegraph.py` を開きます。
2. **`_invoke` メソッドの実装:** ファイルの内容を以下のコードに置き換えます:
```python
from collections.abc import Generator
from typing import Any
from ytelegraph import TelegraphAPI # 使用するライブラリをインポート
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
class TelegraphTool(Tool):
"""
シンプルな Telegraph 公開ツールです。
"""
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None]:
"""
入力されたタイトルと内容に基づいて、新しい Telegraph ページを作成します。
Args:
tool_parameters: ツールの入力パラメータを含む辞書:
- p_title (str): Telegraph ページのタイトル。
- p_content (str): 公開する Markdown 形式の内容。
Yields:
ToolInvokeMessage: 正常に作成された Telegraph ページの URL を含むメッセージ。
Raises:
Exception: ページの作成に失敗した場合、エラー情報を含む例外をスローします。
"""
# 1. ランタイムから認証情報を取得
try:
access_token = self.runtime.credentials["telegraph_access_token"]
except KeyError:
raise Exception("Telegraph アクセストークンが設定されていないか無効です。プラグイン設定で提供してください。")
# 2. ツールの入力パラメータを取得
title = tool_parameters.get("p_title", "Untitled") # .get を使用してデフォルト値を提供
content = tool_parameters.get("p_content", "")
if not content:
raise Exception("公開するコンテンツは空にできません。")
# 3. ライブラリを呼び出して操作を実行
try:
telegraph = TelegraphAPI(access_token) # Telegraph API を初期化
ph_link = telegraph.create_page_md(title, content) # ページを作成
except Exception as e:
# ライブラリ呼び出しに失敗した場合、例外をスロー
raise Exception(f"Telegraph API の呼び出しに失敗しました: {e}")
# 4. 結果を返す
# create_link_message を使用してリンクを含む出力メッセージを生成
yield self.create_link_message(ph_link)
```
- **重要なポイント:**
- `self.runtime.credentials` から認証情報を取得します。
- `tool_parameters` からツールの入力パラメータを取得します(パラメータ名は次のステップの YAML で定義します)。`.get()` を使用する方が堅牢な方法です。
- `ytelegraph` ライブラリを呼び出して実際の操作を実行します。
- `try...except` を使用して起こりうるエラーをキャッチし、例外をスローします。
- `yield self.create_link_message(url)` を使用して URL を含む結果を Dify に返します。
### 4.5 ツール (Tool) パラメータの設定
このツールがどの入力パラメータを受け取るかを Dify に伝える必要があります。
1. **ツール YAML ファイルの編集:** `telegraph/tools/telegraph.yaml` を開きます。
2. **パラメータの定義:** ファイルの内容を以下のように置き換えるか変更します:
```yaml
identity:
name: telegraph_publisher # ツールの一意の内部名
author: alterxyz
label: # Dify UI に表示されるツール名 (多言語対応)
en_US: Publish to Telegraph
ja: Telegraph に公開
# ... (その他の言語)
description:
human: # 人間ユーザー向けのツールの説明 (多言語対応)
en_US: Publish content to Telegraph as a new page.
ja: コンテンツを新しいページとして Telegraph に公開します。
# ... (その他の言語)
llm: # LLM 向けのツールの説明 (Agent モード用)
A tool that takes a title and markdown content, then publishes it as a new page on Telegraph, returning the URL of the published page. Use this when the user wants to publish formatted text content publicly via Telegraph.
parameters: # ツールの入力パラメータリストを定義
- name: p_title # パラメータの内部名、Python コードのキーに対応
type: string # パラメータタイプ
required: true # 必須かどうか
label: # Dify UI に表示されるパラメータラベル (多言語対応)
en_US: Post Title
ja: 記事タイトル
human_description: # 人間ユーザー向けのパラメータの説明 (多言語対応)
en_US: The title for the Telegraph page.
ja: Telegraph ページのタイトル。
llm_description: # LLM 向けのパラメータの説明 (Agent がどのように入力するかを指示)
The title of the post. Should be a concise and meaningful plain text string.
form: llm # パラメータフォームタイプ ('llm' または 'form')
- name: p_content
type: string
required: true
label:
en_US: Content (Markdown)
ja: 内容 (Markdown)
human_description:
en_US: The main content for the Telegraph page, written in Markdown format.
ja: Telegraph ページの主な内容、Markdown 形式で記述してください。
llm_description: # フォーマット要件を強調することは LLM にとって重要
The full content to be published on the Telegraph page. Must be provided in Markdown format. Ensure proper Markdown syntax for formatting like headings, lists, links, etc.
form: llm
extra: # 追加設定
python:
source: tools/telegraph.py # このツールのロジックを実装する Python ファイルを指す
```
- **フィールドの説明:**
- `identity`: ツールの基本情報、`name` は一意の識別子です。
- `description`: `human` (ユーザー向け) と `llm` (Agent 向け) に分かれます。**`llm` の説明は、Agent がツールを正しく理解して使用できるかどうかにおいて非常に重要です。**
- `parameters`: 各入力パラメータを定義します。
- `name`: 内部名、Python コードの `tool_parameters.get("...")` のキーと一致する必要があります。
- `type`: データ型 (例: `string`, `number`, `boolean` など)。
- `required`: 提供が必須かどうか。
- `label`, `human_description`, `llm_description`: `identity` の説明と同様ですが、特定のパラメータに対するものです。**`llm_description` は、LLM がそのパラメータの値をどのように生成または取得するか(ここでの Markdown のようなフォーマット要件を含む)を明確に指示する必要があります。**
- `form`: パラメータが Dify でどのように表示され、入力されるかを定義します。`llm` は、そのパラメータ値をユーザーが入力したり、変数を介して渡したり、Agent モードで LLM が自律的に決定したりできることを示します。`form` は通常、ユーザーが UI 上で固定的に入力する必要がある設定項目を示します。ツール入力の場合、`llm` の方が一般的です。
- `extra.python.source`: このツールのロジックを実装する Python ファイルのパス(プロジェクトルートディレクトリからの相対パス)を示します。
### 4.6 プロバイダー認証情報の検証実装(オプションだが推奨)
ユーザーが提供した認証情報が有効であることを保証するために、検証ロジックを実装すべきです。
1. **プロバイダー Python ファイルの編集:** `telegraph/provider/telegraph.py` を開きます。
2. **`_validate_credentials` メソッドの実装:** ファイルの内容を以下に置き換えます:
```python
from typing import Any
from dify_plugin import ToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError
class TelegraphProvider(ToolProvider):
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
"""
提供された Telegraph アクセストークンが有効かどうかを検証します。
このトークンを使用してテストページを作成しようとします。
検証に失敗した場合、ToolProviderCredentialValidationError 例外をスローする必要があります。
"""
access_token = credentials.get("telegraph_access_token")
if not access_token:
raise ToolProviderCredentialValidationError("Telegraph アクセストークンは空にできません。")
try:
# 認証情報が必要な簡単な操作を実行して検証を試みる
from ytelegraph import TelegraphAPI
ph = TelegraphAPI(access_token=access_token)
# 検証手段として、一時的で無害なページを作成してみる
# 注意: より良い検証方法は、API の 'getAccountInfo' などの読み取り専用メソッドを呼び出すことです(存在する場合)
test_page = ph.create_page_md("Dify Validation Test", "This is a test page created by Dify plugin validation.")
# 必要であれば、このテストページをすぐに編集または削除することを検討できますが、複雑さが増します
# print(f"Validation successful. Test page created: {test_page}")
except Exception as e:
# API 呼び出しに失敗した場合、認証情報が無効である可能性が高い
raise ToolProviderCredentialValidationError(f"Telegraph 認証情報の検証に失敗しました: {e}")
```
- **重要なポイント:**
- `credentials` 辞書から認証情報を取得します。
- その認証情報が必要な API 呼び出しを実行します(アカウント情報の取得など、読み取り専用操作が望ましいです。もしなければ、無害なテストページを作成することもできますが、副作用の可能性に注意してください)。
- API 呼び出しが成功した場合、例外はスローされず、検証が通過したことを示します。
- API 呼び出しが失敗した場合、例外をキャッチして `ToolProviderCredentialValidationError` をスローし、元のエラーメッセージを含めます。
## 5. ローカルでの実行とデバッグ
これでプラグインをローカルで実行し、Dify でデバッグできます。
1. **`.env` ファイルの準備:**
- `telegraph` プロジェクトディレクトリにいることを確認してください。
- 環境変数テンプレートファイルをコピーします:
```bash
cp .env.example .env
```
- **`.env` ファイルの編集:** 作成したばかりの `.env` ファイルを開き、Dify 環境情報を入力します:
```dotenv
DIFY_API_HOST=https://your-dify-host.com # ご自身の Dify インスタンスアドレスに置き換えてください (例: https://cloud.dify.ai)
DIFY_API_KEY=your-api-key # ご自身の Dify API キーに置き換えてください
```
- **ホストとキーの取得:** Dify 環境にログインし、右上の「プラグイン」アイコンをクリックし、次にデバッグアイコンまたは虫のような形をクリックします。ポップアップウィンドウで、「API キー (Key)」と「ホストアドレス (Host)」をコピーします。 _(ローカルの対応するスクリーンショットを参照してください。キーとホストアドレスの取得画面が表示されています)_
2. **ローカルプラグインサービスの起動:**
- Python 仮想環境がアクティベートされていることを確認してください。
- `telegraph` ディレクトリで、メインプログラムを実行します:
```bash
python -m main
```
- **ターミナル出力の確認:** すべてが正常であれば、以下のようなログ情報が表示され、プラグインツールが正常にロードされ、Dify に接続されたことを示します:
```json
{"event": "log", "data": {"level": "INFO", "message": "Installed tool: telegraph_publisher", "timestamp": 1678886400.123456}}
{"event": "log", "data": {"level": "INFO", "message": "Plugin daemon started, waiting for requests...", "timestamp": 1678886400.123457}}
```
3. **Dify での確認とテスト:**
- **Dify ページを更新:** Dify 環境(ブラウザ)に戻り、プラグイン管理ページ (通常は `https://your-dify-host.com/plugins`) を更新します。
- **プラグインを検索:** リストに "Telegraph" (またはプロバイダー YAML で定義した `label`) という名前のプラグインが表示され、「デバッグ中」のマークが付いている場合があります。
- **認証情報を追加:** そのプラグインをクリックすると、以前 `provider/telegraph.yaml` で定義した "Telegraph Access Token" の入力を求められます。有効なトークンを入力して保存します。検証ロジック (`_validate_credentials`) が正しく実装されていれば、ここで検証が行われます。 _(ローカルの対応するスクリーンショットを参照してください。プラグインがリストに表示され、認証を要求する画面が表示されています)_
- **アプリケーションで使用:** これで、Dify のアプリケーションChatbot や Workflow など)にこのツールノードを追加し、呼び出すことができます!アプリケーションで実行してツールをトリガーすると、リクエストはローカルで実行されている `python -m main` プロセスに転送されて処理されます。ローカルターミナルで関連するログ出力を確認し、デバッグできます。
4. **ローカルサービスの停止:** ターミナルで `Ctrl + C` を押すと、ローカルプラグインサービスを停止できます。
この実行 -> テスト -> 停止 -> コード修正 -> 再実行のサイクルが、プラグイン開発の主なフローです。
## 6. プラグインメタ情報の整備
プラグインをより専門的に、発見・理解しやすくするために、いくつかの表示情報を整備する必要があります。
1. **アイコン (Icon):**
- `telegraph/_assets` ディレクトリに、プラグインを表すアイコンファイル(例:`icon.png`, `icon.svg`)を配置します。正方形で鮮明な画像を推奨します。
2. **プロバイダー情報 (`provider/telegraph.yaml`):**
- `identity` セクションの `label` (表示名)、`description` (機能説明)、`icon` (アイコンファイル名、例:`icon.png` を記入) が入力され、多言語対応していることを確認します。この情報は主に Dify アプリケーションオーケストレーションインターフェースでプラグインを_使用する_ユーザーに表示されます。
```yaml
identity:
author: alterxyz
name: telegraph # 内部名、変更なし
label:
en_US: Telegraph
ja: Telegraph 記事公開
description:
en_US: A Telegraph plugin that allow you publish your content easily
ja: コンテンツを簡単に公開できるTelegraphプラグイン
icon: icon.png # _assets ディレクトリ内のアイコンファイル名を参照
```
3. **プラグインマニフェスト (`manifest.yaml`):**
- プロジェクトルートディレクトリにある `telegraph/manifest.yaml` ファイルを編集します。これはプラグイン全体の「身分証明書」のようなもので、その情報は Dify の**プラグイン管理ページ**や**プラグインマーケットプレイス (Marketplace)** に表示されます。
- 以下のフィールドを必ず更新または確認してください:
- `label`: プラグインの**主要な表示名** (多言語対応)。
- `description`: プラグイン機能の**全体的な概要** (多言語対応)。その核心的な価値を明確に要約する必要があります。マーケットプレイスでの表示には文字数制限があることに注意してください。
- `icon`: プラグインの**メインアイコン** (`_assets` ディレクトリ内のアイコンファイル名を直接記入、例:`icon.png`)。
- `tags`: プラグインに分類タグを追加し、ユーザーがマーケットプレイスでフィルタリングするのに役立ちます。選択可能な値は、Dify が提供する列挙型またはドキュメントの説明を参照してください (例: `media`, `tools`, `data-processing` など)。[ToolLabelEnum 定義](https://github.com/langgenius/dify-plugin-sdks/blob/main/python/dify_plugin/entities/tool.py) を参照してください。
```yaml
label:
en_US: Telegraph Publisher
ja: Telegraph 公開アシスタント
description:
en_US: Easily publish content to Telegraph pages directly from your Dify applications. Supports Markdown formatting.
ja: Dify アプリケーションから直接 Telegraph ページにコンテンツを簡単に公開できます。Markdown 形式をサポートしています。
icon: icon.png
tags: ['media', 'content-creation'] # タグの例
# ... (author, name など他のフィールドは変更なし)
```
4. **README とプライバシーポリシー:**
- `README.md`: プロジェクトルートディレクトリの `README.md` ファイルを編集します。これはプラグインの **Marketplace** 上の詳細な紹介ページとなり、機能詳細、使用例、設定ガイド、よくある質問など、より豊富な情報を含めるべきです。[AWS プラグインマーケットプレイスページ](https://marketplace.dify.ai/plugins/langgenius/aws_tools) のスタイルを参考にしてください。
- `PRIVACY.md`: プラグインを公式 Marketplace に公開する予定がある場合は、プラグインがデータをどのように処理するかを説明するプライバシーポリシー説明ファイル `PRIVACY.md` を提供する必要があります。
## 7. プラグインのパッケージ化
プラグイン開発が完了し、ローカルテストに合格したら、配布またはインストール用に `.difypkg` ファイルにパッケージ化できます。プラグインのパッケージ化と公開の詳細については、[公開概要](/plugin_dev_ja/0321-release-overview.ja) を参照してください。
1. **親ディレクトリに戻る:** ターミナルの現在のパスが `telegraph` フォルダの**一つ上**であることを確認してください。
```bash
cd ..
```
2. **パッケージ化コマンドの実行:**
```bash
./dify plugin package ./telegraph
```
`./telegraph` をプラグインプロジェクトの実際のパスに置き換えてください)
3. **パッケージファイルの取得:** コマンドが正常に実行されると、現在のディレクトリに `telegraph.difypkg` (または `あなたのプラグイン名.difypkg`) という名前のファイルが生成されます。
この `.difypkg` ファイルは完全なプラグインパッケージです。これを以下のことができます:
- Dify のプラグイン管理ページで手動で**アップロードしてインストール**する。
- 他の人に**共有**してインストールしてもらう。
- Dify の規範と手順に従って、**公式プラグインマーケットプレイス (Marketplace)** に公開し、すべての Dify ユーザーがあなたのプラグインを発見して使用できるようにする。具体的な公開手順については、[Dify マーケットプレイスへの公開](/plugin_dev_ja/0322-release-to-dify-marketplace.ja) を参照してください。
おめでとうございます! これで最初の Dify プラグインの開発、デバッグ、整備、パッケージ化の全プロセスを完了しました。この基礎を元に、より複雑で強力なプラグイン機能を探求できます。
## 次の学習ステップ
- [リモートでプラグインをデバッグする](/plugin_dev_ja/0411-remote-debug-a-plugin.ja) - より高度なプラグインデバッグテクニックを学ぶ
- [永続ストレージ](/plugin_dev_ja/0411-persistent-storage-kv.ja) - プラグインでデータストレージを使用する方法を学ぶ
- [Slack ボットプラグイン開発例](/plugin_dev_ja/0432-develop-a-slack-bot-plugin.ja) - より複雑なプラグイン開発事例を見る
- [ツールプラグイン](/plugin_dev_ja/0222-tool-plugin.ja) - ツールプラグインの高度な機能を探る

View File

@@ -0,0 +1,114 @@
---
dimensions:
type:
primary: implementation
detail: basic
level: beginner
standard_title: Getting Started New Model
language: ja
title: 新しいモデルを迅速に統合する
description: このドキュメントでは、専門家でない開発者がDifyに新しいモデルを追加する方法を説明します。既存のモデルプロバイダーに設定ファイルを変更することで新しいモデルタイプを追加することに焦点を当てています。リポジトリのフォーク、モデル設定のコピーと変更、プロバイダーバージョンの更新、ローカルテスト、およびコントリビューションの提出までの完全なプロセスを含みます。
---
Difyのプラグイン開発の世界へようこそDifyの強力な機能は、コミュニティ貢献者の共同の努力なしにはありえません。たとえプロのプログラマーでなくても、AI技術に情熱を持ち、資料を調べる意欲があれば、Difyにより多くの、より新しいAIモデルをサポートするなど、Difyに貢献できると信じています。
この記事では、最も簡潔な方法で、最も一般的で簡単な貢献、つまりDifyが**既にサポートしている**モデルプロバイダーに、**新しいモデルタイプ**を追加する方法を説明します。この方法は通常、**設定ファイルの変更のみ**が必要で、コードを書く必要がないため、最初の貢献として非常に適しています!
> **関連概念**:開始する前に、[モデルプラグイン](/plugin_dev_ja/0131-model-plugin-introduction.ja)のドキュメントを読んで、モデルプラグインの基本概念と構造を理解することをお勧めします。
**この迅速な統合方法は、以下の場合に適しています:**
- 新しいモデルが、Difyが既にプラグインでサポートしているプロバイダーOpenAI、Google Gemini、Anthropic Claudeなどに属している場合。
- 新しいモデルが、同じシリーズの他のモデルと同じAPI認証および基本的な呼び出しロジックを使用している場合。
- 主な違いが、モデルID、コンテキスト長、最大トークン数、価格設定などの設定パラメーターにある場合。
_(追加する必要のあるモデルが新しいAPIロジックを必要とするか、特殊な機能をサポートする場合、Pythonコードの記述が必要になります。[新しいモデルプロバイダーの作成](/plugin_dev_ja/0222-creating-new-model-provider.ja) で詳細なガイドを参照してください。)_
**準備作業:**
- 基本的なGit操作Fork、Clone、Pull Requestに慣れていること。
- GitHubアカウント。
- Difyプラグイン開発ツールキットをインストールし、設定済みであること[開発ツールの初期化](/plugin_dev_ja/0221-initialize-development-tools.ja)を参照)。
**操作手順:**
1. **公式プラグインリポジトリをフォーク&クローン:**
- Dify公式プラグインリポジトリ `https://github.com/langgenius/dify-official-plugins` にアクセスします。
- 「Fork」ボタンをクリックして、リポジトリを自分のGitHubアカウントにフォークします。
- Gitを使用して、フォークしたリポジトリをローカルコンピュータにクローンします。
2. **モデル設定ファイルを見つけてコピー:**
- ローカルリポジトリで、`models/` ディレクトリに移動し、モデルを追加したいプロバイダーのフォルダ(例:`vertex_ai`)を見つけます。
- そのプロバイダーに対応するモデルタイプのサブディレクトリ(通常はテキスト生成モデルの場合 `models/llm/`)に入ります。
- そのディレクトリ内で、追加したい新しいモデルに最も似ている既存モデルのYAML設定ファイル`gemini-1.0-pro-001.yaml`)を見つけます。
- このYAMLファイルをコピーし、新しいモデルタイプを明確に識別できる名前に変更します`gemini-1.5-pro-latest.yaml`)。
3. **モデル設定の変更 (YAML):**
- 先ほど名前を変更したYAMLファイル`gemini-1.5-pro-latest.yaml`)を開きます。
- **核心ステップ:** **モデルプロバイダーの公式ドキュメント**を参照し、ファイル内の以下の重要な情報を注意深く確認して変更します:
- `model`: **必須** 新しいモデルタイプの公式API識別子に更新します。
- `label`: **必須** Difyインターフェースでユーザーに表示されるモデル名に更新します`en_US` と `zh_Hans` の両方の言語を提供することをお勧めします)。
- `model_properties`: `context_size`(コンテキストウィンドウサイズ)を更新します。
- `parameter_rules`: モデルパラメータの制限、特に `max_tokens`(最大出力トークン数)の `default`、`min`、`max` 値を確認して更新します。
- `pricing`: モデルの入力(`input`)と出力(`output`)の価格設定、および単位(`unit`、通常は百万トークンを表す `0.000001`)と通貨(`currency`)を更新します。
- _(参考)_ モデルYAMLファイルの各フィールドの詳細な仕様については、[モデル設計ルール](/plugin_dev_ja/0411-model-designing-rules.ja) および [モデルスキーマ定義](/plugin_dev_ja/0412-model-schema.ja) を参照してください。
**例 (Gemini 1.5 Pro の追加):**
| パラメータ | 既存モデルの可能性 (例) | 新しい Gemini 1.5 Pro (例) | 説明 |
| :---------------- | :------------------- | :----------------------- | :--------------------------------------------- |
| `model` | `gemini-1.0-pro-001` | `gemini-1.5-pro-latest` | **必須** 公式モデルIDに変更 |
| `label: en_US` | Gemini 1.0 Pro | Gemini 1.5 Pro | **必須** ユーザーに表示されるラベルに変更 |
| `context_size` | 30720 | 1048576 | **必須** 公式ドキュメントに基づいて変更 |
| `max_tokens` (下) | 2048 | 8192 | **必須** 公式ドキュメントに基づいてデフォルト/最大値を変更 |
4. **プロバイダーマニフェストのバージョンを更新:**
- そのモデルプロバイダーのルートディレクトリ(例:`models/vertex_ai/`)に戻ります。
- `manifest.yaml` ファイルを見つけて開きます。
- その中の `version` フィールドをマイナーバージョン番号でインクリメントします(例:`version: 0.0.8` -> `version: 0.0.9`。これにより、Difyにこれが更新であることを伝えます。
5. **パッケージ化とローカルテスト:**
- ターミナル(コマンドラインツール)を開きます。
- **現在のディレクトリが `dify-official-plugins` リポジトリのルートディレクトリ**(つまり、`models`、`tools` などのフォルダが含まれるディレクトリ)であることを確認してください。
- パッケージ化コマンドを実行します:
```bash
# <provider_name> を実際のプロバイダーディレクトリ名(例: cohere や vertex_aiに置き換えます
dify plugin package models/<provider_name>
```
- _成功すると、`plugin packaged successfully, output path: <provider_name>.difypkg` のようなメッセージが表示され、現在のプロジェクトのルートディレクトリに `<provider_name>.difypkg` という名前のプラグインパッケージファイルが生成されます。_
- Difyインスタンスローカルデプロイまたはクラウドバージョンのいずれかにログインします。
- Difyページ最上部のナビゲーションバー右側にある **「プラグイン」** メニュー項目をクリックします。
- プラグインページで、**「プラグインをインストール」** ボタンをクリックします。
- **「ローカルプラグイン」** タブを選択します。
- アップロードエリアをクリックし、先ほどローカルで生成した `<provider_name>.difypkg` ファイルを選択またはドラッグアンドドロップしてアップロードします。
- プラグインのインストールまたは更新が完了するのを待ちます。
- インストールが成功したら、通常、「設定」->「モデルプロバイダー」に移動して対応するプロバイダーを見つけ、API認証情報以前に設定していない場合を設定する必要があります。
- 新しいDifyアプリケーションを作成するか、既存のアプリケーションを編集し、「プロンプトエンジニアリング」->「モデル」設定で、新しく追加したモデルを選択してみてください。簡単な会話や呼び出しテストを行い、正常に動作し、期待される結果が返されることを確認します。
6. **コントリビューションを提出:**
- ローカルテストで問題がなければ、変更新しいモデルYAMLファイルと更新された `manifest.yaml`をGitでコミットcommitし、フォークしたGitHubリポジトリにプッシュpushします。
- GitHub上で、`langgenius/dify-official-plugins` のメインリポジトリに対してプルリクエストPRを作成します。PRの説明には、どのモデルを追加したかを簡潔に説明し、そのモデルの公式ドキュメントへのリンクを添付して、レビュー担当者がパラメータを確認しやすくします。
---
**それで、次は?**
PRがレビューされマージされると、あなたの貢献はDify公式プラグインの一部となり、すべてのDifyユーザーがこの新しいモデルを簡単に利用できるようになります
この迅速な統合方法は、Difyが新しいモデルをサポートするための最速の方法です。もちろん、将来このモデルがより複雑な機能例えば、画像入力、関数呼び出しなどをサポートする必要がある場合、経験豊富な開発者がプラグインをコードレベルで更新する必要があるかもしれません。しかし、あなたが今完了したこのステップは、既に非常に価値のある貢献です
**さらに探求する:**
- [モデルスキーマ定義](/plugin_dev_ja/0412-model-schema.ja) (モデルYAMLファイルの詳細なルールを理解する)
- [モデル設計ルール](/plugin_dev_ja/0411-model-designing-rules.ja) (モデルパラメータ設計の仕様を理解する)
- [一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) (`manifest.yaml` の役割を理解する)
- [新しいモデルプロバイダーの作成](/plugin_dev_ja/0222-creating-new-model-provider.ja) (新しいモデルプロバイダーの追加方法を理解する)
- [Difyマーケットプレイスへの公開](/plugin_dev_ja/0322-release-to-dify-marketplace.ja) (プラグインの公開方法を学ぶ)
- [Dify公式プラグインリポジトリ](https://github.com/langgenius/dify-official-plugins) (他のプラグインの例を見る)

View File

@@ -0,0 +1,66 @@
---
dimensions:
type:
primary: implementation
detail: standard
level: beginner
standard_title: Initialize Development Tools
language: ja
title: 開発ツールの初期化
description: このドキュメントでは、Difyプラグイン開発を開始する前に必要な準備作業について詳しく説明します。これには、Difyプラグインのひな形ツールdify-plugin-daemonのインストールとPython環境バージョン要件≥3.12)の設定の完全な手順が含まれます。また、さまざまなタイプのプラグイン開発の参考リンクも提供しています。
---
Dify プラグインを開発するには、以下の準備が必要です。このドキュメントは、[プラグイン開発](/plugin_dev_ja/0111-getting-started-dify-plugin.ja)を開始するための最初のステップです。
* Dify プラグインのひな形ツール
* Python 環境、バージョン ≥ 3.12
> Dify プラグイン開発のひな形ツールは `dify-plugin-daemon` とも呼ばれ、**プラグイン開発 SDK** と見なすことができます。
### **1. Dify プラグイン開発のひな形ツールのインストール**
[Dify Plugin CLI](https://github.com/langgenius/dify-plugin-daemon/releases) プロジェクトのページにアクセスし、最新バージョンとお使いのオペレーティングシステムに対応するツールをダウンロードしてインストールしてください。
この記事では、**Mシリーズチップを搭載した macOS** を例に説明します。`dify-plugin-darwin-arm64` ファイルをダウンロードした後、実行権限を付与します。
```
chmod +x dify-plugin-darwin-arm64
```
以下のコマンドを実行して、インストールが成功したかどうかを確認します。
```
./dify-plugin-darwin-arm64 version
```
> 「Apple では確認できませんでした」というエラーが表示された場合は、**「設定 → プライバシーとセキュリティ → セキュリティ」** に移動し、「このまま開く」ボタンをタップしてください。
コマンドを実行した後、ターミナルに `v0.0.1-beta.15` のようなバージョン情報が返されれば、インストールは成功です。
> **💡 ヒント:**
>
> システム全体で `dify` コマンドを使用してひな形ツールを実行したい場合は、このバイナリファイルの名前を `dify` に変更し、`/usr/local/bin` システムパスにコピーすることをお勧めします。
>
> 設定完了後、ターミナルで `dify version` コマンドを入力すると、バージョン情報が出力されます。
>
> <img src="https://assets-docs.dify.ai/2025/02/74e57a57c1ae1cc70f4a45084cbbb37e.png" alt="" />
### **2. Python 環境の初期化**
詳細については、[Python インストールチュートリアル](https://pythontest.com/python/installing-python-3-11/) を参照するか、LLM にバージョン ≥ 3.12 の Python 環境のインストールについて質問してください。
### 3. プラグインの開発
さまざまな種類のプラグイン開発の例については、以下の内容を参照してください。
- [ツールプラグイン開発ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja) - Hello World 入門チュートリアル
- [モデルプラグイン開発ガイド](/plugin_dev_ja/0211-getting-started-new-model.ja) - 新しいモデルへの迅速な統合
- [Agent戦略プラグイン開発ガイド](/plugin_dev_ja/9433-agent-strategy-plugin.ja) - カスタム推論戦略の作成
- [拡張プラグイン開発ガイド](/plugin_dev_ja/9231-extension-plugin.ja) - Webhook を介した外部サービス統合の実装
- [プラグインのパッケージ化とリリース](/plugin_dev_ja/0321-release-overview.ja) - プラグインの公開
## 次のステップ
- [Dify プラグイン開発Hello World ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja) - 最初のプラグイン開発を始める
- [プラグイン開発チートシート](/plugin_dev_ja/0131-cheatsheet.ja) - 一般的なコマンドと概念の理解
- [一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - プラグインのメタデータ設定を学ぶ

View File

@@ -0,0 +1,274 @@
---
dimensions:
type:
primary: implementation
detail: standard
level: intermediate
standard_title: Creating New Model Provider Extra
language: ja
title: 標準モデル統合の実装
description: このドキュメントは、Pythonコードを記述してDifyのモデルサポートを追加または強化する必要がある開発者向けのもので、ディレクトリ構造の作成、モデル設定の記述、モデル呼び出しロジックの実装、プラグインのデバッグと公開までの完全なプロセスを詳細にガイドし、コアメソッドの実装とエラー処理の詳細を含んでいます。
---
このドキュメントは、Pythonコードを記述してDifyのモデルサポートを追加または強化する必要がある開発者向けの標準ガイドです。追加したいモデルが新しいAPI呼び出しロジック、特別なパラメータ処理、またはDifyが明示的にサポートする必要がある新機能Vision、Tool Callingなどを含む場合、このガイドの手順に従う必要があります。
**本文を読む前に、以下のことをお勧めします:**
* Pythonプログラミングの基礎とオブジェクト指向プログラミングの基本的な理解があること。
* 統合したいモデルプロバイダーが提供するAPIドキュメントと認証方法に精通していること。
* Difyプラグイン開発ツールキットをインストールし、設定済みであること[開発ツールの初期化](../initialize-development-tools.md)を参照)。
* (オプション)[モデルプラグインの紹介](link-to-conceptual-intro)ドキュメントを読み、モデルプラグインの基本概念とアーキテクチャを理解していること。
このガイドでは、ディレクトリ構造の作成、モデル設定YAMLの記述、モデル呼び出しロジックPythonの実装、およびプラグインのデバッグと公開までの全プロセスを案内します。
---
## ステップ1ディレクトリ構造の作成
整理されたディレクトリ構造は、保守可能なプラグインを開発するための基礎です。モデルプロバイダープラグインのために特定のディレクトリとファイルを作成する必要があります。
1. **プロバイダーディレクトリの特定または作成:** プラグインプロジェクト(通常は `dify-official-plugins` のローカルクローン)の `models/` ディレクトリ内で、モデルプロバイダー名でフォルダを見つけるか作成します(例:`models/my_new_provider`)。
2. **`models` サブディレクトリの作成:** プロバイダーディレクトリ内に `models` サブディレクトリを作成します。
3. **モデルタイプごとのサブディレクトリ作成:** `models/models/` ディレクトリ内に、サポートする必要のある**各モデルタイプ**ごとにサブディレクトリを作成します。一般的なタイプには以下が含まれます:
* `llm`: テキスト生成モデル
* `text_embedding`: テキストEmbeddingモデル
* `rerank`: Rerankモデル
* `speech2text`: 音声認識モデル
* `tts`: テキスト読み上げモデル
* `moderation`: コンテンツ審査モデル
4. **実装ファイルの準備:**
* 各モデルタイプディレクトリ(例:`models/models/llm/`に、そのタイプのモデル呼び出しロジックを実装するためのPythonファイルを作成します`llm.py`)。
* 同じディレクトリに、そのタイプ下の各具体的なモデルごとにYAML設定ファイルを作成します`my-model-v1.yaml`)。
* (オプション)`_position.yaml` ファイルを作成して、そのタイプ下のモデルがDify UIに表示される順序を制御できます。
**構造例(プロバイダー `my_provider` がLLMとEmbeddingをサポートすると仮定**
```bash
models/my_provider/
├── models # モデル実装と設定ディレクトリ
│ ├── llm # LLMタイプ
│ │ ├── _position.yaml (オプション、ソート順制御)
│ │ ├── my-llm-model-v1.yaml
│ │ ├── my-llm-model-v2.yaml
│ │ └── llm.py # LLM実装ロジック
│ └── text_embedding # Embeddingタイプ
│ ├── _position.yaml (オプション、ソート順制御)
│ ├── my-embedding-model.yaml
│ └── text_embedding.py # Embedding実装ロジック
├── provider # プロバイダーレベルのコードディレクトリ
│ └── my_provider.py (認証情報検証などに使用、詳細は「モデルプロバイダーの作成」ドキュメント参照)
└── manifest.yaml # プラグインマニフェストファイル
```
---
## ステップ2モデル設定の定義YAML
各具体的なモデルについて、Difyがそれを正しく理解し使用できるように、その属性、パラメータ、および機能を記述するYAMLファイルを作成する必要があります。
1. **YAMLファイルの作成** 対応するモデルタイプディレクトリ(例:`models/models/llm/`に、追加するモデル用のYAMLファイルを作成します。ファイル名は通常、モデルIDと一致させるか、説明的なものにします`my-llm-model-v1.yaml`)。
2. **設定内容の記述:** [AIModelEntityスキーマ定義](../../../schema-definition/model/model-designing-rules.md#aimodelentity)仕様に従って内容を記述します。主要なフィールドは以下の通りです:
* `model`: 必須モデルの公式API識別子。
* `label`: 必須Dify UIに表示される名前多言語対応
* `model_type`: (必須)所在するディレクトリタイプと一致する必要があります(例:`llm`)。
* `features`: (オプション)モデルがサポートする特殊機能(`vision`、`tool-call`、`stream-tool-call`など)を宣言します。
* `model_properties`: (必須)モデル固有のプロパティ(`mode``chat`または`completion`)、`context_size`など)を定義します。
* `parameter_rules`: (必須)ユーザーが調整可能なパラメータとそのルール(名前`name`、タイプ`type`、必須`required`、デフォルト値`default`、範囲`min`/`max`、オプション`options`など)を定義します。`use_template`を使用して事前定義されたテンプレートを参照し、一般的なパラメータ(`temperature`、`max_tokens`など)の設定を簡略化できます。
* `pricing`: (オプション)モデルの課金情報を定義します。
**例(`claude-3-5-sonnet-20240620.yaml`**
```yaml
model: claude-3-5-sonnet-20240620
label:
en_US: claude-3-5-sonnet-20240620
model_type: llm
features:
- agent-thought
- vision
- tool-call
- stream-tool-call
- document
model_properties:
mode: chat
context_size: 200000
parameter_rules:
- name: temperature
use_template: temperature
- name: top_p
use_template: top_p
- name: max_tokens
use_template: max_tokens
required: true
default: 8192
min: 1
max: 8192 # Difyレベルで制限がある可能性に注意
pricing:
input: '3.00'
output: '15.00'
unit: '0.000001' # 100万トークンあたり
currency: USD
```
---
## ステップ3モデル呼び出しコードの記述Python
これはモデル機能実装の中核となるステップです。対応するモデルタイプのPythonファイル`llm.py`に、API呼び出し、パラメータ変換、結果返却を処理するコードを記述する必要があります。
1. **Pythonファイルの作成/編集:** モデルタイプディレクトリ(例:`models/models/llm/`で、対応するPythonファイル`llm.py`)を作成または開きます。
2. **実装クラスの定義:**
* クラスを定義します。例:`MyProviderLargeLanguageModel`。
* このクラスは、DifyプラグインSDK内の対応する**モデルタイプベースクラス**を継承する必要があります。例えば、LLMの場合は `dify_plugin.provider_kits.llm.LargeLanguageModel` を継承します。
```python
import logging
from typing import Union, Generator, Optional, List
from dify_plugin.provider_kits.llm import LargeLanguageModel # ベースクラスをインポート
from dify_plugin.provider_kits.llm import LLMResult, LLMResultChunk, LLMUsage # 結果と使用量クラスをインポート
from dify_plugin.provider_kits.llm import PromptMessage, PromptMessageTool # メッセージとツールクラスをインポート
from dify_plugin.errors.provider_error import InvokeError, InvokeAuthorizationError # エラークラスをインポート
# APIを呼び出すための vendor_sdk があると仮定します
# import vendor_sdk
logger = logging.getLogger(__name__)
class MyProviderLargeLanguageModel(LargeLanguageModel):
# ... メソッドを実装 ...
```
3. **主要メソッドの実装:**具体的に実装が必要なメソッドは継承するベースクラスによって異なります。以下はLLMを例とします
* `_invoke(...)`: **コア呼び出しメソッド**。
* **シグネチャ:** `def _invoke(self, model: str, credentials: dict, prompt_messages: List[PromptMessage], model_parameters: dict, tools: Optional[List[PromptMessageTool]] = None, stop: Optional[List[str]] = None, stream: bool = True, user: Optional[str] = None) -> Union[LLMResult, Generator[LLMResultChunk, None, None]]:`
* **責務:**
* `credentials` と `model_parameters` を使用してAPIリクエストを準備します。
* Difyの `prompt_messages` 形式をプロバイダーAPIが必要とする形式に変換します。
* Function Calling / Tool Useをサポートするために `tools` パラメータを処理します(モデルがサポートしている場合)。
* `stream` パラメータに基づいて、ストリーミング呼び出しを行うか同期呼び出しを行うかを決定します。
* **ストリーミング返却:** `stream=True` の場合、このメソッドはジェネレータ(`Generator`)を返す必要があり、`yield` を介して `LLMResultChunk` オブジェクトを逐次返却します。各チャンクには部分的な結果(テキスト、ツール呼び出しチャンクなど)とオプションの使用量情報が含まれます。
* **同期返却:** `stream=False` の場合、このメソッドは完全な `LLMResult` オブジェクトを返す必要があります。これには最終的なテキスト結果、完全なツール呼び出しリスト、および総使用量情報(`LLMUsage`)が含まれます。
* **実装パターン:** 同期ロジックとストリーミングロジックを内部ヘルパーメソッドに分割することを強く推奨します。
```python
def _invoke(self, ..., stream: bool = True, ...) -> Union[LLMResult, Generator[LLMResultChunk, None, None]]:
# APIリクエストパラメータの準備認証、モデルパラメータ変換、メッセージ形式変換など
api_params = self._prepare_api_params(credentials, model_parameters, prompt_messages, tools, stop)
try:
if stream:
return self._invoke_stream(model, api_params, user)
else:
return self._invoke_sync(model, api_params, user)
except vendor_sdk.APIError as e:
# APIエラーを処理し、Difyエラーにマッピングします_invoke_error_mappingを参照
# ... mapped_error を発生させる ...
pass # 実際のエラー処理に置き換えてください
except Exception as e:
logger.exception("モデル呼び出し中の不明なエラー")
raise e # または汎用的な InvokeError を発生させる
def _invoke_stream(self, model: str, api_params: dict, user: Optional[str]) -> Generator[LLMResultChunk, None, None]:
# vendor_sdk のストリーミングインターフェースを呼び出す
# for api_chunk in vendor_sdk.create_stream(...):
# # api_chunk を LLMResultChunk に変換する
# dify_chunk = self._convert_api_chunk_to_llm_result_chunk(api_chunk)
# yield dify_chunk
pass # 実際の実装に置き換えてください
def _invoke_sync(self, model: str, api_params: dict, user: Optional[str]) -> LLMResult:
# vendor_sdk の同期インターフェースを呼び出す
# api_response = vendor_sdk.create_sync(...)
# api_response を LLMResult (message.content, tools, usage を含む) に変換する
# dify_result = self._convert_api_response_to_llm_result(api_response)
# return dify_result
pass # 実際の実装に置き換えてください
```
* `validate_credentials(self, model: str, credentials: dict) -> None`: 必須ユーザーが認証情報を追加または変更する際にその有効性を検証するために使用されます。通常、簡単で低コストのAPIエンドポイント利用可能なモデルのリスト表示、残高確認などを呼び出すことで実装されます。検証に失敗した場合は、`CredentialsValidateFailedError` またはそのサブクラスをスローする必要があります。
* `get_num_tokens(self, model: str, credentials: dict, prompt_messages: List[PromptMessage], tools: Optional[List[PromptMessageTool]] = None) -> int`: オプションだが推奨与えられた入力のトークン数を推定するために使用されます。正確に計算できない場合やAPIがサポートしていない場合は、0を返すことができます。
* `@property _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]`: (必須)**エラーマッピング**辞書を定義します。キーはDifyの標準 `InvokeError` サブクラスであり、値はその標準エラーにマッピングされるべきプロバイダーSDKがスローする可能性のある例外タイプのリストです。これはDifyが異なるプロバイダーのエラーを統一的に処理するために不可欠です。
```python
@property
def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]:
# マッピング例
mapping = {
InvokeAuthorizationError: [
vendor_sdk.AuthenticationError,
vendor_sdk.PermissionDeniedError,
],
InvokeRateLimitError: [
vendor_sdk.RateLimitError,
],
# ... その他のマッピング ...
}
# ここにベースクラスのデフォルトマッピングを追加できます(ベースクラスが提供している場合)
# base_mapping = super()._invoke_error_mapping
# mapping.update(base_mapping) # マージ戦略に注意
return mapping
```
---
## ステップ4プラグインのデバッグ
プラグインをコミュニティに貢献する前に、十分なテストとデバッグが不可欠です。Difyはリモートデバッグ機能を提供しており、ローカルでコードを修正し、Difyインスタンスでリアルタイムに効果をテストできます。
1. **デバッグ情報の取得:**
* Difyインスタンスで、「プラグイン管理」ページに移動します管理者権限が必要な場合があります
* ページ右上の「プラグインのデバッグ」をクリックして、`デバッグキー`と`リモートサーバーアドレス`(例:`http://<your-dify-domain>:5003`)を取得します。
2. **ローカル環境の設定:**
* ローカルプラグインプロジェクトの**ルートディレクトリ**で、`.env`ファイルを見つけるか作成します(`.env.example`からコピーできます)。
* `.env`ファイルを編集し、デバッグ情報を入力します:
```dotenv
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=<your-dify-domain-or-ip> # Difyサーバーアドレス
REMOTE_INSTALL_PORT=5003 # デバッグポート
REMOTE_INSTALL_KEY=****-****-****-****-**** # あなたのデバッグキー
```
3. **ローカルプラグインサービスの起動:**
* プラグインプロジェクトのルートディレクトリで、Python環境がアクティブになっていることを確認します仮想環境を使用している場合
* メインプログラムを実行します:
```bash
python -m main
```
* ターミナルの出力を観察し、接続が成功すると、通常、対応するログが表示されます。
4. **Difyでのテスト**
* Difyの「プラグイン」または「モデルプロバイダー」ページを更新すると、ローカルプラグインインスタンスが表示され、「デバッグ中」のマークが付いている場合があります。
* 「設定」->「モデルプロバイダー」に移動し、プラグインを見つけて有効なAPI認証情報を設定します。
* Difyアプリケーションでモデルを選択して使用し、テストを行います。ローカルでのPythonコードの変更保存後、通常はサービスが自動的に再読み込みされますは、Difyでの呼び出し動作に直接影響します。Difyのデバッグプレビュー機能を使用すると、入出力とエラー情報を確認するのに役立ちます。
---
## ステップ5パッケージ化と公開
開発とデバッグが完了し、プラグインの機能に満足したら、パッケージ化してDifyコミュニティに貢献できます。
1. **プラグインのパッケージ化:**
* ローカルデバッグサービスを停止します(`Ctrl+C`)。
* プラグインプロジェクトの**ルートディレクトリ**でパッケージ化コマンドを実行します:
```bash
# <provider_name> をプロバイダーのディレクトリ名に置き換えます
dify plugin package models/<provider_name>
```
* これにより、プロジェクトのルートディレクトリに `<provider_name>.difypkg` ファイルが生成されます。
2. **プルリクエストの送信:**
* コードスタイルが良好で、Difyの[プラグイン公開仕様](https://docs.dify.ai/zh-hans/plugins/publish-plugins/publish-to-dify-marketplace)に従っていることを確認します。
* ローカルGitのコミットをフォークした `dify-official-plugins` リポジトリにプッシュします。
* GitHub上で `langgenius/dify-official-plugins` メインリポジトリに対してプルリクエストを作成します。PRの説明には、行った変更、追加したモデルや機能、および必要なテスト手順を明確に記述します。
* Difyチームのレビューを待ちます。レビューが承認されマージされると、あなたの貢献は公式プラグインに含まれ、[Difyマーケットプレイス](https://marketplace.dify.ai/)で利用可能になります。
---
## さらに探る
* [モデルスキーマ定義](/plugin_dev_ja/0412-model-schema.ja) モデルYAML仕様
* [プラグインマニフェスト構造](/plugin_dev_ja/0411-general-specifications.ja) `manifest.yaml` 仕様)
* [Dify Plugin SDKリファレンス](https://github.com/langgenius/dify-plugin-sdks) (ベースクラス、データ構造、エラータイプを検索)
* [Dify公式プラグインリポジトリ](https://github.com/langgenius/dify-official-plugins) (既存プラグインの実装を参照)

View File

@@ -0,0 +1,262 @@
---
dimensions:
type:
primary: implementation
detail: standard
level: intermediate
standard_title: Creating New Model Provider
language: ja
title: モデルプロバイダーの作成
description: このドキュメントでは、モデルプロバイダープラグインを作成する方法について詳しく説明します。プロジェクトの初期化、モデル設定方法事前定義モデルとカスタムモデルの選択、プロバイダー設定YAMLファイルの作成、およびプロバイダーコードの作成の完全なプロセスが含まれます。
---
Modelタイプのプラグインを作成する最初のステップは、プラグインプロジェクトを初期化し、モデルプロバイダーファイルを作成することです。その後、具体的な事前定義済み/カスタムモデルのコードを記述します。既存のモデルプロバイダーに新しいモデルを追加したいだけの場合は、[新しいモデルの迅速な統合](/plugin_dev_ja/0211-getting-started-new-model.ja)を参照してください。
### 事前準備
* Dify プラグインスケルトンツール
* Python 環境、バージョン ≥ 3.12
プラグイン開発用のスケルトンツールを準備する方法の詳細については、[開発ツールの初期化](/plugin_dev_ja/0221-initialize-development-tools.ja)を参照してください。開始する前に、[モデルプラグイン](/plugin_dev_ja/0131-model-plugin-introduction.ja)の基本的な概念と構造を理解することをお勧めします。
### 新規プロジェクトの作成
スケルトンコマンドラインツールのパスで、新しい Dify プラグインプロジェクトを作成します。
```
./dify-plugin-darwin-arm64 plugin init
```
このバイナリファイルを `dify` にリネームし、`/usr/local/bin` パスにコピーした場合、次のコマンドを実行して新しいプラグインプロジェクトを作成できます:
```bash
dify plugin init
```
### モデルプラグインテンプレートの選択
スケルトンツール内のすべてのテンプレートには、完全なコードプロジェクトが提供されています。`LLM` タイプのプラグインテンプレートを選択します。
![プラグインタイプ: llm](https://assets-docs.dify.ai/2024/12/8efe646e9174164b9edbf658b5934b86.png)
#### プラグイン権限の設定
このLLMプラグインに次の権限を設定します
* Models
* LLM
* Storage
![モデルプラグイン権限](https://assets-docs.dify.ai/2024/12/10f3b3ee6c03a1215309f13d712455d4.png)
#### モデルタイプ設定の説明
モデルプロバイダーは、以下の2つのモデル設定方法をサポートしています
* `predefined-model` **事前定義済みモデル**
一般的な大規模モデルタイプで、統一されたプロバイダーの認証情報を設定するだけで、プロバイダー下の事前定義済みモデルを使用できます。例えば、`OpenAI` モデルプロバイダーは `gpt-3.5-turbo-0125` や `gpt-4o-2024-05-13` などの一連の事前定義済みモデルを提供しています。詳細な開発手順については、事前定義済みモデルの統合を参照してください。
* `customizable-model` **カスタムモデル**
各モデルの認証情報設定を手動で追加する必要があります。例えば `Xinference` は、LLMとText Embeddingの両方をサポートしていますが、各モデルには一意の **model\_uid** があります。両方を同時に統合したい場合は、各モデルに **model\_uid** を設定する必要があります。詳細な開発手順については、カスタムモデルの統合を参照してください。
2つの設定方法は**共存をサポート**しており、つまり、プロバイダーが `predefined-model` + `customizable-model` または `predefined-model` などをサポートする場合、プロバイダーの統一された認証情報を設定することで、事前定義済みモデルとリモートから取得したモデルを使用できます。新しいモデルを追加した場合は、これに加えてカスタムモデルを使用できます。
### 新しいモデルプロバイダーの追加
新しいモデルプロバイダーを追加するには、主に次の手順が含まれます:
1. **モデルプロバイダー設定YAMLファイルの作成**
プロバイダーディレクトリに新しいYAMLファイルを追加し、プロバイダーの基本情報とパラメータ設定を記述します。ProviderSchemaの要件に従って内容を記述し、システム仕様との一貫性を確保します。
2. **モデルプロバイダーコードの記述**
プロバイダーのクラスコードを作成し、システムのインターフェース要件に準拠したPythonクラスを実装して、プロバイダーのAPIと連携し、コア機能を実現します。
***
以下は、各ステップの完全な操作詳細です。
#### 1. **モデルプロバイダー設定ファイルの作成**
ManifestはYAML形式のファイルであり、モデルプロバイダーの基本情報、サポートされるモデルタイプ、設定方法、認証情報ルールを宣言します。プラグインプロジェクトテンプレートは、`/providers` パスに設定ファイルを自動的に生成します。
以下は、`Anthropic` モデル設定ファイル `anthropic.yaml` のサンプルコードです:
```yaml
provider: anthropic
label:
en_US: Anthropic
description:
en_US: Anthropic's powerful models, such as Claude 3.
zh_Hans: Anthropic の強力なモデル、例えば Claude 3。
icon_small:
en_US: icon_s_en.svg
icon_large:
en_US: icon_l_en.svg
background: "#F0F0EB"
help:
title:
en_US: Get your API Key from Anthropic
zh_Hans: Anthropic から API キーを取得
url:
en_US: https://console.anthropic.com/account/keys
supported_model_types:
- llm
configurate_methods:
- predefined-model
provider_credential_schema:
credential_form_schemas:
- variable: anthropic_api_key
label:
en_US: API Key
type: secret-input
required: true
placeholder:
zh_Hans: ここに API キーを入力してください
en_US: Enter your API Key
- variable: anthropic_api_url
label:
en_US: API URL
type: text-input
required: false
placeholder:
zh_Hans: ここに API URL を入力してください
en_US: Enter your API URL
models:
llm:
predefined:
- "models/llm/*.yaml"
position: "models/llm/_position.yaml"
extra:
python:
provider_source: provider/anthropic.py
model_sources:
- "models/llm/llm.py"
```
接続するプロバイダーがカスタムモデルを提供する場合、例えば`OpenAI`がファインチューニングモデルを提供する場合、`model_credential_schema` フィールドを追加する必要があります。
以下は `OpenAI` ファミリーモデルのサンプルコードです:
```yaml
model_credential_schema:
model: # ファインチューニングモデル名
label:
en_US: Model Name
zh_Hans: モデル名
placeholder:
en_US: Enter your model name
zh_Hans: モデル名を入力
credential_form_schemas:
- variable: openai_api_key
label:
en_US: API Key
type: secret-input
required: true
placeholder:
zh_Hans: ここに API キーを入力してください
en_US: Enter your API Key
- variable: openai_organization
label:
zh_Hans: 組織 ID
en_US: Organization
type: text-input
required: false
placeholder:
zh_Hans: ここに組織 ID を入力してください
en_US: Enter your Organization ID
- variable: openai_api_base
label:
zh_Hans: API ベース
en_US: API Base
type: text-input
required: false
placeholder:
zh_Hans: ここに API ベースを入力してください
en_US: Enter your API Base
```
より完全なモデルプロバイダーYAML仕様については、[モデルスキーマ](/plugin_dev_ja/0412-model-schema.ja)ドキュメントを参照してください。
#### 2. **モデルプロバイダーコードの記述**
`/providers` フォルダに同名の Python ファイルを作成します。例えば `anthropic.py` とし、`__base.provider.Provider` 基本クラスを継承する `class` を実装します。例えば `AnthropicProvider` です。
以下は `Anthropic` のサンプルコードです:
```python
import logging
from dify_plugin.entities.model import ModelType
from dify_plugin.errors.model import CredentialsValidateFailedError
from dify_plugin import ModelProvider
logger = logging.getLogger(__name__)
class AnthropicProvider(ModelProvider):
def validate_provider_credentials(self, credentials: dict) -> None:
"""
Validate provider credentials
if validate failed, raise exception
:param credentials: provider credentials, credentials form defined in `provider_credential_schema`.
"""
try:
model_instance = self.get_model_instance(ModelType.LLM)
model_instance.validate_credentials(model="claude-3-opus-20240229", credentials=credentials)
except CredentialsValidateFailedError as ex:
raise ex
except Exception as ex:
logger.exception(f"{self.get_provider_schema().provider} credentials validate failed")
raise ex
```
プロバイダーは `__base.model_provider.ModelProvider` 基本クラスを継承し、`validate_provider_credentials` プロバイダー統一認証情報検証メソッドを実装するだけで済みます。
```python
def validate_provider_credentials(self, credentials: dict) -> None:
"""
Validate provider credentials
You can choose any validate_credentials method of model type or implement validate method by yourself,
such as: get model list api
if validate failed, raise exception
:param credentials: provider credentials, credentials form defined in `provider_credential_schema`.
"""
```
もちろん、`validate_provider_credentials` の実装を一旦プレースホルダとして残しておき、モデル認証情報検証メソッドの実装後に直接再利用することも可能です。
#### **カスタムモデルプロバイダー**
他のタイプのモデルプロバイダーについては、以下の設定方法を参照してください。
`Xinference` のようなカスタムモデルプロバイダーの場合、完全な実装手順をスキップできます。`XinferenceProvider` という名前の空のクラスを作成し、その中に空の `validate_provider_credentials` メソッドを実装するだけです。
**詳細説明:**
• `XinferenceProvider` は、カスタムモデルプロバイダーを識別するためのプレースホルダクラスです。
• `validate_provider_credentials` メソッドは実際には呼び出されませんが、存在する必要があります。これは、その親クラスが抽象クラスであり、すべてのサブクラスにこのメソッドの実装を要求するためです。空の実装を提供することで、抽象メソッドが未実装であることによるインスタンス化エラーを回避できます。
```python
class XinferenceProvider(Provider):
def validate_provider_credentials(self, credentials: dict) -> None:
pass
```
モデルプロバイダーを初期化した後、次にプロバイダーが提供する具体的なLLMモデルを統合する必要があります。詳細については、以下の内容を参照してください
* [モデル設計ルール](/plugin_dev_ja/0411-model-designing-rules.ja) - 事前定義済みモデルを統合するための仕様を理解する
* [モデルスキーマ](/plugin_dev_ja/0412-model-schema.ja) - カスタムモデルを統合するための仕様を理解する
* [リリース概要](/plugin_dev_ja/0321-release-overview.ja) - プラグインのリリースプロセスを学ぶ
## 参考リソース
- [新しいモデルの迅速な統合](/plugin_dev_ja/0211-getting-started-new-model.ja) - 既存のプロバイダーに新しいモデルを追加する方法
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - プラグイン開発入門ガイドに戻る
- [新しいモデルプロバイダー作成の補足](/plugin_dev_ja/0222-creating-new-model-provider-extra.ja) - より高度な設定について学ぶ
- [一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - プラグインマニフェストファイルの設定を理解する

View File

@@ -0,0 +1,376 @@
---
dimensions:
type:
primary: implementation
detail: standard
level: intermediate
standard_title: Tool Plugin
language: ja
title: Tool プラグイン
description: このドキュメントでは、Difyのツールプラグインを開発する方法を詳しく説明します。Google Searchを例に、プラグインの初期化、テンプレートの選択、ツールプロバイダー設定ファイルの定義、サードパーティサービス認証情報の追加、ツール機能コードの実装、デバッグ、パッケージ化と公開までの完全なツールプラグイン開発フローを紹介します。
---
ツールとは、Chatflow / Workflow / Agent タイプのアプリケーションから呼び出すことができるサードパーティサービスを指し、Difyアプリケーションの能力を強化するための完全なAPI実装機能を提供します。例えば、アプリケーションにオンライン検索や画像生成などの追加機能を追加します。
![ツールプラグインの例](https://assets-docs.dify.ai/2024/12/7e7bcf1f9e3acf72c6917ea9de4e4613.png)
この記事では、**「ツールプラグイン」** とは、ツールプロバイダーファイル、機能コードなどの構造を含む完全なプロジェクトを指します。1つのツールプロバイダーには複数のツール個々のツール内で提供される追加機能と理解できますを含めることができ、構造は以下の通りです。
```
- ツールプロバイダー
- Tool A
- Tool B
```
![ツールプラグインの構造](https://assets-docs.dify.ai/2025/02/60c4c86a317d865133aa460592eac079.png)
この記事では、`Google Search` を例に、ツールプラグインを迅速に開発する方法を紹介します。
### 事前準備
- Difyプラグインスキャフォールドツール
- Python環境、バージョン ≥ 3.12
プラグイン開発用のスキャフォールドツールの準備方法については、[開発ツールの初期化](/plugin_dev_ja/0221-initialize-development-tools.ja)を参照してください。初めてプラグインを開発する場合は、まず[Difyプラグイン開発Hello Worldガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja)を読むことをお勧めします。
### 新規プロジェクトの作成
スキャフォールドコマンドラインツールを実行し、新しいDifyプラグインプロジェクトを作成します。
```bash
./dify-plugin-darwin-arm64 plugin init
```
このバイナリファイルを `dify` にリネームし、`/usr/local/bin` パスにコピーした場合、以下のコマンドを実行して新しいプラグインプロジェクトを作成できます。
```bash
dify plugin init
```
> 以下では、コマンドラインの例として `dify` を使用します。問題が発生した場合は、`dify` コマンドをコマンドラインツールの実際のパスに置き換えてください。
### プラグインタイプとテンプレートの選択
スキャフォールドツール内のすべてのテンプレートは、完全なコードプロジェクトを提供しています。この記事の例では、`Tool` プラグインを選択します。
> プラグイン開発に慣れている場合は、テンプレートを使用せずに、[一般仕様](/plugin_dev_ja/0411-general-specifications.ja)のガイドラインを参照して、さまざまなタイプのプラグイン開発を完了できます。
![プラグインタイプ:ツール](https://assets-docs.dify.ai/2024/12/dd3c0f9a66454e15868eabced7b74fd6.png)
#### プラグイン権限の設定
プラグインはDifyプラットフォームの権限も読み取る必要があり、このサンプルプラグインには以下の権限を付与します。
- Tools
- Apps
- 永続ストレージStorageを有効にし、デフォルトサイズのストレージを割り当てる
- Endpointの登録を許可する
> ターミナル内で方向キーを使用して権限を選択し、「Tab」キーを使用して権限を付与します。
すべての権限項目にチェックを入れた後、Enterキーを押してプラグインの作成を完了します。システムは自動的にプラグインプロジェクトコードを生成します。
![プラグイン権限](https://assets-docs.dify.ai/2024/12/9cf92c2e74dce55e6e9e331d031e5a9f.png)
### ツールプラグインの開発
#### 1. ツールプロバイダーファイルの作成
ツールプロバイダーファイルはYAML形式のファイルで、ツールプラグインの基本設定エントリと理解でき、ツールに必要な認証情報を提供するために使用されます。
プラグインテンプレートプロジェクトの `/provider` パスに移動し、そこにあるyamlファイルを `google.yaml` にリネームします。この `yaml` ファイルには、ツールプロバイダーの情報(プロバイダー名、アイコン、作成者などの詳細)が含まれます。この情報はプラグインのインストール時に表示されます。
**コード例**
```yaml
identity: # ツールプロバイダーの基本情報
author: Your-name # 作成者
name: google # 名称、一意であり、他のプロバイダーと重複することはできません
label: # ラベル、フロントエンド表示用
en_US: Google # 英語ラベル
zh_Hans: Google # 中国語ラベル
description: # 説明、フロントエンド表示用
en_US: Google # 英語の説明
zh_Hans: Google # 中国語の説明
icon: icon.svg # ツールアイコン、_assetsフォルダに配置する必要があります
tags: # タグ、フロントエンド表示用
- search
```
このファイルパスが `/tools` ディレクトリに配置されるようにしてください。完全なパスは次のとおりです。
```yaml
plugins:
tools:
- 'google.yaml'
```
`google.yaml`ファイルは、プラグインプロジェクトにおける絶対パスを使用する必要があります。この例では、プロジェクトのルートディレクトリにあります。YAMLファイル内のidentityフィールドは次のように説明されます`identity`には、作成者、名前、ラベル、説明、アイコンなど、ツールプロバイダーの基本情報が含まれます。
- アイコンは添付リソースに属する必要があり、プロジェクトのルートディレクトリにある `_assets` フォルダに配置する必要があります。
- タグは、ユーザーがカテゴリ別にプラグインをすばやく見つけるのに役立ちます。以下は現在サポートされているすべてのタグです。
```python
class ToolLabelEnum(Enum):
SEARCH = 'search'
IMAGE = 'image'
VIDEOS = 'videos'
WEATHER = 'weather'
FINANCE = 'finance'
DESIGN = 'design'
TRAVEL = 'travel'
SOCIAL = 'social'
NEWS = 'news'
MEDICAL = 'medical'
PRODUCTIVITY = 'productivity'
EDUCATION = 'education'
BUSINESS = 'business'
ENTERTAINMENT = 'entertainment'
UTILITIES = 'utilities'
OTHER = 'other'
```
#### **2. サードパーティサービス認証情報の補完**
開発を容易にするため、サードパーティサービス `SerpApi` が提供する Google Search API を採用することを選択します。`SerpApi` は使用にあたって API Key の入力を要求するため、`yaml` ファイル内に `credentials_for_provider` フィールドを追加する必要があります。
完全なコードは以下の通りです。
```yaml
identity:
author: Dify
name: google
label:
en_US: Google
zh_Hans: Google
pt_BR: Google
description:
en_US: Google
zh_Hans: GoogleSearch
pt_BR: Google
icon: icon.svg
tags:
- search
credentials_for_provider: # credentials_for_provider フィールドを追加
serpapi_api_key:
type: secret-input
required: true
label:
en_US: SerpApi API key
zh_Hans: SerpApi APIキー
placeholder:
en_US: Please input your SerpApi API key
zh_Hans: SerpApi APIキーを入力してください
help:
en_US: Get your SerpApi API key from SerpApi
zh_Hans: SerpApiからSerpApi APIキーを取得します
url: https://serpapi.com/manage-api-key
tools:
- tools/google_search.yaml
extra:
python:
source: google.py
```
- `credentials_for_provider` の子構造は、[一般仕様](/plugin_dev_ja/0411-general-specifications.ja)の要件を満たす必要があります。
- このプロバイダーにどのツールが含まれているかを指定する必要があります。この例では、`tools/google_search.yaml` ファイルのみが含まれています。
- プロバイダーとして、基本情報を定義するだけでなく、そのコードロジックの一部を実装する必要があるため、その実装ロジックを指定する必要があります。この例では、機能のコードファイルを `google.py` に配置しましたが、一時的に実装せず、まず `google_search` のコードを作成します。
#### 3. ツールyamlファイルの記入
1つのツールプラグインには複数のツール機能を含めることができ、各ツール機能には、ツール機能の基本情報、パラメータ、出力などを含む `yaml` ファイルで記述する必要があります。
引き続き `GoogleSearch` ツールを例に、`/tools` フォルダ内に新しい `google_search.yaml` ファイルを作成します。
```yaml
identity:
name: google_search
author: Dify
label:
en_US: GoogleSearch
zh_Hans: Google検索
pt_BR: GoogleSearch
description:
human:
en_US: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
zh_Hans: Google SERP検索を実行し、スニペットとウェブページを抽出するためのツールです。入力は検索クエリである必要があります。
pt_BR: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
llm: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
parameters:
- name: query
type: string
required: true
label:
en_US: Query string
zh_Hans: クエリ文
pt_BR: Query string
human_description:
en_US: used for searching
zh_Hans: ウェブコンテンツの検索に使用
pt_BR: used for searching
llm_description: key words for searching
form: llm
extra:
python:
source: tools/google_search.py
```
- `identity` には、ツールの基本情報(名前、作成者、ラベル、説明など)が含まれます。
- `parameters` パラメータリスト
- `name` (必須)パラメータ名、一意であり、他のパラメータと重複することはできません。
- `type` (必須)パラメータタイプ。現在、`string`(文字列)、`number`(数値)、`boolean`(ブール値)、`select`(ドロップダウンリスト)、`secret-input`暗号化入力フィールドの5種類をサポートしています。機密情報には`secret-input`タイプを使用してください。
- `label`(必須)パラメータラベル、フロントエンド表示用。
- `form` (必須)フォームタイプ。現在、`llm`、`form`の2種類をサポートしています。
- Agentアプリケーションでは、`llm` はLLMが自身で推論するパラメータを示し、`form` はこのツールを使用するために事前に設定できるパラメータを示します。
- Workflowアプリケーションでは、`llm` と `form` の両方をフロントエンドで入力する必要がありますが、`llm` のパラメータはツールノードの入力変数として機能します。
- `required` 必須かどうか
- `llm` モードでは、パラメータが必須の場合、Agentはこのパラメータを推論する必要があります。
- `form` モードでは、パラメータが必須の場合、ユーザーは対話開始前にフロントエンドでこのパラメータを入力する必要があります。
- `options` パラメータオプション
- `llm` モードでは、DifyはすべてのオプションをLLMに渡し、LLMはこれらのオプションに基づいて推論できます。
- `form` モードで `type` が `select` の場合、フロントエンドはこれらのオプションを表示します。
- `default` デフォルト値。
- `min` 最小値、パラメータタイプが `number` の場合に設定できます。
- `max` 最大値、パラメータタイプが `number` の場合に設定できます。
- `human_description` フロントエンド表示用の説明、多言語対応。
- `placeholder` フィールド入力ボックスのヒントテキスト。フォームタイプが`form`で、パラメータタイプが`string`、`number`、`secret-input`の場合に設定でき、多言語対応です。
- `llm_description` LLMに渡す説明。LLMがこのパラメータをよりよく理解できるように、ここにこのパラメータに関するできるだけ詳細な情報を記述してください。
#### 4. ツールコードの準備
ツールの設定情報を入力した後、ツールの機能コードの作成を開始し、ツールの論理的な目的を実現できます。`/tools`ディレクトリに`google_search.py`を作成し、内容は以下の通りです。
```python
from collections.abc import Generator
from typing import Any
import requests
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
SERP_API_URL = "https://serpapi.com/search"
class GoogleSearchTool(Tool):
def _parse_response(self, response: dict) -> dict:
result = {}
if "knowledge_graph" in response:
result["title"] = response["knowledge_graph"].get("title", "")
result["description"] = response["knowledge_graph"].get("description", "")
if "organic_results" in response:
result["organic_results"] = [
{
"title": item.get("title", ""),
"link": item.get("link", ""),
"snippet": item.get("snippet", ""),
}
for item in response["organic_results"]
]
return result
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
params = {
"api_key": self.runtime.credentials["serpapi_api_key"],
"q": tool_parameters["query"],
"engine": "google",
"google_domain": "google.com",
"gl": "us",
"hl": "en",
}
response = requests.get(url=SERP_API_URL, params=params, timeout=5)
response.raise_for_status()
valuable_res = self._parse_response(response.json())
yield self.create_json_message(valuable_res)
```
この例の意味は、`serpapi` にリクエストを送信し、`self.create_json_message` を使用して `json` 形式のフォーマット済みデータを返すことです。返されるデータ型の詳細については、[プラグインのリモートデバッグ](/plugin_dev_ja/0411-remote-debug-a-plugin.ja)および[永続ストレージKV](/plugin_dev_ja/0411-persistent-storage-kv.ja)のドキュメントを参照してください。
#### 4. ツールプロバイダーコードの完成
最後に、認証情報検証ロジックを実装するためのプロバイダーの実装コードを作成する必要があります。認証情報検証が失敗した場合、`ToolProviderCredentialValidationError`例外がスローされます。検証が成功すると、`google_search`ツールサービスに正しくリクエストが送信されます。
`/provider` ディレクトリに `google.py` ファイルを作成し、コードの内容は以下の通りです。
```python
from typing import Any
from dify_plugin import ToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError
from tools.google_search import GoogleSearchTool
class GoogleProvider(ToolProvider):
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
try:
for _ in GoogleSearchTool.from_credentials(credentials).invoke(
tool_parameters={"query": "test", "result_type": "link"},
):
pass
except Exception as e:
raise ToolProviderCredentialValidationError(str(e))
```
### プラグインのデバッグ
プラグインの開発が完了したら、次にプラグインが正常に動作するかをテストする必要があります。Difyは便利なリモートデバッグ方法を提供し、テスト環境でプラグイン機能を迅速に検証するのに役立ちます。
[「プラグイン管理」](https://cloud.dify.ai/plugins)ページに移動して、リモートサーバーアドレスとデバッグキーを取得します。
![Remote Debug Key](https://assets-docs.dify.ai/2024/12/053415ef127f1f4d6dd85dd3ae79626a.png)
プラグインプロジェクトに戻り、`.env.example` ファイルをコピーして `.env` にリネームし、取得したリモートサーバーアドレスとデバッグキーなどの情報を入力します。
`.env` ファイル:
```bash
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=remote
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****
```
`python -m main` コマンドを実行してプラグインを起動します。プラグインページで、このプラグインがWorkspaceにインストールされていることが確認でき、チームの他のメンバーもこのプラグインにアクセスできます。
![](https://assets-docs.dify.ai/2024/11/0fe19a8386b1234755395018bc2e0e35.png)
### プラグインのパッケージ化(オプション)
プラグインが正常に動作することを確認した後、以下のコマンドラインツールを使用してプラグインをパッケージ化し、名前を付けることができます。実行後、現在のフォルダに `google.difypkg` ファイルが見つかります。これは最終的なプラグインパッケージです。
```bash
# ./google をプラグインプロジェクトの実際のパスに置き換えてください
dify plugin package ./google
```
おめでとうございます、これでツールタイププラグインの完全な開発、デバッグ、パッケージ化プロセスを完了しました!
### プラグインの公開(オプション)
プラグインをDify Marketplaceに公開したい場合は、プラグインが[Difyマーケットプレイスへの公開](/plugin_dev_ja/0322-release-to-dify-marketplace.ja)の仕様に従っていることを確認してください。審査に合格すると、コードはメインブランチにマージされ、自動的に[Dify Marketplace](https://marketplace.dify.ai/)に公開されます。
[公開概要](/plugin_dev_ja/0321-release-overview.ja)
### さらに探る
#### **クイックスタート:**
- [Extensionプラグインの開発](/plugin_dev_ja/9231-extension-plugin.ja)
- [Modelプラグインの開発](/plugin_dev_ja/0211-getting-started-new-model.ja)
- [Bundleプラグイン複数のプラグインをパッケージ化](/plugin_dev_ja/9241-bundle.ja)
#### **プラグインインターフェースドキュメント:**
- [一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - Manifest構造とツール仕様
- [エンドポイント](/plugin_dev_ja/0432-endpoint.ja) - Endpoint詳細定義
- [リバースコール](/plugin_dev_ja/9241-reverse-invocation.ja) - Dify機能のリバースコール
- [モデルスキーマ](/plugin_dev_ja/0412-model-schema.ja) - モデル
- [Agentプラグイン](/plugin_dev_ja/9232-agent.ja) - Agent戦略の拡張
## 次のステップ
- [プラグインのリモートデバッグ](/plugin_dev_ja/0411-remote-debug-a-plugin.ja) - より高度なデバッグテクニックを学ぶ
- [永続ストレージ](/plugin_dev_ja/0411-persistent-storage-kv.ja) - プラグインでデータストレージを使用する方法を学ぶ
- [Slackボットプラグイン開発例](/plugin_dev_ja/0432-develop-a-slack-bot-plugin.ja) - より複雑なプラグイン開発事例を見る
- [ツールプラグイン](/plugin_dev_ja/0411-tool.ja) - ツールプラグインの高度な機能を探る

View File

@@ -0,0 +1,62 @@
---
dimensions:
type:
primary: operational
detail: setup
level: intermediate
standard_title: Contributor Covenant Code of Conduct
language: ja
title: プラグイン開発者ガイドライン
description: このドキュメントは、Difyプラグイン開発者がプルリクエストを送信する前に従うべきガイドラインを提供します。これには、プラグインが正常に機能すること、ドキュメントが完全であること、独自の価値を提供すること、データプライバシーとセキュリティ規範に準拠することが含まれます。説明ドキュメントの要件、重複プラグインを避けるためのガイドライン、プライバシー情報収集の宣言要件が含まれています。
---
### プルリクエストPRを送信する前に
1. **プラグインが正常に機能し、ドキュメントが完全であることを確認する**
* プラグインが正常に機能することを確認してください。詳細は[プラグインのリモートデバッグ](/plugin_dev_ja/0411-remote-debug-a-plugin.ja)を参照してください。
* 包括的な**READMEファイル**を提供してください。内容は以下の通りです:
* 設定手順と使用ガイド。
* プラグインユーザーがプラグインをサービスに接続するために必要なコード、API、認証情報、またはその他の情報。
* 収集されたユーザー情報は、サービスの接続とプラグイン機能の改善にのみ使用されることを確認してください。
* [プラグインのプライバシーデータ保護ガイドライン](/plugin_dev_ja/0312-privacy-protection-guidelines.ja)に従って、プライバシーポリシーの内容ファイルまたはオンラインドキュメントのURLを準備してください。
2. **プラグインの貢献価値を確認する**
* プラグインがDifyユーザーに独自の価値を提供することを確認してください。
* プラグインは、Difyや他のプラグインがまだ提供していない機能やサービスを導入する必要があります。
* コミュニティ基準に従ってください:
* コンテンツは非暴力的であり、グローバルなユーザーコミュニティを尊重するものであること。
* 統合サービスの関連ポリシーに準拠していること。
* **類似のプラグインが既に存在するかどうかを確認する方法は?**
* 既存のプラグインやPRと機能が重複するものを提出することは避けてください。ただし、新しいプラグインが以下の特徴を備えている場合は除きます
* 新しい機能を導入する。
* パフォーマンスの改善を提供する。
* **プラグインが十分にユニークかどうかを判断する方法:**
* プラグインが既存の機能にわずかな調整(言語パラメータの追加など)を加えるだけの場合は、既存のプラグインを直接拡張することをお勧めします。
* プラグインが大幅な機能変更(バッチ処理の最適化やエラー処理の改善など)を実現する場合は、新しいプラグインとして提出できます。
* 不明な場合は、PR提出時に簡単な説明を添付し、なぜ新しいプラグインを提出する必要があるのかを説明してください。
**例:** Google検索プラグインを例にとると、単一の入力クエリを受け付け、Google検索APIを使用してGoogle検索結果のリストを出力します。もし、同様の基盤実装を持つ新しいGoogle検索プラグインを提供するが、入力にわずかな調整例えば、新しい言語パラメータの追加を加えるだけの場合、既存のプラグインを拡張することをお勧めします。一方、プラグインが最適化されたバッチ検索やエラー処理能力を新しい方法で実装した場合、それは個別のプラグインとして審査される可能性があります。
3. **プラグインが以下のプライバシーデータ規範に準拠していることを確認する**
### 情報開示要件:
* 開発者は、アプリケーション/ツールを提出する際に、いかなる種類のユーザー個人データを収集するかどうかを**必ず**宣言する必要があります。詳細は[プラグインのプライバシーデータ保護ガイドライン](/plugin_dev_ja/0312-privacy-protection-guidelines.ja)を参照してください。
* 収集する場合、収集するデータタイプを**簡単にリストアップ**する必要がありますユーザー名、メールアドレス、デバイスID、位置情報など。**詳細すぎる必要はありません**。
* 開発者は**必ず**プライバシーポリシーへのリンクを提供する必要があります。プライバシーポリシーには、収集する情報、その情報の使用方法、第三者に開示される情報、および関連する第三者のプライバシーポリシーへのリンクを記載するだけで十分です。
**審査のポイント:**
* **形式審査:** 要件に従ってデータ収集状況が宣言されているかを確認します。
* **高リスクデータの調査:** 機密データ(例:健康情報、財務情報、子供の個人情報など)を収集しているかどうかに重点を置きます。機密データを収集している場合は、その使用目的とセキュリティ対策について**追加審査**が必要です。
* **悪意のある行為の調査:** ユーザーの同意なしにデータを収集したり、ユーザーデータを未知のサーバーにアップロードしたりするなどの明らかな悪意のある行為が存在しないかを確認します。
## 関連リソース
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - プラグイン開発の基礎を理解する
- [プラグインのリリース](/plugin_dev_ja/0321-release-overview.ja) - プラグインリリースプロセスの概要
- [プラグインのプライバシーデータ保護ガイドライン](/plugin_dev_ja/0312-privacy-protection-guidelines.ja) - プライバシーポリシー作成ガイド
- [Dify Marketplaceへのリリース](/plugin_dev_ja/0322-release-to-dify-marketplace.ja) - 公式マーケットプレイスでプラグインをリリースする
- [プラグインのリモートデバッグ](/plugin_dev_ja/0411-remote-debug-a-plugin.ja) - プラグインデバッグガイド

View File

@@ -0,0 +1,90 @@
---
dimensions:
type:
primary: operational
detail: setup
level: intermediate
standard_title: Privacy Protection Guidelines
language: ja
title: プラグインのプライバシーポリシーガイドライン
description: このドキュメントでは、開発者がDifyマーケットプレイスにプラグインを提出する際にプライバシーポリシーを作成する方法のガイドラインを説明します。内容には、収集される個人データの種類直接識別情報、間接識別情報、組み合わせ情報の確認とリストアップ方法、プラグインのプライバシーポリシーの記入方法、マニフェストファイルでのプライバシーポリシー宣言の導入方法、および関連するよくある質問への回答が含まれます。
---
Difyマーケットプレイスにプラグインを提出申請する際には、ユーザーデータの取り扱い方法を公開する必要があります。以下は、プラグイン関連のプライバシー問題とユーザーデータ処理の記入に関するガイドラインです。まだプラグインを開発していない場合は、[プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja)を参照してください。
プラグインのプライバシーポリシー宣言の内容は、以下の問題を中心に展開されます:
**あなたのプラグインはユーザーの個人データを収集・使用しますか?** もしそうであれば、具体的な種類を整理してリストアップしてください。
> 個人データとは、特定の個人を識別できるあらゆる情報を指し、単独で、または他の情報と組み合わせて個人を識別、連絡、または特定するために使用できる情報を含みます。
#### **1. 収集されるデータの種類をリストアップする**
**タイプ1直接識別情報**
* 氏名(フルネーム、名、姓)
* メールアドレス
* 電話番号
* 住所
* 身分証明書番号IDカード、パスポート、運転免許証など
**タイプ2間接識別情報**
* デバイス識別子IMEI、MACアドレス、デバイスID
* IPアドレス
* 位置情報GPS座標、都市、地域
* オンライン識別子Cookie、広告ID
* ユーザー名
* プロフィール画像
* 生体認証情報(指紋、顔認証)
* 閲覧履歴
* 購入履歴
* 健康データ
* 財務情報
**タイプ3個人を識別するために使用される組み合わせ情報**
* 年齢
* 性別
* 職業
* 趣味・関心事
あなたのプラグイン自体が個人情報を収集しない場合でも、プラグインが使用するサードパーティサービスがデータ収集または処理に関与しているかどうかを確認してください。開発者として、サードパーティサービスによるデータ処理を含む、すべてのデータ収集活動を公開する必要があります。サードパーティサービスのプライバシーポリシーを必ず読み、提出時にプラグインに関連するすべてのデータ収集状況を宣言するようにしてください。
例えば、開発中のプラグインがSlackサービスに関わる場合、プラグインのプライバシーポリシー宣言ファイルで[Slackのプライバシーポリシー](https://slack.com/trust/privacy/privacy-policy)を参照し、データ収集状況を宣言してください。
#### 2. 最新バージョンのプラグインプライバシーポリシーを記入する
**プラグインのプライバシーポリシー**には、以下を含める必要があります:
* 収集されるデータの種類
* データの使用目的
* 第三者とデータを共有するかどうか(共有する場合、第三者サービスの名称とそのプライバシーポリシーへのリンクを記載)
* プライバシーポリシーの書き方に慣れていない場合は、Dify公式がメンテナンスしているプラグイン内のプライバシーポリシーを参考にすることができます。
#### **3. プラグインのマニフェストファイル内でプライバシーポリシー宣言を導入する**
詳細なフィールドの記入方法については、[マニフェストファイルによるプラグイン情報の定義](/plugin_dev_ja/0411-plugin-info-by-manifest.ja)を参照してください。
### **よくある質問**
1. **ユーザー個人データの「収集と使用」とは何ですか?一般的なケースにはどのようなものがありますか?**
「収集と使用」とは、ユーザーデータの収集、転送、使用、または共有を指します。一般的な状況には以下が含まれます:
* フォームを通じて個人情報を収集する;
* ログイン機能を使用する(サードパーティ認証を含む);
* 個人情報を含む可能性のある入力またはリソースを収集する;
* ユーザーの行動、インタラクション、および使用状況を分析する;
* メッセージ、チャット履歴、メールなどの通信内容を保存する;
* 関連するソーシャルメディアのユーザープロフィールにアクセスする;
* 運動、心拍数、医療情報などの健康データを収集する;
* 検索履歴または閲覧行動を保存する;
* 銀行情報、信用スコア、取引記録などの財務情報を処理する。
## 関連リソース
- [プラグインの公開](/plugin_dev_ja/0321-release-overview.ja) - プラグインの公開プロセスを理解する
- [Difyマーケットプレイスへの公開](/plugin_dev_ja/0322-release-to-dify-marketplace.ja) - 公式マーケットプレイスへのプラグイン提出方法を学ぶ
- [プラグイン開発者ガイドライン](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja) - プラグイン提出の規範を理解する
- [マニフェストファイルによるプラグイン情報の定義](/plugin_dev_ja/0411-plugin-info-by-manifest.ja) - プラグインメタデータの設定

View File

@@ -0,0 +1,84 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: beginner
standard_title: Release Overview
language: ja
title: プラグインのリリース
description: このドキュメントでは、Difyプラグインの3つのリリース方法公式Marketplace、オープンソースのGitHubリポジトリ、ローカルプラグインファイルパッケージを紹介します。各リリース方法の特徴、リリースプロセス、適用シナリオについて詳しく説明し、さまざまな開発者のニーズを満たすための具体的なリリースに関する推奨事項を提供します。
---
### リリース方法
さまざまな開発者のリリースニーズを満たすために、Difyは以下の3つのプラグインリリース方法を提供しています。リリース前に、プラグインの開発とテストが完了していることを確認し、[プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja)と[プラグイン開発者行動規範](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja)をお読みください。
#### **1. Marketplace**
**概要**Dify公式が提供するプラグインマーケットで、ユーザーはここでさまざまなプラグインを閲覧、検索し、ワンクリックでインストールできます。
**特徴**
* プラグインは審査後に公開され、**安全で信頼性があります**。
* 個人またはチームの **Workspace** に直接インストールできます。
**リリースプロセス**
* プラグインプロジェクトを **Dify Marketplace** の[コードリポジトリ](https://github.com/langgenius/dify-plugins)に提出します。
* 公式審査後、プラグインはマーケット内で公開され、他のユーザーがインストールして使用できるようになります。
詳細については、以下を参照してください:
[Dify Marketplaceへのリリース](/plugin_dev_ja/0322-release-to-dify-marketplace.ja)
#### 2. **GitHub リポジトリ**
**概要**:プラグインをオープンソース化または **GitHub** 上でホストし、他の人が閲覧、ダウンロード、インストールしやすくします。
**特徴**
* **バージョン管理**と**オープンソース共有**に便利です。
* ユーザーはプラグインリンクを通じて直接インストールでき、プラットフォームの審査は不要です。
**リリースプロセス**
* プラグインコードを GitHub リポジトリにプッシュします。
* リポジトリリンクを共有し、ユーザーはリンクを通じてプラグインを **Dify Workspace** に統合できます。
詳細については、以下を参照してください:
[個人の GitHub リポジトリへのリリース](/plugin_dev_ja/0322-release-to-individual-github-repo.ja)
#### 3. プラグインファイルパッケージ(ローカルインストール)
**概要**:プラグインをローカルファイル(例:`.difypkg` 形式)にパッケージ化し、ファイル共有を通じて他の人がインストールできるようにします。
**特徴**
* オンラインプラットフォームに依存せず、プラグインを**迅速かつ柔軟に**共有できます。
* **プライベートプラグイン**または**内部テスト**に適しています。
**リリースプロセス**
* プラグインプロジェクトをローカルファイルにパッケージ化します。
* Dify プラグインページで**プラグインをアップロード**をクリックし、ローカルファイルを選択してプラグインをインストールします。
プラグインプロジェクトをローカルファイルにパッケージ化して他の人と共有し、プラグインページでファイルをアップロードすると、プラグインを Dify Workspace 内にインストールできます。
詳細については、以下を参照してください:
[ローカルファイルへのパッケージ化と共有](/plugin_dev_ja/0322-release-by-file.ja)
### **リリースに関する推奨事項**
* **プラグインを宣伝したい場合** → **Marketplace の使用を推奨します**。公式審査を通じてプラグインの品質を保証し、露出度を高めます。
* **オープンソース共有プロジェクトの場合** → **GitHub の使用を推奨します**。バージョン管理とコミュニティ連携に便利です。
* **迅速な配布または内部テストの場合** → **プラグインファイルの使用を推奨します**。簡単かつ効率的にインストールおよび共有できます。
## 関連リソース
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - Difyプラグイン開発の全体像を理解する
- [プラグイン開発者行動規範](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja) - プラグイン提出の規範を理解する
- [プラグインのプライバシーデータ保護ガイドライン](/plugin_dev_ja/0312-privacy-protection-guidelines.ja) - プライバシーポリシー作成要件を理解する
- [一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - プラグインマニフェストファイルの設定を理解する

View File

@@ -0,0 +1,63 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: intermediate
standard_title: Release by File
language: ja
title: ローカルファイルへのパッケージ化と共有
description: このドキュメントでは、Difyプラグインプロジェクトをローカルファイルにパッケージ化し、他のユーザーと共有するための詳細な手順を説明します。内容には、プラグインのパッケージ化前の準備作業、Difyプラグイン開発ツールを使用したパッケージ化コマンドの実行、生成された.difypkgファイルのインストール方法、およびプラグインファイルを他のユーザーと共有する方法が含まれます。
---
プラグイン開発が完了したら、プラグインプロジェクトをローカルファイルにパッケージ化し、他のユーザーと共有できます。プラグインファイルを使用して、Dify Workspaceにインストールできます。まだプラグインを開発していない場合は、[プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja)を参照してください。
* **特徴**
* オンラインプラットフォームに依存せず、**迅速かつ柔軟**にプラグインを共有できます。
* **プライベートプラグイン**または**内部テスト**に適しています。
* **リリースフロー**
* プラグインプロジェクトをローカルファイルにパッケージ化します。
* Difyプラグインページでファイルをアップロードしてプラグインをインストールします。
この記事では、プラグインプロジェクトをローカルファイルにパッケージ化する方法、およびローカルファイルを使用してプラグインをインストールする方法について説明します。
### 事前準備
* **Difyプラグイン開発ツール**、詳細については[開発ツールの初期化](/plugin_dev_ja/0221-initialize-development-tools.ja)を参照してください。
設定が完了したら、ターミナルで `dify version` コマンドを入力し、バージョン番号情報が出力されるか確認して、必要な開発ツールがインストールされていることを確認します。
### プラグインのパッケージ化
> プラグインをパッケージ化する前に、プラグインの `manifest.yaml` ファイルと `/provider` パス以下の `.yaml` ファイル内の `author` フィールドがGitHub IDと一致していることを確認してください。マニフェストファイルの詳細については、[一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja)を参照してください。
プラグインプロジェクトの開発が完了したら、[リモートデバッグテスト](/plugin_dev_ja/0411-remote-debug-a-plugin.ja)が完了していることを確認してください。プラグインプロジェクトの親ディレクトリに移動し、以下のプラグインパッケージ化コマンドを実行します。
```bash
dify plugin package ./your_plugin_project
```
コマンドを実行すると、現在のパスに `.difypkg` という拡張子で終わるファイルが生成されます。
![プラグインファイルの生成](https://assets-docs.dify.ai/2024/12/98e09c04273eace8fe6e5ac976443cca.png)
### プラグインのインストール
Difyプラグイン管理ページにアクセスし、右上の**プラグインをインストール** → **ローカルファイル経由**でインストールをクリックするか、プラグインファイルをページの空白部分にドラッグアンドドロップしてプラグインをインストールします。
![プラグインファイルのインストール](https://assets-docs.dify.ai/2024/12/8c31c4025a070f23455799f942b91a57.png)
### プラグインの公開
プラグインファイルを他のユーザーと共有したり、インターネットにアップロードして他のユーザーがダウンロードできるようにしたりできます。より広範囲にプラグインを共有したい場合は、次の方法を検討してください。
1. [個人のGitHubリポジトリに公開する](/plugin_dev_ja/0322-release-to-individual-github-repo.ja) - GitHub経由でプラグインを共有
2. [Dify Marketplaceに公開する](/plugin_dev_ja/0322-release-to-dify-marketplace.ja) - 公式マーケットプレイスでプラグインを公開
## 関連リソース
- [プラグインの公開](/plugin_dev_ja/0321-release-overview.ja) - 様々な公開方法について理解する
- [開発ツールの初期化](/plugin_dev_ja/0221-initialize-development-tools.ja) - プラグイン開発環境を設定する
- [プラグインのリモートデバッグ](/plugin_dev_ja/0411-remote-debug-a-plugin.ja) - プラグインのデバッグ方法を学ぶ
- [一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - プラグインのメタデータを定義する
- [プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja) - ゼロからプラグインを開発する

View File

@@ -0,0 +1,101 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: intermediate
standard_title: Release to Dify Marketplace
language: ja
title: Dify Marketplaceへの公開
description: このガイドでは、Dify Marketplaceにプラグインを公開する完全なプロセスを詳細に説明します。PRの提出、審査プロセス、公開後のメンテナンスなど、主要なステップと注意事項を含みます。
---
Dify Marketplaceは、パートナーやコミュニティ開発者からのプラグインの登録申請を歓迎します。あなたの貢献は、Difyプラグインの可能性をさらに豊かにします。このガイドでは、明確な公開プロセスとベストプラクティスの推奨事項を提供し、あなたのプラグインがスムーズに公開され、コミュニティに価値をもたらすことを目指します。まだプラグインを開発していない場合は、[プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja)を参照してください。
以下の手順に従って、[GitHubコードリポジトリ](https://github.com/langgenius/dify-plugins)でプラグインのPull RequestPRを提出し、審査を受けてください。承認されると、プラグインは正式にDify Marketplaceに公開されます。
### プラグインの公開プロセス
Dify Marketplaceへのプラグイン公開には、以下のステップが含まれます
1. [プラグイン開発者行動規範](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja)に従ってプラグインの開発とテストを完了します。
2. [プラグインプライバシーデータ保護ガイドライン](/plugin_dev_ja/0312-privacy-protection-guidelines.ja)に従ってプラグインのプライバシーポリシーを作成し、そのプライバシーポリシーのファイルパスまたはURLをプラグインの[一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja)に記述します。
3. プラグインのパッケージングを完了します。
4. [Dify Plugins](https://github.com/langgenius/dify-plugins)コードリポジトリをフォークします。
5. Organizationディレクトリを作成し、Organizationディレクトリ内にプラグイン名ディレクトリを作成し、プラグインのコードとpkgファイルを対応するプラグイン名ディレクトリにアップロードします。
6. GitHubのPRテンプレートのコンテンツ形式に従ってPull RequestPRを提出し、審査を待ちます。
7. 審査に合格すると、プラグインコードはMainブランチにマージされ、プラグインは自動的に[Dify Marketplace](https://marketplace.dify.ai/)に登録されます。
プラグインの提出、審査、登録のフロー図:
![The process of uploading plugins](https://assets-docs.dify.ai/2025/01/05df333acfaf662e99316432db23ba9f.png)
> **注**: 上図のContributor Agreementは[プラグイン開発者行動規範](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja)を指します。
***
### Pull RequestPR審査期間中
審査担当者からの質問やフィードバックに積極的に対応してください:
* **14日以内**に解決されないPRコメントは古いものとしてマークされます再開可能
* **30日以内**に解決されないPRコメントはクローズされます再開不可、新しいPRを作成する必要があります
***
### **Pull RequestPR審査承認後**
**1. 継続的なメンテナンス**
* ユーザーから報告された問題や機能リクエストに対応します。
* 重大なAPI変更が発生した場合のプラグイン移行
* Difyは事前に変更通知と移行手順を公開します。
* Difyのエンジニアが移行サポートを提供できます。
**2. Marketplace公開ベータテスト段階での制限**
* 既存のプラグインに破壊的な変更を導入することを避けてください。
***
### 審査プロセス
**1. 審査順序**
* PRは**先着順**で処理されます。審査は1週間以内に開始されます。遅延がある場合、審査担当者はコメントを通じてPR作成者に通知します。
**2. 審査の重点**
* プラグイン名、説明、設定手順が明確で指導的であるかを確認します。
* プラグインの[一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja)が形式仕様に準拠しており、有効な作成者の連絡先情報が含まれているかを確認します。
3. **プラグインの機能性と関連性**
* [プラグイン開発ガイド](/plugin_dev_ja/0111-getting-started-dify-plugin.ja)に従ってプラグインをテストします。
* Difyエコシステムにおけるプラグインの用途が合理的であることを確認します。
[Dify.AI](https://dify.ai/)は、プラグイン提出の承認または拒否の権利を留保します。
***
### よくある質問
1. **プラグインがユニークであるかどうかをどのように判断しますか?**
Google検索プラグインが多言語バージョンを追加しただけの場合、既存プラグインの最適化と見なされるべきです。しかし、プラグインが顕著な機能改善バッチ処理の最適化やエラー処理などを実現している場合は、新しいプラグインとして提出できます。
2. **私のPRが古いものとしてマークされたり、クローズされた場合はどうすればよいですか**
古いものとしてマークされたPRは、フィードバックを解決した後に再開できます。クローズされたPR30日以上経過は、新しいPRを再作成する必要があります。
3. **ベータテスト段階でプラグインを更新できますか?**
はい、ただし破壊的な変更を導入することは避けるべきです。
## 関連リソース
- [プラグインの公開](/plugin_dev_ja/0321-release-overview.ja) - さまざまな公開方法を理解する
- [プラグイン開発者行動規範](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja) - プラグイン提出規範
- [プラグインプライバシーデータ保護ガイドライン](/plugin_dev_ja/0312-privacy-protection-guidelines.ja) - プライバシーポリシー作成要件
- [ローカルファイルとしてのパッケージ化と共有](/plugin_dev_ja/0322-release-by-file.ja) - プラグインのパッケージ化方法
- [一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - プラグインメタデータ定義

View File

@@ -0,0 +1,106 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: intermediate
standard_title: Release to Individual GitHub Repo
language: ja
title: 個人のGitHubリポジトリへの公開
description: このドキュメントでは、Difyプラグインを個人のGitHubリポジトリに公開する方法について詳しく説明します。準備作業、ローカルプラグインリポジトリの初期化、リモートリポジトリへの接続、プラグインファイルのアップロード、プラグインコードのパッケージング、GitHub経由でのプラグインインストール方法の全プロセスが含まれます。この方法により、開発者は自身のプラグインコードと更新を完全に管理できます。
---
GitHubリポジトリのリンクからプラグインをインストールできます。プラグインの開発が完了したら、他の人がダウンロードして使用できるように、公開GitHubリポジトリにプラグインを公開することを選択できます。まだプラグインを開発していない場合は、[プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja)を参照してください。
この方法には、以下の利点があります。
• **個人管理**:プラグインのコードと更新を完全に制御できます
• **迅速な共有**GitHubリンクを通じて他のユーザーやチームメンバーに簡単に共有でき、テストと使用に便利です
• **協力とフィードバック**プラグインをオープンソースにすると、GitHub上の潜在的な協力者を引き付け、プラグインの迅速な改善に役立つ可能性があります
この記事では、プラグインをGitHubリポジトリに公開する方法を説明します。
### 準備作業
まず、プラグインを開発しテスト済みであること、および[プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja)と[プラグイン開発者行動規範](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja)を読んだことを確認してください。プラグインを公開する前に、ローカルに以下のツールがインストールされていることを確認してください:
* GitHubアカウント
* 新しい公開GitHubリポジトリを作成する
* ローカルにGitツールがインストール済みであること
GitHubの基本知識については、[GitHubドキュメント](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-new-repository)を参照してください。
### 1. プラグインプロジェクトの完成
公開GitHubにアップロードするということは、プラグインを公開することを意味します。プラグインのデバッグと検証が完了し、プラグインの `README.md` ファイルの説明が完成していることを確認してください。
説明ファイルには、以下の内容を含めることをお勧めします:
* プラグインの概要と機能説明
* インストールと設定の手順
* 使用例
* 連絡先または貢献ガイドライン
### 2. ローカルプラグインリポジトリの初期化
プラグインをGitHubに公開アップロードする前に、プラグインのデバッグと検証作業が完了していることを確認してください。詳細は[リモートデバッグプラグイン](/plugin_dev_ja/0411-remote-debug-a-plugin.ja)を参照してください。ターミナルでプラグインプロジェクトフォルダに移動し、以下のコマンドを実行します:
```bash
git init
git add .
git commit -m "Initial commit: Add plugin files"
```
初めてGitを使用する場合、Gitのユーザー名とメールアドレスを設定する必要があるかもしれません
```bash
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
```
### 3. リモートリポジトリへの接続
以下のコマンドを使用して、ローカルリポジトリをGitHubリポジトリに接続します
```bash
git remote add origin https://github.com/<your-username>/<repository-name>.git
```
### 4. プラグインファイルのアップロード
> プラグインをパッケージ化する前に、プラグインの`manifest.yaml`ファイルと`/provider`パス以下の`.yaml`ファイル内のauthorフィールドがGitHub IDと一致していることを確認してください。マニフェストファイルの详细な仕様については、[マニフェストファイルによるプラグイン情報の定義](/plugin_dev_ja/0411-plugin-info-by-manifest.ja)を参照してください。
プラグインプロジェクトをGitHubリポジトリにプッシュします
```bash
git branch -M main
git push -u origin main
```
コードをアップロードする際には、後でコードをパッケージ化するためにタグを付けることをお勧めします。
```bash
git tag -a v0.0.1 -m "Release version 0.0.1"
git push origin v0.0.1
```
### 5. プラグインコードのパッケージング
GitHubコードリポジトリのReleasesページに移動し、新しいバージョンリリースを作成します。バージョンをリリースする際には、プラグインファイルをアップロードする必要があります。プラグインファイルのパッケージング方法については、[ローカルファイルとしてパッケージ化して共有](/plugin_dev_ja/0322-release-by-file.ja)で詳しく説明しています。
![プラグインのパッケージング](https://assets-docs.dify.ai/2024/12/5cb4696348cc6903e380287fce8f529d.png)
### GitHub経由でのプラグインインストール
他の人はGitHubリポジトリのアドレスを通じてこのプラグインをインストールできます。Difyプラットフォームのプラグイン管理ページにアクセスし、「GitHub経由でプラグインをインストール」を選択し、リポジトリのアドレスを入力後、バージョン番号とパッケージファイルを選択してインストールを完了します。
![](https://assets-docs.dify.ai/2024/12/3c2612349c67e6898a1f33a7cc320468.png)
## 関連リソース
- [プラグインの公開](/plugin_dev_ja/0321-release-overview.ja) - さまざまな公開方法を理解する
- [ローカルファイルとしてパッケージ化して共有](/plugin_dev_ja/0322-release-by-file.ja) - プラグインのパッケージング方法
- [マニフェストファイルによるプラグイン情報の定義](/plugin_dev_ja/0411-plugin-info-by-manifest.ja) - プラグインのメタデータを定義する
- [プラグイン開発者行動規範](/plugin_dev_ja/0312-contributor-covenant-code-of-conduct.ja) - プラグイン開発の規範を理解する
- [リモートデバッグプラグイン](/plugin_dev_ja/0411-remote-debug-a-plugin.ja) - プラグインのデバッグ方法を学ぶ

View File

@@ -0,0 +1,35 @@
---
dimensions:
type:
primary: operational
detail: maintenance
level: beginner
standard_title: Faq
language: ja
title: よくある質問
description: Author Allen このドキュメントでは、Difyプラグインの開発とインストールプロセスにおける一般的な質問に答えます。これには、プラグインのアップロード失敗の解決策authorフィールドの変更や、プラグインインストール中の検証例外の対処法FORCE_VERIFYING_SIGNATURE環境変数の設定が含まれます。
---
## プラグインインストール時にアップロード失敗と表示された場合の対処法は?
**エラー詳細**`PluginDaemonBadRequestError: plugin_unique_identifier is not valid` というエラーが表示されます。
**解決策**:プラグインプロジェクト下の `manifest.yaml` ファイルおよび `/provider` パス下の `.yaml` ファイル内の `author` フィールドを GitHub ID に変更します。
プラグインのパッケージングコマンドを再実行し、新しいプラグインパッケージをインストールします。
## プラグインインストール時に例外が発生した場合の対処法は?
**問題の説明**:プラグインインストール時に例外メッセージ:`plugin verification has been enabled, and the plugin you want to install has a bad signature` が表示された場合、どうすればよいですか?
**解決策**`/docker/.env` 設定ファイルの末尾に `FORCE_VERIFYING_SIGNATURE=false` フィールドを追加し、以下のコマンドを実行してDifyサービスを再起動します
```bash
cd docker
docker compose down
docker compose up -d
```
このフィールドを追加すると、DifyプラットフォームはDify Marketplaceに未登録未審査のすべてのプラグインのインストールを許可するようになり、セキュリティ上のリスクが生じる可能性があります。
テスト環境またはサンドボックス環境でプラグインをインストールし、安全性を確認してから本番環境にインストールすることをお勧めします。

View File

@@ -0,0 +1,120 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: General Specifications
language: ja
title: 一般的な仕様定義
description: このドキュメントでは、Difyプラグイン開発における一般的な構造と仕様、パスの仕様、国際化オブジェクト(I18nObject)、プロバイダー設定フォーム構造(ProviderConfig)、モデル設定(ModelConfig)、ノードレスポンス(NodeResponse)、ツールセレクター(ToolSelector)などの重要なデータ構造の定義と用途について詳しく説明します。
---
本稿では、プラグイン開発で一般的に使用される構造について簡単に説明します。開発プロセス中は、全体のアーキテクチャをよりよく理解するために、[プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja)および[開発者向けチートシート](/plugin_dev_ja/0131-cheatsheet.ja)と合わせてお読みになることを強くお勧めします。
### パスの仕様
Manifestファイルまたは任意のYAMLファイルにファイルパスを記入する際、ファイルの種類に応じて以下の2つの仕様に従ってください
* 対象ファイルが画像や動画などのマルチメディアファイルである場合(例:プラグインの `icon` を記入する場合)、これらのファイルをプラグインのルートディレクトリにある `_assets` フォルダに配置する必要があります。
* 対象ファイルが `.py` や `.yaml` などの通常のテキストファイル(コードファイル)である場合、プラグインプロジェクト内でのそのファイルの絶対パスを記入する必要があります。
### 一般的な構造
プラグインを定義する際、ツール、モデル、Endpoint間で共有できるいくつかのデータ構造があります。ここでは、これらの共通構造を定義します。
#### I18nObject
`I18nObject`は、[IETF BCP 47](https://tools.ietf.org/html/bcp47)標準に準拠した国際化構造であり、現在サポートされている4つの言語は次のとおりです。
* en_US
* zh_Hans
* ja_Jp
* pt_BR
#### ProviderConfig
`ProviderConfig`は、`Tool`および`Endpoint`に適用可能な汎用的なプロバイダー設定フォーム構造です。
* `name`(string):フォーム項目の名前
* `label`([I18nObject](#i18nobject), 必須)[IETF BCP 47](https://tools.ietf.org/html/bcp47)に準拠
* `type`([provider_config_type](#providerconfigtype-string), 必須):フォームタイプ
* `scope`([provider_config_scope](#providerconfigscope-string)):オプションの範囲、`type`によって変動
* `required`(bool):必須(空にできません)
* `default`(any):デフォルト値、基本型 `float` `int` `string` のみをサポート
* `options`(list\[[provider_config_option](#providerconfigoption-object)])オプション項目、typeが `select` の場合のみ使用
* `helper`(object):ヘルプドキュメントリンクのラベル、[IETF BCP 47](https://tools.ietf.org/html/bcp47)に準拠
* `url` (string):ヘルプドキュメントリンク
* `placeholder`(object)[IETF BCP 47](https://tools.ietf.org/html/bcp47)に準拠
#### ProviderConfigOption(object)
* `value`(string, 必須):値
* `label`(object, 必須)[IETF BCP 47](https://tools.ietf.org/html/bcp47)に準拠
#### ProviderConfigType(string)
* `secret-input` (string):設定情報は暗号化されます
* `text-input`(string):通常のテキスト
* `select`(string):ドロップダウンリスト
* `boolean`(bool):スイッチ
* `model-selector`(object):モデル設定情報、プロバイダー名、モデル名、モデルパラメータなどを含む
* `app-selector`(object)アプリID
* `tool-selector`(object):ツール設定情報、ツールプロバイダー、名前、パラメータなどを含む
* `dataset-selector`(string):未定
#### ProviderConfigScope(string)
* `type`が `model-selector` の場合
* `all`
* `llm`
* `text-embedding`
* `rerank`
* `tts`
* `speech2text`
* `moderation`
* `vision`
* `type`が `app-selector` の場合
* `all`
* `chat`
* `workflow`
* `completion`
* `type`が `tool-selector` の場合
* `all`
* `plugin`
* `api`
* `workflow`
#### ModelConfig
* `provider` (string): `plugin_id`を含むモデルプロバイダー名。形式は`langgenius/openai/openai`のようになります。
* `model` (string): 具体的なモデル名。
* `model_type` (enum): モデルタイプの列挙型。[モデル設計規則](/plugin_dev_ja/0411-model-designing-rules#modeltype.ja)ドキュメントを参照できます。
#### NodeResponse
* `inputs` (dict): 最終的にノードに入力される変数。
* `outputs` (dict): ノードの出力結果。
* `process_data` (dict): ノード実行中に生成されるデータ。
#### ToolSelector
* `provider_id` (string): ツールプロバイダー名
* `tool_name` (string): ツール名
* `tool_description` (string): ツールの説明
* `tool_configuration` (dict\[str, Any]): ツールの設定情報
* `tool_parameters` (dict\[str, dict]): LLMによる推論が必要なパラメータ
* `name` (string): パラメータ名
* `type` (string): パラメータタイプ
* `required` (bool): 必須かどうか
* `description` (string): パラメータの説明
* `default` (any): デフォルト
* `options`(list\[string]): オプション項目
## 関連リソース
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - Difyプラグイン開発の全体像を理解する
- [開発者向けチートシート](/plugin_dev_ja/0131-cheatsheet.ja) - プラグイン開発でよく使われるコマンドと概念のクイックリファレンス
- [ツールプラグイン開発詳細](/plugin_dev_ja/0222-tool-plugin.ja) - ツールプラグイン開発プロセスの詳細を理解する
- [モデル設計規則](/plugin_dev_ja/0411-model-designing-rules.ja) - モデル設定の仕様を理解する

View File

@@ -0,0 +1,214 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Model Designing Rules
language: ja
title: モデル設計ルール
description: 本書では、Difyモデルプラグイン開発のコアコンセプトと構造を詳細に定義します。これには、モデルプロバイダーProvider、AIモデルエンティティAIModelEntity、モデルタイプModelType、設定方法ConfigurateMethod、モデル特性ModelFeature、パラメータルールParameterRule、価格設定PriceConfig、およびさまざまな認証情報スキーマの詳細なデータ構造仕様が含まれます。
---
* モデルプロバイダールールは [Provider](#provider) エンティティに基づきます。
* モデルルールは [AIModelEntity](#aimodelentity) エンティティに基づきます。
> 以下のすべてのエンティティは `Pydantic BaseModel` に基づいており、`entities` モジュールに対応するエンティティがあります。
### Provider
* `provider` (string) プロバイダー識別子、例:`openai`
* `label` (object) プロバイダー表示名、i18n、`en_US` 英語、`zh_Hans` 中国語の2言語設定可能
* `zh_Hans` (string) \[optional] 中国語ラベル名、`zh_Hans` を設定しない場合はデフォルトで `en_US` が使用されます。
* `en_US` (string) 英語ラベル名
* `description` (object) \[optional] プロバイダー説明、i18n
* `zh_Hans` (string) \[optional] 中国語説明
* `en_US` (string) 英語説明
* `icon_small` (string) \[optional] プロバイダー小アイコン、対応するプロバイダー実装ディレクトリ下の `_assets` ディレクトリに保存、中英ポリシーは `label` と同様
* `zh_Hans` (string) \[optional] 中国語アイコン
* `en_US` (string) 英語アイコン
* `icon_large` (string) \[optional] プロバイダー大アイコン、対応するプロバイダー実装ディレクトリ下の `_assets` ディレクトリに保存、中英ポリシーは `label` と同様
* `zh_Hans` (string) \[optional] 中国語アイコン
* `en_US` (string) 英語アイコン
* `background` (string) \[optional] 背景色カラーコード、例:#FFFFFF、空の場合はフロントエンドのデフォルトカラー値が表示されます。
* `help` (object) \[optional] ヘルプ情報
* `title` (object) ヘルプタイトル、i18n
* `zh_Hans` (string) \[optional] 中国語タイトル
* `en_US` (string) 英語タイトル
* `url` (object) ヘルプリンク、i18n
* `zh_Hans` (string) \[optional] 中国語リンク
* `en_US` (string) 英語リンク
* `supported_model_types` (array\[[ModelType](#modeltype)]) サポートされるモデルタイプ
* `configurate_methods` (array\[[ConfigurateMethod](#configuratemethod)]) 設定方法
* `provider_credential_schema` (\[[ProviderCredentialSchema](#providercredentialschema)]) プロバイダー認証情報スキーマ
* `model_credential_schema` (\[[ModelCredentialSchema](#modelcredentialschema)]) モデル認証情報スキーマ
### AIModelEntity
* `model` (string) モデル識別子、例:`gpt-3.5-turbo`
* `label` (object) \[optional] モデル表示名、i18n、`en_US` 英語、`zh_Hans` 中国語の2言語設定可能
* `zh_Hans` (string) \[optional] 中国語ラベル名
* `en_US` (string) 英語ラベル名
* `model_type` ([ModelType](#modeltype)) モデルタイプ
* `features` (array\[[ModelFeature](#modelfeature)]) \[optional] サポート機能リスト
* `model_properties` (object) モデルプロパティ
* `mode` ([LLMMode](#llmmode)) モード (モデルタイプ `llm` で利用可能)
* `context_size` (int) コンテキストサイズ (モデルタイプ `llm` `text-embedding` で利用可能)
* `max_chunks` (int) 最大チャンク数 (モデルタイプ `text-embedding moderation` で利用可能)
* `file_upload_limit` (int) ファイル最大アップロード制限、単位MB。モデルタイプ `speech2text` で利用可能)
* `supported_file_extensions` (string) サポートされるファイル拡張子、例mp3,mp4モデルタイプ `speech2text` で利用可能)
* `default_voice` (string) デフォルトボイス、必須alloy,echo,fable,onyx,nova,shimmerモデルタイプ `tts` で利用可能)
* `voices` (list) 選択可能なボイスリスト。
* `mode` (string) ボイスモデル。(モデルタイプ `tts` で利用可能)
* `name` (string) ボイスモデル表示名。(モデルタイプ `tts` で利用可能)
* `language` (string) ボイスモデルがサポートする言語。(モデルタイプ `tts` で利用可能)
* `word_limit` (int) 1回の変換文字数制限、デフォルトは段落ごとに分割モデルタイプ `tts` で利用可能)
* `audio_type` (string) サポートされる音声ファイル拡張子、例mp3,wavモデルタイプ `tts` で利用可能)
* `max_workers` (int) サポートされるテキスト音声変換の同時実行タスク数(モデルタイプ `tts` で利用可能)
* `max_characters_per_chunk` (int) 各チャンクの最大文字数 (モデルタイプ `moderation` で利用可能)
* `parameter_rules` (array\[[ParameterRule](#parameterrule)]) \[optional] モデル呼び出しパラメータールール
* `pricing` (\[[PriceConfig](#priceconfig)]) \[optional] 価格情報
* `deprecated` (bool) 非推奨かどうか。非推奨の場合、モデルリストには表示されなくなりますが、既に設定されているものは引き続き使用可能です。デフォルトは False。
### ModelType
* `llm` テキスト生成モデル
* `text-embedding` テキスト埋め込みモデル
* `rerank` Rerank モデル
* `speech2text` 音声テキスト変換
* `tts` テキスト音声合成
* `moderation` モデレーション
### ConfigurateMethod
* `predefined-model` 事前定義モデル
ユーザーは統一されたプロバイダー認証情報を設定するだけで、プロバイダー下の事前定義モデルを使用できることを示します。
* `customizable-model` カスタマイズ可能モデル
ユーザーは各モデルの認証情報設定を新たに追加する必要があります。
* `fetch-from-remote` リモートから取得
`predefined-model` の設定方法と同様に、統一されたプロバイダー認証情報を設定するだけで、モデルは認証情報を通じてプロバイダーから取得されます。
### ModelFeature
* `agent-thought` エージェント思考、通常70Bを超えると思考連鎖能力があります。
* `vision` ビジョン、すなわち画像理解。
* `tool-call` ツール呼び出し
* `multi-tool-call` マルチツール呼び出し
* `stream-tool-call` ストリーミングツール呼び出し
### FetchFrom
* `predefined-model` 事前定義モデル
* `fetch-from-remote` リモートモデル
### LLMMode
* `completion` テキスト補完
* `chat` 対話
### ParameterRule
* `name` (string) モデル呼び出し時の実際のパラメータ名
* `use_template` (string) \[optional] テンプレートを使用
> テンプレートの具体的な使用方法については、[新しいモデルプロバイダーの作成](/plugin_dev_ja/0222-creating-new-model-provider.ja)の例を参照してください。
デフォルトで5種類の変数コンテンツ設定テンプレートがプリセットされています
* `temperature`
* `top_p`
* `frequency_penalty`
* `presence_penalty`
* `max_tokens`
`use_template` に直接テンプレート変数名を設定すると、`entities.defaults.PARAMETER_RULE_TEMPLATE` のデフォルト設定が使用され、`name` と `use_template` 以外のすべてのパラメータを設定する必要はありません。追加の設定パラメータが設定された場合、デフォルト設定が上書きされます。`openai/llm/gpt-3.5-turbo.yaml` を参照してください。
* `label` (object) \[optional] ラベル、i18n
* `zh_Hans`(string) \[optional] 中国語ラベル名
* `en_US` (string) 英語ラベル名
* `type`(string) \[optional] パラメータタイプ
* `int` 整数
* `float` 浮動小数点数
* `string` 文字列
* `boolean` ブール型
* `help` (string) \[optional] ヘルプ情報
* `zh_Hans` (string) \[optional] 中国語ヘルプ情報
* `en_US` (string) 英語ヘルプ情報
* `required` (bool) 必須項目かどうか、デフォルトは False。
* `default`(int/float/string/bool) \[optional] デフォルト値
* `min`(int/float) \[optional] 最小値、数値タイプのみ適用
* `max`(int/float) \[optional] 最大値、数値タイプのみ適用
* `precision`(int) \[optional] 精度、小数点以下の保持桁数、数値タイプのみ適用
* `options` (array\[string]) \[optional] ドロップダウン選択肢の値、`type` が `string` の場合にのみ適用、設定しない場合または null の場合は選択肢の値を制限しません
### PriceConfig
* `input` (float) 入力単価、すなわちプロンプト単価
* `output` (float) 出力単価、すなわち返却コンテンツ単価
* `unit` (float) 価格単位、例えば1Mトークンで計算する場合、単価に対応する単位トークン数は `0.000001` です
* `currency` (string) 通貨単位
### ProviderCredentialSchema
* `credential_form_schemas` (array\[[CredentialFormSchema](#credentialformschema)]) 認証情報フォームスキーマ
### ModelCredentialSchema
* `model` (object) モデル識別子、変数名はデフォルトで `model`
* `label` (object) モデルフォーム項目表示名
* `en_US` (string) 英語
* `zh_Hans`(string) \[optional] 中国語
* `placeholder` (object) モデルのプレースホルダーコンテンツ
* `en_US`(string) 英語
* `zh_Hans`(string) \[optional] 中国語
* `credential_form_schemas` (array\[[CredentialFormSchema](#credentialformschema)]) 認証情報フォームスキーマ
### CredentialFormSchema
* `variable` (string) フォーム項目変数名
* `label` (object) フォーム項目ラベル名
* `en_US`(string) 英語
* `zh_Hans` (string) \[optional] 中国語
* `type` ([FormType](#formtype)) フォーム項目タイプ
* `required` (bool) 必須項目かどうか
* `default`(string) デフォルト値
* `options` (array\[[FormOption](#formoption)]) フォーム項目が `select` または `radio` の場合の専用プロパティ、ドロップダウン内容を定義
* `placeholder`(object) フォーム項目が `text-input` の場合の専用プロパティ、フォーム項目のプレースホルダー
* `en_US`(string) 英語
* `zh_Hans` (string) \[optional] 中国語
* `max_length` (int) フォーム項目が`text-input`の場合の専用プロパティ、入力最大長を定義、0は無制限。
* `show_on` (array\[[FormShowOnObject](#formshowonobject)]) 他のフォーム項目の値が条件に一致する場合に表示、空の場合は常に表示。
#### FormType
* `text-input` テキスト入力コンポーネント
* `secret-input` パスワード入力コンポーネント
* `select` 単一選択ドロップダウン
* `radio` ラジオコンポーネント
* `switch` スイッチコンポーネント、`true` と `false` のみをサポート
#### FormOption
* `label` (object) ラベル
* `en_US`(string) 英語
* `zh_Hans`(string) \[optional] 中国語
* `value` (string) ドロップダウン選択肢の値
* `show_on` (array\[[FormShowOnObject](#formshowonobject)]) 他のフォーム項目の値が条件に一致する場合に表示、空の場合は常に表示。
#### FormShowOnObject
* `variable` (string) 他のフォーム項目変数名
* `value` (string) 他のフォーム項目変数値
## 関連リソース
- [モデルアーキテクチャ詳解](/plugin_dev_ja/0412-model-schema.ja) - モデルプラグインのアーキテクチャ仕様を深く理解する
- [新しいモデルの迅速な統合](/plugin_dev_ja/0211-getting-started-new-model.ja) - これらのルールを適用して新しいモデルを追加する方法を学ぶ
- [一般仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - プラグインマニフェストファイルの設定を理解する
- [新しいモデルプロバイダーの作成](/plugin_dev_ja/0222-creating-new-model-provider.ja) - 全く新しいモデルプロバイダープラグインを開発する

View File

@@ -0,0 +1,82 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Model Plugin Introduction
language: ja
title: モデルプラグイン
description: モデルプラグインの基本概念と構造を紹介します。モデルプラグインは、DifyがさまざまなプロバイダーOpenAI、Anthropic、Googleなどの、大規模言語モデルLLM、テキスト埋め込み、音声テキスト変換といったさまざまなタイプのモデルを呼び出すことを可能にします。
---
Modelプラグインは、DifyプラットフォームがそのモデルプロバイダーのすべてのLLMを呼び出すことを可能にします。例えば、OpenAIモデルプラグインをインストールすると、DifyプラットフォームはOpenAIが提供する`GPT-4`、`GPT-4o-2024-05-13`などのモデルを呼び出すことができます。
## モデルプラグインの構造
モデルプラグイン開発プロセスで関連する可能性のある概念を理解しやすくするために、以下にモデルプラグイン内の構造の簡単な紹介を示します。
* **モデルプロバイダー**:大規模モデルの開発会社。例:**OpenAI、Anthropic、Google**など。
* **モデルカテゴリ**モデルプロバイダーによって、大規模言語モデルLLM、テキスト埋め込みモデルText embedding、音声テキスト変換Speech2textなどのカテゴリが存在します。
* **特定のモデル**`claude-3-5-sonnet`、`gpt-4-turbo`など。
プラグインプロジェクト内のコード階層構造:
```bash
- モデルプロバイダー
- モデルカテゴリ
- 特定のモデル
```
**Anthropic**を例にとると、モデルプラグインのサンプル構造は次のようになります。
```bash
- Anthropic
- llm
claude-3-5-sonnet-20240620
claude-3-haiku-20240307
claude-3-opus-20240229
claude-3-sonnet-20240229
claude-instant-1.2
claude-instant-1
```
OpenAIを例にとると、複数のモデルタイプをサポートしているため、複数のモデルカテゴリレイヤーが存在し、構造は次のようになります。
```bash
├── models
│ ├── llm
│ │ ├── chatgpt-4o-latest
│ │ ├── gpt-3.5-turbo
│ │ ├── gpt-4-0125-preview
│ │ ├── gpt-4-turbo
│ │ ├── gpt-4o
│ │ ├── llm
│ │ ├── o1-preview
│ │ └── text-davinci-003
│ ├── moderation
│ │ ├── moderation
│ │ └── text-moderation-stable
│ ├── speech2text
│ │ ├── speech2text
│ │ └── whisper-1
│ ├── text_embedding
│ │ ├── text-embedding-3-large
│ │ └── text_embedding
│ └── tts
│ ├── tts-1-hd
│ ├── tts-1
│ └── tts
```
## モデル設定
モデルプラグインは、設定ファイルを通じてモデルの動作と属性を定義します。詳細なモデル設計ルールと設定フォーマットについては、[モデル設計ルール](/plugin_dev_ja/0411-model-designing-rules.ja)ドキュメントと[モデルスキーマ](/plugin_dev_ja/0412-model-schema.ja)仕様を参照してください。
## さらに読む
- [新しいモデルの迅速な統合](/plugin_dev_ja/0211-getting-started-new-model.ja) - 既にサポートされているプロバイダーに新しいモデルを追加する方法を学ぶ
- [モデル設計ルール](/plugin_dev_ja/0411-model-designing-rules.ja) - モデル設定の仕様を詳しく理解する
- [モデルスキーマ](/plugin_dev_ja/0412-model-schema.ja) - モデルプラグインのアーキテクチャを深く理解する
- [共通仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - プラグインメタデータの定義方法を理解する
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - プラグイン開発入門ガイドに戻る

View File

@@ -0,0 +1,62 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Persistent Storage KV
language: ja
title: 永続ストレージ
description: このドキュメントでは、Difyプラグインの永続ストレージ機能について説明し、プラグインでKVデータベースを使用してデータを保存、取得、削除する方法を詳しく説明します。この機能により、プラグインは同じワークスペース内でデータを永続的に保存でき、セッションをまたいだデータ保存のニーズに対応できます。
---
プラグイン内のツールおよびエンドポイントを個別に見てみると、ほとんどの場合、単一のインタラクションしか完了できず、リクエスト後にデータを返してタスクが終了することがわかります。
永続的な記憶の実装など、長期間保存する必要があるデータが存在する場合、プラグインには永続ストレージ機能が求められます。**永続ストレージメカニズムにより、プラグインは同一ワークスペース内でデータを永続的に保存することが可能になります。**現在はKVデータベースを提供することでストレージのニーズに対応していますが、将来的には実際の使用状況に基づき、より柔軟で強力なストレージインターフェースを提供する可能性があります。
### キーの保存
#### **エントリポイント**
```python
self.session.storage
```
#### **インターフェース**
```python
def set(self, key: str, val: bytes) -> None:
pass
```
渡されるのはbytesであることに注意してください。そのため、実際にはその中にファイルを保存することができます。
### キーの取得
#### **エントリポイント**
```python
self.session.storage
```
#### **インターフェース**
```python
def get(self, key: str) -> bytes:
pass
```
### キーの削除
#### **エントリポイント**
```python
self.session.storage
```
#### **インターフェース**
```python
def delete(self, key: str) -> None:
pass
```

View File

@@ -0,0 +1,115 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Plugin info by Manifest
language: ja
title: マニフェスト
description: 作成者 Yeuoly、Allen このドキュメントでは、Difyプラグインのマニフェストファイルについて詳しく説明します。これは、プラグインの基本情報を定義するYAMLファイルです。ドキュメントには、完全なコード例と詳細な構造説明が含まれており、プラグインのバージョン、タイプ、作成者、名称、リソース使用、権限申請、機能定義、ランタイムなど、各方面の設定情報を網羅しています。
---
マニフェストは、yaml 仕様に準拠したファイルであり、プラグイン名、作成者、含まれるツール、モデルなどの情報を含む、**プラグイン**の最も基本的な情報を定義します。プラグインの全体的なアーキテクチャについては、[プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja)および[開発者向けチートシート](/plugin_dev_ja/0131-cheatsheet.ja)を参照してください。
このファイルの形式が間違っている場合、プラグインの解析とパッケージ化プロセスは失敗します。
### コード例
以下は、マニフェストファイルの簡単な例です。各データの意味と役割については、後ほど説明します。他のプラグインのコードを参照する必要がある場合は、[GitHub コードリポジトリ](https://github.com/langgenius/dify-official-plugins/blob/main/tools/google/manifest.yaml)を参照してください。
```yaml
version: 0.0.1
type: "plugin"
author: "Yeuoly"
name: "neko"
label:
en_US: "Neko"
created_at: "2024-07-12T08:03:44.658609186Z"
icon: "icon.svg"
resource:
memory: 1048576
permission:
tool:
enabled: true
model:
enabled: true
llm: true
endpoint:
enabled: true
app:
enabled: true
storage:
enabled: true
size: 1048576
plugins:
endpoints:
- "provider/neko.yaml"
meta:
version: 0.0.1
arch:
- "amd64"
- "arm64"
runner:
language: "python"
version: "3.10"
entrypoint: "main"
privacy: "./privacy.md"
```
### 構造
* `version`(version, 必須):プラグインのバージョン
* `type`(type, 必須):プラグインタイプ。現在は `plugin` のみをサポートし、将来的には `bundle` をサポート予定です。
* `author`(string, 必須)作成者。Marketplace では組織名として定義されます。
* `label`(label, 必須):多言語名称
* `created_at`(RFC3339, 必須)作成日時。Marketplace では、作成日時が現在時刻を超えてはなりません。
* `icon`(asset, 必須):アイコンのパス
* `resource` (object):申請が必要なリソース
* `memory` (int64):最大メモリ使用量。主に SaaS 上の AWS Lambda リソース申請に関連し、単位はバイトです。
* `permission`(object):権限申請
* `tool`(object):ツールを逆呼び出しする権限
* `enabled` (bool)
* `model`(object):モデルを逆呼び出しする権限
* `enabled`(bool)
* `llm`(bool)
* `text_embedding`(bool)
* `rerank`(bool)
* `tts`(bool)
* `speech2text`(bool)
* `moderation`(bool)
* `node`(object):ノードを逆呼び出しする権限
* `enabled`(bool)
* `endpoint`(object)`endpoint` の登録を許可する権限
* `enabled`(bool)
* `app`(object)`app` を逆呼び出しする権限
* `enabled`(bool)
* `storage`(object):永続ストレージを申請する権限
* `enabled`(bool)
* `size`(int64):許可される永続メモリの最大サイズ。単位はバイトです。
* `plugins`(object, 必須):プラグインが拡張する具体的な機能の `yaml` ファイルリスト。プラグインパッケージ内の絶対パスです。例えば、モデルを拡張する必要がある場合、`openai.yaml` のようなファイルを定義し、そのファイルパスをここに記入します。そのパス上のファイルは実際に存在しなければならず、そうでなければパッケージ化は失敗します。
* 形式
* `tools`(list\[string]):プラグインが拡張する[ツール](/plugin_dev_ja/0222-tool-plugin.ja)プロバイダー
* `models`(list\[string]):プラグインが拡張する[モデル](/plugin_dev_ja/0131-model-plugin-introduction.ja)プロバイダー
* `endpoints`(list\[string]):プラグインが拡張する [Endpoints](/plugin_dev_ja/0432-endpoint.ja) プロバイダー
* `agent_strategies` (list\[string]):プラグインが拡張する [Agent 戦略](/plugin_dev_ja/9433-agent-strategy-plugin.ja)プロバイダー
* 制限
* ツールとモデルを同時に拡張することはできません
* 拡張機能がまったくない状態は許可されません。
* モデルと Endpoint を同時に拡張することはできません
* 現在、各タイプの拡張は最大1つのプロバイダーのみサポートしています
* `meta`(object)
* `version`(version, 必須)`manifest` フォーマットバージョン。初期バージョンは `0.0.1` です。
* `arch`(list\[string], 必須):サポートされるアーキテクチャ。現在は `amd64`、`arm64` のみをサポートしています。
* `runner`(object, 必須):ランタイム設定
* `language`(string):現在は python のみをサポートしています。
* `version`(string):言語のバージョン。現在は `3.12` のみをサポートしています。
* `entrypoint`(string)プログラムのエントリポイント。python では `main` であるべきです。
* `privacy` (string, オプション):オプション項目。プラグインのプライバシーポリシーファイルの相対パスまたは URL を指定します。例:`"./privacy.md"` または `"https://your-web/privacy"`。プラグインを Dify Marketplace に公開する予定がある場合、**このフィールドは必須です**。明確なユーザーデータの使用とプライバシーに関する声明を提供するために使用されます。詳細な記入ガイドラインについては、[プラグインのプライバシーデータ保護ガイドライン](/plugin_dev_ja/0312-privacy-protection-guidelines.ja)を参照してください。
## 関連リソース
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - Difyプラグイン開発の全体像を理解する
- [新しいモデルを迅速に導入する](/plugin_dev_ja/0211-getting-started-new-model.ja) - 既存のプロバイダーに新しいモデルを追加する方法を学ぶ
- [共通仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - プラグイン開発における共通構造を理解する
- [リリース概要](/plugin_dev_ja/0321-release-overview.ja) - プラグインのリリースプロセスを学ぶ

View File

@@ -0,0 +1,32 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Remote Debug a Plugin
language: ja
title: プラグインのデバッグ
description: このドキュメントでは、Dify のリモートデバッグ機能を使用してプラグインをテストする方法を紹介します。デバッグ情報の取得、環境変数ファイルの設定、プラグインのリモートデバッグの開始、およびプラグインインストール状況の確認といった一連のプロセスを詳しく説明します。これにより、開発者はローカルで開発しながら、Dify 環境でリアルタイムにプラグインをテストできます。
---
プラグイン開発が完了したら、次にプラグインが正常に動作するかをテストする必要があります。Difyは便利なリモートデバッグ方法を提供し、テスト環境でプラグインの機能を迅速に検証するのに役立ちます。
[「プラグイン管理」](https://cloud.dify.ai/plugins)ページに移動し、リモートサーバーアドレスとデバッグキーを取得します。
![リモートデバッグプラグイン](https://assets-docs.dify.ai/2024/12/053415ef127f1f4d6dd85dd3ae79626a.png)
プラグインプロジェクトに戻り、`.env.example` ファイルをコピーして `.env` にリネームし、取得したリモートサーバーアドレスやデバッグキーなどの情報を入力します。
`.env` ファイル:
```bash
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=remote
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****
```
`python -m main` コマンドを実行してプラグインを起動します。「プラグイン」ページで、このプラグインがワークスペース内にインストールされていることが確認でき、チームの他のメンバーもこのプラグインにアクセスできます。
![プラグインをワークスペースにインストール](https://assets-docs.dify.ai/2024/12/ec26e5afc57bbfeb807719638f603807.png)

View File

@@ -0,0 +1,121 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Tool
language: ja
title: ツールの返り値
description: このドキュメントでは、Difyプラグインにおけるツールのデータ構造と使用方法について詳しく説明します。内容には、さまざまなタイプのメッセージ画像URL、リンク、テキスト、ファイル、JSONを返す方法、変数およびストリーミング変数メッセージを作成する方法、そしてworkflowで参照しやすくするためにツールの出力変数スキーマを定義する方法が含まれます。
---
詳細なインターフェースドキュメントを読む前に、Difyプラグインのツール統合プロセスについて、大まかな理解があることを確認してください。
### データ構造
#### メッセージの返却
Difyは、`テキスト`、`リンク`、`画像`、`ファイルBLOB`、`JSON`など、さまざまなメッセージタイプをサポートしており、以下の異なるインターフェースを通じてさまざまなタイプのメッセージを返すことができます。
デフォルトでは、`workflow`内のツールの出力には、`files`、`text`、`json`の3つの固定変数が含まれ、以下の方法でこれらの変数のデータを返すことができます。
例えば、`create_image_message`を使用して画像を返しますが、ツールはカスタム出力変数もサポートしているため、`workflow`内でこれらの変数をより便利に参照できます。
#### **画像URL**
画像のURLを渡すだけで、Difyはリンクを通じて自動的に画像をダウンロードし、ユーザーに返します。
```python
def create_image_message(self, image: str) -> ToolInvokeMessage:
pass
```
#### **リンク**
リンクを返す必要がある場合は、以下のインターフェースを使用してください。
```python
def create_link_message(self, link: str) -> ToolInvokeMessage:
pass
```
#### **テキスト**
テキストメッセージを返す必要がある場合は、以下のインターフェースを使用してください。
```python
def create_text_message(self, text: str) -> ToolInvokeMessage:
pass
```
**ファイル**
画像、音声、動画、PPT、Word、Excelなどのファイルの生データを返す必要がある場合は、以下のインターフェースを使用できます。
* `blob` ファイルの生データ、bytes型。
* `meta` ファイルのメタデータ。開発者が明確なファイルタイプを必要とする場合は、`mime_type`を指定してください。そうでない場合、Difyはデフォルトタイプとして`octet/stream`を使用します。
```python
def create_blob_message(self, blob: bytes, meta: dict = None) -> ToolInvokeMessage:
pass
```
#### **JSON**
フォーマットされたJSONを返す必要がある場合は、以下のインターフェースを使用できます。これは通常、workflow内のード間のデータ転送に使用されます。agentモードでは、ほとんどの大規模モデルもJSONを読み取り、理解することができます。
* `object` Pythonの辞書オブジェクトで、自動的にJSONにシリアライズされます。
```python
def create_json_message(self, json: dict) -> ToolInvokeMessage:
pass
```
#### **変数**
非ストリーミング出力の変数の場合、以下のインターフェースを使用して返すことができます。複数作成した場合、後者が前者を上書きします。
```python
def create_variable_message(self, variable_name: str, variable_value: Any) -> ToolInvokeMessage:
pass
```
#### **ストリーミング変数**
「タイプライター」効果でテキストを出力したい場合は、ストリーミング変数を使用してテキストを出力できます。`chatflow`アプリケーションで`answer`ノードを使用し、この変数を参照すると、テキストは「タイプライター」効果で出力されます。ただし、現在この方法は文字列型のデータのみをサポートしています。
```python
def create_stream_variable_message(
self, variable_name: str, variable_value: str
) -> ToolInvokeMessage:
```
#### カスタム変数の返却
`workflow`アプリケーションで`tool`の出力変数を参照したい場合は、出力される可能性のある変数を事前に定義する必要があります。Difyプラグインは、[`json_schema`](https://json-schema.org/)形式の出力変数定義をサポートしています。以下に簡単な例を示します。
```yaml
identity:
author: author
name: tool
label:
en_US: label
zh_Hans: 标签
ja_JP: レベル
pt_BR: etiqueta
description:
human:
en_US: description
zh_Hans: 描述
ja_JP: 説明
pt_BR: descrição
llm: description
output_schema:
type: object
properties:
name:
type: string
```
上記のサンプルコードは、簡単なツールを定義し、それに`output_schema`を指定しています。これには`name`フィールドが含まれており、この時点で`workflow`内でこのフィールドを参照できます。ただし、実際に使用するためには、ツールの実装コードで変数を返す必要があることに注意してください。そうしないと、`None`の戻り結果が得られます。

View File

@@ -0,0 +1,684 @@
---
dimensions:
type:
primary: reference
detail: core
level: intermediate
standard_title: Model Schema
language: ja
title: モデルインターフェース
description: 本書では、Difyモデルプラグイン開発に必要なインターフェース仕様について詳しく説明します。これには、モデルプロバイダーの実装、5つのモデルタイプLLM、TextEmbedding、Rerank、Speech2text、Text2speechのインターフェース定義、およびPromptMessage、LLMResultなどの関連データ構造の完全な仕様が含まれます。本書は、開発者が様々なモデル統合を実装する際の開発リファレンスとして適しています。
---
ここでは、プロバイダーと各モデルタイプが実装する必要のあるインターフェースメソッドとパラメータについて説明します。モデルプラグインを開発する前に、まず[モデル設計ルール](/plugin_dev_ja/0411-model-designing-rules.ja)と[モデルプラグイン紹介](/plugin_dev_ja/0131-model-plugin-introduction.ja)を読むことをお勧めします。
### モデルプロバイダー
`__base.model_provider.ModelProvider` ベースクラスを継承し、以下のインターフェースを実装します:
```python
def validate_provider_credentials(self, credentials: dict) -> None:
"""
プロバイダーのクレデンシャルを検証します
モデルタイプの任意の validate_credentials メソッドを選択するか、自分で検証メソッドを実装することができますモデルリスト取得API
検証に失敗した場合は、例外を発生させます
:param credentials: プロバイダーのクレデンシャル。クレデンシャルの形式は `provider_credential_schema` で定義されます。
"""
```
* `credentials` (object) クレデンシャル情報
クレデンシャル情報のパラメータは、プロバイダーのYAML設定ファイルの `provider_credential_schema` で定義され、`api_key` などが渡されます。検証に失敗した場合は、`errors.validate.CredentialsValidateFailedError` エラーをスローしてください。**注:事前定義モデルはこのインターフェースを完全に実装する必要がありますが、カスタムモデルプロバイダーは以下のように簡単な実装で済みます:**
```python
class XinferenceProvider(Provider):
def validate_provider_credentials(self, credentials: dict) -> None:
pass
```
### モデル
モデルは5つの異なるモデルタイプに分かれ、モデルタイプごとに継承するベースクラスや実装が必要なメソッドも異なります。
#### 共通インターフェース
すべてのモデルは、以下の2つのメソッドを共通して実装する必要があります
* モデルクレデンシャルの検証
プロバイダーのクレデンシャル検証と同様に、ここでは個別のモデルに対して検証を行います。
```python
def validate_credentials(self, model: str, credentials: dict) -> None:
"""
モデルのクレデンシャルを検証します
:param model: モデル名
:param credentials: モデルのクレデンシャル
:return:
"""
```
パラメータ:
* `model` (string) モデル名
* `credentials` (object) クレデンシャル情報
クレデンシャル情報のパラメータは、プロバイダーのYAML設定ファイルの `provider_credential_schema` または `model_credential_schema` で定義され、`api_key` などが渡されます。検証に失敗した場合は、`errors.validate.CredentialsValidateFailedError` エラーをスローしてください。
* 呼び出し例外エラーマッピングテーブル
モデル呼び出し時に例外が発生した場合、Runtime が指定する `InvokeError` タイプにマッピングする必要があります。これにより、Dify は異なるエラーに対して異なる後続処理を行うことができます。Runtime Errors:
* `InvokeConnectionError` 呼び出し接続エラー
* `InvokeServerUnavailableError` 呼び出し先サーバー利用不可
* `InvokeRateLimitError` 呼び出しレート制限超過
* `InvokeAuthorizationError` 呼び出し認証失敗
* `InvokeBadRequestError` 呼び出しパラメータ不正
```python
@property
def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]:
"""
モデルの呼び出しエラーを統一エラーにマッピングします
キーは呼び出し元にスローされるエラータイプです
値はモデルによってスローされるエラータイプであり、呼び出し元のために統一エラータイプに変換する必要があります。
:return: 呼び出しエラーマッピング
"""
```
対応するエラーを直接スローし、以下のように定義することも可能です。これにより、その後の呼び出しで `InvokeConnectionError` などの例外を直接スローできます。
#### LLM
`__base.large_language_model.LargeLanguageModel` ベースクラスを継承し、以下のインターフェースを実装します:
* LLM 呼び出し
LLM 呼び出しのコアメソッドを実装し、ストリーミングと同期的な返却の両方をサポートできます。
```python
def _invoke(self, model: str, credentials: dict,
prompt_messages: list[PromptMessage], model_parameters: dict,
tools: Optional[list[PromptMessageTool]] = None, stop: Optional[list[str]] = None,
stream: bool = True, user: Optional[str] = None) \
-> Union[LLMResult, Generator]:
"""
大規模言語モデルを呼び出します
:param model: モデル名
:param credentials: モデルのクレデンシャル
:param prompt_messages: プロンプトメッセージ
:param model_parameters: モデルパラメータ
:param tools: ツール呼び出し用のツール
:param stop: ストップワード
:param stream: ストリーム応答かどうか
:param user: 一意のユーザーID
:return: 完全な応答またはストリーム応答チャンクジェネレータの結果
"""
```
* パラメータ:
* `model` (string) モデル名
* `credentials` (object) クレデンシャル情報
クレデンシャル情報のパラメータは、プロバイダーのYAML設定ファイルの `provider_credential_schema` または `model_credential_schema` で定義され、`api_key` などが渡されます。
* `prompt_messages` (array\[[PromptMessage](#promptmessage)]) プロンプトリスト
モデルが `Completion` タイプの場合、リストには [UserPromptMessage](#userpromptmessage) 要素を1つ渡すだけで十分です。モデルが `Chat` タイプの場合、メッセージに応じて [SystemPromptMessage](#systempromptmessage)、[UserPromptMessage](#userpromptmessage)、[AssistantPromptMessage](#assistantpromptmessage)、[ToolPromptMessage](#toolpromptmessage) 要素のリストを渡す必要があります。
* `model_parameters` (object) モデルパラメータ。モデルパラメータはモデルのYAML設定の `parameter_rules` で定義されます。
* `tools` (array\[[PromptMessageTool](#promptmessagetool)]) \[optional] ツールリスト。`function calling` における `function` と同等です。つまり、tool calling に渡すツールリストです。
* `stop` (array\[string]) \[optional] ストップシーケンス。モデルの返却は、ストップシーケンスで定義された文字列の直前で停止します。
* `stream` (bool) ストリーミング出力かどうか、デフォルトは True。ストリーミング出力は Generator\[[LLMResultChunk](#llmresultchunk)] を返し、非ストリーミング出力は [LLMResult](#llmresult) を返します。
* `user` (string) \[optional] ユーザーの一意の識別子。プロバイダーが不正利用を監視および検出するのに役立ちます。
* 返り値
ストリーミング出力は Generator\[[LLMResultChunk](#llmresultchunk)] を返し、非ストリーミング出力は [LLMResult](#llmresult) を返します。
* 入力トークンの事前計算
モデルがトークン事前計算インターフェースを提供していない場合、直接 0 を返すことができます。
```python
def get_num_tokens(self, model: str, credentials: dict, prompt_messages: list[PromptMessage],
tools: Optional[list[PromptMessageTool]] = None) -> int:
"""
指定されたプロンプトメッセージのトークン数を取得します
:param model: モデル名
:param credentials: モデルのクレデンシャル
:param prompt_messages: プロンプトメッセージ
:param tools: ツール呼び出し用のツール
:return:
"""
```
パラメータの説明は上記の `LLM 呼び出し` を参照してください。このインターフェースは、対応する `model` に基づいて適切な `tokenizer` を選択して計算する必要があります。対応するモデルが `tokenizer` を提供していない場合は、`AIModel` ベースクラスの `_get_num_tokens_by_gpt2(text: str)` メソッドを使用して計算できます。
* カスタムモデルルールの取得 \[オプション]
```python
def get_customizable_model_schema(self, model: str, credentials: dict) -> Optional[AIModelEntity]:
"""
カスタマイズ可能なモデルスキーマを取得します
:param model: モデル名
:param credentials: モデルのクレデンシャル
:return: モデルスキーマ
"""
```
プロバイダーがカスタムLLMの追加をサポートしている場合、このメソッドを実装することで、カスタムモデルがモデルルールを取得できるようになります。デフォルトでは None を返します。
`OpenAI` プロバイダーのほとんどのファインチューニングモデルでは、ファインチューニングモデル名(例:`gpt-3.5-turbo-1106`)からベースモデルを取得し、そのベースモデルの事前定義パラメータルールを返すことができます。[OpenAI](https://github.com/langgenius/dify-official-plugins/tree/main/models/openai) の具体的な実装を参照してください。
#### TextEmbedding
`__base.text_embedding_model.TextEmbeddingModel` ベースクラスを継承し、以下のインターフェースを実装します:
* Embedding 呼び出し
```python
def _invoke(self, model: str, credentials: dict,
texts: list[str], user: Optional[str] = None) \
-> TextEmbeddingResult:
"""
テキスト埋め込みモデルを呼び出します
:param model: モデル名
:param credentials: モデルのクレデンシャル
:param texts: 埋め込むテキスト
:param user: 一意のユーザーID
:return: 埋め込み結果
"""
```
* パラメータ:
* `model` (string) モデル名
* `credentials` (object) クレデンシャル情報
クレデンシャル情報のパラメータは、プロバイダーのYAML設定ファイルの `provider_credential_schema` または `model_credential_schema` で定義され、`api_key` などが渡されます。
* `texts` (array\[string]) テキストリスト、バッチ処理可能
* `user` (string) \[optional] ユーザーの一意の識別子。プロバイダーが不正利用を監視および検出するのに役立ちます。
* 返り値:
[TextEmbeddingResult](#textembeddingresult) エンティティ。
* トークンの事前計算
```python
def get_num_tokens(self, model: str, credentials: dict, texts: list[str]) -> int:
"""
指定されたテキストのトークン数を取得します
:param model: モデル名
:param credentials: モデルのクレデンシャル
:param texts: 埋め込むテキスト
:return:
"""
```
パラメータの説明は上記の `Embedding 呼び出し` を参照してください。
上記の `LargeLanguageModel` と同様に、このインターフェースは対応する `model` に基づいて適切な `tokenizer` を選択して計算する必要があります。対応するモデルが `tokenizer` を提供していない場合は、`AIModel` ベースクラスの `_get_num_tokens_by_gpt2(text: str)` メソッドを使用して計算できます。
#### Rerank
`__base.rerank_model.RerankModel` ベースクラスを継承し、以下のインターフェースを実装します:
* rerank 呼び出し
```python
def _invoke(self, model: str, credentials: dict,
query: str, docs: list[str], score_threshold: Optional[float] = None, top_n: Optional[int] = None,
user: Optional[str] = None) \
-> RerankResult:
"""
Rerankモデルを呼び出します
:param model: モデル名
:param credentials: モデルのクレデンシャル
:param query: 検索クエリ
:param docs: リランキング対象のドキュメント
:param score_threshold: スコアのしきい値
:param top_n: 上位n件
:param user: 一意のユーザーID
:return: リランキング結果
"""
```
* パラメータ:
* `model` (string) モデル名
* `credentials` (object) クレデンシャル情報
クレデンシャル情報のパラメータは、プロバイダーのYAML設定ファイルの `provider_credential_schema` または `model_credential_schema` で定義され、`api_key` などが渡されます。
* `query` (string) クエリリクエストの内容
* `docs` (array\[string]) リランキングが必要なドキュメント(チャンク)のリスト
* `score_threshold` (float) \[optional] スコアのしきい値
* `top_n` (int) \[optional] 上位n個のドキュメントチャンクを取得
* `user` (string) \[optional] ユーザーの一意の識別子。プロバイダーが不正利用を監視および検出するのに役立ちます。
* 返り値:
[RerankResult](#rerankresult) エンティティ。
#### Speech2text
`__base.speech2text_model.Speech2TextModel` ベースクラスを継承し、以下のインターフェースを実装します:
* Invoke 呼び出し
```python
def _invoke(self, model: str, credentials: dict,
file: IO[bytes], user: Optional[str] = None) \
-> str:
"""
音声テキスト変換モデルを呼び出します
:param model: モデル名
:param credentials: モデルのクレデンシャル
:param file: 音声ファイル
:param user: 一意のユーザーID
:return: 指定された音声ファイルに対するテキスト
"""
```
* パラメータ:
* `model` (string) モデル名
* `credentials` (object) クレデンシャル情報
クレデンシャル情報のパラメータは、プロバイダーのYAML設定ファイルの `provider_credential_schema` または `model_credential_schema` で定義され、`api_key` などが渡されます。
* `file` (File) ファイルストリーム
* `user` (string) \[optional] ユーザーの一意の識別子。プロバイダーが不正利用を監視および検出するのに役立ちます。
* 返り値:
音声変換された文字列。
#### Text2speech
`__base.text2speech_model.Text2SpeechModel` ベースクラスを継承し、以下のインターフェースを実装します:
* Invoke 呼び出し
```python
def _invoke(self, model: str, credentials: dict, content_text: str, streaming: bool, user: Optional[str] = None):
"""
大規模言語モデルを呼び出します
:param model: モデル名
:param credentials: モデルの認証情報
:param content_text: 変換するテキストコンテンツ
:param streaming: 出力がストリーミングであるか
:param user: 一意のユーザーID
:return: 変換された音声ファイル
"""
```
* パラメータ:
* `model` (string) モデル名
* `credentials` (object) 認証情報
認証情報のパラメータは、プロバイダーのYAML設定ファイルの `provider_credential_schema` または `model_credential_schema` で定義され、`api_key` などが渡されます。
* `content_text` (string) 変換が必要なテキストコンテンツ
* `streaming` (bool) ストリーミング出力を行うかどうか
* `user` (string) \[optional] ユーザーの一意の識別子
プロバイダーが不正利用を監視および検出するのに役立ちます。
* 戻り値:
テキスト変換後の音声ストリーム。
#### Moderation
`__base.moderation_model.ModerationModel` ベースクラスを継承し、以下のインターフェースを実装します:
* Invoke 呼び出し
```python
def _invoke(self, model: str, credentials: dict,
text: str, user: Optional[str] = None) \
-> bool:
"""
大規模言語モデルを呼び出します
:param model: モデル名
:param credentials: モデルの認証情報
:param text: モデレーションするテキスト
:param user: 一意のユーザーID
:return: テキストが安全な場合はfalse、それ以外の場合はtrue
"""
```
* パラメータ:
* `model` (string) モデル名
* `credentials` (object) 認証情報
認証情報のパラメータは、プロバイダーのYAML設定ファイルの `provider_credential_schema` または `model_credential_schema` で定義され、`api_key` などが渡されます。
* `text` (string) テキストコンテンツ
* `user` (string) \[optional] ユーザーの一意の識別子
プロバイダーが不正利用を監視および検出するのに役立ちます。
* 戻り値:
Falseは渡されたテキストが安全であることを示し、Trueはその逆を示します。
### エンティティ
#### PromptMessageRole
メッセージロール
```python
class PromptMessageRole(Enum):
"""
プロンプトメッセージのEnumクラス。
"""
SYSTEM = "system"
USER = "user"
ASSISTANT = "assistant"
TOOL = "tool"
```
#### PromptMessageContentType
メッセージコンテントタイプ。プレーンテキストと画像に分かれます。
```python
class PromptMessageContentType(Enum):
"""
プロンプトメッセージコンテントタイプのEnumクラス。
"""
TEXT = 'text'
IMAGE = 'image'
```
#### PromptMessageContent
メッセージコンテントのベースクラス。パラメータ宣言専用であり、初期化できません。
```python
class PromptMessageContent(BaseModel):
"""
プロンプトメッセージコンテントのモデルクラス。
"""
type: PromptMessageContentType
data: str # コンテンツデータ
```
現在、テキストと画像の2つのタイプをサポートしており、テキストと複数の画像を同時に渡すことができます。
それぞれ `TextPromptMessageContent` と `ImagePromptMessageContent` を初期化して渡す必要があります。
#### TextPromptMessageContent
```python
class TextPromptMessageContent(PromptMessageContent):
"""
テキストプロンプトメッセージコンテントのモデルクラス。
"""
type: PromptMessageContentType = PromptMessageContentType.TEXT
```
画像とテキストを渡す場合、その中のテキストはこのエンティティを `content` リストの一部として構築する必要があります。
#### ImagePromptMessageContent
```python
class ImagePromptMessageContent(PromptMessageContent):
"""
画像プロンプトメッセージコンテントのモデルクラス。
"""
class DETAIL(Enum):
LOW = 'low'
HIGH = 'high'
type: PromptMessageContentType = PromptMessageContentType.IMAGE
detail: DETAIL = DETAIL.LOW # 解像度
```
画像とテキストを渡す場合、その中の画像はこのエンティティを `content` リストの一部として構築する必要があります。
`data` は `url` または画像の `base64` エンコードされた文字列です。
#### PromptMessage
すべてのRoleメッセージボディのベースクラス。パラメータ宣言専用であり、初期化できません。
```python
class PromptMessage(ABC, BaseModel):
"""
プロンプトメッセージのモデルクラス。
"""
role: PromptMessageRole # メッセージロール
content: Optional[str | list[PromptMessageContent]] = None # 文字列とコンテントリストの2つのタイプをサポートします。コンテントリストはマルチモーダルのニーズを満たすためのもので、詳細は `PromptMessageContent` の説明を参照してください。
name: Optional[str] = None # 名称、オプション。
```
#### UserPromptMessage
UserMessageメッセージボディ。ユーザーメッセージを表します。
```python
class UserPromptMessage(PromptMessage):
"""
ユーザープロンプトメッセージのモデルクラス。
"""
role: PromptMessageRole = PromptMessageRole.USER
```
#### AssistantPromptMessage
モデルの返信メッセージを表します。通常、`few-shots` またはチャット履歴の入力に使用されます。
```python
class AssistantPromptMessage(PromptMessage):
"""
アシスタントプロンプトメッセージのモデルクラス。
"""
class ToolCall(BaseModel):
"""
アシスタントプロンプトメッセージツールコールのモデルクラス。
"""
class ToolCallFunction(BaseModel):
"""
アシスタントプロンプトメッセージツールコール関数のモデルクラス。
"""
name: str # ツール名
arguments: str # ツールパラメータ
id: str # ツールID。OpenAI の tool call のみで有効で、ツールの呼び出しの一意のIDです。同じツールを複数回呼び出すことができます。
type: str # デフォルトは function
function: ToolCallFunction # ツール呼び出し情報
role: PromptMessageRole = PromptMessageRole.ASSISTANT
tool_calls: list[ToolCall] = [] # モデルが応答したツール呼び出し結果tools が渡され、かつモデルがツールの呼び出しが必要だと判断した場合にのみ返されます)
```
この `tool_calls` は、モデルを呼び出す際に `tools` を渡した後、モデルから返される `tool call` のリストです。
#### SystemPromptMessage
システムメッセージを表します。通常、モデルに設定するシステム指示に使用されます。
```python
class SystemPromptMessage(PromptMessage):
"""
システムプロンプトメッセージのモデルクラス。
"""
role: PromptMessageRole = PromptMessageRole.SYSTEM
```
#### ToolPromptMessage
ツールメッセージを表します。ツールの実行後に結果をモデルに渡し、次のステップを計画するために使用されます。
```python
class ToolPromptMessage(PromptMessage):
"""
ツールプロンプトメッセージのモデルクラス。
"""
role: PromptMessageRole = PromptMessageRole.TOOL
tool_call_id: str # ツール呼び出しID。OpenAI tool call をサポートしていない場合、ツール名を渡すこともできます。
```
ベースクラスの `content` にツールの実行結果を渡します。
#### PromptMessageTool
```python
class PromptMessageTool(BaseModel):
"""
プロンプトメッセージツールのモデルクラス。
"""
name: str # ツール名
description: str # ツールの説明
parameters: dict # ツールパラメータのdict
```
***
#### LLMResult
```python
class LLMResult(BaseModel):
"""
LLM結果のモデルクラス。
"""
model: str # 実際に使用されたモデル
prompt_messages: list[PromptMessage] # プロンプトメッセージのリスト
message: AssistantPromptMessage # 返信メッセージ
usage: LLMUsage # 使用されたトークンおよび料金情報
system_fingerprint: Optional[str] = None # リクエストフィンガープリント。OpenAI の当該パラメータ定義を参照できます。
```
#### LLMResultChunkDelta
ストリーミングレスポンスにおける各イテレーション内部の `delta` エンティティ
```python
class LLMResultChunkDelta(BaseModel):
"""
LLM結果チャンクデルタのモデルクラス。
"""
index: int # シーケンス番号
message: AssistantPromptMessage # 返信メッセージ
usage: Optional[LLMUsage] = None # 使用されたトークンおよび料金情報。最後のメッセージでのみ返されます。
finish_reason: Optional[str] = None # 終了理由。最後のメッセージでのみ返されます。
```
#### LLMResultChunk
ストリーミングレスポンスにおける各イテレーションのエンティティ
```python
class LLMResultChunk(BaseModel):
"""
LLM結果チャンクのモデルクラス。
"""
model: str # 実際に使用されたモデル
prompt_messages: list[PromptMessage] # プロンプトメッセージのリスト
system_fingerprint: Optional[str] = None # リクエストフィンガープリント。OpenAI の当該パラメータ定義を参照できます。
delta: LLMResultChunkDelta # 各イテレーションで変化のある内容
```
#### LLMUsage
```python
class LLMUsage(ModelUsage):
"""
LLM使用量のモデルクラス。
"""
prompt_tokens: int # プロンプト使用トークン数
prompt_unit_price: Decimal # プロンプト単価
prompt_price_unit: Decimal # プロンプト価格単位(単価が何トークンに基づいているか)
prompt_price: Decimal # プロンプト料金
completion_tokens: int # 返信使用トークン数
completion_unit_price: Decimal # 返信単価
completion_price_unit: Decimal # 返信価格単位(単価が何トークンに基づいているか)
completion_price: Decimal # 返信料金
total_tokens: int # 総使用トークン数
total_price: Decimal # 総料金
currency: str # 通貨単位
latency: float # リクエスト遅延(秒)
```
***
#### TextEmbeddingResult
```python
class TextEmbeddingResult(BaseModel):
"""
テキスト埋め込み結果のモデルクラス。
"""
model: str # 実際に使用されたモデル
embeddings: list[list[float]] # embeddingベクトルリスト。渡された texts リストに対応します。
usage: EmbeddingUsage # 使用情報
```
#### EmbeddingUsage
```python
class EmbeddingUsage(ModelUsage):
"""
埋め込み使用量のモデルクラス。
"""
tokens: int # 使用トークン数
total_tokens: int # 総使用トークン数
unit_price: Decimal # 単価
price_unit: Decimal # 価格単位(単価が何トークンに基づいているか)
total_price: Decimal # 総料金
currency: str # 通貨単位
latency: float # リクエスト遅延(秒)
```
***
#### RerankResult
```python
class RerankResult(BaseModel):
"""
Rerank結果のモデルクラス。
"""
model: str # 実際に使用されたモデル
docs: list[RerankDocument] # リランキング後のドキュメントリスト
```
#### RerankDocument
```python
class RerankDocument(BaseModel):
"""
Rerankドキュメントのモデルクラス。
"""
index: int # 元のシーケンス番号
text: str # ドキュメントのテキスト内容
score: float # スコア
```
## 関連リソース
- [モデル設計ルール](/plugin_dev_ja/0411-model-designing-rules.ja) - モデル設定の仕様を理解する
- [モデルプラグイン紹介](/plugin_dev_ja/0131-model-plugin-introduction.ja) - モデルプラグインの基本概念を素早く理解する
- [新しいモデルへの迅速な接続](/plugin_dev_ja/0211-getting-started-new-model.ja) - 既存のプロバイダーに新しいモデルを追加する方法を学ぶ
- [新規モデルプロバイダーの作成](/plugin_dev_ja/0222-creating-new-model-provider.ja) - 全く新しいモデルプロバイダーを開発する方法を学ぶ

View File

@@ -0,0 +1,345 @@
---
dimensions:
type:
primary: reference
detail: examples
level: intermediate
standard_title: Develop A Slack Bot Plugin
language: ja
title: Slack Bot プラグインの開発
description: このドキュメントでは、プロジェクトの初期化、設定フォームの編集、機能コードの実装、プラグインのデバッグ、エンドポイントの設定、効果検証からパッケージ化、リリースまでの完全なSlack Botプラグイン開発ガイドを提供します。Slackプラットフォーム上でAI駆動のチャットボットを構築するために、Difyプラグインスキャフォールディングツールと作成済みのSlack Appが必要です。
---
**本稿では、次のことをお手伝いします。**
Slack Bot の構築方法を深く理解し、AI 駆動の Slack チャットボットを作成し、 Slack プラットフォームでユーザーの質問にインテリジェントに応答します。プラグイン開発の経験がない場合は、まず[プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja)を読むことをお勧めします。
### プロジェクトの背景
Dify プラグインエコシステムは、よりシンプルで使いやすいアクセス方法のサポートに取り組んでいます。本稿では Slack を例に、Slack Bot プラグインの開発方法を詳しく説明し、チームメンバーが Slack プラットフォーム内で直接 LLM と対話し、AI サービスの使用効率を向上させるのに役立ちます。
Dify プラグインエコシステムは、よりシンプルで便利なアクセス方法を提供することを目指しています。本稿では Slack を例に、Slack Bot プラグインの開発方法を詳細に解説し、チームメンバーが Slack プラットフォームで直接 AI アプリケーションを使用し、業務効率を向上させるのに役立ちます。
Slack は、自由でオープンなリアルタイムオフィスコミュニケーションプラットフォームであり、豊富な API を備えています。その中でも、イベントベースの Webhook 機能は開発に着手しやすいです。このメカニズムを利用して Slack Bot プラグインを作成します。その原理は下図の通りです。
![Slack Bot の原理図](https://assets-docs.dify.ai/2025/01/a0865d18f1ca4051601ca53fa6f92db2.png)
> 混乱を避けるため、以下の概念について説明します。
>
> * **Slack Bot** は Slack プラットフォーム上のチャットボットであり、仮想キャラクターと見なすことができ、チャットで対話することができます。
> * **Slack Bot プラグイン**とは、Dify Marketplace 上のプラグインで、Dify アプリケーションと Slack プラットフォームを接続するために使用されます。本稿では、主にこのプラグイン開発について説明します。
**原理の概要:**
1. **Slack Bot にメッセージを送信**
ユーザーが Slack で Bot にメッセージを送信すると、Slack Bot は Dify プラットフォームに Webhook リクエストを送信します。
2. **メッセージを Slack Bot プラグインに転送**
ユーザーが Slack bot と対話する際、メッセージを Dify アプリケーションに転送する必要があります。メールシステムが受信者のメールアドレスを必要とするように、Slack の API を介して Slack Webhook のアドレスを設定し、それを Slack Bot プラグインに入力して接続を確立することができます。
3. **プラグインがメッセージを受信後、特定の Dify アプリケーションに返す**
Slack Bot プラグインは Slack リクエストを処理し、Dify 内のアプリケーションに送信します。LLM がユーザーの入力内容を分析し、応答します。
4. **Dify アプリケーションが応答後、メッセージを Slack Bot に返し、ユーザーに回答する**
Slack Bot は Dify アプリケーションの応答を取得後、プラグインを介してメッセージを元の経路で Slack Bot に返し、ユーザーが Slack を使用しながら直接 Dify アプリケーションと対話できるようにします。
### 事前準備
* Dify プラグインスキャフォールディングツール。詳細については、[開発ツールの初期化](/plugin_dev_ja/0221-initialize-development-tools.ja)を参照してください。
* Python 環境、バージョン番号 ≥ 3.12。詳細については、[Python インストールチュートリアル](https://pythontest.com/python/installing-python-3-11/)を参照するか、LLM に完全なインストールチュートリアルを問い合わせてください。
* Slack App を作成し、OAuth トークンを取得する
[Slack API](https://api.slack.com/apps) プラットフォームにアクセスし、scratch 方式で Slack APP を作成し、アプリケーションをデプロイする Slack スペースを選択します。
![Slack API トークン](https://assets-docs.dify.ai/2025/01/8217c23ee16c47c586a1387a442ea6f0.png)
Webhooks 機能を有効にします。
![Webhooks 機能を有効にする](https://assets-docs.dify.ai/2025/01/fc9d7797608422219a01248f7151fc81.png)
App を Slack ワークスペースにインストールします。
![ワークスペースにインストール](https://assets-docs.dify.ai/2025/01/6ab7226078f88853fc7f4d3520245d63.png)
OAuth トークンを取得し、後続のプラグイン開発に使用します。
![OAuth トークンを取得](https://assets-docs.dify.ai/2025/01/f08052044c8c17eebbffacdc9b2558e6.png)
### 1. プラグインの開発
ここから実際のプラグインコーディング作業を開始します。開始する前に、[Extension プラグインの開発](/plugin_dev_ja/9231-extension-plugin.ja)を読んだか、Dify プラグインを一度開発したことがあることを確認してください。
#### プロジェクトの初期化
以下のコマンドを実行してプラグイン開発プロジェクトを初期化します。
```bash
dify plugin init
```
プロンプトに従ってプロジェクトの基本情報を入力し、`extension` テンプレートを選択し、`Apps` と `Endpoints` の 2 つの権限を付与します。
プラグインが Dify プラットフォームの機能を逆引き呼び出しする方法の詳細については、[逆引き呼び出し](/plugin_dev_ja/9241-reverse-invocation.ja)を参照してください。
![プラグイン権限](https://assets-docs.dify.ai/2024/12/d89a6282c5584fc43a9cadeddf09c0de.png)
#### 1. 設定フォームの編集
このプラグインでは、どの Dify の App を使用して返信するかを指定する必要があり、返信する際には Slack の App token を使用する必要があるため、プラグインフォームにこれらの 2 つのフィールドを追加する必要があります。
group パス以下の yaml ファイルを変更します。例:`group/slack.yaml`。フォーム設定ファイルの名前は、プラグイン作成時に記入した基本情報によって決まります。対応する yaml ファイルを変更できます。
**サンプルコード:**
`slack.yaml`
```yaml
settings:
- name: bot_token
type: secret-input
required: true
label:
en_US: Bot Token
zh_Hans: Bot Token
pt_BR: Token do Bot
ja_JP: Bot Token
placeholder:
en_US: Please input your Bot Token
zh_Hans: 请输入你的 Bot Token
pt_BR: Por favor, insira seu Token do Bot
ja_JP: ボットトークンを入力してください
- name: allow_retry
type: boolean
required: false
label:
en_US: Allow Retry
zh_Hans: 允许重试
pt_BR: Permitir Retentativas
ja_JP: 再試行を許可
default: false
- name: app
type: app-selector
required: true
label:
en_US: App
zh_Hans: 应用
pt_BR: App
ja_JP: アプリ
placeholder:
en_US: the app you want to use to answer Slack messages
zh_Hans: 你想要用来回答 Slack 消息的应用
pt_BR: o app que você deseja usar para responder mensagens do Slack
ja_JP: あなたが Slack メッセージに回答するために使用するアプリ
endpoints:
- endpoints/slack.yaml
```
コードデータ構造の説明:
```
- name: app
type: app-selector
scope: chat
```
* `type` フィールドは `app-selector` フィールドとして指定されます。
ユーザーはプラグイン使用時に特定の Dify アプリケーションにアクセスし、メッセージ転送を行うことができます。
* `scope` フィールドは `chat` フィールドとして指定されます。
`agent`、`chatbot`、`chatflow` などのタイプのアプリのみ使用できます。
最後に `endpoints/slack.yaml` ファイル内のリクエストパスとリクエストメソッドを変更し、method を POST 方式に変更する必要があります。
**サンプルコード:**
`endpoints/slack.yaml`
```yaml
path: "/"
method: "POST"
extra:
python:
source: "endpoints/slack.py"
```
#### 2. 機能コードの編集
`endpoints/slack.py` ファイルを変更し、以下のコードを追加します。
````python
import json
import traceback
from typing import Mapping
from werkzeug import Request, Response
from dify_plugin import Endpoint
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
class SlackEndpoint(Endpoint):
def _invoke(self, r: Request, values: Mapping, settings: Mapping) -> Response:
"""
Invokes the endpoint with the given request.
"""
retry_num = r.headers.get("X-Slack-Retry-Num")
if (not settings.get("allow_retry") and (r.headers.get("X-Slack-Retry-Reason") == "http_timeout" or ((retry_num is not None and int(retry_num) > 0)))):
return Response(status=200, response="ok")
data = r.get_json()
# Handle Slack URL verification challenge
if data.get("type") == "url_verification":
return Response(
response=json.dumps({"challenge": data.get("challenge")}),
status=200,
content_type="application/json"
)
if (data.get("type") == "event_callback"):
event = data.get("event")
if (event.get("type") == "app_mention"):
message = event.get("text", "")
if message.startswith("<@"):
message = message.split("> ", 1)[1] if "> " in message else message
channel = event.get("channel", "")
blocks = event.get("blocks", [])
blocks[0]["elements"][0]["elements"] = blocks[0].get("elements")[0].get("elements")[1:]
token = settings.get("bot_token")
client = WebClient(token=token)
try:
response = self.session.app.chat.invoke(
app_id=settings["app"]["app_id"],
query=message,
inputs={},
response_mode="blocking",
)
try:
blocks[0]["elements"][0]["elements"][0]["text"] = response.get("answer")
result = client.chat_postMessage(
channel=channel,
text=response.get("answer"),
blocks=blocks
)
return Response(
status=200,
response=json.dumps(result),
content_type="application/json"
)
except SlackApiError as e:
raise e
except Exception as e:
err = traceback.format_exc()
return Response(
status=200,
response="Sorry, I'm having trouble processing your request. Please try again later." + str(err),
content_type="text/plain",
)
else:
return Response(status=200, response="ok")
else:
return Response(status=200, response="ok")
else:
return Response(status=200, response="ok")
```
````
テストを容易にするため、プラグイン機能は現在ユーザーの入力内容を繰り返すことしかできず、Dify app の呼び出しは一時的に行いません。
### 2. プラグインのデバッグ
Dify プラットフォームにアクセスし、Dify プラグインのリモートデバッグ接続アドレスとキーを取得します。
![プラグインのテスト](https://assets-docs.dify.ai/2025/01/8d24006f0cabf5bf61640a9023c45db8.png)
プラグインプロジェクトに戻り、`.env.example` ファイルをコピーして `.env` に名前を変更します。
```bash
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=remote
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****
```
`python -m main` コマンドを実行してプラグインを起動します。プラグインページで、このプラグインがワークスペースにインストールされていることが確認できます。他のチームメンバーもこのプラグインにアクセスできます。
```bash
python -m main
```
#### プラグインのエンドポイントを設定
Dify のプラグイン管理ページで、自動インストールされたテストプラグインを見つけ、新しいエンドポイントを作成し、名前、Bot token を入力し、接続するアプリを選択します。
![POST リクエストアドレスの生成](https://assets-docs.dify.ai/2025/01/e6952a5798a7ae793b3fe7df6f76ea73.png)
保存後、POST リクエストアドレスが生成されます。
![POST リクエストアドレスの生成](https://assets-docs.dify.ai/2025/01/e6952a5798a7ae793b3fe7df6f76ea73.png)
次に、Slack App の設定を完了する必要があります。
1. Event サブスクリプションを有効にする
![Event サブスクリプションを有効にする](https://assets-docs.dify.ai/2025/01/1d33bb9cde78a1b5656ad6a0b8350195.png)
上記で生成されたプラグインの POST リクエストアドレスを貼り付けます。
![生成されたプラグイン POST リクエストアドレスを貼り付け](https://assets-docs.dify.ai/2025/01/65aa41f37c3800af49e944f9ff28e121.png)
Slack App が持つべき権限にチェックを入れます。
![Slack App に必要な権限を選択](https://assets-docs.dify.ai/2025/01/25c38a2cf10ec6c55ae54970d790f37e.png)
### 3. プラグイン効果の検証
コードは `self.session.app.chat.invoke` を使用して Dify プラットフォーム内の App を呼び出し、`app_id` や `query` などの情報を渡し、最後にレスポンスの内容を Slack Bot に返します。`python -m main` コマンドを実行してプラグインを再起動してデバッグし、Slack Bot が Dify App の応答メッセージを正しく出力できるか確認します。
![POST リクエストアドレスの生成](https://assets-docs.dify.ai/2025/01/e6952a5798a7ae793b3fe7df6f76ea73.png)
### 4. プラグインのパッケージ化(オプション)
プラグインが正常に動作することを確認した後、以下のコマンドラインツールを使用してプラグインをパッケージ化し、名前を付けることができます。実行後、現在のフォルダに `slack_bot.difypkg` ファイルが見つかります。これが最終的なプラグインパッケージです。パッケージ化の詳細な手順については、[ローカルファイルとしてパッケージ化して共有](/plugin_dev_ja/0322-release-by-file.ja)を参照してください。
```bash
# ./slack_bot を実際のプラグインプロジェクトパスに置き換えてください。
dify plugin package ./slack_bot
```
おめでとうございます。これでプラグインの完全な開発、テスト、パッケージ化プロセスが完了しました!
### 5. プラグインの公開(オプション)
これで、[Dify Marketplace リポジトリ](https://github.com/langgenius/dify-plugins)にアップロードしてプラグインを公開できます!ただし、公開する前に、プラグインが[Dify Marketplace への公開](/plugin_dev_ja/0322-release-to-dify-marketplace.ja)の規範に従っていることを確認してください。
## 関連リソース
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - Difyプラグイン開発の全体像を理解する
- [プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja) - ゼロからプラグインを開発する
- [Extension プラグインの開発](/plugin_dev_ja/9231-extension-plugin.ja) - 拡張プラグイン開発を理解する
- [Dify サービスの逆引き呼び出し](/plugin_dev_ja/9241-reverse-invocation.ja) - Dify プラットフォームの機能を呼び出す方法を理解する
- [App の逆引き呼び出し](/plugin_dev_ja/9242-reverse-invocation-app.ja) - プラットフォーム内の App を呼び出す方法を理解する
- [プラグインの公開](/plugin_dev_ja/0321-release-overview.ja) - 公開プロセスを学ぶ
- [Dify Marketplace への公開](/plugin_dev_ja/0322-release-to-dify-marketplace.ja) - マーケットプレイス公開ガイド
- [エンドポイントの詳細定義](/plugin_dev_ja/0432-endpoint.ja) - エンドポイントの詳細定義
### 参考文献
完全な Dify プラグインのプロジェクトコードを確認したい場合は、[Github コードリポジトリ](https://github.com/langgenius/dify-plugins)にアクセスしてください。その他、他のプラグインの完全なコードと詳細を確認できます。
さらに多くのプラグインについて知りたい場合は、以下の内容を参照してください。
**クイックスタート:**
* [Extension プラグインの開発](/plugin_dev_ja/9231-extension-plugin.ja)
* [Model プラグインの開発](/plugin_dev_ja/0211-getting-started-new-model.ja)
* [Bundle タイププラグイン:複数のプラグインをパッケージ化](/plugin_dev_ja/9241-bundle.ja)
**プラグインインターフェースドキュメント:**
* [マニフェストファイルによるプラグイン情報の定義](/plugin_dev_ja/0411-plugin-info-by-manifest.ja) - マニフェスト構造
* [エンドポイント](/plugin_dev_ja/0432-endpoint.ja) - エンドポイントの詳細定義
* [逆引き呼び出し](/plugin_dev_ja/9241-reverse-invocation.ja) - Dify 機能の逆引き呼び出し
* [共通仕様](/plugin_dev_ja/0411-general-specifications.ja) - ツール仕様
* [モデルアーキテクチャ](/plugin_dev_ja/0412-model-schema.ja) - モデル

View File

@@ -0,0 +1,114 @@
---
dimensions:
type:
primary: reference
detail: examples
level: intermediate
standard_title: Endpoint
language: ja
title: エンドポイント
description: 作成者: Yeuoly、Allen このドキュメントでは、Difyプラグインにおけるエンドポイントの構造と実装方法について、虹猫Nekoプロジェクトを例に詳しく説明します。内容は、エンドポイントグループの定義方法、インターフェースの設定、_invokeメソッドの実装、リクエストとレスポンスの処理を含みます。ドキュメントでは、さまざまなYAML設定フィールドの意味と使用方法を詳細に解説しています。
---
本稿では、[虹猫](/plugin_dev_ja/9231-extension-plugin.ja)プロジェクトを例に、プラグイン内のエンドポイントの構造について説明します。エンドポイントは、プラグインが外部に公開するHTTPインターフェースであり、外部システムとの統合に使用できます。完全なプラグインコードは、[Githubリポジトリ](https://github.com/langgenius/dify-plugin-sdks/tree/main/python/examples/neko)を参照してください。
### グループ定義
`Endpoint` グループは複数の `Endpoint` の集合であり、`Dify` プラグイン内で新しい `Endpoint` を作成する際に、以下のような設定を記入する必要がある場合があります。
![](https://assets-docs.dify.ai/2024/11/763dbf86e4319591415dc5a1b6948ccb.png)
`Endpoint Name` 以外に、グループの設定情報を記述することで新しいフォーム項目を追加できます。保存をクリックすると、そこに含まれる複数のインターフェースが表示され、それらは同じ設定情報を使用します。
![](https://assets-docs.dify.ai/2024/11/b778b7093b7df0dc80a476c65ddcbe58.png)
#### **構造**
* `settings`(map\[string] [ProviderConfig](/plugin_dev_ja/0411-general-specifications#providerconfig.ja) ):エンドポイント設定定義
* `endpoints`(list\[string], required):具体的な `endpoint` インターフェース定義を指します
```yaml
settings:
api_key:
type: secret-input
required: true
label:
en_US: API key
zh_Hans: API key
ja_Jp: API key
pt_BR: API key
placeholder:
en_US: Please input your API key
zh_Hans: 请输入你的 API key
ja_Jp: あなたの API key を入れてください
pt_BR: Por favor, insira sua chave API
endpoints:
- endpoints/duck.yaml
- endpoints/neko.yaml
```
### インターフェース定義
* `path`(string)werkzeugインターフェース標準に従います
* `method`(string):インターフェースメソッド。`HEAD` `GET` `POST` `PUT` `DELETE` `OPTIONS` のみをサポートします
* `extra`(object):基本情報以外の設定情報
* `python`(object)
* `source`(string):このインターフェースを実装するソースコード
```yaml
path: "/duck/<app_id>"
method: "GET"
extra:
python:
source: "endpoints/duck.py"
```
### インターフェース実装
`dify_plugin.Endpoint` を継承したサブクラスを実装し、`_invoke` メソッドを実装する必要があります。
* **入力パラメータ**
* `r`(Request)`werkzeug` の `Request` オブジェクト
* `values`(Mapping)pathから解析されたパスパラメータ
* `settings`(Mapping):この `Endpoint` の設定情報
* **戻り値**
* `werkzeug` の `Response` オブジェクト。ストリーミング応答をサポートします
* 文字列の直接返却はサポートしていません
サンプルコード:
```python
import json
from typing import Mapping
from werkzeug import Request, Response
from dify_plugin import Endpoint
class Duck(Endpoint):
def _invoke(self, r: Request, values: Mapping, settings: Mapping) -> Response:
"""
Invokes the endpoint with the given request.
"""
app_id = values["app_id"]
def generator():
yield f"{app_id} <br>"
return Response(generator(), status=200, content_type="text/html")
```
## 注意事項
* エンドポイントはプラグインが呼び出されたときにのみインスタンス化され、常時実行されるサービスではありません
* エンドポイントを開発する際は、セキュリティに注意し、危険な操作の実行を避けてください
* エンドポイントは、Webhookコールバックの処理や、他のシステムが接続するためのインターフェースの提供に使用できます
プラグイン開発を学習している場合は、まず[プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja)と[開発者向けチートシート](/plugin_dev_ja/0131-cheatsheet.ja)を読むことをお勧めします。
## 関連リソース
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - プラグイン開発の全体的なアーキテクチャを理解する
- [虹猫Nekoインスタンス](/plugin_dev_ja/9231-extension-plugin.ja) - 拡張プラグイン開発の例
- [共通仕様定義](/plugin_dev_ja/0411-general-specifications.ja) - ProviderConfigなどの共通構造を理解する
- [Slackボットプラグイン開発例](/plugin_dev_ja/0432-develop-a-slack-bot-plugin.ja) - 別のプラグイン開発例
- [プラグイン開発入門ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja) - ゼロからプラグインを開発する
- [Difyサービスの逆呼び出し](/plugin_dev_ja/9241-reverse-invocation.ja) - 逆呼び出し機能の使用方法を理解する

View File

@@ -0,0 +1,284 @@
---
dimensions:
type:
primary: implementation
detail: high
level: beginner
standard_title: Extension Plugin
language: ja
title: Extension 插件
description: 本文档提供了开发Extension类型插件的完整教程详细介绍了环境准备、创建项目、定义插件请求入口、编写功能代码、调试、打包发布等全过程。示例项目是一个彩虹猫插件展示了如何通过Extension插件处理HTTP请求并提供网页服务。
---
本文将引导你快速开发一个 Extension 类型的插件,以帮助你了解插件开发的基础流程。
### 前置准备
* Dify 插件脚手架工具
* Python 环境,版本号 ≥ 3.12
关于如何准备插件开发的脚手架工具,详细说明请参考[初始化开发工具](initialize-development-tools.md)。
### 创建新项目
在当前路径下,运行脚手架命令行工具,创建一个新的 dify 插件项目。
```
./dify-plugin-darwin-arm64 plugin init
```
如果你已将该二进制文件重命名为了 `dify` 并拷贝到了 `/usr/local/bin` 路径下,可以运行以下命令创建新的插件项目:
```bash
dify plugin init
```
### **填写插件信息**
按照提示配置插件名称、作者信息与插件描述。如果你是团队协作,也可以将作者填写为组织名。
> 插件名称长度必须为 1-128 个字符,并且只能包含字母、数字、破折号和下划线。
![Plugins details](https://assets-docs.dify.ai/2024/12/75cfccb11fe31c56c16429b3998f2eb0.png)
填写完成后,在插件开发语言环节中选择 Python。
![Plugins development: Python](https://assets-docs.dify.ai/2024/11/1129101623ac4c091a3f6f75f4103848.png)
### 3. 选择插件类型并初始化项目模板
脚手架工具内的所有模板均已提供完整的代码项目。出于演示说明,本文将以 `Extension` 类型插件模板作为示例。对于已熟悉插件的开发者而言,无需借助模板,可参考[接口文档](../../schema-definition/)指引完成不同类型的插件开发。
![Extension](https://assets-docs.dify.ai/2024/11/ff08f77b928494e10197b456fc4e2d5b.png)
#### 配置插件权限
插件还需要读取 Dify 主平台的权限才能正常连接。需要为该示例插件授予以下权限:
* Tools
* LLMs
* Apps
* 启用持久化存储 Storage分配默认大小存储
* 允许注册 Endpoint
> 在终端内使用方向键选择权限,使用 “Tab” 按钮授予权限。
勾选所有权限项后,轻点回车完成插件的创建。系统将自动生成插件项目代码。
![Plugins 权限](https://assets-docs.dify.ai/2024/11/5518ca1e425a7135f18f499e55d16bdd.png)
插件的基础文件结构包含以下内容:
```
.
├── 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` 类型插件模板,该目录存放所有 Endpoint 的功能实现代码。
* `group` 指定密钥类型、多语言设置以及 API 定义的文件路径。
* `main.py` 整个项目的入口文件。
* `manifest.yaml` 整个插件的基础配置文件,包含该插件需要什么权限、是什么类型的扩展等配置信息。
* `requirements.txt` 存放 Python 环境的依赖项。
### 开发插件
#### 1. 定义插件的请求入口 Endpoint
编辑 `endpoints/test_plugin.yaml` ,参考以下代码进行修改:
```yaml
path: "/neko"
method: "GET"
extra:
python:
source: "endpoints/test_plugin.py"
```
该代码的意图是定义该插件的入口路径为 `/neko`,请求方法为 GET 类型。插件的功能实现代码为 `endpoints/test_plugin.py` 文件。
#### 2. 编写插件功能
插件功能:请求服务,输出一只彩虹猫。
编写插件的功能实现代码 `endpoints/test_plugin.py` 文件,参考以下示例代码:
```python
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 依赖包:
```python
pip install werkzeug
pip install flask
pip install dify-plugin
```
### 调试插件
接下来需测试插件是否可以正常运行。Dify 提供远程调试方式,前往“插件管理”页获取调试 Key 和远程服务器地址。
![](https://assets-docs.dify.ai/2024/11/1cf15bc59ea10eb67513c8bdca557111.png)
回到插件项目,拷贝 `.env.example` 文件并重命名为 `.env`,将获取的远程服务器地址和调试 Key 等信息填入其中。
`.env` 文件
```bash
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=remote
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****
```
运行 `python -m main` 命令启动插件。在插件页即可看到该插件已被安装至 Workspace 内。其他团队成员也可以访问该插件。
![](https://assets-docs.dify.ai/2024/11/0fe19a8386b1234755395018bc2e0e35.png)
在插件内新增 Endpoint随意填写名称和 `api_key` 等信息。访问自动生成的 URL即可看到由插件提供的网页服务。
![](https://assets-docs.dify.ai/2024/11/c76375b8df2449d0d8c31a7c2a337579.png)
### 打包插件
确认插件能够正常运行后,可以通过以下命令行工具打包并命名插件。运行以后你可以在当前文件夹发现 `neko.difypkg` 文件,该文件为最终的插件包。
```bash
# 将 ./neko 替换为插件项目的实际路径
dify plugin package ./neko
```
恭喜,你已完成一个插件的完整开发、测试打包过程!
### 发布插件
现在可以将它上传至 [Dify Plugins 代码仓库](https://github.com/langgenius/dify-plugins) 来发布你的插件了!上传前,请确保你的插件遵循了[插件发布规范](https://docs.dify.ai/zh-hans/plugins/publish-plugins/publish-to-dify-marketplace)。审核通过后,代码将合并至主分支并自动上线至 [Dify Marketplace](https://marketplace.dify.ai/)。
### 探索更多
**快速开始:**
* [Tool 插件Google Search](tool-plugin.md)
* [Model 插件](model-plugin/)
* [Bundle 插件:将多个插件打包](bundle.md)
**插件接口文档:**
* [Manifest](../../schema-definition/manifest.md) 结构
* [Endpoint](../../schema-definition/endpoint.md) 详细定义
* [反向调用 Dify 能力](../../schema-definition/reverse-invocation-of-the-dify-service/)
* [工具](../../schema-definition/tool.md)
* [模型](../../schema-definition/model/)
* [扩展 Agent 策略](../../schema-definition/agent.md)
**最佳实践:**
[开发 Slack Bot 插件](../../best-practice/develop-a-slack-bot-plugin.md)

View File

@@ -0,0 +1,426 @@
---
dimensions:
type:
primary: implementation
detail: high
level: intermediate
standard_title: Agent
language: ja
title: Agent
description: このドキュメントでは、DifyのAgent戦略プラグインの開発プロセスについて詳しく説明します。ManifestファイルへのAgent戦略フィールドの追加、Agentプロバイダーの定義、Agent戦略を実装するためのコアステップが含まれます。パラメータの取得、モデルの呼び出し、ツールの呼び出し、ログの生成と管理に関する完全なサンプルコードも詳細に解説しています。
---
Agent戦略は、標準の入力内容と出力形式を定義する拡張可能なテンプレートです。具体的なAgent戦略インターフェースの機能コードを開発することで、CoT思考の連鎖/ ToT思考の木/ GoT思考のグラフ/ BoT思考の骨格など、さまざまなAgent戦略を実現し、[Sementic Kernel](https://learn.microsoft.com/en-us/semantic-kernel/overview/) のような複雑な戦略を実装できます。
### Manifest内へのフィールド追加
プラグインにAgent戦略を追加するには、`manifest.yaml`ファイル内に`plugins.agent_strategies`フィールドを新たに追加し、Agentプロバイダーも定義する必要があります。サンプルコードは以下の通りです。
```yaml
version: 0.0.2
type: plugin
author: "langgenius"
name: "agent"
plugins:
agent_strategies:
- "provider/agent.yaml"
```
ここでは、`manifest`ファイル内の一部の無関係なフィールドは省略されています。Manifestの詳細な形式については、[マニフェストファイルによるプラグイン情報の定義](/plugin_dev_ja/0411-plugin-info-by-manifest.ja)ドキュメントを参照してください。
### Agentプロバイダーの定義
次に、`agent.yaml`ファイルを新規作成し、基本的なAgentプロバイダー情報を入力する必要があります。
```yaml
identity:
author: langgenius
name: agent
label:
en_US: Agent
zh_Hans: Agent
pt_BR: Agent
description:
en_US: Agent
zh_Hans: Agent
pt_BR: Agent
icon: icon.svg
strategies:
- strategies/function_calling.yaml
```
主にいくつかの記述的な基本情報を含み、現在のプロバイダーがどの戦略を含むかを指定します。上記のサンプルコードでは、最も基本的な`function_calling.yaml`戦略ファイルのみが指定されています。
### Agent戦略の定義と実装
#### 定義
次に、Agent戦略を実現できるコードを定義する必要があります。`function_calling.yaml`ファイルを新規作成します:
```yaml
identity:
name: function_calling
author: Dify
label:
en_US: FunctionCalling
zh_Hans: FunctionCalling
pt_BR: FunctionCalling
description:
en_US: Function Calling is a basic strategy for agent, model will use the tools provided to perform the task.
zh_Hans: Function Callingは基本的なAgent戦略であり、モデルは提供されたツールを使用してタスクを実行します。
pt_BR: Function Calling is a basic strategy for agent, model will use the tools provided to perform the task.
parameters:
- name: model
type: model-selector
scope: tool-call&llm
required: true
label:
en_US: Model
zh_Hans: モデル
pt_BR: Model
- name: tools
type: array[tools]
required: true
label:
en_US: Tools list
zh_Hans: ツールリスト
pt_BR: Tools list
- name: query
type: string
required: true
label:
en_US: Query
zh_Hans: ユーザーの質問
pt_BR: Query
- name: max_iterations
type: number
required: false
default: 5
label:
en_US: Max Iterations
zh_Hans: 最大反復回数
pt_BR: Max Iterations
max: 50
min: 1
extra:
python:
source: strategies/function_calling.py
```
コード形式は[`Tool`標準形式](tool.md)に似ており、`model`、`tools`、`query`、`max_iterations`など合計4つのパラメータを定義し、最も基本的なAgent戦略の実装を容易にします。このコードの意味は、ユーザーがモデルと使用するツールを選択し、最大反復回数を設定し、最終的にqueryを渡してAgentの実行を開始できるようにすることです。
#### 機能実装コードの作成
**パラメータの取得**
上記で定義された4つのパラメータに基づき、`model`タイプのパラメータは`model-selector`であり、`tool`タイプのパラメータは特殊な`array[tools]`です。パラメータで取得された形式は、SDKに組み込まれている`AgentModelConfig`と`list[ToolEntity]`を使用して変換できます。
```python
from dify_plugin.interfaces.agent import AgentModelConfig, AgentStrategy, ToolEntity
class FunctionCallingParams(BaseModel):
query: str
model: AgentModelConfig
tools: list[ToolEntity] | None
maximum_iterations: int = 3
class FunctionCallingAgentStrategy(AgentStrategy):
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
"""
Run FunctionCall agent application
"""
fc_params = FunctionCallingParams(**parameters)
```
**モデルの呼び出し**
指定されたモデルの呼び出しは、Agentプラグインに不可欠な機能です。SDK内の`session.model.invoke()`関数を使用してモデルを呼び出します。`model`から必要な入力パラメータを取得できます。
`invoke model`のメソッドシグネチャのサンプルコード:
```python
def invoke(
self,
model_config: LLMModelConfig,
prompt_messages: list[PromptMessage],
tools: list[PromptMessageTool] | None = None,
stop: list[str] | None = None,
stream: bool = True,
) -> Generator[LLMResultChunk, None, None] | LLMResult:
```
モデル情報`model_config`、プロンプト情報`prompt_messages`、およびツール情報`tools`を渡す必要があります。
そのうち`prompt_messages`パラメータは以下のサンプルコードを参照して呼び出すことができますが、`tool_messages`は一定の変換が必要です。
`invoke model`の使用方法のサンプルコードを参照してください:
```python
from collections.abc import Generator
from typing import Any
from pydantic import BaseModel
from dify_plugin.entities.agent import AgentInvokeMessage
from dify_plugin.entities.model.llm import LLMModelConfig
from dify_plugin.entities.model.message import (
PromptMessageTool,
SystemPromptMessage,
UserPromptMessage,
)
from dify_plugin.entities.tool import ToolParameter
from dify_plugin.interfaces.agent import AgentModelConfig, AgentStrategy, ToolEntity
class FunctionCallingParams(BaseModel):
query: str
instruction: str | None
model: AgentModelConfig
tools: list[ToolEntity] | None
maximum_iterations: int = 3
class FunctionCallingAgentStrategy(AgentStrategy):
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
"""
Run FunctionCall agent application
"""
# init params
fc_params = FunctionCallingParams(**parameters)
query = fc_params.query
model = fc_params.model
stop = fc_params.model.completion_params.get("stop", []) if fc_params.model.completion_params else []
prompt_messages = [
SystemPromptMessage(content="あなたのシステムプロンプトメッセージ"),
UserPromptMessage(content=query),
]
tools = fc_params.tools
prompt_messages_tools = self._init_prompt_tools(tools)
# invoke llm
chunks = self.session.model.llm.invoke(
model_config=LLMModelConfig(**model.model_dump(mode="json")),
prompt_messages=prompt_messages,
stream=True,
stop=stop,
tools=prompt_messages_tools,
)
def _init_prompt_tools(self, tools: list[ToolEntity] | None) -> list[PromptMessageTool]:
"""
Init tools
"""
prompt_messages_tools = []
for tool in tools or []:
try:
prompt_tool = self._convert_tool_to_prompt_message_tool(tool)
except Exception:
# APIツールは削除された可能性があります
continue
# save prompt tool
prompt_messages_tools.append(prompt_tool)
return prompt_messages_tools
def _convert_tool_to_prompt_message_tool(self, tool: ToolEntity) -> PromptMessageTool:
"""
convert tool to prompt message tool
"""
message_tool = PromptMessageTool(
name=tool.identity.name,
description=tool.description.llm if tool.description else "",
parameters={
"type": "object",
"properties": {},
"required": [],
},
)
parameters = tool.parameters
for parameter in parameters:
if parameter.form != ToolParameter.ToolParameterForm.LLM:
continue
parameter_type = parameter.type
if parameter.type in {
ToolParameter.ToolParameterType.FILE,
ToolParameter.ToolParameterType.FILES,
}:
continue
enum = []
if parameter.type == ToolParameter.ToolParameterType.SELECT:
enum = [option.value for option in parameter.options] if parameter.options else []
message_tool.parameters["properties"][parameter.name] = {
"type": parameter_type,
"description": parameter.llm_description or "",
}
if len(enum) > 0:
message_tool.parameters["properties"][parameter.name]["enum"] = enum
if parameter.required:
message_tool.parameters["required"].append(parameter.name)
return message_tool
```
**ツールの呼び出し**
ツールの呼び出しもAgentプラグインに不可欠な機能です。`self.session.tool.invoke()`を使用して呼び出すことができます。`invoke tool`のメソッドシグネチャのサンプルコード:
```python
def invoke(
self,
provider_type: ToolProviderType,
provider: str,
tool_name: str,
parameters: dict[str, Any],
) -> Generator[ToolInvokeMessage, None, None]
```
必須パラメータは`provider_type`、`provider`、`tool_name`、`parameters`です。そのうち`tool_name`と`parameters`は、Function CallingではLLMによって生成されることがよくあります。`invoke tool`の使用例コード:
```python
from dify_plugin.entities.tool import ToolProviderType
class FunctionCallingAgentStrategy(AgentStrategy):
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
"""
Run FunctionCall agent application
"""
fc_params = FunctionCallingParams(**parameters)
# tool_call_name and tool_call_args parameter is obtained from the output of LLM
tool_instances = {tool.identity.name: tool for tool in fc_params.tools} if fc_params.tools else {}
tool_instance = tool_instances[tool_call_name]
tool_invoke_responses = self.session.tool.invoke(
provider_type=ToolProviderType.BUILT_IN,
provider=tool_instance.identity.provider,
tool_name=tool_instance.identity.name,
# デフォルト値を追加
parameters={**tool_instance.runtime_parameters, **tool_call_args},
)
```
`self.session.tool.invoke()`関数の出力はGeneratorであり、同様にストリーミング解析が必要であることを意味します。
解析方法については、以下の関数を参照してください:
```python
import json
from collections.abc import Generator
from typing import cast
from dify_plugin.entities.agent import AgentInvokeMessage
from dify_plugin.entities.tool import ToolInvokeMessage
def parse_invoke_response(tool_invoke_responses: Generator[AgentInvokeMessage]) -> str:
result = ""
for response in tool_invoke_responses:
if response.type == ToolInvokeMessage.MessageType.TEXT:
result += cast(ToolInvokeMessage.TextMessage, response.message).text
elif response.type == ToolInvokeMessage.MessageType.LINK:
result += (
f"結果リンク: {cast(ToolInvokeMessage.TextMessage, response.message).text}。"
+ " ユーザーに確認するよう伝えてください。"
)
elif response.type in {
ToolInvokeMessage.MessageType.IMAGE_LINK,
ToolInvokeMessage.MessageType.IMAGE,
}:
result += (
"画像は既に作成されユーザーに送信済みです。"
+ "作成する必要はありません。ユーザーに今すぐ確認するよう伝えてください。"
)
elif response.type == ToolInvokeMessage.MessageType.JSON:
text = json.dumps(cast(ToolInvokeMessage.JsonMessage, response.message).json_object, ensure_ascii=False)
result += f"ツール応答: {text}。"
else:
result += f"ツール応答: {response.message!r}。"
return result
```
#### Log
Agentの思考プロセスを確認したい場合、正常に返されたメッセージを確認する以外に、専用のインターフェースを使用してAgent全体の思考プロセスをツリー構造で表示することもできます。
**ログの作成**
* このインターフェースは`AgentLogMessage`を作成して返します。このMessageはログ内のツリーのードを表します。
* `parent`が渡された場合、そのノードは親ノードを持つことを示します。
* ステータスはデフォルトで"Success"(成功)です。ただし、タスクの実行プロセスをよりよく表示したい場合は、まずステータスを"start"に設定して「実行中」のログを表示し、タスク完了後にそのログのステータスを"Success"に更新することができます。これにより、ユーザーはタスクの開始から完了までの全プロセスを明確に確認できます。
* `label`は、最終的にユーザーにログのタイトルを表示するために使用されます。
```python
def create_log_message(
self,
label: str,
data: Mapping[str, Any],
status: AgentInvokeMessage.LogMessage.LogStatus = AgentInvokeMessage.LogMessage.LogStatus.SUCCESS,
parent: AgentInvokeMessage | None = None,
) -> AgentInvokeMessage
```
**ログの完了**
前のステップで開始ステータスとして`start`状態を選択した場合、ログ完了インターフェースを使用してステータスを変更できます。
```python
def finish_log_message(
self,
log: AgentInvokeMessage,
status: AgentInvokeMessage.LogMessage.LogStatus = AgentInvokeMessage.LogMessage.LogStatus.SUCCESS,
error: Optional[str] = None,
) -> AgentInvokeMessage
```
**インスタンス**
この例では、単純な2ステップの実行プロセスを示しています。まず「思考中」のステータスログを出力し、次に実際のタスク処理を完了します。
```python
class FunctionCallingAgentStrategy(AgentStrategy):
def _invoke(self, parameters: dict[str, Any]) -> Generator[AgentInvokeMessage]:
thinking_log = self.create_log_message(
data={
"Query": parameters.get("query"),
},
label="思考中",
status=AgentInvokeMessage.LogMessage.LogStatus.START,
)
yield thinking_log
llm_response = self.session.model.llm.invoke(
model_config=LLMModelConfig(
provider="openai",
model="gpt-4o-mini",
mode="chat",
completion_params={},
),
prompt_messages=[
SystemPromptMessage(content="あなたは役立つアシスタントです"),
UserPromptMessage(content=parameters.get("query")),
],
stream=False,
tools=[],
)
thinking_log = self.finish_log_message(
log=thinking_log,
)
yield thinking_log
yield self.create_text_message(text=llm_response.message.content)
```
## 関連リソース
- [プラグイン開発の基本概念](/plugin_dev_ja/0111-getting-started-dify-plugin.ja) - プラグイン開発の全体的なアーキテクチャを理解する
- [Agent戦略プラグイン開発例](/plugin_dev_ja/9433-agent-strategy-plugin.ja) - 実際のAgent戦略プラグイン開発例
- [マニフェストファイルによるプラグイン情報の定義](/plugin_dev_ja/0411-plugin-info-by-manifest.ja) - Manifestファイルの詳細な形式を理解する
- [モデルの逆呼び出し](/plugin_dev_ja/9242-reverse-invocation-model.ja) - プラットフォーム内のモデル機能を呼び出す方法を理解する
- [ツールの逆呼び出し](/plugin_dev_ja/9242-reverse-invocation-tool.ja) - 他のプラグインを呼び出す方法を理解する

View File

@@ -0,0 +1,94 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: beginner
standard_title: Bundle
language: ja
title: Bundle プラグインパッケージ
description: 本ドキュメントでは、Bundle プラグインパッケージの概念および開発方法について解説します。Bundle プラグインパッケージは、複数のプラグインを一つに統合することができ、Marketplace タイプ、GitHub タイプ、Package タイプの3種類をサポートしています。本ドキュメントでは、Bundle プロジェクトの作成、さまざまなタイプの依存関係の追加、および Bundle プロジェクトのパッケージ化に至る全プロセスを詳細に説明します。
---
Bundle プラグインパッケージは、複数のプラグインの集合です。これにより、複数のプラグインを単一のプラグイン内にパッケージ化し、プラグインの一括インストールを実現するとともに、より強力なサービスを提供できます。
Dify CLI ツールを使用して、複数のプラグインを Bundle としてパッケージ化できます。Bundle プラグインパッケージには、次の3つのタイプがあります。
* `Marketplace` タイプ。プラグインの ID とバージョン情報を保存します。インポート時には Dify Marketplace を通じて具体的なプラグインパッケージがダウンロードされます。
* `GitHub` タイプ。GitHub のリポジトリURL、リリースバージョン番号、アセットファイル名を保存します。インポート時には Dify が対応する GitHub リポジトリにアクセスしてプラグインパッケージをダウンロードします。
* `Package` タイプ。プラグインパッケージは Bundle 内に直接保存されます。参照元を保存しないため、Bundle パッケージのサイズが大きくなる可能性があります。
### 事前準備
* Dify プラグインスキャフォールディングツール
* Python 環境、バージョン ≥ 3.10
プラグイン開発用のスキャフォールディングツールの準備方法については、[開発ツールの初期化](initialize-development-tools.md)を参照してください。
### Bundle プロジェクトの作成
現在のパスで、スキャフォールディングコマンドラインツールを実行して、新しいプラグインパッケージプロジェクトを作成します。
```bash
./dify-plugin-darwin-arm64 bundle init
```
このバイナリファイルを `dify` にリネームし、`/usr/local/bin` パスにコピーした場合、次のコマンドを実行して新しいプラグインプロジェクトを作成できます。
```bash
dify bundle init
```
#### 1. プラグイン情報の入力
プロンプトに従って、プラグイン名、作成者情報、プラグインの説明を設定します。チームで作業している場合は、作成者として組織名を記入することもできます。
> 名称は1128文字で、使用できる文字は英字、数字、ハイフン、アンダースコアのみです。
![Bundle の基本情報](https://assets-docs.dify.ai/2024/12/03a1c4cdc72213f09523eb1b40832279.png)
情報を入力して Enter キーを押すと、Bundle プラグインプロジェクトディレクトリが自動的に作成されます。
![](https://assets-docs.dify.ai/2024/12/356d1a8201fac3759bf01ee64e79a52b.png)
#### 2. 依存関係の追加
* **Marketplace**
次のコマンドを実行します。
```bash
dify-plugin bundle append marketplace . --marketplace_pattern=langgenius/openai:0.0.1
```
ここで、`marketplace_pattern` は Marketplace でのプラグイン参照であり、フォーマットは `組織名/プラグイン名:バージョン番号` です。
* **Github**
次のコマンドを実行します。
```bash
dify-plugin bundle append github . --repo_pattern=langgenius/openai:0.0.1/openai.difypkg
```
ここで、`repo_pattern` は GitHub でのプラグイン参照であり、フォーマットは `組織名/リポジトリ名:release/アセットファイル名` です。
* **Package**
次のコマンドを実行します。
```bash
dify-plugin bundle append package . --package_path=./openai.difypkg
```
ここで、`package_path` はプラグインパッケージのパスです。
### Bundle プロジェクトのパッケージ化
次のコマンドを実行して Bundle プラグインをパッケージ化します。
```bash
dify-plugin bundle package ./bundle
```
コマンドを実行すると、現在のディレクトリに `bundle.difybndl` ファイルが自動的に作成されます。このファイルが最終的なパッケージ結果です。

View File

@@ -0,0 +1,35 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: beginner
standard_title: Reverse Invocation
language: ja
title: Difyサービスのリバース呼び出し
description: このドキュメントでは、Difyプラグインのリバース呼び出し機能について簡単に説明します。この機能は、プラグインがDifyメインプラットフォーム内の指定されたサービスを呼び出すことを可能にします。本文書では、呼び出し可能なモジュールとして、Appアプリデータへのアクセス、Modelプラットフォーム内のモデル機能の呼び出し、Toolプラットフォーム内の他のツールプラグインの呼び出し、NodeChatflow/Workflowアプリケーション内のード呼び出しの4つのカテゴリをリストアップしています。
---
プラグインは、Difyメインプラットフォーム内の一部のサービスを自由に呼び出し、プラグインの機能を向上させることができます。
### 呼び出し可能なDifyモジュール
* [App](/plugin_dev_ja/9242-reverse-invocation-app.ja)
プラグインはDifyプラットフォーム内のアプリデータにアクセスできます。
* [Model](/plugin_dev_ja/9242-reverse-invocation-model.ja)
プラグインはDifyプラットフォーム内のLLM機能をリバース呼び出しできます。これには、TTS、Rerankなど、プラットフォーム内のすべてのモデルタイプと機能が含まれます。
* [Tool](/plugin_dev_ja/9242-reverse-invocation-tool.ja)
プラグインはDifyプラットフォーム内の他のツールタイプのプラグインを呼び出すことができます。
* [Node](/plugin_dev_ja/9243-reverse-invocation-node.ja)
プラグインはDifyプラットフォーム内の特定のChatflow/Workflowアプリケーション内のードを呼び出すことができます。
## 関連リソース
- [Extensionプラグインの開発](/plugin_dev_ja/9231-extension-plugin.ja) - 外部システムと統合するプラグインの開発方法を学びます
- [Slack Botプラグインの開発](/plugin_dev_ja/0432-develop-a-slack-bot-plugin.ja) - リバース呼び出しを使用してSlackプラットフォームとの統合を実現する実装例
- [バンドルタイプのプラグイン](/plugin_dev_ja/9241-bundle.ja) - リバース呼び出しを使用する複数のプラグインをパッケージ化する方法を学びます
- [永続ストレージの使用](/plugin_dev_ja/0411-persistent-storage-kv.ja) - KVストレージを通じてプラグインの機能を向上させます

View File

@@ -0,0 +1,123 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: intermediate
standard_title: Reverse Invocation App
language: ja
title: アプリ
description: このドキュメントでは、プラグインがDifyプラットフォーム内のAppサービスをリバース呼び出しする方法について詳しく説明します。内容には、チャットインターフェースChatbot/Agent/Chatflowタイプのアプリケーションに適用、Workflowインターフェース、Completionインターフェースの3種類のインターフェースが含まれ、各インターフェースのエントリーポイント、呼び出し規約、および実際の呼び出し例のコードが提供されています。
---
アプリのリバース呼び出しとは、プラグインがDify内のアプリデータにアクセスできることを指します。このモジュールは、ストリーミングと非ストリーミングの両方のアプリ呼び出しをサポートしています。リバース呼び出しの基本的な概念にまだ慣れていない場合は、まず[Difyサービスのリバース呼び出し](/plugin_dev_ja/9241-reverse-invocation.ja)をお読みください。
**インターフェースタイプ:**
* `Chatbot/Agent/Chatflow` タイプのアプリケーションはすべてチャットタイプのアプリケーションであり、同じタイプの入力パラメータと出力パラメータを持つため、統一して**チャットインターフェース**と見なすことができます。
* Workflowアプリケーションの場合、単独で**Workflowインターフェース**を占有します。
* Completionテキスト生成アプリケーションアプリケーションの場合、単独で**Completionインターフェース**を占有します。
注意:プラグインは、プラグインが存在するワークスペース内のアプリにのみアクセスできます。
### チャットインターフェースの呼び出し
#### **エントリーポイント**
```python
self.session.app.chat
```
#### **インターフェース規約**
```python
def invoke(
self,
app_id: str,
inputs: dict,
response_mode: Literal["streaming", "blocking"],
conversation_id: str,
files: list,
) -> Generator[dict, None, None] | dict:
pass
```
`response_mode` が `streaming` の場合、このインターフェースは直接 `Generator[dict]` を返します。そうでない場合は直接 `dict` を返します。具体的なインターフェースフィールドについては、`ServiceApi` の戻り結果を参照してください。
#### **使用例**
`Endpoint`内でチャットタイプのアプリを呼び出し、結果を直接返すことができます。
```python
import json
from typing import Mapping
from werkzeug import Request, Response
from dify_plugin import Endpoint
class Duck(Endpoint):
def _invoke(self, r: Request, values: Mapping, settings: Mapping) -> Response:
"""
Invokes the endpoint with the given request.
"""
app_id = values["app_id"]
def generator():
response = self.session.app.workflow.invoke(
app_id=app_id, inputs={}, response_mode="streaming", files=[]
)
for data in response:
yield f"{json.dumps(data)} <br>"
return Response(generator(), status=200, content_type="text/html")
```
### Workflowインターフェースの呼び出し
#### **エントリーポイント**
```python
self.session.app.workflow
```
#### **インターフェース規約**
```python
def invoke(
self,
app_id: str,
inputs: dict,
response_mode: Literal["streaming", "blocking"],
files: list,
) -> Generator[dict, None, None] | dict:
pass
```
### Completionインターフェースの呼び出し
#### **エントリーポイント**
```python
self.session.app.completion
```
**インターフェース規約**
```python
def invoke(
self,
app_id: str,
inputs: dict,
response_mode: Literal["streaming", "blocking"],
files: list,
) -> Generator[dict, None, None] | dict:
pass
```
## 関連リソース
- [Difyサービスのリバース呼び出し](/plugin_dev_ja/9241-reverse-invocation.ja) - リバース呼び出しの基本的な概念を理解する
- [モデルのリバース呼び出し](/plugin_dev_ja/9242-reverse-invocation-model.ja) - プラットフォーム内のモデル機能を呼び出す方法を理解する
- [ツールのリバース呼び出し](/plugin_dev_ja/9242-reverse-invocation-tool.ja) - 他のプラグインを呼び出す方法を理解する
- [Slack Botプラグインの開発](/plugin_dev_ja/0432-develop-a-slack-bot-plugin.ja) - リバース呼び出しを使用した実際の応用例
- [拡張機能プラグインの開発](/plugin_dev_ja/9231-extension-plugin.ja) - 拡張機能プラグインの開発方法を学ぶ

View File

@@ -0,0 +1,289 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: intermediate
standard_title: Reverse Invocation Model
language: ja
title: モデル
description: このドキュメントでは、プラグインがDifyプラットフォーム内のモデルサービスをリバースコールする方法について詳しく説明します。内容は、LLM、Summary、TextEmbedding、Rerank、TTS、Speech2Text、Moderationなどのモデルをリバースコールする具体的な方法を含み、各モデルの呼び出しには、対応するエントリポイント、インターフェースパラメータの説明、および実際の使用例コードが付随しており、モデル呼び出しのベストプラクティスも提供しています。
---
リバースコールモデルとは、プラグインがDify内のLLMTTS、Rerankなど、プラットフォーム内のすべてのモデルタイプと機能を含むをリバースコールする能力を指します。リバースコールの基本概念にまだ慣れていない場合は、まず[Difyサービスのリバースコール](/plugin_dev_ja/9241-reverse-invocation.ja)をお読みください。
ただし、モデルの呼び出しには `ModelConfig` 型のパラメータを渡す必要があり、その構造は[一般的な仕様定義](/plugin_dev_ja/0411-general-specifications.ja)を参照できます。また、モデルの種類によって、この構造にはわずかな違いがあることに注意してください。
例えば、`LLM` タイプのモデルの場合、`completion_params` と `mode` パラメータも含まれている必要があり、この構造を手動で構築するか、`model-selector` タイプのパラメータまたは設定を使用できます。
### LLMの呼び出し
#### **エントリポイント**
```python
self.session.model.llm
```
#### **エンドポイント**
```python
def invoke(
self,
model_config: LLMModelConfig,
prompt_messages: list[PromptMessage],
tools: list[PromptMessageTool] | None = None,
stop: list[str] | None = None,
stream: bool = True,
) -> Generator[LLMResultChunk, None, None] | LLMResult:
pass
```
呼び出すモデルに `tool_call` の機能がない場合、ここで渡される `tools` は有効にならないことに注意してください。
#### **使用例**
`Tool` 内で `OpenAI` の `gpt-4o-mini` モデルを呼び出したい場合は、以下のサンプルコードを参照してください。
```python
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.model.llm import LLMModelConfig
from dify_plugin.entities.tool import ToolInvokeMessage
from dify_plugin.entities.model.message import SystemPromptMessage, UserPromptMessage
class LLMTool(Tool):
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
response = self.session.model.llm.invoke(
model_config=LLMModelConfig(
provider='openai',
model='gpt-4o-mini',
mode='chat',
completion_params={}
),
prompt_messages=[
SystemPromptMessage(
content='you are a helpful assistant'
),
UserPromptMessage(
content=tool_parameters.get('query')
)
],
stream=True
)
for chunk in response:
if chunk.delta.message:
assert isinstance(chunk.delta.message.content, str)
yield self.create_text_message(text=chunk.delta.message.content)
```
コード内で `tool_parameters` の `query` パラメータが渡されていることに注意してください。
### **ベストプラクティス**
`LLMModelConfig` を手動で構築することは推奨されません。代わりに、ユーザーがUI上で使用したいモデルを選択できるようにすることを推奨します。この場合、ツールのパラメータリストを次のように変更し、`model` パラメータを追加できます。
```yaml
identity:
name: llm
author: Dify
label:
en_US: LLM
zh_Hans: LLM
pt_BR: LLM
ja: LLM
description:
human:
en_US: A tool for invoking a large language model
zh_Hans: 用于调用大型语言模型的工具
pt_BR: A tool for invoking a large language model
ja: 大規模言語モデルを呼び出すためのツール
llm: A tool for invoking a large language model
parameters:
- name: prompt
type: string
required: true
label:
en_US: Prompt string
zh_Hans: 提示字符串
pt_BR: Prompt string
ja: プロンプト文字列
human_description:
en_US: used for searching
zh_Hans: 用于搜索网页内容
pt_BR: used for searching
ja: ウェブコンテンツの検索に使用
llm_description: key words for searching
form: llm
- name: model
type: model-selector
scope: llm
required: true
label:
en_US: Model
zh_Hans: 使用的模型
pt_BR: Model
ja: 使用するモデル
human_description:
en_US: Model
zh_Hans: 使用的模型
pt_BR: Model
ja: 使用するモデル
llm_description: which Model to invoke
form: form
extra:
python:
source: tools/llm.py
```
この例では `model` の `scope` が `llm` に指定されていることに注意してください。この場合、ユーザーは `llm` タイプのパラメータしか選択できず、上記の使用例のコードを次のように変更できます。
```python
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.model.llm import LLMModelConfig
from dify_plugin.entities.tool import ToolInvokeMessage
from dify_plugin.entities.model.message import SystemPromptMessage, UserPromptMessage
class LLMTool(Tool):
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
response = self.session.model.llm.invoke(
model_config=tool_parameters.get('model'),
prompt_messages=[
SystemPromptMessage(
content='you are a helpful assistant'
),
UserPromptMessage(
content=tool_parameters.get('query')
)
],
stream=True
)
for chunk in response:
if chunk.delta.message:
assert isinstance(chunk.delta.message.content, str)
yield self.create_text_message(text=chunk.delta.message.content)
```
### Summaryの呼び出し
このエンドポイントにリクエストしてテキストを要約することができます。現在のワークスペース内のシステムモデルを使用してテキストを要約します。
**エントリポイント**
```python
self.session.model.summary
```
**エンドポイント**
* `text` は要約されるテキストです。
* `instruction` は追加したい指示であり、これによりテキストを特定のスタイルで要約できます。
```python
def invoke(
self, text: str, instruction: str,
) -> str:
```
### TextEmbeddingの呼び出し
**エントリポイント**
```python
self.session.model.text_embedding
```
**エンドポイント**
```python
def invoke(
self, model_config: TextEmbeddingResult, texts: list[str]
) -> TextEmbeddingResult:
pass
```
### Rerankの呼び出し
**エントリポイント**
```python
self.session.model.rerank
```
**エンドポイント**
```python
def invoke(
self, model_config: RerankModelConfig, docs: list[str], query: str
) -> RerankResult:
pass
```
### TTSの呼び出し
**エントリポイント**
```python
self.session.model.tts
```
**エンドポイント**
```python
def invoke(
self, model_config: TTSModelConfig, content_text: str
) -> Generator[bytes, None, None]:
pass
```
`tts` エンドポイントが返す `bytes` ストリームは `mp3` オーディオバイトストリームであり、各イテレーションで返されるのは完全なオーディオであることに注意してください。より高度な処理タスクを実行したい場合は、適切なライブラリを選択してください。
### Speech2Textの呼び出し
**エントリポイント**
```python
self.session.model.speech2text
```
**エンドポイント**
```python
def invoke(
self, model_config: Speech2TextModelConfig, file: IO[bytes]
) -> str:
pass
```
ここで `file` は `mp3` 形式でエンコードされたオーディオファイルです。
### Moderationの呼び出し
**エントリポイント**
```python
self.session.model.moderation
```
**エンドポイント**
```python
def invoke(self, model_config: ModerationModelConfig, text: str) -> bool:
pass
```
このエンドポイントが `true` を返した場合、`text` に機密コンテンツが含まれていることを示します。
## 関連リソース
- [Difyサービスのリバースコール](/plugin_dev_ja/9241-reverse-invocation.ja) - リバースコールの基本概念を理解する
- [Appのリバースコール](/plugin_dev_ja/9242-reverse-invocation-app.ja) - プラットフォーム内のAppを呼び出す方法を理解する
- [Toolのリバースコール](/plugin_dev_ja/9242-reverse-invocation-tool.ja) - 他のプラグインを呼び出す方法を理解する
- [モデルプラグイン開発ガイド](/plugin_dev_ja/0211-getting-started-new-model.ja) - カスタムモデルプラグインの開発方法を学ぶ
- [モデル設計規則](/plugin_dev_ja/0411-model-designing-rules.ja) - モデルプラグインの設計原則を理解する

View File

@@ -0,0 +1,92 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: intermediate
standard_title: Reverse Invocation Tool
language: ja
title: ツール
description: このドキュメントでは、プラグインがDifyプラットフォーム内のツールサービスをリバース呼び出しする方法について詳しく説明します。内容は、インストール済みのツールBuilt-in Toolの呼び出し、Workflow as Toolの呼び出し、カスタムツールCustom Toolの呼び出しという3つの異なるタイプのツール呼び出し方法を網羅しています。各呼び出し方法には、対応するエントリポイントとインターフェースパラメータの説明が付いています。
---
リバース呼び出しツールとは、プラグインがDifyプラットフォーム内の他のツールタイプのプラグインを呼び出すことができることを指します。リバース呼び出しの基本概念にまだ慣れていない場合は、まず[Difyサービスのリバース呼び出し](/plugin_dev_ja/9241-reverse-invocation.ja)をお読みください。
次のような要求に遭遇した場合:
* あるツールタイプのプラグインが既に機能を実装しているが、期待通りの効果が得られず、データの二次加工が必要な場合。
* あるタスクでクローラーを使用する必要があり、クローラーサービスを自由に選択したい場合。
* 複数のツールの結果を統合する必要があるが、Workflowアプリケーションでは処理が難しい場合。
この場合、プラグイン内で既に実装されている他のツールを呼び出す必要があります。そのツールは、マーケットプレイスのツールプラグイン、独自に構築したWorkflow as a Tool、またはカスタムツールである可能性があります。
上記の要求は、プラグインの `self.session.tool` フィールドを呼び出すことで実現できます。
### インストール済みのツールの呼び出し
プラグインが現在のワークスペースにインストールされている各ツール(他のツールタイプのプラグインも含む)を呼び出すことを許可します。
**エントリポイント**
```python
self.session.tool
```
**インターフェース**
```python
def invoke_builtin_tool(
self, provider: str, tool_name: str, parameters: dict[str, Any]
) -> Generator[ToolInvokeMessage, None, None]:
pass
```
ここで、provider はプラグインのIDにツールサプライヤー名を加えたもので、`langgenius/google/google` のような形式です。tool\_name は具体的なツール名で、`parameters` は最終的にそのツールに渡されるパラメータです。
### Workflow as Tool の呼び出し
Workflow as Tool に関する詳細については、[ツールプラグインのドキュメント](/plugin_dev_ja/9223-tool.ja)を参照してください。
**エントリポイント**
```python
self.session.tool
```
**インターフェース**
```python
def invoke_workflow_tool(
self, provider: str, tool_name: str, parameters: dict[str, Any]
) -> Generator[ToolInvokeMessage, None, None]:
pass
```
この場合、provider はそのツールのIDです。tool\_name はそのツールの作成時に記入が求められます。
### カスタムツールの呼び出し
**エントリポイント**
```python
self.session.tool
```
**インターフェース**
```python
def invoke_api_tool(
self, provider: str, tool_name: str, parameters: dict[str, Any]
) -> Generator[ToolInvokeMessage, None, None]:
pass
```
この場合、`provider` はそのツールのIDです。`tool_name` は OpenAPI の `operation_id` であり、存在しない場合は Dify が自動生成した `tool_name` となります。具体的な名称はツール管理ページで確認できます。
## 関連リソース
- [Difyサービスのリバース呼び出し](/plugin_dev_ja/9241-reverse-invocation.ja) - リバース呼び出しの基本概念を理解する
- [Appのリバース呼び出し](/plugin_dev_ja/9242-reverse-invocation-app.ja) - プラットフォーム内のAppを呼び出す方法を理解する
- [Modelのリバース呼び出し](/plugin_dev_ja/9242-reverse-invocation-model.ja) - プラットフォーム内のモデル機能を呼び出す方法を理解する
- [ツールプラグイン開発ガイド](/plugin_dev_ja/0211-getting-started-dify-tool.ja) - ツールプラグインの開発方法を学ぶ
- [高度なツールプラグイン](/plugin_dev_ja/9223-tool.ja) - Workflow as Tool などの高度な機能を理解する

View File

@@ -0,0 +1,350 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: advanced
standard_title: Customizable Model
language: ja
title: カスタムモデルの統合
description: このドキュメントでは、Difyでカスタムモデルを統合する方法を、Xinferenceモデルを例に詳しく説明します。ドキュメントには、モデルプロバイダーファイルの作成、モデルタイプに応じたコードの記述、モデル呼び出しロジックと例外処理の実装、デバッグと公開までの完全なプロセスが含まれています。特に、LLM呼び出し、トークン計算、認証情報検証、パラメータ生成などのコアメソッドの実装について詳しく説明しています。
---
カスタムモデルとは、自身でデプロイまたは設定する必要があるLLMを指します。本稿では、[Xinferenceモデル](https://inference.readthedocs.io/en/latest/)を例に、モデルプラグイン内でカスタムモデルを統合する方法を説明します。
カスタムモデルはデフォルトでモデルタイプとモデル名の2つのパラメータを含んでおり、プロバイダーのYAMLファイルで定義する必要はありません。
プロバイダー設定ファイルでは、`validate_provider_credential`を実装する必要はありません。Runtimeは、ユーザーが選択したモデルタイプまたはモデル名に基づいて、対応するモデルレイヤーの`validate_credentials`メソッドを自動的に呼び出して検証を行います。
### カスタムモデルプラグインの統合
カスタムモデルの統合は、以下のステップに分かれます:
1. **モデルプロバイダーファイルの作成**
カスタムモデルに含まれるモデルタイプを明確にします。
2. **モデルタイプに基づいたコードファイルの作成**
モデルのタイプ(例:`llm`または`text_embedding`)に基づいてコードファイルを作成します。各モデルタイプが独立したロジックレイヤーを持つようにし、保守と拡張を容易にします。
3. **異なるモデルモジュールに基づいたモデル呼び出しコードの記述**
対応するモデルタイプモジュールの下に、モデルタイプと同名のPythonファイルllm.pyを作成します。ファイル内で具体的なモデルロジックを実装するクラスを定義し、そのクラスはシステムのモデルインターフェース仕様に準拠する必要があります。
4. **プラグインのデバッグ**
新たに追加されたプロバイダー機能に対して単体テストと結合テストを作成し、すべての機能モジュールが期待通りに動作することを確認します。
***
### 1. **モデルプロバイダーファイルの作成**
プラグインプロジェクトの`/provider`パスの下に、新しい`xinference.yaml`ファイルを作成します。
`Xinference`ファミリーモデルは`LLM`、`Text Embedding`、`Rerank`モデルタイプをサポートしているため、`xinference.yaml`ファイルにこれらのモデルタイプを含める必要があります。
サンプルコード:
```yaml
provider: xinference # プロバイダー識別子を決定
label: # プロバイダー表示名。en_US (英語)、zh_Hans (中国語)の2言語を設定可能。zh_Hans を設定しない場合はデフォルトで en_US が使用されます。
en_US: Xorbits Inference
zh_Hans: Xorbits Inference # 中国語の表示名(例として英語と同じにしていますが、通常は中国語訳)
icon_small: # 小アイコン。他のプロバイダーのアイコンを参考に、対応するプロバイダー実装ディレクトリ下の _assets ディレクトリに保存。中英ポリシーは label と同様。
en_US: icon_s_en.svg
icon_large: # 大アイコン
en_US: icon_l_en.svg
help: # ヘルプ
title:
en_US: How to deploy Xinference
zh_Hans: Xinferenceのデプロイ方法
url:
en_US: https://github.com/xorbitsai/inference
supported_model_types: # サポートされるモデルタイプ。XinferenceはLLM/Text Embedding/Rerankを同時にサポートします。
- llm
- text-embedding
- rerank
configurate_methods: # Xinferenceはローカルデプロイのプロバイダーであり、事前定義されたモデルはありません。どのモデルを使用するかはXinferenceのドキュメントに従ってデプロイする必要があるため、ここのメソッドはカスタムモデルです。
- customizable-model
provider_credential_schema:
credential_form_schemas:
```
次に、`provider_credential_schema`フィールドを定義する必要があります。`Xinference`は`text-generation`、`embeddings`、`reranking`モデルをサポートしています。サンプルコードは以下の通りです:
```yaml
provider_credential_schema:
credential_form_schemas:
- variable: model_type
type: select
label:
en_US: Model type
zh_Hans: モデルタイプ
required: true
options:
- value: text-generation
label:
en_US: Language Model
zh_Hans: 言語モデル
- value: embeddings
label:
en_US: Text Embedding
zh_Hans: テキスト埋め込み # 中国語の表示名(例)
- value: reranking
label:
en_US: Rerank
zh_Hans: リランク # 中国語の表示名(例)
```
Xinferenceの各モデルでは、名前`model_name`を定義する必要があります。
```yaml
- variable: model_name
type: text-input
label:
en_US: Model name
zh_Hans: モデル名
required: true
placeholder:
zh_Hans: モデル名を入力してください
en_US: Input model name
```
Xinferenceモデルでは、ユーザーがモデルのローカルデプロイアドレスを入力する必要があります。プラグイン内では、Xinferenceモデルのローカルデプロイアドレスserver\_urlとモデルUIDを入力できる場所を提供する必要があります。サンプルコードは以下の通りです
```yaml
- variable: server_url
label:
zh_Hans: サーバーURL
en_US: Server url
type: text-input
required: true
placeholder:
zh_Hans: ここにXinferenceのサーバーアドレスを入力してくださいhttps://example.com/xxx
en_US: Enter the url of your Xinference, for example https://example.com/xxx
- variable: model_uid
label:
zh_Hans: モデルUID
en_US: Model uid
type: text-input
required: true
placeholder:
zh_Hans: ここにあなたのモデルUIDを入力してください
en_US: Enter the model uid
```
すべてのパラメータを入力すると、カスタムモデルプロバイダーのYAML設定ファイルの作成が完了します。次に、設定ファイル内で定義されたモデルに具体的な機能コードファイルを追加する必要があります。
### 2. モデルコードの記述
Xinferenceモデルプロバイダーのモデルタイプには、llm、rerank、speech2text、ttsタイプが含まれるため、`/models`パスの下に各モデルタイプごとに独立したグループを作成し、対応する機能コードファイルを作成する必要があります。
以下では、llmタイプを例に、`llm.py`コードファイルの作成方法を説明します。コード作成時には、`XinferenceAILargeLanguageModel`という名前のXinference LLMクラスを作成し、`__base.large_language_model.LargeLanguageModel`ベースクラスを継承し、以下のいくつかのメソッドを実装する必要があります:
* **LLM呼び出し**
LLM呼び出しのコアメソッドであり、ストリーミングと同期の両方のレスポンスをサポートします。
```python
def _invoke(self, model: str, credentials: dict,
prompt_messages: list[PromptMessage], model_parameters: dict,
tools: Optional[list[PromptMessageTool]] = None, stop: Optional[list[str]] = None,
stream: bool = True, user: Optional[str] = None) \
-> Union[LLMResult, Generator]:
"""
大規模言語モデルを呼び出す
:param model: モデル名
:param credentials: モデルの認証情報
:param prompt_messages: プロンプトメッセージ
:param model_parameters: モデルパラメータ
:param tools: ツール呼び出し用のツール
:param stop: ストップワード
:param stream: ストリーム応答であるか
:param user: 一意のユーザーID
:return: 完全な応答またはストリーム応答チャンクジェネレータの結果
"""
```
コードを実装する際には、同期応答とストリーミング応答をそれぞれ処理するために、2つの関数を使用してデータを返す必要があることに注意してください。
Pythonは、関数内に`yield`キーワードが含まれる関数をジェネレータ関数として認識し、返されるデータ型は`Generator`に固定されるため、同期応答とストリーミング応答をそれぞれ実装する必要があります。例えば、以下のサンプルコードです:
> この例では簡略化されたパラメータを使用しています。実際のコード作成時には、上記のパラメータリストを参照してください。
```python
def _invoke(self, stream: bool, **kwargs) \
-> Union[LLMResult, Generator]:
if stream:
return self._handle_stream_response(**kwargs)
return self._handle_sync_response(**kwargs)
def _handle_stream_response(self, **kwargs) -> Generator:
for chunk in response:
yield chunk
def _handle_sync_response(self, **kwargs) -> LLMResult:
return LLMResult(**response)
```
* **入力トークンの事前計算**
モデルがトークンを事前計算するインターフェースを提供していない場合は、直接0を返すことができます。
```python
def get_num_tokens(self, model: str, credentials: dict, prompt_messages: list[PromptMessage],
tools: Optional[list[PromptMessageTool]] = None) -> int:
"""
指定されたプロンプトメッセージのトークン数を取得する
:param model: モデル名
:param credentials: モデルの認証情報
:param prompt_messages: プロンプトメッセージ
:param tools: ツール呼び出し用のツール
:return:
"""
```
場合によっては、直接0を返したくない場合は、`self._get_num_tokens_by_gpt2(text: str)`メソッドを使用してトークンを計算できます。このメソッドは`AIModel`ベースクラスにあり、GPT-2のTokenizerを使用して計算します。ただし、これは代替案であり、計算結果にはある程度の誤差が生じる可能性があることに注意してください。
* **モデル認証情報検証**
プロバイダーの認証情報検証と同様に、ここでは個別のモデルに対して検証を行います。
```python
def validate_credentials(self, model: str, credentials: dict) -> None:
"""
モデルの認証情報を検証する
:param model: モデル名
:param credentials: モデルの認証情報
:return:
"""
```
* **モデルパラメータスキーマ**
[事前定義済みモデルタイプ](integrate-the-predefined-model.md)とは異なり、YAMLファイルでモデルがサポートするパラメータが事前設定されていないため、モデルパラメータのスキーマを動的に生成する必要があります。
例えば、Xinferenceは`max_tokens`、`temperature`、`top_p`の3つのモデルパラメータをサポートしています。しかし、一部のプロバイダー例えばOpenLLMは、具体的なモデルによって異なるパラメータをサポートします。
例を挙げると、プロバイダー`OpenLLM`のAモデルは`top_k`パラメータをサポートしていますが、Bモデルは`top_k`をサポートしていません。この場合、各モデルに対応するパラメータスキーマを動的に生成する必要があります。サンプルコードは以下の通りです:
```python
def get_customizable_model_schema(self, model: str, credentials: dict) -> AIModelEntity | None:
"""
カスタマイズ可能なモデルスキーマを定義するために使用されます
"""
rules = [
ParameterRule(
name='temperature', type=ParameterType.FLOAT,
use_template='temperature',
label=I18nObject(
zh_Hans='温度', en_US='Temperature'
)
),
ParameterRule(
name='top_p', type=ParameterType.FLOAT,
use_template='top_p',
label=I18nObject(
zh_Hans='Top P', en_US='Top P'
)
),
ParameterRule(
name='max_tokens', type=ParameterType.INT,
use_template='max_tokens',
min=1,
default=512,
label=I18nObject(
zh_Hans='最大生成長', en_US='Max Tokens'
)
)
]
# モデルがAの場合、top_kをルールに追加
if model == 'A':
rules.append(
ParameterRule(
name='top_k', type=ParameterType.INT,
use_template='top_k',
min=1,
default=50,
label=I18nObject(
zh_Hans='Top K', en_US='Top K'
)
)
)
"""
ここには重要でないコードがあります
"""
entity = AIModelEntity(
model=model,
label=I18nObject(
en_US=model,
zh_Hans=model # 必要に応じて翻訳
),
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_type=model_type,
model_properties={
ModelPropertyKey.MODE: ModelType.LLM,
},
parameter_rules=rules
)
return entity
```
* **呼び出し例外エラーマッピング表**
モデル呼び出しが例外をスローした場合、Runtimeが指定する`InvokeError`タイプにマッピングする必要があります。これにより、Difyが異なるエラーに対して異なる後続処理を行うのに便利です。
Runtimeエラー:
* `InvokeConnectionError` 呼び出し接続エラー
* `InvokeServerUnavailableError` 呼び出しサービス利用不可
* `InvokeRateLimitError` 呼び出しレート制限到達
* `InvokeAuthorizationError` 呼び出し認証失敗
* `InvokeBadRequestError` 呼び出しパラメータ不正
```python
@property
def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]:
"""
モデル呼び出しエラーを統一エラーにマッピングする
キーは呼び出し元にスローされるエラータイプです
値はモデルによってスローされるエラータイプであり、呼び出し元のために統一されたエラータイプに変換する必要があります。
:return: 呼び出しエラーマッピング
"""
```
より多くのインターフェースメソッドについては、[インターフェースドキュメントModel](../../../schema-definition/model/)を参照してください。
本稿で扱った完全なコードファイルを入手するには、[GitHubコードリポジトリ](https://github.com/langgenius/dify-official-plugins/tree/main/models/xinference)にアクセスしてください。
### 3. プラグインのデバッグ
プラグインの開発が完了したら、次にプラグインが正常に動作するかをテストする必要があります。詳細については、以下を参照してください:
[debug-plugin.md](../../debug-plugin.md)
### 4. プラグインの公開
プラグインをDify Marketplaceに公開したい場合は、以下の内容を参照してください
[publish-to-dify-marketplace](../../../publish-plugins/publish-to-dify-marketplace/)
### **さらに探索**
**クイックスタート:**
* [Extensionプラグインの開発](../extension-plugin.md)
* [Toolプラグインの開発](../tool-plugin.md)
* [Bundleプラグイン複数のプラグインをバンドルする](../bundle.md)
**プラグインインターフェースドキュメント:**
* [Manifest構造](../../../schema-definition/manifest.md)
* [Endpoint詳細定義](../../../schema-definition/endpoint.md)
* [Dify機能の逆呼び出し](../../../schema-definition/reverse-invocation-of-the-dify-service/)
* [ツール](../../../schema-definition/tool.md)
* [モデル](../../../schema-definition/model/)

View File

@@ -0,0 +1,96 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: advanced
standard_title: Reverse Invocation Node
language: ja
title: ノード
description: このドキュメントでは、プラグインがDifyプラットフォーム内のChatflow/Workflowアプリケーションード機能を逆呼び出しする方法について説明します。主な内容は、パラメータ抽出器ードParameterExtractorと問題分類器ードQuestionClassifierという2つの特殊なードの呼び出し方法です。また、これら2つのードの呼び出しエントリーポイント、インターフェースパラメータ、および使用例コードについて詳しく説明します。
---
逆呼び出しードとは、プラグインがDify内のChatflow/Workflowアプリケーション内部のードにアクセスできる機能を指します。
`Workflow` 内の `ParameterExtractorパラメータ抽出器`と `QuestionClassifier問題分類器`ードは、より複雑なプロンプトとコードロジックをカプセル化しており、LLM を通じて多くのハードコーディングでは解決困難なタスクを完了することができます。プラグインはこれら2つのードを呼び出すことができます。
### パラメータ抽出器ノードの呼び出し;
#### **エントリーポイント**
```python
self.session.workflow_node.parameter_extractor
```
#### **インターフェース**
```python
def invoke(
self,
parameters: list[ParameterConfig],
model: ModelConfig,
query: str,
instruction: str = "",
) -> NodeResponse
pass
```
ここで、`parameters` は抽出する必要のあるパラメータのリストであり、`model` は `LLMModelConfig` 仕様に準拠し、`query` はパラメータを抽出する元のテキストであり、`instruction` はLLMに追加で与える必要のある可能性のある指示です。`NodeResponse` の構造については、こちらの[ドキュメント](../general-specifications.md#noderesponse)を参照してください。
#### **使用例**
会話の中から特定の人物名を抽出したい場合は、以下のコードを参照してください。
```python
from collections.abc import Generator
from dify_plugin.entities.tool import ToolInvokeMessage
from dify_plugin import Tool
from dify_plugin.entities.workflow_node import ModelConfig, ParameterConfig
class ParameterExtractorTool(Tool):
def _invoke(
self, tool_parameters: dict
) -> Generator[ToolInvokeMessage, None, None]:
response = self.session.workflow_node.parameter_extractor.invoke(
parameters=[
ParameterConfig(
name="name",
description="name of the person",
required=True,
type="string",
)
],
model=ModelConfig(
provider="langgenius/openai/openai",
name="gpt-4o-mini",
completion_params={},
),
query="My name is John Doe",
instruction="Extract the name of the person",
)
yield self.create_text_message(response.outputs["name"])
```
### 問題分類器ノードの呼び出し
#### **エントリーポイント**
```python
self.session.workflow_node.question_classifier
```
#### **インターフェース**
```python
def invoke(
self,
classes: list[ClassConfig],
model: ModelConfig,
query: str,
instruction: str = "",
) -> NodeResponse:
pass
```
このインターフェースパラメータは `ParameterExtractor` と同じで、最終的な戻り結果は `NodeResponse.outputs['class_name']` に格納されます。

File diff suppressed because it is too large Load Diff