consolidate plugin dev docs into main structure (#581)

* move files & renames

* rename files and doc entries

* sync develop plugin files

* update group label translations

* some cleanups

* update configs

* update links

* add remote debug doc

* delete redundant slashes and unnecessary notes

* update ja and zh links

---------

Co-authored-by: Riskey <riskey47@dify.ai>
This commit is contained in:
Chenhe Gu
2025-12-04 17:28:47 +09:00
committed by GitHub
parent 84bc14cc0b
commit f1f025b75d
221 changed files with 21698 additions and 29576 deletions

View File

@@ -0,0 +1,164 @@
---
dimensions:
type:
primary: conceptual
detail: architecture
level: beginner
standard_title: Cheatsheet
language: en
title: Dify プラグイン開発チートシート
description: 環境要件、インストール方法、開発プロセス、プラグインのカテゴリとタイプ、一般的なコードスニペット、よくある問題の解決策を含む、Dify プラグイン開発の包括的なリファレンスガイドです。開発者が素早く参照できるように設計されています。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/cheatsheet)を参照してください。</Note>
### 環境要件
- Python バージョン ≥ 3.12
- Dify プラグインスキャフォールドツール (dify-plugin-daemon)
> 詳細: [開発ツールの初期化](/ja/develop-plugin/getting-started/cli)
### Dify プラグイン開発パッケージの取得
[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
# Download dify-plugin-darwin-arm64
chmod +x dify-plugin-darwin-arm64
./dify-plugin-darwin-arm64 version
```
**macOS Intel:**
```bash
# Download dify-plugin-darwin-amd64
chmod +x dify-plugin-darwin-amd64
./dify-plugin-darwin-amd64 version
```
**Linux:**
```bash
# Download dify-plugin-linux-amd64
chmod +x dify-plugin-linux-amd64
./dify-plugin-linux-amd64 version
```
**グローバルインストール (推奨):**
```bash
# Rename and move to system path
# Example (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 ガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)
#### 2. 開発モードで実行
`.env` ファイルを設定し、プラグインディレクトリで以下のコマンドを実行します:
```bash
python -m main
```
> 詳細: [プラグインのリモートデバッグ](/ja/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin)
#### 4. パッケージングとデプロイ
プラグインをパッケージ化:
```bash
cd ..
dify plugin package ./yourapp
```
> 詳細: [公開の概要](/ja/develop-plugin/publishing/marketplace-listing/release-overview)
### プラグインカテゴリ
#### ツールラベル
カテゴリ `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 とサービスを統合
> 詳細: [Dify プラグイン開発: Hello World ガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)
- **モデルプラグイン**: AI モデルを統合
> 詳細: [モデルプラグイン](/ja/develop-plugin/features-and-specs/plugin-types/model-designing-rules)、[新しいモデルのクイック統合](/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider)
- **エージェント戦略プラグイン**: エージェントの思考と意思決定戦略をカスタマイズ
> 詳細: [エージェント戦略プラグイン](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation)
- **拡張プラグイン**: Endpoints や WebAPP など、Dify プラットフォームの機能を拡張
> 詳細: [拡張プラグイン](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint)
- **データソースプラグイン**: ナレッジベースパイプラインのドキュメントデータソースおよび開始点として機能
> 詳細: [データソースプラグイン](/ja/develop-plugin/dev-guides-and-walkthroughs/datasource-plugin)
- **トリガープラグイン**: サードパーティのイベントに基づいてワークフローの実行を自動的にトリガー
> 詳細: [トリガープラグイン](/ja/develop-plugin/dev-guides-and-walkthroughs/trigger-plugin)
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/cheatsheet.mdx) | [問題を報告](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,462 @@
---
dimensions:
type:
primary: implementation
detail: standard
level: intermediate
standard_title: Model Provider Plugin
language: en
title: モデルプロバイダープラグイン
description: この包括的なガイドでは、モデルプロバイダープラグインの作成について詳細な手順を提供し、プロジェクトの初期化、ディレクトリ構造の編成、モデル構成方法、プロバイダーコードの記述、およびコア API 実装の詳細な例を含むモデル統合の実装について説明します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider)を参照してください。</Note>
### 前提条件
* [Dify CLI](/ja/develop-plugin/getting-started/cli)
* 基本的な Python プログラミングスキルとオブジェクト指向プログラミングの理解
* 統合したいモデルプロバイダーの API ドキュメントへの精通
## ステップ 1: 新しいプラグインプロジェクトの作成と設定
### プロジェクトの初期化
```bash
dify plugin init
```
### モデルプラグインテンプレートの選択
利用可能なオプションから `LLM` タイプのプラグインテンプレートを選択します。このテンプレートは、モデル統合のための完全なコード構造を提供します。
![Plugin type: llm](https://assets-docs.dify.ai/2024/12/8efe646e9174164b9edbf658b5934b86.png)
### プラグイン権限の設定
モデルプロバイダープラグインには、以下の必須権限を設定します:
* **Models** - モデル操作の基本権限
* **LLM** - 大規模言語モデル機能の権限
* **Storage** - ファイル操作の権限(必要な場合)
![Model Plugin Permission](https://assets-docs.dify.ai/2024/12/10f3b3ee6c03a1215309f13d712455d4.png)
### ディレクトリ構造の概要
初期化後、プラグインプロジェクトは以下のようなディレクトリ構造になりますLLM と Embedding をサポートする `my_provider` という名前のプロバイダーを想定):
```bash
models/my_provider/
├── models # モデル実装と設定ディレクトリ
│ ├── llm # LLM タイプ
│ │ ├── _position.yaml (オプション、ソート順を制御)
│ │ ├── model1.yaml # 特定モデルの設定
│ │ └── llm.py # LLM 実装ロジック
│ └── text_embedding # Embedding タイプ
│ ├── _position.yaml
│ ├── embedding-model.yaml
│ └── text_embedding.py
├── provider # プロバイダーレベルのコードディレクトリ
│ └── my_provider.py # プロバイダー認証情報の検証
└── manifest.yaml # プラグインマニフェストファイル
```
## ステップ 2: モデル設定方法の理解
Dify は、ユーザーがプロバイダーのモデルとどのようにやり取りするかを決定する 2 つのモデル設定方法をサポートしています:
### 事前定義モデル(`predefined-model`
これらは、統一されたプロバイダー認証情報のみで使用できるモデルです。ユーザーがプロバイダーの API キーやその他の認証詳細を設定すると、すべての事前定義モデルにすぐにアクセスできます。
**例:** `OpenAI` プロバイダーは、`gpt-3.5-turbo-0125` や `gpt-4o-2024-05-13` などの事前定義モデルを提供しています。ユーザーは OpenAI API キーを一度設定するだけで、これらすべてのモデルにアクセスできます。
### カスタムモデル(`customizable-model`
これらは、各特定のモデルインスタンスに追加の設定が必要です。このアプローチは、モデルがプロバイダーレベルの認証情報以外の個別パラメータを必要とする場合に便利です。
**例:** `Xinference` は LLM と Text Embedding の両方をサポートしていますが、各モデルには固有の **model_uid** があります。ユーザーは使用したい各モデルごとにこの model_uid を個別に設定する必要があります。
これらの設定方法は、単一のプロバイダー内で**共存できます**。たとえば、プロバイダーがいくつかの事前定義モデルを提供しながら、ユーザーが特定の設定でカスタムモデルを追加できるようにすることができます。
## ステップ 3: モデルプロバイダーファイルの作成
新しいモデルプロバイダーの作成には、2 つの主要なコンポーネントが含まれます:
1. **プロバイダー設定 YAML ファイル** - プロバイダーの基本情報、サポートされるモデルタイプ、認証情報要件を定義
2. **プロバイダークラスの実装** - 認証検証やその他のプロバイダーレベルの機能を実装
***
### 3.1 モデルプロバイダー設定ファイルの作成
プロバイダー設定は、プロバイダーの基本情報、サポートされるモデルタイプ、設定方法、認証情報ルールを宣言する YAML ファイルで定義されます。このファイルは、プラグインプロジェクトのルートディレクトリに配置されます。
以下は、`anthropic.yaml` 設定ファイルの注釈付き例です:
```yaml
# 基本プロバイダー識別
provider: anthropic # プロバイダー ID一意である必要があります
label:
en_US: Anthropic # UI での表示名
description:
en_US: Anthropic's powerful models, such as Claude 3.
zh_Hans: Anthropic 的强大模型,例如 Claude 3。
icon_small:
en_US: icon_s_en.svg # プロバイダーの小さいアイコン(選択 UI に表示)
icon_large:
en_US: icon_l_en.svg # 大きいアイコン(詳細ビューに表示)
background: "#F0F0EB" # UI でのプロバイダーの背景色
# ユーザー向けヘルプ情報
help:
title:
en_US: Get your API Key from Anthropic
zh_Hans: 从 Anthropic 获取 API Key
url:
en_US: https://console.anthropic.com/account/keys
# サポートされるモデルタイプと設定アプローチ
supported_model_types:
- llm # このプロバイダーは LLM モデルを提供
configurate_methods:
- predefined-model # 事前定義モデルアプローチを使用
# プロバイダーレベルの認証情報フォーム定義
provider_credential_schema:
credential_form_schemas:
- variable: anthropic_api_key # API キーの変数名
label:
en_US: API Key
type: secret-input # 機密データ用のセキュア入力
required: true
placeholder:
zh_Hans: 在此输入你的 API Key
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: # LLM タイプモデルの設定
predefined:
- "models/llm/*.yaml" # モデル設定ファイルを見つけるパターン
position: "models/llm/_position.yaml" # 表示順序を定義するファイル
# 実装ファイルの場所
extra:
python:
provider_source: provider/anthropic.py # プロバイダークラスの実装
model_sources:
- "models/llm/llm.py" # モデル実装ファイル
```
### カスタムモデル設定
プロバイダーがカスタムモデルをサポートする場合、各個別モデルに対してユーザーが設定する必要がある追加フィールドを定義する `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 Key
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
# 必要に応じて追加フィールド...
```
完全なモデルプロバイダー YAML 仕様については、[モデルスキーマ](/ja/develop-plugin/features-and-specs/plugin-types/model-schema)ドキュメントを参照してください。
### 3.2 モデルプロバイダーコードの記述
次に、プロバイダークラス実装用の Python ファイルを作成します。このファイルは、プロバイダー名に一致する名前で `/provider` ディレクトリに配置する必要があります(例:`anthropic.py`)。
プロバイダークラスは `ModelProvider` を継承し、少なくとも `validate_provider_credentials` メソッドを実装する必要があります:
```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:
"""
API に対して認証情報をテストして検証します。
このメソッドは、認証情報が有効であることを確認するために
簡単な API 呼び出しを試みる必要があります。
:param credentials: YAML スキーマで定義されたプロバイダー認証情報
:raises CredentialsValidateFailedError: 検証が失敗した場合
"""
try:
# LLM モデルタイプのインスタンスを取得し、認証情報を検証
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
```
`validate_provider_credentials` メソッドは、ユーザーが Dify でプロバイダー認証情報を保存しようとするたびに呼び出されるため、非常に重要です。このメソッドは:
1. 簡単な API 呼び出しを行って認証情報を検証しようとする
2. 検証が成功した場合は静かに戻る
3. 検証が失敗した場合は、役立つメッセージとともに `CredentialsValidateFailedError` をスロー
#### カスタムモデルプロバイダーの場合
カスタムモデルのみを使用するプロバイダー(各モデルに独自の設定が必要な場合)には、より単純なプロバイダークラスを実装できます。たとえば、`Xinference` の場合:
```python
from dify_plugin import ModelProvider
class XinferenceProvider(ModelProvider):
def validate_provider_credentials(self, credentials: dict) -> None:
"""
カスタムモデルのみのプロバイダーの場合、検証はモデルレベルで行われます。
このメソッドは、抽象基底クラスの要件を満たすために存在します。
"""
pass
```
## ステップ 4: モデル固有のコードの実装
プロバイダーの設定後、サポートする各モデルタイプの API 呼び出しを処理するモデル固有のコードを実装する必要があります。これには以下が含まれます:
1. 各特定モデルのモデル設定 YAML ファイルの作成
2. API 通信を処理するモデルタイプクラスの実装
これらのステップの詳細な手順については、以下を参照してください:
* [モデル設計ルール](/ja/develop-plugin/features-and-specs/plugin-types/model-designing-rules) - 事前定義モデルを統合するための標準
* [モデルスキーマ](/ja/develop-plugin/features-and-specs/plugin-types/model-schema) - モデル設定ファイルの標準
### 4.1 モデル設定の定義YAML
各特定モデルについて、適切なモデルタイプディレクトリ(例:`models/llm/`)に YAML ファイルを作成し、そのプロパティ、パラメータ、機能を定義します。
**例(`claude-3-5-sonnet-20240620.yaml`:**
```yaml
model: claude-3-5-sonnet-20240620 # モデルの API 識別子
label:
en_US: claude-3-5-sonnet-20240620 # UI での表示名
model_type: llm # ディレクトリタイプと一致する必要があります
features: # 特別な機能
- agent-thought
- vision
- tool-call
- stream-tool-call
- document
model_properties: # モデル固有のプロパティ
mode: chat # "chat" または "completion"
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
pricing: # オプションの価格情報
input: '3.00'
output: '15.00'
unit: '0.000001' # 100万トークンあたり
currency: USD
```
### 4.2 モデル呼び出しコードの実装Python
サポートする各モデルタイプ用の Python ファイルを作成します(例:`models/llm/` ディレクトリ内の `llm.py`。このクラスは、API 通信、パラメータ変換、結果のフォーマットを処理します。
以下は LLM の実装構造の例です:
```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 # エラークラス
logger = logging.getLogger(__name__)
class MyProviderLargeLanguageModel(LargeLanguageModel):
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]]:
"""
モデル API を呼び出すためのコアメソッド。
パラメータ:
model: 呼び出すモデル識別子
credentials: 認証情報
prompt_messages: 送信するメッセージのリスト
model_parameters: temperature、max_tokens などのパラメータ
tools: 関数呼び出し用のオプションのツール定義
stop: オプションの停止シーケンスのリスト
stream: レスポンスをストリーミングするかTrue、完全なレスポンスを返すかFalse
user: API トラッキング用のオプションのユーザー識別子
戻り値:
stream=True の場合: LLMResultChunk オブジェクトを生成するジェネレータ
stream=False の場合: 完全な LLMResult オブジェクト
"""
# 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 Exception as e:
# エラーを処理してマッピング
self._handle_api_error(e)
def _invoke_stream(self, model: str, api_params: dict, user: Optional[str]) -> Generator[LLMResultChunk, None, None]:
"""ストリーミング API 呼び出し用のヘルパーメソッド"""
# ストリーミング呼び出しの実装詳細
pass
def _invoke_sync(self, model: str, api_params: dict, user: Optional[str]) -> LLMResult:
"""同期 API 呼び出し用のヘルパーメソッド"""
# 同期呼び出しの実装詳細
pass
def validate_credentials(self, model: str, credentials: dict) -> None:
"""
この特定のモデルに対して認証情報が機能するかを検証します。
ユーザーが認証情報を追加または変更しようとするときに呼び出されます。
"""
# 認証情報検証の実装
pass
def get_num_tokens(self, model: str, credentials: dict,
prompt_messages: List[PromptMessage],
tools: Optional[List[PromptMessageTool]] = None) -> int:
"""
指定された入力のトークン数を推定します。
オプションですが、正確なコスト見積もりのために推奨されます。
"""
# トークンカウントの実装
pass
@property
def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]:
"""
ベンダー固有の例外から Dify 標準の例外へのマッピングを定義します。
これにより、異なるプロバイダー間でエラー処理を標準化できます。
"""
return {
InvokeAuthorizationError: [
# ベンダー固有の認証エラーをここにリスト
],
# その他のエラーマッピング
}
```
実装する最も重要なメソッドは `_invoke` で、コア API 通信を処理します。このメソッドは:
1. Dify の標準化された入力をプロバイダーの API が必要とする形式に変換
2. 適切なエラー処理で API 呼び出しを実行
3. API レスポンスを Dify の標準化された出力形式に変換
4. ストリーミングモードと非ストリーミングモードの両方を処理
## ステップ 5: プラグインのデバッグとテスト
Dify は、開発中にプラグインをテストできるリモートデバッグ機能を提供しています:
1. Dify インスタンスで「プラグイン管理」に移動し、「プラグインをデバッグ」をクリックしてデバッグキーとサーバーアドレスを取得
2. `.env` ファイルでこれらの値をローカル環境に設定:
```dotenv
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=<your-dify-domain-or-ip>
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****
```
3. `python -m main` でプラグインをローカルで実行し、Dify でテスト
## ステップ 6: パッケージ化と公開
プラグインの準備ができたら:
1. スキャフォールディングツールを使用してパッケージ化:
```bash
dify plugin package models/<provider_name>
```
2. 提出前にパッケージ化されたプラグインをローカルでテスト
3. [Dify 公式プラグインリポジトリ](https://github.com/langgenius/dify-official-plugins)にプルリクエストを提出
公開プロセスの詳細については、[公開の概要](/ja/develop-plugin/publishing/marketplace-listing/release-overview)を参照してください。
## 参考リソース
- [新しいモデルのクイック統合](/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider) - 既存のプロバイダーに新しいモデルを追加する方法
- [プラグイン開発の基本概念](/ja/develop-plugin/getting-started/getting-started-dify-plugin) - プラグイン開発入門ガイドに戻る
- [モデルスキーマ](/ja/develop-plugin/features-and-specs/plugin-types/model-schema) - 詳細なモデル設定仕様を学ぶ
- [一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - プラグインマニフェストファイルの設定を学ぶ
- [Dify プラグイン SDK リファレンス](https://github.com/langgenius/dify-plugin-sdks) - 基底クラス、データ構造、エラータイプを参照
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,458 @@
---
title: "データソースプラグイン"
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/datasource-plugin)を参照してください。</Note>
データソースプラグインは、Dify 1.9.0で導入された新しいタイプのプラグインです。ナレッジパイプラインにおいて、ドキュメントデータソースとして機能し、パイプライン全体の起点となります。
この記事では、データソースプラグインの開発方法について、プラグインアーキテクチャ、コード例、デバッグ方法を網羅し、データソースプラグインの迅速な開発とリリースを支援します。
## 前提条件
読み進める前に、ナレッジパイプラインの基本的な理解とプラグイン開発に関する知識があることを確認してください。関連情報はこちらで確認できます:
- [ステップ2ナレッジパイプラインオーケストレーション](/ja/guides/knowledge-base/knowledge-pipeline/knowledge-pipeline-orchestration)
- [Difyプラグイン開発Hello Worldガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)
## **データソースプラグインの種類**
Difyは3種類のデータソースプラグインをサポートしていますWebクローラー、オンラインドキュメント、オンラインドライブ。プラグインコードを実装する際、プラグインの機能を提供するクラスは特定のデータソースクラスを継承する必要があります。3種類のプラグインタイプはそれぞれ異なる親クラスに対応しています。
<Info>
親クラスを継承してプラグイン機能を実装する方法については、[Difyプラグイン開発Hello Worldガイド - 4.4 ツールロジックの実装](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin#4-4-implementing-tool-logic)を参照してください。
</Info>
各データソースプラグインタイプは複数のデータソースをサポートしています。例えば:
- **Webクローラー**Jina Reader、FireCrawl
- **オンラインドキュメント**Notion、Confluence、GitHub
- **オンラインドライブ**OneDrive、Google Drive、Box、AWS S3、Tencent COS
データソースタイプとデータソースプラグインタイプの関係を以下に示します。
![](/images/data_source_type.png)
## データソースプラグインの開発
### データソースプラグインの作成
スキャフォールディングコマンドラインツールを使用して、`datasource`タイプを選択することでデータソースプラグインを作成できます。セットアップが完了すると、コマンドラインツールが自動的にプラグインプロジェクトコードを生成します。
```powershell
dify plugin init
```
![](/images/datasource_plugin_init.png)
<Info>
通常、データソースプラグインはDifyプラットフォームの他の機能を使用する必要がないため、追加の権限は必要ありません。
</Info>
#### データソースプラグインの構造
データソースプラグインは3つの主要コンポーネントで構成されています
- `manifest.yaml`ファイル:プラグインの基本情報を記述します。
- `provider`ディレクトリ:プラグインプロバイダーの説明と認証実装コードを含みます。
- `datasources`ディレクトリ:データソースからデータを取得するための説明とコアロジックを含みます。
```
├── _assets
│ └── icon.svg
├── datasources
│ ├── your_datasource.py
│ └── your_datasource.yaml
├── main.py
├── manifest.yaml
├── PRIVACY.md
├── provider
│ ├── your_datasource.py
│ └── your_datasource.yaml
├── README.md
└── requirements.txt
```
#### 正しいバージョンとタグの設定
- `manifest.yaml`ファイルで、最小サポートDifyバージョンを以下のように設定します
```yaml
minimum_dify_version: 1.9.0
```
- `manifest.yaml`ファイルで、Dify Marketplaceのデータソースカテゴリにプラグインを表示するために以下のタグを追加します
```yaml
tags:
- rag
```
- `requirements.txt`ファイルで、データソースプラグイン開発に使用するプラグインSDKバージョンを以下のように設定します
```yaml
dify-plugin>=0.5.0,<0.6.0
```
### データソースプロバイダーの追加
#### プロバイダーYAMLファイルの作成
プロバイダーYAMLファイルの内容は基本的にツールプラグインと同じですが、以下の2点のみ異なります
```yaml
# データソースプラグインのプロバイダータイプを指定online_drive、online_document、またはwebsite_crawl
provider_type: online_drive # online_document, website_crawl
# データソースを指定
datasources:
- datasources/PluginName.yaml
```
<Info>
プロバイダーYAMLファイルの作成について詳しくは、[Difyプラグイン開発Hello Worldガイド-4.3 プロバイダー認証情報の設定](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin#4-3-configuring-provider-credentials)を参照してください。
</Info>
<Info>
データソースプラグインはOAuth 2.0またはAPIキーによる認証をサポートしています。
OAuthの設定については、[ツールプラグインにOAuthサポートを追加する](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-oauth)を参照してください。
</Info>
#### プロバイダーコードファイルの作成
- APIキー認証モードを使用する場合、データソースプラグインのプロバイダーコードファイルはツールプラグインと同一です。プロバイダークラスが継承する親クラスを`DatasourceProvider`に変更するだけです。
```python
class YourDatasourceProvider(DatasourceProvider):
def _validate_credentials(self, credentials: Mapping[str, Any]) -> None:
try:
"""
IMPLEMENT YOUR VALIDATION HERE
"""
except Exception as e:
raise ToolProviderCredentialValidationError(str(e))
```
- OAuth認証モードを使用する場合、データソースプラグインはツールプラグインとわずかに異なります。OAuthでアクセス権限を取得する際、データソースプラグインはフロントエンドに表示するユーザー名とアバターを同時に返すことができます。そのため、`_oauth_get_credentials`と`_oauth_refresh_credentials`は`name`、`avatar_url`、`expires_at`、`credentials`を含む`DatasourceOAuthCredentials`型を返す必要があります。
`DatasourceOAuthCredentials`クラスは以下のように定義されており、返す際に対応する型を設定する必要があります:
```python
class DatasourceOAuthCredentials(BaseModel):
name: str | None = Field(None, description="The name of the OAuth credential")
avatar_url: str | None = Field(None, description="The avatar url of the OAuth")
credentials: Mapping[str, Any] = Field(..., description="The credentials of the OAuth")
expires_at: int | None = Field(
default=-1,
description="""The expiration timestamp (in seconds since Unix epoch, UTC) of the credentials.
Set to -1 or None if the credentials do not expire.""",
)
```
`_oauth_get_authorization_url`、`_oauth_get_credentials`、`_oauth_refresh_credentials`の関数シグネチャは以下の通りです:
<Tabs>
<Tab title="_oauth_get_authorization_url">
```python
def _oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
"""
Generate the authorization URL for {{ .PluginName }} OAuth.
"""
try:
"""
IMPLEMENT YOUR AUTHORIZATION URL GENERATION HERE
"""
except Exception as e:
raise DatasourceOAuthError(str(e))
return ""
```
</Tab>
<Tab title="_oauth_get_credentials">
```python
def _oauth_get_credentials(
self, redirect_uri: str, system_credentials: Mapping[str, Any], request: Request
) -> DatasourceOAuthCredentials:
"""
Exchange code for access_token.
"""
try:
"""
IMPLEMENT YOUR CREDENTIALS EXCHANGE HERE
"""
except Exception as e:
raise DatasourceOAuthError(str(e))
return DatasourceOAuthCredentials(
name="",
avatar_url="",
expires_at=-1,
credentials={},
)
```
</Tab>
<Tab title="_oauth_refresh_credentials">
```python
def _oauth_refresh_credentials(
self, redirect_uri: str, system_credentials: Mapping[str, Any], credentials: Mapping[str, Any]
) -> DatasourceOAuthCredentials:
"""
Refresh the credentials
"""
return DatasourceOAuthCredentials(
name="",
avatar_url="",
expires_at=-1,
credentials={},
)
```
</Tab>
</Tabs>
### データソースの追加
YAMLファイル形式とデータソースコード形式は、3種類のデータソースによって異なります。
#### Webクローラー
WebクローラーデータソースプラグインのプロバイダーYAMLファイルでは、`output_schema`は常に4つのパラメータを返す必要があります`source_url`、`content`、`title`、`description`。
```yaml
output_schema:
type: object
properties:
source_url:
type: string
description: the source url of the website
content:
type: string
description: the content from the website
title:
type: string
description: the title of the website
"description":
type: string
description: the description of the website
```
Webクローラープラグインのメインロジックコードでは、クラスは`WebsiteCrawlDatasource`を継承し、`_get_website_crawl`メソッドを実装する必要があります。次に、`create_crawl_message`メソッドを使用してWebクロールメッセージを返します。
複数のWebページをクロールしてバッチで返すには、`WebSiteInfo.status`を`processing`に設定し、`create_crawl_message`メソッドを使用して各バッチのクロールされたページを返します。すべてのページがクロールされた後、`WebSiteInfo.status`を`completed`に設定します。
```python
class YourDataSource(WebsiteCrawlDatasource):
def _get_website_crawl(
self, datasource_parameters: dict[str, Any]
) -> Generator[ToolInvokeMessage, None, None]:
crawl_res = WebSiteInfo(web_info_list=[], status="", total=0, completed=0)
crawl_res.status = "processing"
yield self.create_crawl_message(crawl_res)
### your crawl logic
...
crawl_res.status = "completed"
crawl_res.web_info_list = [
WebSiteInfoDetail(
title="",
source_url="",
description="",
content="",
)
]
crawl_res.total = 1
crawl_res.completed = 1
yield self.create_crawl_message(crawl_res)
```
#### オンラインドキュメント
オンラインドキュメントデータソースプラグインの戻り値には、ドキュメントの内容を表す`content`フィールドを少なくとも含める必要があります。例えば:
```yaml
output_schema:
type: object
properties:
workspace_id:
type: string
description: workspace id
page_id:
type: string
description: page id
content:
type: string
description: page content
```
オンラインドキュメントプラグインのメインロジックコードでは、クラスは`OnlineDocumentDatasource`を継承し、2つのメソッドを実装する必要があります`_get_pages`と`_get_content`。
ユーザーがプラグインを実行すると、まず`_get_pages`メソッドを呼び出してドキュメントのリストを取得します。ユーザーがリストからドキュメントを選択した後、`_get_content`メソッドを呼び出してドキュメントのコンテンツを取得します。
<Tabs>
<Tab title="_get_pages">
```python
def _get_pages(self, datasource_parameters: dict[str, Any]) -> DatasourceGetPagesResponse:
# your get pages logic
response = requests.get(url, headers=headers, params=params, timeout=30)
pages = []
for item in response.json().get("results", []):
page = OnlineDocumentPage(
page_name=item.get("title", ""),
page_id=item.get("id", ""),
type="page",
last_edited_time=item.get("version", {}).get("createdAt", ""),
parent_id=item.get("parentId", ""),
page_icon=None,
)
pages.append(page)
online_document_info = OnlineDocumentInfo(
workspace_name=workspace_name,
workspace_icon=workspace_icon,
workspace_id=workspace_id,
pages=[page],
total=pages.length(),
)
return DatasourceGetPagesResponse(result=[online_document_info])
```
</Tab>
<Tab title="_get_content">
```python
def _get_content(self, page: GetOnlineDocumentPageContentRequest) -> Generator[DatasourceMessage, None, None]:
# your fetch content logic, example
response = requests.get(url, headers=headers, params=params, timeout=30)
...
yield self.create_variable_message("content", "")
yield self.create_variable_message("page_id", "")
yield self.create_variable_message("workspace_id", "")
```
</Tab>
</Tabs>
#### オンラインドライブ
オンラインドライブデータソースプラグインはファイルを返すため、以下の仕様に準拠する必要があります:
```yaml
output_schema:
type: object
properties:
file:
$ref: "https://dify.ai/schemas/v1/file.json"
```
オンラインドライブプラグインのメインロジックコードでは、クラスは`OnlineDriveDatasource`を継承し、2つのメソッドを実装する必要があります`_browse_files`と`_download_file`。
ユーザーがプラグインを実行すると、まず`_browse_files`を呼び出してファイルリストを取得します。この時点で、`prefix`は空であり、ルートディレクトリのファイルリストを要求していることを示します。ファイルリストにはフォルダとファイルタイプの変数が含まれています。ユーザーがフォルダを開くと、`_browse_files`メソッドが再度呼び出されます。この時点で、`OnlineDriveBrowseFilesRequest`の`prefix`はそのフォルダ内のファイルリストを取得するために使用されるフォルダIDになります。
ユーザーがファイルを選択した後、プラグインは`_download_file`メソッドとファイルIDを使用してファイルのコンテンツを取得します。`_get_mime_type_from_filename`メソッドを使用してファイルのMIMEタイプを取得でき、パイプラインが異なるファイルタイプを適切に処理できるようになります。
ファイルリストに複数のファイルが含まれている場合、`OnlineDriveFileBucket.is_truncated`を`True`に設定し、`OnlineDriveFileBucket.next_page_parameters`をファイルリストの次のページを取得するために必要なパラメータサービスプロバイダーに応じて次のページのリクエストIDやURLなどに設定できます。
<Tabs>
<Tab title="_browse_files">
```python
def _browse_files(
self, request: OnlineDriveBrowseFilesRequest
) -> OnlineDriveBrowseFilesResponse:
credentials = self.runtime.credentials
bucket_name = request.bucket
prefix = request.prefix or "" # Allow empty prefix for root folder; When you browse the folder, the prefix is the folder id
max_keys = request.max_keys or 10
next_page_parameters = request.next_page_parameters or {}
files = []
files.append(OnlineDriveFile(
id="",
name="",
size=0,
type="folder" # or "file"
))
return OnlineDriveBrowseFilesResponse(result=[
OnlineDriveFileBucket(
bucket="",
files=files,
is_truncated=False,
next_page_parameters={}
)
])
```
</Tab>
<Tab title="_download_file">
```python
def _download_file(self, request: OnlineDriveDownloadFileRequest) -> Generator[DatasourceMessage, None, None]:
credentials = self.runtime.credentials
file_id = request.id
file_content = bytes()
file_name = ""
mime_type = self._get_mime_type_from_filename(file_name)
yield self.create_blob_message(file_content, meta={
"file_name": file_name,
"mime_type": mime_type
})
def _get_mime_type_from_filename(self, filename: str) -> str:
"""Determine MIME type from file extension."""
import mimetypes
mime_type, _ = mimetypes.guess_type(filename)
return mime_type or "application/octet-stream"
```
</Tab>
</Tabs>
AWS S3のようなストレージサービスでは、`prefix`、`bucket`、`id`変数には特別な用途があり、開発中に必要に応じて柔軟に適用できます:
- `prefix`:ファイルパスのプレフィックスを表します。例えば、`prefix=container1/folder1/`は`container1`バケット内の`folder1`フォルダからファイルまたはファイルリストを取得します。
- `bucket`:ファイルバケットを表します。例えば、`bucket=container1`は`container1`バケット内のファイルまたはファイルリストを取得します。このフィールドは、非標準S3プロトコルドライブでは空白のままにできます。
- `id``_download_file`メソッドは`prefix`変数を使用しないため、完全なファイルパスを`id`に含める必要があります。例えば、`id=container1/folder1/file1.txt`は`container1`バケット内の`folder1`フォルダから`file1.txt`ファイルを取得することを示します。
<Tip>
[公式Google Driveプラグイン](https://github.com/langgenius/dify-official-plugins/blob/main/datasources/google_cloud_storage/datasources/google_cloud_storage.py)と[公式AWS S3プラグイン](https://github.com/langgenius/dify-official-plugins/blob/main/datasources/aws_s3_storage/datasources/aws_s3_storage.py)の具体的な実装を参照できます。
</Tip>
## プラグインのデバッグ
データソースプラグインは、リモートデバッグまたはローカルプラグインとしてインストールしてデバッグする2つのデバッグ方法をサポートしています。以下の点に注意してください
- プラグインがOAuth認証を使用している場合、リモートデバッグの`redirect_uri`はローカルプラグインのものとは異なります。サービスプロバイダーのOAuth Appの関連設定を適宜更新してください。
- データソースプラグインはシングルステップデバッグをサポートしていますが、完全な機能を確保するために、完全なナレッジパイプラインでテストすることをお勧めします。
## 最終チェック
パッケージ化と公開の前に、以下のすべてを完了していることを確認してください:
- 最小サポートDifyバージョンを`1.9.0`に設定。
- SDKバージョンを`dify-plugin>=0.5.0,<0.6.0`に設定。
- `README.md`と`PRIVACY.md`ファイルを作成。
- コードファイルには英語のコンテンツのみを含める。
- デフォルトアイコンをデータソースプロバイダーのロゴに置き換える。
## パッケージ化と公開
プラグインディレクトリで以下のコマンドを実行して`.difypkg`プラグインパッケージを生成します:
```
dify plugin package . -o your_datasource.difypkg
```
次に、以下のことができます:
- Dify環境にプラグインをインポートして使用する。
- プルリクエストを送信してDify Marketplaceにプラグインを公開する。
<Info>
プラグイン公開プロセスについては、[プラグインの公開](/ja/develop-plugin/publishing/marketplace-listing/release-overview)を参照してください。
</Info>
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/datasource-plugin.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,358 @@
---
dimensions:
type:
primary: reference
detail: examples
level: intermediate
standard_title: Develop A Slack Bot Plugin
language: en
title: Slack Botプラグインの開発
description: このガイドでは、Slack Botプラグインの開発について、プロジェクトの初期化、設定フォームの編集、機能の実装、デバッグ、エンドポイントのセットアップ、検証、パッケージングまで完全なウォークスルーを提供します。Slack上でAIを活用したチャットボットを構築するために、Difyプラグインスキャフォールディングツールと事前に作成したSlack Appが必要です。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/develop-a-slack-bot-plugin)を参照してください。</Note>
**学習内容:**
AIを活用したSlack Botの構築方法をしっかりと理解できます。このBotはSlack内でユーザーの質問に直接回答できます。プラグインを初めて開発する場合は、まず[プラグイン開発クイックスタートガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)を読むことをお勧めします。
### プロジェクトの背景
Difyプラグインエコシステムは、統合をよりシンプルでアクセスしやすくすることに焦点を当てています。このガイドでは、Slackを例として、Slack Botプラグインの開発プロセスを順を追って説明します。これにより、チームはSlack内でLLMと直接チャットでき、AIの活用効率が大幅に向上します。
Slackは、堅牢なAPIを備えたオープンなリアルタイムコミュニケーションプラットフォームです。その機能の中には、webhookベースのイベントシステムがあり、開発が非常に簡単です。このシステムを活用してSlack Botプラグインを作成します。以下の図に示されています
![Slack Bot diagram ](https://assets-docs.dify.ai/2025/01/a0865d18f1ca4051601ca53fa6f92db2.png)
> 混乱を避けるため、以下の概念を説明します:
>
> * **Slack Bot** Slackプラットフォーム上のチャットボットで、リアルタイムでやり取りできる仮想ユーザーとして機能します。
> * **Slack Botプラグイン** DifyアプリケーションとSlackを接続するDify Marketplace内のプラグインです。このガイドでは、そのプラグインの開発方法に焦点を当てています。
**動作の仕組み(簡単な概要):**
1. **Slack Botにメッセージを送信する**
Slack内のユーザーがBotにメッセージを送信すると、Slack Botは即座にDifyプラットフォームにwebhookリクエストを発行します。
2. **メッセージをSlack Botプラグインに転送する**
Difyプラットフォームは、Slack Botプラグインをトリガーし、詳細をDifyアプリケーションに中継します。これは、メールシステムで受信者のアドレスを入力するのと似ています。SlackのAPIを通じてSlack webhookアドレスを設定し、Slack Botプラグインに入力することで、この接続が確立されます。プラグインはSlackリクエストを処理し、Difyアプリケーションに送信します。そこでLLMがユーザーの入力を分析し、応答を生成します。
3. **Slackに応答を返す**
Slack BotプラグインがDifyアプリケーションから応答を受け取ると、同じルートを通じてLLMの回答をSlack Botに送り返します。Slack内のユーザーは、チャットしている場所で、よりインテリジェントでインタラクティブな体験を得られます。
### 前提条件
- **Difyプラグイン開発ツール**:詳細については、[開発ツールの初期化](/ja/develop-plugin/getting-started/cli)を参照してください。
- **Python環境バージョン ≥ 3.12**:この[Pythonインストールチュートリアル](https://pythontest.com/python/installing-python-3-11/)を参照するか、LLMに完全なセットアップガイドを尋ねてください。
- Slack Appを作成してOAuthトークンを取得する
[Slack APIプラットフォーム](https://api.slack.com/apps)にアクセスし、Slack appをゼロから作成し、デプロイするワークスペースを選択します。
![](https://assets-docs.dify.ai/2025/01/c1fd0ac1467faf5a3ebf3818bb234aa8.png)
1. **Webhooksを有効にする**
![](https://assets-docs.dify.ai/2025/01/7112e0710300f1db16827e17f3deac00.png)
2. **Slackワークスペースにアプリをインストールする**
![](https://assets-docs.dify.ai/2025/01/88c360ff4f7b04fea52174ce330522fa.png)
3. 将来のプラグイン開発のために**OAuthトークンを取得する**
![](https://assets-docs.dify.ai/2025/01/dcd8ec947253f2ef9ae121ed77ec9f26.png)
### 1. プラグインの開発
ここから実際のコーディングに入ります。開始する前に、[クイックスタート:拡張プラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint)を読んでいるか、すでにDifyプラグインを構築した経験があることを確認してください。
#### 1.1 プロジェクトの初期化
以下のコマンドを実行して、プラグイン開発環境をセットアップします:
```bash
dify plugin init
```
プロンプトに従って基本的なプロジェクト情報を入力します。`extension`テンプレートを選択し、`Apps`と`Endpoints`の両方の権限を付与します。
プラグイン内でDifyサービスを逆呼び出しする方法の詳細については、[逆呼び出しApp](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-app)を参照してください。
![Plugins permission](https://assets-docs.dify.ai/2024/12/d89a6282c5584fc43a9cadeddf09c0de.png)
#### 1.2 設定フォームの編集
このプラグインは、どのDifyアプリが応答を処理するか、およびBotの応答を認証するためのSlack Appトークンを知る必要があります。そのため、プラグインのフォームにこれら2つのフィールドを追加します。
groupディレクトリ内のYAMLファイルを修正します。例えば、`group/slack.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に設定すると、プラグインはエージェント、チャットボット、またはchatflowなどのアプリタイプとのみやり取りできます。
最後に、`endpoints/slack.yaml`ファイルで、受信するSlackメッセージを適切に処理するためにリクエストメソッドを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")
```
### 2. プラグインのデバッグ
Difyプラットフォームに移動し、プラグインのリモートデバッグアドレスとキーを取得します。
![](https://assets-docs.dify.ai/2025/01/8d24006f0cabf5bf61640a9023c45db8.png)
プラグインプロジェクトに戻り、`.env.example`ファイルをコピーして`.env`にリネームします。
```bash
INSTALL_METHOD=remote
REMOTE_INSTALL_URL=debug.dify.ai:5003
REMOTE_INSTALL_KEY=********-****-****-****-************
```
`python -m main`を実行してプラグインを起動します。Difyのプラグイン管理ページで、ワークスペースにプラグインがインストールされているのが確認できるはずです。他のチームメンバーもアクセスできるようになります。
```bash
python -m main
```
#### プラグインエンドポイントの設定
Difyのプラグイン管理ページから、新しくインストールされたテストプラグインを見つけ、新しいエンドポイントを作成します。名前、Botトークンを入力し、接続するアプリを選択します。
<img
src="https://assets-docs.dify.ai/2025/01/07f87e8a2786d6f5f05195961c5630c3.png"
className="mx-auto"
alt="Test Plugins"
/>
保存後、**POST**リクエストURLが生成されます
<img
src="https://assets-docs.dify.ai/2025/01/e6952a5798a7ae793b3fe7df6f76ea73.png"
className="mx-auto"
alt="Generated POST Request URL"
/>
次に、Slack Appのセットアップを完了します
1. **Event Subscriptionsを有効にする**
![](https://assets-docs.dify.ai/2025/01/1d33bb9cde78a1b5656ad6a0b8350195.png)
上記で生成したPOSTリクエストURLを貼り付けます。
![](https://assets-docs.dify.ai/2025/01/65aa41f37c3800af49e944f9ff28e121.png)
2. **必要な権限を付与する**
![](https://assets-docs.dify.ai/2025/01/25c38a2cf10ec6c55ae54970d790f37e.png)
---
### 3. プラグインの検証
コード内で、`self.session.app.chat.invoke`がDifyアプリケーションを呼び出すために使用され、`app_id`や`query`などのパラメータを渡します。応答はSlack Botに返されます。`python -m main`を再度実行してプラグインをデバッグ用に再起動し、SlackがDify Appの応答を正しく表示するかどうかを確認します
![](https://assets-docs.dify.ai/2025/01/6fc872d1343ce8503d63c5222f7f26f9.png)
---
### 4. プラグインのパッケージ化(オプション)
プラグインが正しく動作することを確認したら、以下のコマンドでパッケージ化して名前を付けることができます。実行後、現在のディレクトリに`slack_bot.difypkg`ファイルが作成されます。これが最終的なプラグインパッケージです。詳細なパッケージ化手順については、[ローカルファイルとしてパッケージ化して共有](/ja/develop-plugin/publishing/marketplace-listing/release-by-file)を参照してください。
```bash
# ./slack_botを実際のプラグインプロジェクトパスに置き換えてください。
dify plugin package ./slack_bot
```
おめでとうございます!プラグインの開発、テスト、パッケージ化が正常に完了しました!
---
### 5. プラグインの公開(オプション)
[Dify Marketplaceリポジトリ](https://github.com/langgenius/dify-plugins)にアップロードして公開できます。公開前に、プラグインが[Dify Marketplace公開ガイドライン](/ja/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace)に準拠していることを確認してください。承認されると、コードはメインブランチにマージされ、プラグインは[Dify Marketplace](https://marketplace.dify.ai/)で公開されます。
---
## 関連リソース
- [プラグイン開発の基礎](/ja/develop-plugin/getting-started/getting-started-dify-plugin) - Difyプラグイン開発の包括的な概要
- [プラグイン開発クイックスタートガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin) - ゼロからプラグイン開発を始める
- [拡張プラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint) - 拡張プラグイン開発について学ぶ
- [Difyサービスの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation) - Difyプラットフォームの機能を呼び出す方法を理解する
- [逆呼び出しApp](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-app) - プラットフォーム内でアプリを呼び出す方法を学ぶ
- [プラグインの公開](/ja/develop-plugin/publishing/marketplace-listing/release-overview) - 公開プロセスを学ぶ
- [Dify Marketplaceへの公開](/ja/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace) - Marketplace公開ガイド
- [エンドポイントの詳細定義](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint) - 詳細なエンドポイント定義
### さらに読む
完全なDifyプラグインプロジェクトの例については、[GitHubリポジトリ](https://github.com/langgenius/dify-plugins)をご覧ください。完全なソースコードと実装の詳細を含む追加のプラグインも見つかります。
プラグイン開発についてさらに探求したい場合は、以下を確認してください:
**クイックスタート:**
- [拡張プラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint)
- [モデルプラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider)
- [バンドルプラグイン:複数のプラグインのパッケージング](/ja/develop-plugin/features-and-specs/advanced-development/bundle)
**プラグインインターフェースドキュメント:**
- [Manifestファイルによるプラグイン情報の定義](/ja/develop-plugin/features-and-specs/plugin-types/plugin-info-by-manifest) - Manifest構造
- [エンドポイント](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint) - エンドポイントの詳細定義
- [逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation) - Dify機能の逆呼び出し
- [一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - ツール仕様
- [モデルスキーマ](/ja/develop-plugin/features-and-specs/plugin-types/model-schema) - モデル
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/develop-a-slack-bot-plugin.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,349 @@
---
title: '10分でDifyプラグインを構築するガイド'
description: 'わずか10分でFlomoメモサービスと連携する機能的なDifyプラグインの構築方法を学びます'
language: en
standard_title: 10-Minute Guide to Building Dify Plugins
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/develop-flomo-plugin)を参照してください。</Note>
## 構築するもの
このガイドを終えると、以下の機能を持つDifyプラグインが完成します
- Flomoメモ取りAPIへの接続
- AIとの会話から直接Flomoにメモを保存する機能
- 認証とエラー状態の適切な処理
- Dify Marketplaceでの配布準備完了
<CardGroup cols={2}>
<Card title="所要時間" icon="clock">
10分
</Card>
<Card title="前提条件" icon="list-check">
基本的なPythonの知識とFlomoアカウント
</Card>
</CardGroup>
## ステップ1Dify CLIのインストールとプロジェクト作成
<Steps>
<Step title="Dify CLIのインストール">
<Tabs>
<Tab title="Mac">
```bash
brew tap langgenius/dify
brew install dify
```
</Tab>
<Tab title="Linux">
[Dify GitHubリリースページ](https://github.com/langgenius/dify-plugin-daemon/releases)から最新のDify CLIを取得してください
```bash
# Download appropriate version
chmod +x dify-plugin-linux-amd64
mv dify-plugin-linux-amd64 dify
sudo mv dify /usr/local/bin/
```
</Tab>
</Tabs>
インストールを確認:
```bash
dify version
```
</Step>
<Step title="プラグインプロジェクトの初期化">
以下のコマンドで新しいプラグインプロジェクトを作成します:
```bash
dify plugin init
```
プロンプトに従ってプラグインをセットアップします:
- 名前を「flomo」にする
- プラグインタイプとして「tool」を選択
- その他の必須フィールドを入力
</Step>
<Step title="プロジェクトに移動">
```bash
cd flomo
```
これにより、必要なすべてのファイルを含むプラグインの基本構造が作成されます。
</Step>
</Steps>
## ステップ2プラグインマニフェストの定義
<Info>
manifest.yamlファイルはプラグインのメタデータ、権限、機能を定義します。
</Info>
`manifest.yaml`ファイルを作成します:
```yaml
version: 0.0.4
type: plugin
author: yourname
label:
en_US: Flomo
zh_Hans: Flomo 浮墨笔记
created_at: "2023-10-01T00:00:00Z"
icon: icon.png
resource:
memory: 67108864 # 64MB
permission:
storage:
enabled: false
plugins:
tools:
- flomo.yaml
meta:
version: 0.0.1
arch:
- amd64
- arm64
runner:
language: python
version: 3.12
entrypoint: main
```
## ステップ3ツール定義の作成
ツールインターフェースを定義する`flomo.yaml`ファイルを作成します:
```yaml
identity:
author: yourname
name: flomo
label:
en_US: Flomo Note
zh_Hans: Flomo 浮墨笔记
description:
human:
en_US: Add notes to your Flomo account directly from Dify.
zh_Hans: 直接从Dify添加笔记到您的Flomo账户。
llm: >
A tool that allows users to save notes to Flomo. Use this tool when users want to save important information from the conversation. The tool accepts a 'content' parameter that contains the text to be saved as a note.
credential_schema:
api_url:
type: string
required: true
label:
en_US: API URL
zh_Hans: API URL
human_description:
en_US: Flomo API URL from your Flomo account settings.
zh_Hans: 从您的Flomo账户设置中获取的API URL。
tool_schema:
content:
type: string
required: true
label:
en_US: Note Content
zh_Hans: 笔记内容
human_description:
en_US: Content to save as a note in Flomo.
zh_Hans: 要保存为Flomo笔记的内容。
```
## ステップ4コアユーティリティ関数の実装
API連携用のユーティリティモジュールを`utils/flomo_utils.py`に作成します:
<CodeGroup>
```python utils/flomo_utils.py
import requests
def send_flomo_note(api_url: str, content: str) -> None:
"""
Send a note to Flomo via the API URL. Raises requests.RequestException on network errors,
and ValueError on invalid status codes or input.
"""
api_url = api_url.strip()
if not api_url:
raise ValueError("API URL is required and cannot be empty.")
if not api_url.startswith('https://flomoapp.com/iwh/'):
raise ValueError(
"API URL should be in the format: https://flomoapp.com/iwh/{token}/{secret}/"
)
if not content:
raise ValueError("Content cannot be empty.")
headers = {'Content-Type': 'application/json'}
response = requests.post(api_url, json={"content": content}, headers=headers, timeout=10)
if response.status_code != 200:
raise ValueError(f"API URL is not valid. Received status code: {response.status_code}")
```
</CodeGroup>
## ステップ5ツールプロバイダーの実装
ツールプロバイダーは認証情報の検証を処理します。`provider/flomo.py`を作成します:
<CodeGroup>
```python provider/flomo.py
from typing import Any
from dify_plugin import ToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError
import requests
from utils.flomo_utils import send_flomo_note
class FlomoProvider(ToolProvider):
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
try:
api_url = credentials.get('api_url', '').strip()
# Use utility for validation and sending test note
send_flomo_note(api_url, "Hello, #flomo https://flomoapp.com")
except ValueError as e:
raise ToolProviderCredentialValidationError(str(e))
except requests.RequestException as e:
raise ToolProviderCredentialValidationError(f"Connection error: {str(e)}")
```
</CodeGroup>
## ステップ6ツールの実装
Toolクラスはユーザーがプラグインを呼び出したときに実際のAPI呼び出しを処理します。`tools/flomo.py`を作成します:
<CodeGroup>
```python tools/flomo.py
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
import requests
from utils.flomo_utils import send_flomo_note
class FlomoTool(Tool):
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
content = tool_parameters.get("content", "")
api_url = self.runtime.credentials.get("api_url", "")
try:
send_flomo_note(api_url, content)
except ValueError as e:
yield self.create_text_message(str(e))
return
except requests.RequestException as e:
yield self.create_text_message(f"Connection error: {str(e)}")
return
# Return success message and structured data
yield self.create_text_message(
"Note created successfully! Your content has been sent to Flomo."
)
yield self.create_json_message({
"status": "success",
"content": content,
})
```
</CodeGroup>
<Warning>
常に例外を適切に処理し、ユーザーフレンドリーなエラーメッセージを返すようにしてください。あなたのプラグインはDifyエコシステムにおけるブランドを代表するものであることを忘れないでください。
</Warning>
## ステップ7プラグインのテスト
<Steps>
<Step title="デバッグ環境のセットアップ">
サンプル環境ファイルをコピーします:
```bash
cp .env.example .env
```
`.env`ファイルをDify環境の詳細で編集します
```
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=debug-plugin.dify.dev
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=your_debug_key
```
デバッグキーとホストはDifyダッシュボードで確認できます右上の「プラグイン」アイコンをクリックし、デバッグアイコンをクリックします。ポップアップウィンドウで「APIキー」と「ホストアドレス」をコピーしてください。
</Step>
<Step title="依存関係のインストールと実行">
```bash
pip install -r requirements.txt
python -m main
```
プラグインがデバッグモードでDifyインスタンスに接続されます。
</Step>
<Step title="機能のテスト">
Difyインスタンスでプラグインに移動し、デバッグ中のプラグイン「debugging」とマークされていますを見つけます。
Flomo APIの認証情報を追加し、メモの送信をテストします。
</Step>
</Steps>
## ステップ9パッケージ化と配布
プラグインを共有する準備ができたら:
```bash
dify plugin package ./
```
これにより、Dify Marketplaceにアップロードできる`plugin.difypkg`ファイルが作成されます。
## FAQとトラブルシューティング
<AccordionGroup title="一般的な問題とトラブルシューティング">
<Accordion title="デバッグモードでプラグインが表示されない">
`.env`ファイルが正しく設定されていること、正しいデバッグキーを使用していることを確認してください。
</Accordion>
<Accordion title="API認証エラー">
Flomo API URLの形式を再確認してください。形式は次のようになっている必要があります`https://flomoapp.com/iwh/{token}/{secret}/`
</Accordion>
<Accordion title="パッケージ化に失敗">
必要なすべてのファイルが存在し、manifest.yamlの構造が有効であることを確認してください。
</Accordion>
</AccordionGroup>
## まとめ
外部APIサービスと連携する機能的なDifyプラグインを構築しましたこの同じパターンは、データベースや検索エンジンから生産性ツールやカスタムAPIまで、何千ものサービスとの統合に使用できます。
<CardGroup cols={2}>
<Card title="ドキュメント" icon="book">
機能、セットアップ、使用例を説明するREADME.mdを英語en_USで作成してください
</Card>
<Card title="ローカライズ" icon="language">
他の言語用に`readme/README_zh_Hans.md`のような追加のREADMEファイルを作成してください
</Card>
</CardGroup>
<CheckList>
<CheckListItem id="privacy">
プラグインを公開する場合はプライバシーポリシーPRIVACY.mdを追加してください
</CheckListItem>
<CheckListItem id="documentation">
ドキュメントに包括的な例を含めてください
</CheckListItem>
<CheckListItem id="testing">
さまざまなドキュメントサイズとフォーマットで徹底的にテストしてください
</CheckListItem>
</CheckList>
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/develop-flomo-plugin.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,550 @@
---
title: 'Markdownエクスポータープラグインの構築'
description: '会話をさまざまなドキュメント形式にエクスポートするプラグインの作成方法を学ぶ'
language: en
standard_title: Building a Markdown Exporter Plugin
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/develop-md-exporter)を参照してください。</Note>
## 構築するもの
このガイドでは、会話を一般的なドキュメント形式にエクスポートする実用的なDifyプラグインの構築方法を学びます。最終的に、プラグインは以下の機能を持ちます
- MarkdownテキストをWord文書.docxに変換
- 会話をPDFファイルとしてエクスポート
- 適切なフォーマットでファイル作成を処理
- ドキュメントエクスポートのためのクリーンなユーザー体験を提供
<CardGroup cols={2}>
<Card title="所要時間" icon="clock">
15分
</Card>
<Card title="前提条件" icon="list-check">
基本的なPython知識とドキュメント操作ライブラリへの習熟
</Card>
</CardGroup>
## ステップ1環境のセットアップ
<Steps>
<Step title="Dify CLIのインストール">
<Tabs>
<Tab title="Mac">
```bash
brew tap langgenius/dify
brew install dify
```
</Tab>
<Tab title="Linux">
[Dify GitHubリリースページ](https://github.com/langgenius/dify-plugin-daemon/releases)から最新のDify CLIを取得します
```bash
# Download appropriate version
chmod +x dify-plugin-linux-amd64
mv dify-plugin-linux-amd64 dify
sudo mv dify /usr/local/bin/
```
</Tab>
</Tabs>
インストールの確認:
```bash
dify version
```
</Step>
<Step title="プラグインプロジェクトの作成">
新しいプラグインプロジェクトを初期化します:
```bash
dify plugin init
```
プロンプトに従って入力してください:
- Name: "md_exporter"
- Type: "tool"
- その他の詳細は指示に従って完了してください
</Step>
</Steps>
## ステップ2プラグインマニフェストの定義
`manifest.yaml`ファイルを作成してプラグインのメタデータを定義します:
```yaml
version: 0.0.4
type: plugin
author: your_username
label:
en_US: Markdown Exporter
zh_Hans: Markdown导出工具
created_at: "2025-09-30T00:00:00Z"
icon: icon.png
resource:
memory: 134217728 # 128MB
permission:
storage:
enabled: true # We need storage for temp files
plugins:
tools:
- word_export.yaml
- pdf_export.yaml
meta:
version: 0.0.1
arch:
- amd64
- arm64
runner:
language: python
version: 3.11
entrypoint: main
```
## ステップ3Wordエクスポートツールの定義
`word_export.yaml`ファイルを作成してWord文書エクスポートツールを定義します
```yaml
identity:
author: your_username
name: word_export
label:
en_US: Export to Word
zh_Hans: 导出为Word文档
description:
human:
en_US: Export conversation content to a Word document (.docx)
zh_Hans: 将对话内容导出为Word文档(.docx)
llm: >
A tool that converts markdown text to a Word document (.docx) format.
Use this tool when the user wants to save or export the conversation
content as a Word document. The input text should be in markdown format.
credential_schema: {} # No credentials needed
tool_schema:
markdown_content:
type: string
required: true
label:
en_US: Markdown Content
zh_Hans: Markdown内容
human_description:
en_US: The markdown content to convert to Word format
zh_Hans: 要转换为Word格式的Markdown内容
document_name:
type: string
required: false
label:
en_US: Document Name
zh_Hans: 文档名称
human_description:
en_US: Name for the exported document (without extension)
zh_Hans: 导出文档的名称(无需扩展名)
```
## ステップ4PDFエクスポートツールの定義
PDFエクスポート用の`pdf_export.yaml`ファイルを作成します:
```yaml
identity:
author: your_username
name: pdf_export
label:
en_US: Export to PDF
zh_Hans: 导出为PDF文档
description:
human:
en_US: Export conversation content to a PDF document
zh_Hans: 将对话内容导出为PDF文档
llm: >
A tool that converts markdown text to a PDF document.
Use this tool when the user wants to save or export the conversation
content as a PDF file. The input text should be in markdown format.
credential_schema: {} # No credentials needed
tool_schema:
markdown_content:
type: string
required: true
label:
en_US: Markdown Content
zh_Hans: Markdown内容
human_description:
en_US: The markdown content to convert to PDF format
zh_Hans: 要转换为PDF格式的Markdown内容
document_name:
type: string
required: false
label:
en_US: Document Name
zh_Hans: 文档名称
human_description:
en_US: Name for the exported document (without extension)
zh_Hans: 导出文档的名称(无需扩展名)
```
## ステップ5必要な依存関係のインストール
必要なライブラリを含む`requirements.txt`を作成または更新します:
```text
python-docx>=0.8.11
markdown>=3.4.1
weasyprint>=59.0
beautifulsoup4>=4.12.2
```
## ステップ6Wordエクスポート機能の実装
`utils/docx_utils.py`にユーティリティモジュールを作成します:
<CodeGroup>
```python utils/docx_utils.py
import os
import tempfile
import uuid
from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import markdown
from bs4 import BeautifulSoup
def convert_markdown_to_docx(markdown_text, document_name=None):
"""
Convert markdown text to a Word document and return the file path
"""
if not document_name:
document_name = f"exported_document_{uuid.uuid4().hex[:8]}"
# Convert markdown to HTML
html = markdown.markdown(markdown_text)
soup = BeautifulSoup(html, 'html.parser')
# Create a new Word document
doc = Document()
# Process HTML elements and add to document
for element in soup.find_all(['h1', 'h2', 'h3', 'h4', 'p', 'ul', 'ol']):
if element.name == 'h1':
heading = doc.add_heading(element.text.strip(), level=1)
heading.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
elif element.name == 'h2':
doc.add_heading(element.text.strip(), level=2)
elif element.name == 'h3':
doc.add_heading(element.text.strip(), level=3)
elif element.name == 'h4':
doc.add_heading(element.text.strip(), level=4)
elif element.name == 'p':
paragraph = doc.add_paragraph(element.text.strip())
elif element.name in ('ul', 'ol'):
for li in element.find_all('li'):
doc.add_paragraph(li.text.strip(), style='ListBullet')
# Create temp directory if it doesn't exist
temp_dir = tempfile.gettempdir()
if not os.path.exists(temp_dir):
os.makedirs(temp_dir)
# Save the document
file_path = os.path.join(temp_dir, f"{document_name}.docx")
doc.save(file_path)
return file_path
```
</CodeGroup>
## ステップ7PDFエクスポート機能の実装
`utils/pdf_utils.py`にユーティリティモジュールを作成します:
<CodeGroup>
```python utils/pdf_utils.py
import os
import tempfile
import uuid
import markdown
from weasyprint import HTML, CSS
from weasyprint.text.fonts import FontConfiguration
def convert_markdown_to_pdf(markdown_text, document_name=None):
"""
Convert markdown text to a PDF document and return the file path
"""
if not document_name:
document_name = f"exported_document_{uuid.uuid4().hex[:8]}"
# Convert markdown to HTML
html_content = markdown.markdown(markdown_text)
# Add basic styling
styled_html = f"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{document_name}</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }}
h1 {{ text-align: center; color: #333; }}
h2, h3, h4 {{ color: #444; margin-top: 20px; }}
p {{ margin-bottom: 15px; }}
ul, ol {{ margin-left: 20px; }}
</style>
</head>
<body>
{html_content}
</body>
</html>
"""
# Create temp directory if it doesn't exist
temp_dir = tempfile.gettempdir()
if not os.path.exists(temp_dir):
os.makedirs(temp_dir)
# Output file path
file_path = os.path.join(temp_dir, f"{document_name}.pdf")
# Configure fonts
font_config = FontConfiguration()
# Render PDF
HTML(string=styled_html).write_pdf(
file_path,
stylesheets=[],
font_config=font_config
)
return file_path
```
</CodeGroup>
## ステップ8ツール実装の作成
まず、`tools/word_export.py`にWordエクスポートツールを作成します
<CodeGroup>
```python tools/word_export.py
import os
import base64
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
from utils.docx_utils import convert_markdown_to_docx
class WordExportTool(Tool):
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
# Extract parameters
markdown_content = tool_parameters.get("markdown_content", "")
document_name = tool_parameters.get("document_name", "exported_document")
if not markdown_content:
yield self.create_text_message("Error: No content provided for export.")
return
try:
# Convert markdown to Word
file_path = convert_markdown_to_docx(markdown_content, document_name)
# Read the file as binary
with open(file_path, 'rb') as file:
file_content = file.read()
# Encode as base64
file_base64 = base64.b64encode(file_content).decode('utf-8')
# Return success message and file
yield self.create_text_message(
f"Document exported successfully as Word (.docx) format."
)
yield self.create_file_message(
file_name=f"{document_name}.docx",
file_content=file_base64,
mime_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
)
except Exception as e:
yield self.create_text_message(f"Error exporting to Word: {str(e)}")
return
```
</CodeGroup>
次に、`tools/pdf_export.py`にPDFエクスポートツールを作成します
<CodeGroup>
```python tools/pdf_export.py
import os
import base64
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
from utils.pdf_utils import convert_markdown_to_pdf
class PDFExportTool(Tool):
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
# Extract parameters
markdown_content = tool_parameters.get("markdown_content", "")
document_name = tool_parameters.get("document_name", "exported_document")
if not markdown_content:
yield self.create_text_message("Error: No content provided for export.")
return
try:
# Convert markdown to PDF
file_path = convert_markdown_to_pdf(markdown_content, document_name)
# Read the file as binary
with open(file_path, 'rb') as file:
file_content = file.read()
# Encode as base64
file_base64 = base64.b64encode(file_content).decode('utf-8')
# Return success message and file
yield self.create_text_message(
f"Document exported successfully as PDF format."
)
yield self.create_file_message(
file_name=f"{document_name}.pdf",
file_content=file_base64,
mime_type="application/pdf"
)
except Exception as e:
yield self.create_text_message(f"Error exporting to PDF: {str(e)}")
return
```
</CodeGroup>
## ステップ9エントリーポイントの作成
プロジェクトのルートに`main.py`ファイルを作成します:
<CodeGroup>
```python main.py
from dify_plugin import PluginRunner
from tools.word_export import WordExportTool
from tools.pdf_export import PDFExportTool
plugin = PluginRunner(
tools=[
WordExportTool(),
PDFExportTool(),
],
providers=[] # No credential providers needed
)
```
</CodeGroup>
## ステップ10プラグインのテスト
<Steps>
<Step title="デバッグ環境のセットアップ">
まず、テンプレートから`.env`ファイルを作成します:
```bash
cp .env.example .env
```
Dify環境の詳細を設定します
```
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=debug-plugin.dify.dev
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=your_debug_key
```
</Step>
<Step title="依存関係のインストール">
```bash
pip install -r requirements.txt
```
</Step>
<Step title="デバッグモードでプラグインを起動">
```bash
python -m main
```
</Step>
</Steps>
## ステップ11配布用にパッケージ化
プラグインを共有する準備ができたら:
```bash
dify plugin package ./
```
これにより、配布用の`plugin.difypkg`ファイルが作成されます。
## クリエイティブな活用例
<CardGroup cols={2}>
<Card title="レポート生成" icon="file-lines">
このプラグインを使用して、分析サマリーをクライアント向けのプロフェッショナルなレポートに変換
</Card>
<Card title="セッションドキュメント化" icon="book">
コーチングやコンサルティングセッションのノートをフォーマットされたドキュメントとしてエクスポート
</Card>
</CardGroup>
## 基本を超えて
このプラグインを拡張するための興味深い方法をいくつか紹介します:
- **カスタムテンプレート**:企業ブランディングやパーソナライズされたスタイルを追加
- **マルチフォーマットサポート**HTML、Markdown、その他のフォーマットへのエクスポートを拡張
- **画像処理**:会話からの画像を処理して含める
- **テーブルサポート**:データテーブルの適切なフォーマットを実装
- **コラボレーティブ編集**Google Docsや類似のプラットフォームとの統合を追加
<Accordion title="技術的な洞察">
ドキュメント変換の核心的な課題は、フォーマットと構造を維持することです。このプラグインで使用されているアプローチは、まずMarkdownをHTML中間形式に変換し、その後そのHTMLをターゲット形式に処理します。
この2段階のプロセスは柔軟性を提供します—HTML表現で動作する新しい出力モジュールを追加するだけで、追加のフォーマットをサポートするように拡張できます。
PDF生成には、CSSサポート付きの高品質なPDFレンダリングを提供するWeasyPrintが選択されました。Word文書には、python-docxがドキュメント構造に対する詳細な制御を提供します。
</Accordion>
## まとめ
会話をプロフェッショナルなドキュメント形式でエクスポートできるようにすることで、Difyプラットフォームに実際の価値を追加する実用的なプラグインを構築しました。この機能は、AI会話と従来のドキュメントワークフローの間のギャップを埋めます。
<CardGroup cols={2}>
<Card title="ドキュメント" icon="book">
機能、セットアップ、使用例を説明するREADME.mdを英語en_USで作成してください
</Card>
<Card title="ローカライゼーション" icon="language">
他の言語用に`readme/README_zh_Hans.md`などの追加READMEファイルを作成してください
</Card>
</CardGroup>
<CheckList>
<CheckListItem id="privacy">
プラグインを公開する場合はプライバシーポリシーPRIVACY.mdを追加してください
</CheckListItem>
<CheckListItem id="documentation">
ドキュメントに包括的な例を含めてください
</CheckListItem>
<CheckListItem id="testing">
さまざまなドキュメントサイズとフォーマットで徹底的にテストしてください
</CheckListItem>
</CheckList>
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/develop-md-exporter.mdx) | [問題を報告](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,128 @@
---
dimensions:
type:
primary: reference
detail: examples
level: intermediate
standard_title: Endpoint
language: ja
title: Neko Cat Endpoint
description: 著者 Yeuoly、Allen。このドキュメントでは、Neko Cat プロジェクトを例として、Dify プラグインにおける Endpoint の構造と実装について詳しく説明します。Endpoint グループの定義、インターフェースの設定、_invoke メソッドの実装、リクエストとレスポンスの処理について説明します。また、各種 YAML 設定フィールドの意味と使用方法についても解説します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/endpoint)を参照してください。</Note>
# Endpoint
このドキュメントでは、[Neko Cat](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint) プロジェクトを例として、プラグイン内の Endpoint の構造について説明します。Endpoint はプラグインが公開する 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](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications#providerconfig)): Endpoint 設定の定義。
* `endpoints` (list[string], 必須): 具体的な `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): パスから解析されたパスパラメータ。
* `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")
```
## 注意事項
* Endpoint はプラグインが呼び出されたときにのみインスタンス化されます。常時稼働するサービスではありません。
* Endpoint を開発する際はセキュリティに注意し、危険な操作の実行を避けてください。
* Endpoint は Webhook コールバックの処理や、他のシステムが接続するためのインターフェースの提供に使用できます。
プラグイン開発を学習中の場合は、まず[プラグイン開発入門](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)と[開発者チートシート](/ja/develop-plugin/dev-guides-and-walkthroughs/cheatsheet)を読むことをお勧めします。
## 関連リソース
* [プラグイン開発の基本概念](/ja/develop-plugin/getting-started/getting-started-dify-plugin) - プラグイン開発の全体的なアーキテクチャを理解する。
* [Neko Cat サンプル](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint) - 拡張プラグイン開発のサンプル。
* [汎用仕様定義](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - ProviderConfig などの共通構造を理解する。
* [Slack Bot プラグイン開発サンプル](/ja/develop-plugin/dev-guides-and-walkthroughs/develop-a-slack-bot-plugin) - 別のプラグイン開発サンプル。
* [プラグイン開発入門](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin) - ゼロからプラグインを開発する。
* [Dify サービスの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-app) - 逆呼び出し機能の使用方法を学ぶ。
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/endpoint.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,382 @@
---
title: "ツールプラグインにOAuthサポートを追加する"
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/tool-oauth)を参照してください。</Note>
![b0e673ba3e339b31ac36dc3cd004df04787bcaa64bb6d2cac6feb7152b7b515f.png](/images/b0e673ba3e339b31ac36dc3cd004df04787bcaa64bb6d2cac6feb7152b7b515f.png)
このガイドでは、ツールプラグインに[OAuth](https://oauth.net/2/)サポートを組み込む方法を説明します。
OAuthは、GmailやGitHubなどのサードパーティサービスからユーザーデータにアクセスする必要があるツールプラグインを認可するためのより優れた方法です。ユーザーがAPIキーを手動で入力する必要がなく、OAuthを使用することでツールはユーザーの明示的な同意のもとでユーザーに代わって動作できます。
## 背景
DifyにおけるOAuthには、開発者が理解し設計すべき**2つの別々のフロー**があります。
### フロー1: OAuthクライアントセットアップ管理者/開発者フロー)
<Note>
Dify Cloudでは、Difyチームが人気のあるツールプラグイン用のOAuthアプリを作成し、OAuthクライアントをセットアップするため、ユーザーは自分で設定する手間が省けます。
セルフホストDifyインスタンスの管理者は、このセットアップフローを実行する必要があります。
</Note>
Difyインスタンスの管理者または開発者は、まずサードパーティサービスに信頼できるアプリケーションとしてOAuthアプリを登録する必要があります。これにより、DifyツールプロバイダーをOAuthクライアントとして設定するために必要な資格情報を取得できます。
例として、DifyのGmailツールプロバイダー用のOAuthクライアントをセットアップする手順を示します
<AccordionGroup>
<Accordion title="Google Cloudプロジェクトを作成する">
1. [Google Cloud Console](https://console.cloud.google.com)にアクセスし、新しいプロジェクトを作成するか、既存のプロジェクトを選択します
2. 必要なAPIGmail APIを有効にします
</Accordion>
<Accordion title="OAuth同意画面を設定する">
1. **APIs & Services** \> **OAuth consent screen**に移動します
2. 公開プラグインの場合は**External**ユーザータイプを選択します
3. アプリケーション名、ユーザーサポートメール、開発者連絡先を入力します
4. 必要に応じて承認済みドメインを追加します
5. テストの場合:**Test users**セクションでテストユーザーを追加します
</Accordion>
<Accordion title="OAuth 2.0資格情報を作成する">
1. **APIs & Services** \> **Credentials**に移動します
2. **Create Credentials** \> **OAuth 2.0 Client IDs**をクリックします
3. **Web application**タイプを選択します
4. `client_id`と`client_secret`が生成されます。これらを資格情報として保存します。
</Accordion>
<Accordion title="Difyに資格情報を入力する">
OAuthクライアント設定ポップアップにclient_idとclient_secretを入力して、ツールプロバイダーをクライアントとしてセットアップします。
<img
src="/images/acd5f5057235c3a0c554abaedcf276fb48f80567f0231eae9158a795f8e1c45d.png"
alt="acd5f5057235c3a0c554abaedcf276fb48f80567f0231eae9158a795f8e1c45d.png"
title="acd5f5057235c3a0c554abaedcf276fb48f80567f0231eae9158a795f8e1c45d.png"
className="mx-auto"
style={{ width:"66%" }}
/>
</Accordion>
<Accordion title="リダイレクトURIを承認する">
Difyが生成したリダイレクトURIをGoogle OAuthクライアントのページに登録します
<img
src="/images/dfe60a714a275c5bf65f814673bd2f0a0db4fda27573a2f0b28a1c39e4c61da2.png"
alt="dfe60a714a275c5bf65f814673bd2f0a0db4fda27573a2f0b28a1c39e4c61da2.png"
title="dfe60a714a275c5bf65f814673bd2f0a0db4fda27573a2f0b28a1c39e4c61da2.png"
className="mx-auto"
style={{ width:"77%" }}
/>
<Info>
Difyは`redirect_uri`をOAuthクライアント設定ポップアップに表示します。通常、次の形式に従います
```bash
https://{your-dify-domain}/console/api/oauth/plugin/{plugin-id}/{provider-name}/{tool-name}/callback
```
セルフホストDifyの場合、`your-dify-domain`は`CONSOLE_WEB_URL`と一致する必要があります。
</Info>
</Accordion>
</AccordionGroup>
<Tip>
各サービスには固有の要件があるため、統合するサービスの特定のOAuthドキュメントを必ず参照してください。
</Tip>
### フロー2: ユーザー認可Difyユーザーフロー
OAuthクライアントを設定した後、個々のDifyユーザーは、プラグインが自分の個人アカウントにアクセスすることを認可できるようになります。
<img
src="/images/833c205f5441910763b27d3e3ff0c4449a730a690da91abc3ce032c70da04223.png"
alt="833c205f5441910763b27d3e3ff0c4449a730a690da91abc3ce032c70da04223.png"
title="833c205f5441910763b27d3e3ff0c4449a730a690da91abc3ce032c70da04223.png"
className="mx-auto"
style={{ width:"67%" }}
/>
## 実装
### 1. プロバイダーマニフェストでOAuthスキーマを定義する
プロバイダーマニフェストの`oauth_schema`セクションは、プラグインのOAuthに必要な資格情報と、OAuthフローが生成するものをDifyに伝えます。OAuthをセットアップするには、2つのスキーマが必要です
#### client_schema
OAuthクライアントセットアップの入力を定義します
```yaml gmail.yaml
oauth_schema:
client_schema:
- name: "client_id"
type: "secret-input"
required: true
url: "https://developers.google.com/identity/protocols/oauth2"
- name: "client_secret"
type: "secret-input"
required: true
```
<Info>
`url`フィールドはサードパーティサービスのヘルプドキュメントに直接リンクします。これは困っている管理者/開発者の助けになります。
</Info>
#### credentials_schema
ユーザー認可フローが生成するものを指定しますDifyがこれらを自動的に管理します
```yaml
# also under oauth_schema
credentials_schema:
- name: "access_token"
type: "secret-input"
- name: "refresh_token"
type: "secret-input"
- name: "expires_at"
type: "secret-input"
```
<Info>
OAuth \+ APIキー認証オプションを提供するには、`oauth_schema`と`credentials_for_provider`の両方を含めてください。
</Info>
### 2. ツールプロバイダーで必要なOAuthメソッドを完成させる
`ToolProvider`を実装している場所に、以下のインポートを追加します:
```python
from dify_plugin.entities.oauth import ToolOAuthCredentials
from dify_plugin.errors.tool import ToolProviderCredentialValidationError, ToolProviderOAuthError
```
`ToolProvider`クラスは、これら3つのOAuthメソッドを実装する必要があります例として`GmailProvider`を使用):
<Warning>
いかなる場合でも、`ToolOAuthCredentials`の資格情報に`client_secret`を返してはなりません。これはセキュリティ上の問題につながる可能性があります。
</Warning>
<CodeGroup>
```python _oauth_get_authorization_url expandable
def _oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
"""
Generate the authorization URL using credentials from OAuth Client Setup Flow.
This URL is where users grant permissions.
"""
# Generate random state for CSRF protection (recommended for all OAuth flows)
state = secrets.token_urlsafe(16)
# Define Gmail-specific scopes - request minimal necessary permissions
scope = "read:user read:data" # Replace with your required scopes
# Assemble Gmail-specific payload
params = {
"client_id": system_credentials["client_id"], # From OAuth Client Setup
"redirect_uri": redirect_uri, # Dify generates this - DON'T modify
"scope": scope,
"response_type": "code", # Standard OAuth authorization code flow
"access_type": "offline", # Critical: gets refresh token (if supported)
"prompt": "consent", # Forces reauth when scopes change (if supported)
"state": state, # CSRF protection
}
return f"{self._AUTH_URL}?{urllib.parse.urlencode(params)}"
```
```python _oauth_get_credentials expandable
def _oauth_get_credentials(
self, redirect_uri: str, system_credentials: Mapping[str, Any], request: Request
) -> ToolOAuthCredentials:
"""
Exchange authorization code for access token and refresh token. This is called
to creates ONE credential set for one account connection
"""
# Extract authorization code from OAuth callback
code = request.args.get("code")
if not code:
raise ToolProviderOAuthError("Authorization code not provided")
# Check for authorization errors from OAuth provider
error = request.args.get("error")
if error:
error_description = request.args.get("error_description", "")
raise ToolProviderOAuthError(f"OAuth authorization failed: {error} - {error_description}")
# Exchange authorization code for tokens using OAuth Client Setup credentials
# Assemble Gmail-specific payload
data = {
"client_id": system_credentials["client_id"], # From OAuth Client Setup
"client_secret": system_credentials["client_secret"], # From OAuth Client Setup
"code": code, # From user's authorization
"grant_type": "authorization_code", # Standard OAuth flow type
"redirect_uri": redirect_uri, # Must exactly match authorization URL
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
try:
response = requests.post(
self._TOKEN_URL,
data=data,
headers=headers,
timeout=10
)
response.raise_for_status()
token_data = response.json()
# Handle OAuth provider errors in response
if "error" in token_data:
error_desc = token_data.get('error_description', token_data['error'])
raise ToolProviderOAuthError(f"Token exchange failed: {error_desc}")
access_token = token_data.get("access_token")
if not access_token:
raise ToolProviderOAuthError("No access token received from provider")
# Build credentials dict matching your credentials_schema
credentials = {
"access_token": access_token,
"token_type": token_data.get("token_type", "Bearer"),
}
# Include refresh token if provided (critical for long-term access)
refresh_token = token_data.get("refresh_token")
if refresh_token:
credentials["refresh_token"] = refresh_token
# Handle token expiration - some providers don't provide expires_in
expires_in = token_data.get("expires_in", 3600) # Default to 1 hour
expires_at = int(time.time()) + expires_in
return ToolOAuthCredentials(credentials=credentials, expires_at=expires_at)
except requests.RequestException as e:
raise ToolProviderOAuthError(f"Network error during token exchange: {str(e)}")
except Exception as e:
raise ToolProviderOAuthError(f"Failed to exchange authorization code: {str(e)}")
```
```python _oauth_refresh_credentials
def _oauth_refresh_credentials(
self, redirect_uri: str, system_credentials: Mapping[str, Any], credentials: Mapping[str, Any]
) -> ToolOAuthCredentials:
"""
Refresh the credentials using refresh token.
Dify calls this automatically when tokens expire
"""
refresh_token = credentials.get("refresh_token")
if not refresh_token:
raise ToolProviderOAuthError("No refresh token available")
# Standard OAuth refresh token flow
data = {
"client_id": system_credentials["client_id"], # From OAuth Client Setup
"client_secret": system_credentials["client_secret"], # From OAuth Client Setup
"refresh_token": refresh_token, # From previous authorization
"grant_type": "refresh_token", # OAuth refresh flow
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
try:
response = requests.post(
self._TOKEN_URL,
data=data,
headers=headers,
timeout=10
)
response.raise_for_status()
token_data = response.json()
# Handle refresh errors
if "error" in token_data:
error_desc = token_data.get('error_description', token_data['error'])
raise ToolProviderOAuthError(f"Token refresh failed: {error_desc}")
access_token = token_data.get("access_token")
if not access_token:
raise ToolProviderOAuthError("No access token received from provider")
# Build new credentials, preserving existing refresh token
new_credentials = {
"access_token": access_token,
"token_type": token_data.get("token_type", "Bearer"),
"refresh_token": refresh_token, # Keep existing refresh token
}
# Handle token expiration
expires_in = token_data.get("expires_in", 3600)
# update refresh token if new one provided
new_refresh_token = token_data.get("refresh_token")
if new_refresh_token:
new_credentials["refresh_token"] = new_refresh_token
# Calculate new expiration timestamp for Dify's token management
expires_at = int(time.time()) + expires_in
return ToolOAuthCredentials(credentials=new_credentials, expires_at=expires_at)
except requests.RequestException as e:
raise ToolProviderOAuthError(f"Network error during token refresh: {str(e)}")
except Exception as e:
raise ToolProviderOAuthError(f"Failed to refresh credentials: {str(e)}")
```
</CodeGroup>
### 3. ツールでトークンにアクセスする
`Tool`実装でOAuth資格情報を使用して認証済みAPI呼び出しを行うことができます
```python
class YourTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
if self.runtime.credential_type == CredentialType.OAUTH:
access_token = self.runtime.credentials["access_token"]
response = requests.get("https://api.service.com/data",
headers={"Authorization": f"Bearer {access_token}"})
return self.create_text_message(response.text)
```
`self.runtime.credentials`は現在のユーザーのトークンを自動的に提供します。Difyはリフレッシュを自動的に処理します。
OAuthとAPI_KEY認証の両方をサポートするプラグインの場合、`self.runtime.credential_type`を使用して2つの認証タイプを区別できます。
### 4. 正しいバージョンを指定する
以前のバージョンのプラグインSDKとDifyはOAuth認証をサポートしていません。そのため、プラグインSDKのバージョンを以下に設定する必要があります
```
dify_plugin>=0.4.2,<0.5.0.
```
`manifest.yaml`に、最小Difyバージョンを追加します
```yaml
meta:
version: 0.0.1
arch:
- amd64
- arm64
runner:
language: python
version: "3.12"
entrypoint: main
minimum_dify_version: 1.7.1
```
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/tool-oauth.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,387 @@
---
dimensions:
type:
primary: implementation
detail: standard
level: intermediate
standard_title: Tool Plugin
language: en
title: ツールプラグイン
description: このドキュメントでは、Dify用のツールプラグインの開発方法について詳細な手順を提供します。Google Searchを例として、完全なツールプラグイン開発プロセスを示します。内容には、プラグインの初期化、テンプレートの選択、ツールプロバイダー設定ファイルの定義、サードパーティサービス認証情報の追加、ツール機能コードの実装、デバッグ、およびリリース用のパッケージングが含まれます。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)を参照してください。</Note>
ツールとは、Chatflow / ワークフロー / エージェントタイプのアプリケーションから呼び出すことができるサードパーティサービスを指し、Difyアプリケーションを強化するための完全なAPI実装機能を提供します。例えば、オンライン検索、画像生成などの追加機能を追加できます。
![Tool Plugin Example](https://assets-docs.dify.ai/2024/12/7e7bcf1f9e3acf72c6917ea9de4e4613.png)
この記事では、**「ツールプラグイン」**とは、ツールプロバイダーファイル、機能コード、およびその他の構造を含む完全なプロジェクトを指します。ツールプロバイダーには複数のツール(単一のツール内で提供される追加機能として理解できます)を含めることができ、構造は以下の通りです:
```
- Tool Provider
- Tool A
- Tool B
```
![Tool Plugin Structure](https://assets-docs.dify.ai/2025/02/60c4c86a317d865133aa460592eac079.png)
この記事では、`Google Search`を例として、ツールプラグインを素早く開発する方法を説明します。
### 前提条件
- Difyプラグインスキャフォールディングツール
- Python環境、バージョン ≥ 3.12
プラグイン開発スキャフォールディングツールの準備方法の詳細については、[開発ツールの初期化](/ja/develop-plugin/getting-started/cli)を参照してください。初めてプラグインを開発する場合は、まず[Difyプラグイン開発Hello Worldガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)を読むことをお勧めします。
### 新しいプロジェクトの作成
スキャフォールディングコマンドラインツールを実行して、新しいDifyプラグインプロジェクトを作成します。
```bash
./dify-plugin-darwin-arm64 plugin init
```
バイナリファイルを`dify`に名前変更し、`/usr/local/bin`パスにコピーした場合は、以下のコマンドを実行して新しいプラグインプロジェクトを作成できます:
```bash
dify plugin init
```
> 以下のテキストでは、`dify`をコマンドライン例として使用します。問題が発生した場合は、`dify`コマンドをコマンドラインツールのパスに置き換えてください。
### プラグインタイプとテンプレートの選択
スキャフォールディングツールのすべてのテンプレートは完全なコードプロジェクトを提供します。この例では、`Tool`プラグインを選択します。
> すでにプラグイン開発に精通しており、テンプレートに依存する必要がない場合は、[一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications)ガイドを参照して、さまざまなタイプのプラグインの開発を完了できます。
![Plugin Type: Tool](https://assets-docs.dify.ai/2024/12/dd3c0f9a66454e15868eabced7b74fd6.png)
#### プラグイン権限の設定
プラグインは、Difyプラットフォームから読み取る権限も必要です。このサンプルプラグインに以下の権限を付与します
- Tools
- Apps
- 永続ストレージStorageを有効にし、デフォルトサイズのストレージを割り当てる
- Endpointsの登録を許可
> ターミナルの矢印キーを使用して権限を選択し、「Tab」ボタンを使用して権限を付与します。
すべての権限項目をチェックした後、Enterを押してプラグインの作成を完了します。システムは自動的にプラグインプロジェクトコードを生成します。
![Plugin Permissions](https://assets-docs.dify.ai/2024/12/9cf92c2e74dce55e6e9e331d031e5a9f.png)
### ツールプラグインの開発
#### 1. ツールプロバイダーファイルの作成
ツールプロバイダーファイルはyaml形式のファイルで、ツールプラグインの基本設定エントリとして理解でき、ツールに必要な認証情報を提供するために使用されます。
プラグインテンプレートプロジェクトの`/provider`パスに移動し、yamlファイルを`google.yaml`に名前変更します。この`yaml`ファイルには、プロバイダーの名前、アイコン、作者などのツールプロバイダーに関する情報が含まれます。この情報は、プラグインのインストール時に表示されます。
**サンプルコード**
```yaml
identity: # Basic information of the tool provider
author: Your-name # Author
name: google # Name, unique, cannot have the same name as other providers
label: # Label, for frontend display
en_US: Google # English label
zh_Hans: Google # Chinese label
description: # Description, for frontend display
en_US: Google # English description
zh_Hans: Google # Chinese description
icon: icon.svg # Tool icon, needs to be placed in the _assets folder
tags: # Tags, for frontend display
- 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: #Add credentials_for_provider field
serpapi_api_key:
type: secret-input
required: true
label:
en_US: SerpApi API key
zh_Hans: SerpApi API key
placeholder:
en_US: Please input your SerpApi API key
zh_Hans: Please enter your SerpApi API key
help:
en_US: Get your SerpApi API key from SerpApi
zh_Hans: Get your SerpApi API key from SerpApi
url: https://serpapi.com/manage-api-key
tools:
- tools/google_search.yaml
extra:
python:
source: google.py
```
- `credentials_for_provider`のサブレベル構造は、[一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications)の要件を満たす必要があります。
- プロバイダーに含まれるツールを指定する必要があります。この例では、`tools/google_search.yaml`ファイルのみが含まれています。
- プロバイダーとして、基本情報を定義するだけでなく、そのコードロジックの一部を実装する必要があるため、その実装ロジックを指定する必要があります。この例では、機能のコードファイルを`google.py`に配置しますが、まだ実装せず、最初に`google_search`のコードを書きます。
#### 3. ツールYAMLファイルの記入
ツールプラグインには複数のツール機能を持たせることができ、各ツール機能には、ツール機能の基本情報、パラメータ、出力などを記述する`yaml`ファイルが必要です。
引き続き`GoogleSearch`ツールを例として、`/tools`フォルダに新しい`google_search.yaml`ファイルを作成します。
```yaml
identity:
name: google_search
author: Dify
label:
en_US: GoogleSearch
zh_Hans: Google Search
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: A tool for performing a Google SERP search and extracting snippets and webpages. Input should be a search query.
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: Query string
pt_BR: Query string
human_description:
en_US: used for searching
zh_Hans: used for searching web content
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つのタイプをサポートしています。
- エージェントアプリケーションでは、`llm`はパラメータがLLM自体によって推論されることを意味し、`form`はこのツールを使用するために事前にパラメータを設定できることを意味します。
- ワークフローアプリケーションでは、`llm`と`form`の両方をフロントエンドで入力する必要がありますが、`llm`パラメータはツールノードの入力変数として使用されます。
- `required`必須かどうか
- `llm`モードでは、パラメータが必須の場合、エージェントはこのパラメータを推論する必要があります。
- `form`モードでは、パラメータが必須の場合、ユーザーは会話開始前にフロントエンドでこのパラメータを入力する必要があります。
- `options`パラメータオプション
- `llm`モードでは、Difyはすべてのオプションをモデルに渡し、モデルはこれらのオプションに基づいて推論できます。
- `form`モードでは、`type`が`select`の場合、フロントエンドはこれらのオプションを表示します。
- `default`デフォルト値。
- `min`最小値、パラメータタイプが`number`の場合に設定できます。
- `max`最大値、パラメータタイプが`number`の場合に設定できます。
- `human_description`フロントエンド表示用の説明、複数言語をサポート。
- `placeholder`入力フィールドのプロンプトテキスト、フォームタイプが`form`でパラメータタイプが`string`、`number`、`secret-input`の場合に設定でき、複数言語をサポート。
- `llm_description`モデルに渡される説明。モデルがこのパラメータをより良く理解できるように、このパラメータに関するできるだけ詳細な情報をここに記述して、モデルがパラメータを理解できるようにしてください。
#### 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`データ文字列を返すことを意味します。返却データタイプの詳細については、[プラグインのリモートデバッグ](/ja/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin)と[永続ストレージKV](/ja/develop-plugin/features-and-specs/plugin-types/persistent-storage-kv)ドキュメントを参照してください。
#### 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_URL=debug.dify.ai:5003
REMOTE_INSTALL_KEY=********-****-****-****-************
```
`python -m main`コマンドを実行してプラグインを起動します。プラグインページで、プラグインがワークスペースにインストールされていることを確認でき、チームの他のメンバーもプラグインにアクセスできます。
![](https://assets-docs.dify.ai/2024/11/0fe19a8386b1234755395018bc2e0e35.png)
### プラグインのパッケージング(オプション)
プラグインが正常に実行できることを確認した後、以下のコマンドラインツールを使用してプラグインをパッケージ化して名前を付けることができます。実行後、現在のフォルダに`google.difypkg`ファイルが作成されます。これが最終的なプラグインパッケージです。
```bash
# Replace ./google with the actual path of the plugin project
dify plugin package ./google
```
おめでとうございます!ツールタイプのプラグインの開発、デバッグ、パッケージングの全プロセスを完了しました!
### プラグインの公開(オプション)
プラグインをDify Marketplaceに公開したい場合は、プラグインが[Dify Marketplaceへの公開](/ja/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace)の仕様に従っていることを確認してください。レビューに合格すると、コードはメインブランチにマージされ、自動的に[Dify Marketplace](https://marketplace.dify.ai/)で公開されます。
[公開の概要](/ja/develop-plugin/publishing/marketplace-listing/release-overview)
### さらに探索
#### **クイックスタート:**
- [拡張プラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint)
- [モデルプラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider)
- [バンドルプラグイン:複数のプラグインのパッケージング](/ja/develop-plugin/features-and-specs/advanced-development/bundle)
#### **プラグインインターフェースドキュメント:**
- [一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - マニフェスト構造とツール仕様
- [Endpoint](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint) - 詳細なEndpointの定義
- [リバース呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation) - Dify機能のリバース呼び出し
- [モデルスキーマ](/ja/develop-plugin/features-and-specs/plugin-types/model-schema) - モデル
- [エージェントプラグイン](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation) - エージェント戦略の拡張
## 次の学習ステップ
- [プラグインのリモートデバッグ](/ja/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin) - より高度なデバッグテクニックを学ぶ
- [永続ストレージ](/ja/develop-plugin/features-and-specs/plugin-types/persistent-storage-kv) - プラグインでのデータストレージの使用方法を学ぶ
- [Slack Botプラグイン開発例](/ja/develop-plugin/dev-guides-and-walkthroughs/develop-a-slack-bot-plugin) - より複雑なプラグイン開発ケースを見る
- [ツールプラグイン](/ja/develop-plugin/features-and-specs/plugin-types/tool) - ツールプラグインの高度な機能を探索
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/tool-plugin.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,665 @@
---
title: "トリガープラグイン"
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/trigger-plugin)を参照してください。</Note>
## トリガープラグインとは?
トリガーは Dify v1.10.0 で新しいタイプの開始ノードとして導入されました。コード、ツール、ナレッジベース検索などの機能ノードとは異なり、トリガーの目的は**サードパーティのイベントを Dify が認識して処理できる入力形式に変換すること**です。
![Trigger Plugin Intro](/images/trigger_plugin_intro.PNG)
例えば、Gmail で Dify を `new email` イベントの受信者として設定すると、新しいメールを受信するたびに、Gmail はワークフローをトリガーするために使用できるイベントを Dify に自動的に送信します。しかし:
- Gmail の元のイベント形式は Dify の入力形式と互換性がありません。
- 世界中には数千のプラットフォームがあり、それぞれ独自のイベント形式を持っています。
そのため、異なるプラットフォームや様々な形式からのこれらのイベントを定義・解析し、Dify が受け入れられる入力形式に統一するトリガープラグインが必要です。
## 技術概要
Dify のトリガーは、Web 全体で広く採用されているメカニズムである webhook に基づいて実装されています。多くの主要な SaaS プラットフォームGitHub、Slack、Linear など)は、包括的な開発者ドキュメントと共に webhook をサポートしています。
webhook は HTTP ベースのイベントディスパッチャーとして理解できます。**イベント受信アドレスが設定されると、これらの SaaS プラットフォームは、購読したイベントが発生するたびに、イベントデータをターゲットサーバーに自動的にプッシュします。**
異なるプラットフォームからの webhook イベントを統一的に処理するために、Dify は 2 つのコアコンセプトを定義しています:**Subscription** と **Event**。
- **Subscription**Webhook ベースのイベントディスパッチには、**サードパーティプラットフォームの開発者コンソールで Dify のネットワークアドレスをターゲットサーバーとして登録する必要があります。Dify では、この設定プロセスを *Subscription* と呼びます。**
- **Event**:プラットフォームは複数のタイプのイベント(*メール受信*、*メール削除*、*メールを既読にマーク*など)を送信する可能性があり、これらはすべて登録されたアドレスにプッシュされます。トリガープラグインは複数のイベントタイプを処理でき、各イベントは Dify ワークフロー内のプラグイントリガーノードに対応します。
## プラグイン開発
トリガープラグインの開発プロセスは、他のプラグインタイプ(ツール、データソース、モデルなど)と一貫しています。
`dify plugin init` コマンドを使用して開発テンプレートを作成できます。生成されるファイル構造は標準のプラグイン形式仕様に従います。
```
├── _assets
│ └── icon.svg
├── events
│ └── star
│ ├── star_created.py
│ └── star_created.yaml
├── main.py
├── manifest.yaml
├── provider
│ ├── github.py
│ └── github.yaml
├── README.md
├── PRIVACY.md
└── requirements.txt
```
- `manifest.yaml`:プラグインの基本的なメタデータを記述します。
- `provider` ディレクトリプロバイダーのメタデータ、サブスクリプション作成のコード、webhook リクエスト受信後のイベント分類のコードを含みます。
- **`events` ディレクトリ:イベント処理とフィルタリングのコードを含み、ノードレベルでのローカルイベントフィルタリングをサポートします。関連するイベントをグループ化するためにサブディレクトリを作成できます。**
<Note>
トリガープラグインの場合、最小必要 Dify バージョンは `1.10.0` に設定し、SDK バージョンは `>= 0.6.0` である必要があります。
</Note>
次に、GitHub を例として、トリガープラグインの開発プロセスを説明します。
### サブスクリプションの作成
Webhook の設定方法は、主要な SaaS プラットフォーム間で大きく異なります:
- 一部のプラットフォームGitHub など)は API ベースの webhook 設定をサポートしています。これらのプラットフォームでは、OAuth 認証が完了すると、Dify は自動的に webhook をセットアップできます。
- 他のプラットフォームNotion など)は webhook 設定 API を提供しておらず、ユーザーが手動で認証を行う必要がある場合があります。
これらの違いに対応するため、サブスクリプションプロセスを 2 つの部分に分けています:**Subscription Constructor** と **Subscription** 自体。
Notion のようなプラットフォームでは、サブスクリプションを作成するには、ユーザーが Dify から提供されたコールバック URL を手動でコピーし、Notion ワークスペースに貼り付けて webhook 設定を完了する必要があります。このプロセスは、Dify インターフェースの **Paste URL to create a new subscription** オプションに対応します。
<img src="/images/trigger_plugin_manual_webhook_setup.PNG" alt="URL を貼り付けて新しいサブスクリプションを作成" width="563" />
手動 URL 貼り付けによるサブスクリプション作成を実装するには、`github.yaml` と `github.py` の 2 つのファイルを変更する必要があります。
<Tabs>
<Tab title="github.yaml">
GitHub の webhook は暗号化メカニズムを使用しているため、受信リクエストを復号化して検証するためにシークレットキーが必要です。そのため、`github.yaml` で `webhook_secret` を宣言する必要があります。
```YAML
subscription_schema:
- name: "webhook_secret"
type: "secret-input"
required: false
label:
zh_Hans: "Webhook Secret"
en_US: "Webhook Secret"
ja_JP: "Webhookシークレット"
help:
en_US: "Optional webhook secret for validating GitHub webhook requests"
ja_JP: "GitHub Webhookリクエストの検証用のオプションのWebhookシークレット"
zh_Hans: "可选的用于验证 GitHub webhook 请求的 webhook 密钥"
```
</Tab>
<Tab title="github.py">
まず、`dispatch_event` インターフェースを実装する必要があります。コールバック URL に送信されるすべてのリクエストはこのインターフェースによって処理され、処理されたイベントはデバッグと検証のために **Request Logs** セクションに表示されます。
<img src="/images/trigger_plugin_manual_webhook_setup_config.PNG" alt="手動設定" width="500" />
コードでは、`subscription.properties` を通じて `github.yaml` で宣言された `webhook_secret` を取得できます。
`dispatch_event` メソッドは、リクエストの内容に基づいてイベントタイプを判断する必要があります。以下の例では、このイベント抽出は `_dispatch_trigger_event` メソッドによって処理されます。
<Tip>
完全なコードサンプルについては、[Dify の GitHub トリガープラグイン](https://github.com/langgenius/dify-plugin-sdks/tree/feat/trigger/python/examples/github_trigger)を参照してください。
</Tip>
```Python
class GithubTrigger(Trigger):
"""Handle GitHub webhook event dispatch."""
def _dispatch_event(self, subscription: Subscription, request: Request) -> EventDispatch:
webhook_secret = subscription.properties.get("webhook_secret")
if webhook_secret:
self._validate_signature(request=request, webhook_secret=webhook_secret)
event_type: str | None = request.headers.get("X-GitHub-Event")
if not event_type:
raise TriggerDispatchError("Missing GitHub event type header")
payload: Mapping[str, Any] = self._validate_payload(request)
response = Response(response='{"status": "ok"}', status=200, mimetype="application/json")
event: str = self._dispatch_trigger_event(event_type=event_type, payload=payload)
return EventDispatch(events=[event] if event else [], response=response)
```
</Tab>
</Tabs>
### イベント処理
イベントが抽出されると、対応する実装は元の HTTP リクエストをフィルタリングし、Dify ワークフローが受け入れられる入力形式に変換する必要があります。
Issue イベントを例にとると、`events/issues/issues.yaml` と `events/issues/issues.py` を通じてイベントとその実装を定義できます。イベントの出力は `issues.yaml` の `output_schema` セクションで定義でき、ツールプラグインと同じ JSON Schema 仕様に従います。
<Tabs>
<Tab title="issues.yaml">
```YAML
identity:
name: issues
author: langgenius
label:
en_US: Issues
zh_Hans: 议题
ja_JP: イシュー
description:
en_US: Unified issues event with actions filter
zh_Hans: 带 actions 过滤的统一 issues 事件
ja_JP: アクションフィルタ付きの統合イシューイベント
output_schema:
type: object
properties:
action:
type: string
issue:
type: object
description: The issue itself
extra:
python:
source: events/issues/issues.py
```
</Tab>
<Tab title="issues.py">
```Python
from collections.abc import Mapping
from typing import Any
from werkzeug import Request
from dify_plugin.entities.trigger import Variables
from dify_plugin.errors.trigger import EventIgnoreError
from dify_plugin.interfaces.trigger import Event
class IssuesUnifiedEvent(Event):
"""Unified Issues event. Filters by actions and common issue attributes."""
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
payload = request.get_json()
if not payload:
raise ValueError("No payload received")
allowed_actions = parameters.get("actions") or []
action = payload.get("action")
if allowed_actions and action not in allowed_actions:
raise EventIgnoreError()
issue = payload.get("issue")
if not isinstance(issue, Mapping):
raise ValueError("No issue in payload")
return Variables(variables={**payload})
```
</Tab>
</Tabs>
### イベントフィルタリング
特定のイベントをフィルタリングするには(例えば、特定のラベルを持つ Issue イベントのみに焦点を当てる場合)、`issues.yaml` のイベント定義に `parameters` を追加できます。その後、`_on_event` メソッドで、設定された条件を満たさないイベントをフィルタリングするために `EventIgnoreError` 例外をスローできます。
<Tabs>
<Tab title="issues.yaml">
```YAML
parameters:
- name: added_label
label:
en_US: Added Label
zh_Hans: 添加的标签
ja_JP: 追加されたラベル
type: string
required: false
description:
en_US: "Only trigger if these specific labels were added (e.g., critical, priority-high, security, comma-separated). Leave empty to trigger for any label addition."
zh_Hans: "仅当添加了这些特定标签时触发例如critical, priority-high, security逗号分隔。留空则对任何标签添加触发。"
ja_JP: "これらの特定のラベルが追加された場合のみトリガー(例: critical, priority-high, securityカンマ区切り。空の場合は任意のラベル追加でトリガー。"
```
</Tab>
<Tab title="issues.py">
```Python
def _check_added_label(self, payload: Mapping[str, Any], added_label_param: str | None) -> None:
"""Check if the added label matches the allowed labels"""
if not added_label_param:
return
allowed_labels = [label.strip() for label in added_label_param.split(",") if label.strip()]
if not allowed_labels:
return
# The payload contains the label that was added
label = payload.get("label", {})
label_name = label.get("name", "")
if label_name not in allowed_labels:
raise EventIgnoreError()
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
# ...
# Apply all filters
self._check_added_label(payload, parameters.get("added_label"))
return Variables(variables={**payload})
```
</Tab>
</Tabs>
### OAuth または API キーによるサブスクリプション作成
OAuth または API キーによる自動サブスクリプション作成を有効にするには、`github.yaml` と `github.py` ファイルを変更する必要があります。
<Tabs>
<Tab title="github.yaml">
`github.yaml` に以下のフィールドを追加します。
```YAML
subscription_constructor:
parameters:
- name: "repository"
label:
en_US: "Repository"
zh_Hans: "仓库"
ja_JP: "リポジトリ"
type: "dynamic-select"
required: true
placeholder:
en_US: "owner/repo"
zh_Hans: "owner/repo"
ja_JP: "owner/repo"
help:
en_US: "GitHub repository in format owner/repo (e.g., microsoft/vscode)"
zh_Hans: "GitHub 仓库,格式为 owner/repo例如microsoft/vscode"
ja_JP: "GitHubリポジトリは owner/repo 形式で入力してください(例: microsoft/vscode"
credentials_schema:
access_tokens:
help:
en_US: Get your Access Tokens from GitHub
ja_JP: GitHub からアクセストークンを取得してください
zh_Hans: 从 GitHub 获取您的 Access Tokens
label:
en_US: Access Tokens
ja_JP: アクセストークン
zh_Hans: Access Tokens
placeholder:
en_US: Please input your GitHub Access Tokens
ja_JP: GitHub のアクセストークンを入力してください
zh_Hans: 请输入你的 GitHub Access Tokens
required: true
type: secret-input
url: https://github.com/settings/tokens?type=beta
extra:
python:
source: provider/github.py
```
`subscription_constructor` は、サブスクリプションの構築方法を定義するために Dify が抽象化した概念です。以下のフィールドが含まれます:
- `parameters`(オプション):購読するイベントタイプやターゲット GitHub リポジトリなど、サブスクリプション作成に必要なパラメータを定義します
- `credentials_schema`オプションAPI キーまたはアクセストークンを使用してサブスクリプションを作成するために必要な認証情報を宣言しますGitHub の `access_tokens` など)。
- `oauth_schema`オプションOAuth によるサブスクリプション作成を実装するために必要です。定義方法の詳細については、[ツールプラグインに OAuth サポートを追加する](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-oauth)を参照してください。
</Tab>
<Tab title="github.py">
`github.py` で、自動サブスクリプションロジックを実装する `Constructor` クラスを作成します。
```Python
class GithubSubscriptionConstructor(TriggerSubscriptionConstructor):
"""Manage GitHub trigger subscriptions."""
def _validate_api_key(self, credentials: Mapping[str, Any]) -> None:
# ...
def _create_subscription(
self,
endpoint: str,
parameters: Mapping[str, Any],
credentials: Mapping[str, Any],
credential_type: CredentialType,
) -> Subscription:
repository = parameters.get("repository")
if not repository:
raise ValueError("repository is required (format: owner/repo)")
try:
owner, repo = repository.split("/")
except ValueError:
raise ValueError("repository must be in format 'owner/repo'") from None
events: list[str] = parameters.get("events", [])
webhook_secret = uuid.uuid4().hex
url = f"https://api.github.com/repos/{owner}/{repo}/hooks"
headers = {
"Authorization": f"Bearer {credentials.get('access_tokens')}",
"Accept": "application/vnd.github+json",
}
webhook_data = {
"name": "web",
"active": True,
"events": events,
"config": {"url": endpoint, "content_type": "json", "insecure_ssl": "0", "secret": webhook_secret},
}
try:
response = requests.post(url, json=webhook_data, headers=headers, timeout=10)
except requests.RequestException as exc:
raise SubscriptionError(f"Network error while creating webhook: {exc}", error_code="NETWORK_ERROR") from exc
if response.status_code == 201:
webhook = response.json()
return Subscription(
expires_at=int(time.time()) + self._WEBHOOK_TTL,
endpoint=endpoint,
parameters=parameters,
properties={
"external_id": str(webhook["id"]),
"repository": repository,
"events": events,
"webhook_secret": webhook_secret,
"active": webhook.get("active", True),
},
)
response_data: dict[str, Any] = response.json() if response.content else {}
error_msg = response_data.get("message", "Unknown error")
error_details = response_data.get("errors", [])
detailed_error = f"Failed to create GitHub webhook: {error_msg}"
if error_details:
detailed_error += f" Details: {error_details}"
raise SubscriptionError(
detailed_error,
error_code="WEBHOOK_CREATION_FAILED",
external_response=response_data,
)
```
</Tab>
</Tabs>
---
これら 2 つのファイルを変更すると、Dify インターフェースに **Create with API Key** オプションが表示されます。
OAuth による自動サブスクリプション作成も同じ `Constructor` クラスで実装できます:`subscription_constructor` の下に `oauth_schema` フィールドを追加することで、OAuth 認証を有効にできます。
<img src="/images/trigger_plugin_oauth_apikey.png" alt="OAuth と API キーオプション" width="563" />
## さらに詳しく
トリガープラグイン開発におけるコアクラスのインターフェース定義と実装方法は以下の通りです。
### Trigger
```Python
class Trigger(ABC):
@abstractmethod
def _dispatch_event(self, subscription: Subscription, request: Request) -> EventDispatch:
"""
Internal method to implement event dispatch logic.
Subclasses must override this method to handle incoming webhook events.
Implementation checklist:
1. Validate the webhook request:
- Check signature/HMAC using properties when you create the subscription from subscription.properties
- Verify request is from expected source
2. Extract event information:
- Parse event type from headers or body
- Extract relevant payload data
3. Return EventDispatch with:
- events: List of Event names to invoke (can be single or multiple)
- response: Appropriate HTTP response for the webhook
Args:
subscription: The Subscription object with endpoint and properties fields
request: Incoming webhook HTTP request
Returns:
EventDispatch: Event dispatch routing information
Raises:
TriggerValidationError: For security validation failures
TriggerDispatchError: For parsing or routing errors
"""
raise NotImplementedError("This plugin should implement `_dispatch_event` method to enable event dispatch")
```
### TriggerSubscriptionConstructor
```Python
class TriggerSubscriptionConstructor(ABC, OAuthProviderProtocol):
# OPTIONAL
def _validate_api_key(self, credentials: Mapping[str, Any]) -> None:
raise NotImplementedError(
"This plugin should implement `_validate_api_key` method to enable credentials validation"
)
# OPTIONAL
def _oauth_get_authorization_url(self, redirect_uri: str, system_credentials: Mapping[str, Any]) -> str:
raise NotImplementedError(
"The trigger you are using does not support OAuth, please implement `_oauth_get_authorization_url` method"
)
# OPTIONAL
def _oauth_get_credentials(
self, redirect_uri: str, system_credentials: Mapping[str, Any], request: Request
) -> TriggerOAuthCredentials:
raise NotImplementedError(
"The trigger you are using does not support OAuth, please implement `_oauth_get_credentials` method"
)
# OPTIONAL
def _oauth_refresh_credentials(
self, redirect_uri: str, system_credentials: Mapping[str, Any], credentials: Mapping[str, Any]
) -> OAuthCredentials:
raise NotImplementedError(
"The trigger you are using does not support OAuth, please implement `_oauth_refresh_credentials` method"
)
@abstractmethod
def _create_subscription(
self,
endpoint: str,
parameters: Mapping[str, Any],
credentials: Mapping[str, Any],
credential_type: CredentialType,
) -> Subscription:
"""
Internal method to implement subscription logic.
Subclasses must override this method to handle subscription creation.
Implementation checklist:
1. Use the endpoint parameter provided by Dify
2. Register webhook with external service using their API
3. Store all necessary information in Subscription.properties for future operations(e.g., dispatch_event)
4. Return Subscription with:
- expires_at: Set appropriate expiration time
- endpoint: The webhook endpoint URL allocated by Dify for receiving events, same with the endpoint parameter
- parameters: The parameters of the subscription
- properties: All configuration and external IDs
Args:
endpoint: The webhook endpoint URL allocated by Dify for receiving events
parameters: Subscription creation parameters
credentials: Authentication credentials
credential_type: The type of the credentials, e.g., "api-key", "oauth2", "unauthorized"
Returns:
Subscription: Subscription details with metadata for future operations
Raises:
SubscriptionError: For operational failures (API errors, invalid credentials)
ValueError: For programming errors (missing required params)
"""
raise NotImplementedError(
"This plugin should implement `_create_subscription` method to enable event subscription"
)
@abstractmethod
def _delete_subscription(
self, subscription: Subscription, credentials: Mapping[str, Any], credential_type: CredentialType
) -> UnsubscribeResult:
"""
Internal method to implement unsubscription logic.
Subclasses must override this method to handle subscription removal.
Implementation guidelines:
1. Extract necessary IDs from subscription.properties (e.g., external_id)
2. Use credentials and credential_type to call external service API to delete the webhook
3. Handle common errors (not found, unauthorized, etc.)
4. Always return UnsubscribeResult with detailed status
5. Never raise exceptions for operational failures - use UnsubscribeResult.success=False
Args:
subscription: The Subscription object with endpoint and properties fields
Returns:
UnsubscribeResult: Always returns result, never raises for operational failures
"""
raise NotImplementedError(
"This plugin should implement `_delete_subscription` method to enable event unsubscription"
)
@abstractmethod
def _refresh_subscription(
self, subscription: Subscription, credentials: Mapping[str, Any], credential_type: CredentialType
) -> Subscription:
"""
Internal method to implement subscription refresh logic.
Subclasses must override this method to handle simple expiration extension.
Implementation patterns:
1. For webhooks without expiration (e.g., GitHub):
- Update the Subscription.expires_at=-1 then Dify will never call this method again
2. For lease-based subscriptions (e.g., Microsoft Graph):
- Use the information in Subscription.properties to call service's lease renewal API if available
- Handle renewal limits (some services limit renewal count)
- Update the Subscription.properties and Subscription.expires_at for next time renewal if needed
Args:
subscription: Current subscription with properties
credential_type: The type of the credentials, e.g., "api-key", "oauth2", "unauthorized"
credentials: Current authentication credentials from credentials_schema.
For API key auth, according to `credentials_schema` defined in the YAML.
For OAuth auth, according to `oauth_schema.credentials_schema` defined in the YAML.
For unauthorized auth, there is no credentials.
Returns:
Subscription: Same subscription with extended expiration
or new properties and expires_at for next time renewal
Raises:
SubscriptionError: For operational failures (API errors, invalid credentials)
"""
raise NotImplementedError("This plugin should implement `_refresh` method to enable subscription refresh")
# OPTIONAL
def _fetch_parameter_options(
self, parameter: str, credentials: Mapping[str, Any], credential_type: CredentialType
) -> list[ParameterOption]:
"""
Fetch the parameter options of the trigger.
Implementation guidelines:
When you need to fetch parameter options from an external service, use the credentials
and credential_type to call the external service API, then return the options to Dify
for user selection.
Args:
parameter: The parameter name for which to fetch options
credentials: Authentication credentials for the external service
credential_type: The type of credentials (e.g., "api-key", "oauth2", "unauthorized")
Returns:
list[ParameterOption]: A list of available options for the parameter
Examples:
GitHub Repositories:
>>> result = provider.fetch_parameter_options(parameter="repository")
>>> print(result) # [ParameterOption(label="owner/repo", value="owner/repo")]
Slack Channels:
>>> result = provider.fetch_parameter_options(parameter="channel")
>>> print(result)
```
### Event
```Python
class Event(ABC):
@abstractmethod
def _on_event(self, request: Request, parameters: Mapping[str, Any], payload: Mapping[str, Any]) -> Variables:
"""
Transform the incoming webhook request into structured Variables.
This method should:
1. Parse the webhook payload from the request
2. Apply filtering logic based on parameters
3. Extract relevant data matching the output_schema
4. Return a structured Variables object
Args:
request: The incoming webhook HTTP request containing the raw payload.
Use request.get_json() to parse JSON body.
parameters: User-configured parameters for filtering and transformation
(e.g., label filters, regex patterns, threshold values).
These come from the subscription configuration.
payload: The decoded payload from previous step `Trigger.dispatch_event`.
It will be delivered into `_on_event` method.
Returns:
Variables: Structured variables matching the output_schema
defined in the event's YAML configuration.
Raises:
EventIgnoreError: When the event should be filtered out based on parameters
ValueError: When the payload is invalid or missing required fields
Example:
>>> def _on_event(self, request, parameters):
... payload = request.get_json()
...
... # Apply filters
... if not self._matches_filters(payload, parameters):
... raise EventIgnoreError()
...
... # Transform data
... return Variables(variables={
... "title": payload["issue"]["title"],
... "author": payload["issue"]["user"]["login"],
... "url": payload["issue"]["html_url"],
... })
"""
def _fetch_parameter_options(self, parameter: str) -> list[ParameterOption]:
"""
Fetch the parameter options of the trigger.
To be implemented by subclasses.
Also, it's optional to implement, that's why it's not an abstract method.
"""
raise NotImplementedError(
"This plugin should implement `_fetch_parameter_options` method to enable dynamic select parameter"
)
```
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/dev-guides-and-walkthroughs/trigger-plugin.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,106 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: beginner
standard_title: Bundle
language: en
title: Bundleプラグインパッケージ
description: このドキュメントでは、Bundleプラグインパッケージの概念と開発方法を紹介します。Bundleプラグインパッケージは複数のプラグインを集約でき、3つのタイプMarketplace、GitHub、Packageをサポートしています。ドキュメントでは、Bundleプロジェクトの作成、異なるタイプの依存関係の追加、Bundleプロジェクトのパッケージ化までの全プロセスを詳しく説明します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/advanced-development/bundle)を参照してください。</Note>
Bundleプラグインパッケージは、複数のプラグインの集合体です。単一のプラグイン内に複数のプラグインをパッケージ化することで、一括インストールを可能にし、より強力なサービスを提供します。
Dify CLIツールを使用して、複数のプラグインをBundleにパッケージ化できます。Bundleプラグインパッケージには3つのタイプがあります
* `Marketplace`タイプ。プラグインのIDとバージョン情報を保存します。インポート時に、特定のプラグインパッケージがDify Marketplaceからダウンロードされます。
* `GitHub`タイプ。GitHubリポジトリアドレス、リリースバージョン番号、アセットファイル名を保存します。インポート時に、Difyは対応するGitHubリポジトリにアクセスしてプラグインパッケージをダウンロードします。
* `Package`タイプ。プラグインパッケージはBundle内に直接保存されます。参照元を保存しませんが、Bundleパッケージのサイズが大きくなる可能性があります。
### 前提条件
* Difyプラグインスキャフォールディングツール
* Python環境、バージョン ≥ 3.10
プラグイン開発スキャフォールディングツールの準備方法の詳細については、[開発ツールの初期化](/ja/develop-plugin/getting-started/cli)を参照してください。
### Bundleプロジェクトの作成
現在のディレクトリで、スキャフォールディングコマンドラインツールを実行して新しいプラグインパッケージプロジェクトを作成します。
```bash
./dify-plugin-darwin-arm64 bundle init
```
バイナリファイルを`dify`にリネームして`/usr/local/bin`パスにコピーしている場合は、次のコマンドを実行して新しいプラグインプロジェクトを作成できます:
```bash
dify bundle init
```
#### 1. プラグイン情報の入力
プロンプトに従って、プラグイン名、作成者情報、プラグインの説明を設定します。チームで共同作業している場合は、作成者として組織名を入力することもできます。
> 名前は1〜128文字で、文字、数字、ハイフン、アンダースコアのみを含めることができます。
![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`はマーケットプレイス内のプラグインへの参照で、形式は`organization_name/plugin_name:version_number`です。
* **GitHub**
次のコマンドを実行します:
```bash
dify-plugin bundle append github . --repo_pattern=langgenius/openai:0.0.1/openai.difypkg
```
`repo_pattern`はGitHub上のプラグインへの参照で、形式は`organization_name/repository_name:release/asset_name`です。
* **Package**
次のコマンドを実行します:
```bash
dify-plugin bundle append package . --package_path=./openai.difypkg
```
`package_path`はプラグインパッケージのディレクトリです。
### Bundleプロジェクトのパッケージ化
次のコマンドを実行してBundleプラグインをパッケージ化します
```bash
dify-plugin bundle package ./bundle
```
コマンドを実行すると、現在のディレクトリに`bundle.difybndl`ファイルが自動的に作成されます。このファイルが最終的なパッケージ化結果です。
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/advanced-development/bundle.mdx) | [問題を報告](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,360 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: advanced
standard_title: Customizable Model
language: ja
title: カスタムモデルの統合
description: このドキュメントでは、Xinferenceモデルを例として、カスタムモデルをDifyに統合する方法を詳しく説明します。モデルプロバイダーファイルの作成、モデルタイプに基づくコードの記述、モデル呼び出しロジックの実装、例外処理、デバッグ、公開までの完全なプロセスをカバーしています。特に、LLM呼び出し、トークン計算、認証情報の検証、パラメータ生成などのコアメソッドの実装を詳しく説明します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/advanced-development/customizable-model)を参照してください。</Note>
**カスタムモデル**とは、自分でデプロイまたは設定するLLMを指します。このドキュメントでは、[Xinferenceモデル](https://inference.readthedocs.io/en/latest/)を例として、カスタムモデルを**モデルプラグイン**に統合する方法を説明します。
デフォルトでは、カスタムモデルは自動的に2つのパラメータ**モデルタイプ**と**モデル名**を含み、プロバイダーYAMLファイルで追加の定義は必要ありません。
プロバイダー設定ファイルに`validate_provider_credential`を実装する必要はありません。ランタイム中、ユーザーが選択したモデルタイプまたはモデル名に基づいて、Difyは自動的に対応するモデルレイヤーの`validate_credentials`メソッドを呼び出して認証情報を検証します。
## カスタムモデルプラグインの統合
以下はカスタムモデルを統合する手順です:
1. **モデルプロバイダーファイルの作成**\
カスタムモデルに含まれるモデルタイプを特定します。
2. **モデルタイプごとのコードファイルの作成**\
モデルのタイプ(例:`llm`や`text_embedding`)に応じて、別々のコードファイルを作成します。各モデルタイプが個別の論理レイヤーに整理されていることを確認し、保守と将来の拡張を容易にします。
3. **モデル呼び出しロジックの開発**\
各モデルタイプモジュール内で、そのモデルタイプの名前を付けたPythonファイル`llm.py`)を作成します。ファイル内でシステムのモデルインターフェース仕様に準拠した特定のモデルロジックを実装するクラスを定義します。
4. **プラグインのデバッグ**\
新しいプロバイダー機能のユニットテストと統合テストを作成し、すべてのコンポーネントが意図どおりに動作することを確認します。
***
### 1. **モデルプロバイダーファイルの作成**
プラグインの`/provider`ディレクトリに、`xinference.yaml`ファイルを作成します。
`Xinference`ファミリーのモデルは**LLM**、**Text Embedding**、**Rerank**モデルタイプをサポートしているため、`xinference.yaml`にはこれら3つすべてを含める必要があります。
**例:**
```yaml
provider: xinference # Identifies the provider
label: # Display name; can set both en_US (English) and zh_Hans (Chinese). If zh_Hans is not set, en_US is used by default.
en_US: Xorbits Inference
icon_small: # Small icon; store in the _assets folder of this provider's directory. The same multi-language logic applies as with label.
en_US: icon_s_en.svg
icon_large: # Large icon
en_US: icon_l_en.svg
help: # Help information
title:
en_US: How to deploy Xinference
zh_Hans: 如何部署 Xinference
url:
en_US: https://github.com/xorbitsai/inference
supported_model_types: # Model types Xinference supports: LLM/Text Embedding/Rerank
- llm
- text-embedding
- rerank
configurate_methods: # Xinference is locally deployed and does not offer predefined models. Refer to its documentation to learn which model to use. Thus, we choose a customizable-model approach.
- customizable-model
provider_credential_schema:
credential_form_schemas:
```
次に、`provider_credential_schema`を定義します。`Xinference`はテキスト生成、エンベディング、リランキングモデルをサポートしているため、以下のように設定できます:
```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
- value: reranking
label:
en_US: Rerank
```
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はローカルでデプロイする必要があるため、ユーザーはサーバーアドレス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: 在此输入你的 Model UID
en_US: Enter the model uid
```
これらのパラメータを定義したら、カスタムモデルプロバイダーのYAML設定は完了です。次に、この設定で定義された各モデルの機能コードファイルを作成します。
### 2. モデルコードの開発
Xinferenceはllm、rerank、speech2text、ttsをサポートしているため、/models下に対応するディレクトリを作成し、それぞれに機能コードを含める必要があります。
以下はllmタイプのモデルの例です。llm.pyという名前のファイルを作成し、\_\_base.large\_language\_model.LargeLanguageModelを拡張するXinferenceAILargeLanguageModelなどのクラスを定義します。このクラスには以下を含める必要があります
* **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]:
"""
Invoke the large language model.
:param model: model name
:param credentials: model credentials
:param prompt_messages: prompt messages
:param model_parameters: model parameters
:param tools: tools for tool calling
:param stop: stop words
:param stream: determines if response is streamed
:param user: unique user id
:return: full response or a chunk generator
"""
```
ストリーミングと同期応答を処理するために2つの別々の関数が必要です。Pythonは`yield`を含む関数を`Generator`型を返すジェネレータとして扱うため、これらを分離することをお勧めします:
```yaml
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:
"""
Get the number of tokens for the given prompt messages.
"""
return 0
```
または、`AIModel`基底クラスから`self._get_num_tokens_by_gpt2(text: str)`を呼び出すことができます。これはGPT-2トークナイザーを使用します。これは近似値であり、モデルと正確に一致しない場合があることに注意してください。
* **モデル認証情報の検証**
プロバイダーレベルの認証情報チェックと似ていますが、単一のモデルにスコープされます:
```python
def validate_credentials(self, model: str, credentials: dict) -> None:
"""
Validate model credentials.
"""
```
* **動的モデルパラメータスキーマ**
[事前定義モデル](/ja/plugins/quick-start/develop-plugins/model-plugin/predefined-model)とは異なり、モデルがサポートするパラメータを定義するYAMLはありません。パラメータスキーマを動的に生成する必要があります。
例えば、Xinferenceは`max_tokens`、`temperature`、`top_p`をサポートしています。他のプロバイダー(例:`OpenLLM`)は、特定のモデルでのみ`top_k`などのパラメータをサポートする場合があります。つまり、各モデルの機能に合わせてスキーマを適応させる必要があります:
```python
def get_customizable_model_schema(self, model: str, credentials: dict) -> AIModelEntity | None:
"""
used to define customizable model schema
"""
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'
)
)
]
# if model is A, add top_k to rules
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'
)
)
)
"""
some NOT IMPORTANT code here
"""
entity = AIModelEntity(
model=model,
label=I18nObject(
en_US=model
),
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_type=model_type,
model_properties={
ModelPropertyKey.MODE: ModelType.LLM,
},
parameter_rules=rules
)
return entity
```
* **エラーマッピング**
モデル呼び出し中にエラーが発生した場合、ランタイムが認識する適切なInvokeErrorタイプにマッピングします。これにより、Difyは異なるエラーを標準化された方法で処理できます
ランタイムエラー:
```
• `InvokeConnectionError`
• `InvokeServerUnavailableError`
• `InvokeRateLimitError`
• `InvokeAuthorizationError`
• `InvokeBadRequestError`
```
```python
@property
def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]:
"""
Map model invocation errors to unified error types.
The key is the error type thrown to the caller.
The value is the error type thrown by the model, which needs to be mapped to a
unified Dify error for consistent handling.
"""
# return {
# InvokeConnectionError: [requests.exceptions.ConnectionError],
# ...
# }
```
インターフェースメソッドの詳細については、[モデルドキュメント](https://docs.dify.ai/zh-hans/plugins/schema-definition/model)を参照してください。
このガイドで説明した完全なコードファイルを表示するには、[GitHubリポジトリ](https://github.com/langgenius/dify-official-plugins/tree/main/models/xinference)にアクセスしてください。
### 3. プラグインのデバッグ
開発が完了したら、プラグインをテストして正しく動作することを確認します。詳細については、以下を参照してください:
<Card title="プラグインのデバッグ" icon="link" href="/en/plugins/quick-start/debug-plugin">
</Card>
### 4. プラグインの公開
このプラグインをDify Marketplaceに掲載したい場合は、以下を参照してください
Dify Marketplaceに公開
## さらに探索
**クイックスタート:**
* [拡張プラグインの開発](/ja/plugins/quick-start/develop-plugins/extension-plugin)
* [ツールプラグインの開発](/ja/plugins/quick-start/develop-plugins/tool-plugin)
* [バンドルプラグイン:複数のプラグインをパッケージ化](/ja/plugins/quick-start/develop-plugins/bundle)
**プラグインエンドポイントドキュメント:**
* [マニフェスト](/ja/plugins/schema-definition/manifest)構造
* [エンドポイント](/ja/plugins/schema-definition/endpoint)定義
* [Difyサービスの逆呼び出し](/ja/plugins/schema-definition/reverse-invocation-of-the-dify-service)
* [ツール](/ja/plugins/schema-definition/tool)
* [モデル](/ja/plugins/schema-definition/model)
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/advanced-development/customizable-model.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,142 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: intermediate
standard_title: Reverse Invocation App
language: ja
title: App
description: このドキュメントでは、プラグインがDifyプラットフォーム内でAppサービスを逆呼び出しする方法について詳しく説明します。ChatインターフェースChatbot/Agent/Chatflowアプリケーション用、Workflowインターフェース、Completionインターフェースの3種類のインターフェースについて、エントリーポイント、呼び出し仕様、および各インターフェースの実用的なコード例を提供します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation-app)を参照してください。</Note>
Appの逆呼び出しとは、プラグインがDify内のAppからデータにアクセスできることを意味します。このモジュールは、ストリーミングと非ストリーミングの両方のApp呼び出しをサポートしています。逆呼び出しの基本概念に不慣れな場合は、まず[Difyサービスの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation)をお読みください。
**インターフェースの種類:**
* `Chatbot/Agent/Chatflow`タイプのアプリケーションは、すべてチャットベースのアプリケーションであり、同じ入出力パラメータタイプを共有しています。したがって、これらは**Chatインターフェース**として統一的に扱うことができます。
* ワークフローアプリケーションは、別個の**Workflowインターフェース**を占有します。
* Completionテキスト生成アプリケーションアプリケーションは、別個の**Completionインターフェース**を占有します。
プラグインは、プラグインが存在するワークスペース内のAppにのみアクセスできることに注意してください。
### Chatインターフェースの呼び出し
#### **エントリーポイント**
```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`内でChatタイプのAppを呼び出し、結果を直接返すことができます。
```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():
# Note: The original example incorrectly called self.session.app.workflow.invoke
# It should call self.session.app.chat.invoke for a chat app.
# Assuming a chat app is intended here based on the section title.
response = self.session.app.chat.invoke(
app_id=app_id,
inputs={}, # Provide actual inputs as needed
response_mode="streaming",
conversation_id="some-conversation-id", # Provide a conversation ID if needed
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サービスの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation) - 逆呼び出しの基本概念を理解する
- [モデルの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-model) - プラットフォーム内でモデル機能を呼び出す方法を学ぶ
- [ツールの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-tool) - 他のプラグインを呼び出す方法を学ぶ
- [Slack Botプラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/develop-a-slack-bot-plugin) - 逆呼び出しを使用した実践的なアプリケーションケース
- [拡張プラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint) - 拡張プラグインの開発方法を学ぶ
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation-app.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,295 @@
---
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モデルの逆呼び出しの具体的な方法を網羅しています。各モデルの呼び出しには、エントリーポイント、インターフェースパラメータの説明、実用的なコード例、モデル呼び出しのベストプラクティス推奨事項が含まれています。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation-model)を参照してください。</Note>
モデルの逆呼び出しとは、プラグインがDifyの内部LLM機能を呼び出す能力を指し、TTS、Rerankなど、プラットフォーム内のすべてのモデルタイプと機能を含みます。逆呼び出しの基本概念に慣れていない場合は、まず[Difyサービスの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation)をお読みください。
ただし、モデルを呼び出すには`ModelConfig`型のパラメータを渡す必要があることに注意してください。その構造は[一般仕様定義](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications)で参照でき、この構造はモデルの種類によってわずかに異なります。
例えば、`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
description:
human:
en_US: A tool for invoking a large language model
zh_Hans: 用于调用大型语言模型的工具
pt_BR: A tool for invoking a large language model
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
human_description:
en_US: used for searching
zh_Hans: 用于搜索网页内容
pt_BR: used for searching
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
human_description:
en_US: Model
zh_Hans: 使用的模型
pt_BR: Model
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') # Assuming 'query' is still needed, otherwise use 'prompt' from parameters
)
],
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サービスの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation) - 逆呼び出しの基本概念を理解する
- [アプリの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-app) - プラットフォーム内でアプリを呼び出す方法を学ぶ
- [ツールの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-tool) - 他のプラグインを呼び出す方法を学ぶ
- [モデルプラグイン開発ガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider) - カスタムモデルプラグインの開発方法を学ぶ
- [モデル設計ルール](/ja/develop-plugin/features-and-specs/plugin-types/model-designing-rules) - モデルプラグインの設計原則を理解する
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation-model.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,110 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: advanced
standard_title: Reverse Invocation Node
language: ja
title: ノード
description: このドキュメントでは、プラグインがDifyプラットフォーム内のChatflow/ワークフローアプリケーションードの機能を逆呼び出しする方法について説明します。主に、ParameterExtractorとQuestionClassifierという2つの特定のードの呼び出し方法について説明します。このドキュメントでは、これら2つのードを呼び出すためのエントリーポイント、インターフェースパラメータ、およびサンプルコードについて詳しく説明します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation-node)を参照してください。</Note>
ードの逆呼び出しとは、プラグインがDify Chatflow/ワークフローアプリケーション内の特定のノードの機能にアクセスできることを意味します。
`ワークフロー`内の`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`の構造については、この[ドキュメント](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications.mdx#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, NodeResponse # Assuming NodeResponse is importable
class ParameterExtractorTool(Tool):
def _invoke(
self, tool_parameters: dict
) -> Generator[ToolInvokeMessage, None, None]:
response: NodeResponse = 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",
)
# Assuming NodeResponse has an 'outputs' attribute which is a dictionary
extracted_name = response.outputs.get("name", "Name not found")
yield self.create_text_message(extracted_name)
```
### 質問分類ノードの呼び出し
#### **エントリーポイント**
```python
self.session.workflow_node.question_classifier
```
#### **インターフェース**
```python
def invoke(
self,
classes: list[ClassConfig], # Assuming ClassConfig is defined/imported
model: ModelConfig,
query: str,
instruction: str = "",
) -> NodeResponse:
pass
```
インターフェースのパラメータは`ParameterExtractor`と一致しています。最終結果は`NodeResponse.outputs['class_name']`に格納されます。
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation-node.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,104 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: intermediate
standard_title: Reverse Invocation Tool
language: en
title: ツール
description: このドキュメントでは、プラグインがDifyプラットフォーム内でツールサービスを逆呼び出しする方法について詳しく説明します。インストール済みツールの呼び出しBuilt-in Tool、Workflowをツールとして呼び出し、カスタムツールの呼び出しCustom Toolの3種類のツール呼び出し方法について説明します。各方法には、対応するエントリーポイントとインターフェースパラメータの説明が含まれています。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation-tool)を参照してください。</Note>
ツールの逆呼び出しとは、プラグインがDifyプラットフォーム内の他のツールタイププラグインを呼び出すことを意味します。逆呼び出しの基本概念に馴染みがない場合は、まず[Difyサービスの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation)をお読みください。
以下のシナリオを考えてみてください:
* ツールタイププラグインが機能を実装したが、結果が期待通りではなく、データの後処理が必要な場合。
* タスクにウェブスクレイパーが必要で、スクレイピングサービスを柔軟に選択したい場合。
* 複数のツールの結果を集約する必要があるが、ワークフローアプリケーションでの処理が難しい場合。
これらの場合、プラグイン内で他の既存のツールを呼び出す必要があります。これらのツールは、マーケットプレイスから、自作のWorkflow as 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の詳細については、[ツールプラグインドキュメント](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)を参照してください。
**エントリーポイント**
```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サービスの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation) - 逆呼び出しの基本概念を理解する
- [アプリの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-app) - プラットフォーム内でアプリを呼び出す方法を学ぶ
- [モデルの逆呼び出し](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-model) - プラットフォーム内でモデル機能を呼び出す方法を学ぶ
- [ツールプラグイン開発ガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin) - ツールプラグインの開発方法を学ぶ
- [高度なツールプラグイン](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin) - Workflow as Toolなどの高度な機能について学ぶ
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation-tool.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,47 @@
---
dimensions:
type:
primary: implementation
detail: advanced
level: beginner
standard_title: Reverse Invocation
language: ja
title: Difyサービスの逆呼び出し
description: このドキュメントでは、Difyプラグインの逆呼び出し機能について簡単に紹介します。これは、プラグインがDifyメインプラットフォーム内の指定されたサービスを呼び出せることを意味します。呼び出し可能な4種類のモジュールを紹介しますAppアプリデータへのアクセス、Modelプラットフォーム内のモデル機能の呼び出し、Toolプラットフォーム内の他のツールプラグインの呼び出し、NodeChatflow/ワークフローアプリケーション内のノードの呼び出し)。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation)を参照してください。</Note>
プラグインは、機能を強化するためにDifyメインプラットフォーム内のいくつかのサービスを自由に呼び出すことができます。
### 呼び出し可能なDifyモジュール
* [App](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-app)
プラグインはDifyプラットフォーム内のアプリからデータにアクセスできます。
* [Model](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-model)
プラグインはDifyプラットフォーム内のLLM機能を逆呼び出しできます。これには、TTS、Rerankなど、プラットフォーム内のすべてのモデルタイプと機能が含まれます。
* [Tool](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-tool)
プラグインはDifyプラットフォーム内の他のツールタイププラグインを呼び出すことができます。
* [Node](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation-node)
プラグインはDifyプラットフォーム内の特定のChatflow/ワークフローアプリケーション内のノードを呼び出すことができます。
## 関連リソース
- [拡張プラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint) - 外部システムと統合するプラグインの開発方法を学ぶ
- [Slack Botプラグインの開発](/ja/develop-plugin/dev-guides-and-walkthroughs/develop-a-slack-bot-plugin) - 逆呼び出しを使用してSlackプラットフォームと統合する例
- [バンドルタイププラグイン](/ja/develop-plugin/features-and-specs/advanced-development/bundle) - 逆呼び出しを使用する複数のプラグインをパッケージ化する方法を学ぶ
- [永続ストレージの使用](/ja/develop-plugin/features-and-specs/plugin-types/persistent-storage-kv) - KVストレージを通じてプラグイン機能を強化する
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/advanced-development/reverse-invocation.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,279 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: General Specs
language: ja
title: 一般仕様
description: この記事では、プラグイン開発における一般的な構造について簡単に紹介します。開発中は、全体的なアーキテクチャをより深く理解するために、[プラグイン開発の基本概念](/ja/develop-plugin/getting-started/getting-started-dify-plugin)と[開発者チートシート](/ja/develop-plugin/getting-started/cli)を併せて読むことを強くお勧めします。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/plugin-types/general-specifications)を参照してください。</Note>
### パス仕様
Manifestまたは任意のyamlファイルでファイルパスを記入する際は、ファイルの種類に応じて以下の2つの仕様に従ってください
* 対象ファイルが画像や動画などのマルチメディアファイルの場合、例えばプラグインの`icon`を記入する際は、これらのファイルをプラグインのルートディレクトリ下の`_assets`フォルダに配置する必要があります。
* 対象ファイルが`.py`や`.yaml`コードファイルなどの通常のテキストファイルの場合、プラグインプロジェクト内でのファイルの絶対パスを記入する必要があります。
### 共通構造
プラグインを定義する際、ツール、モデル、Endpoints間で共有できるデータ構造がいくつかあります。これらの共有構造をここで定義します。
#### I18nObject
`I18nObject`は[IETF BCP 47](https://tools.ietf.org/html/bcp47)標準に準拠した国際化構造です。現在、4つの言語がサポートされています
<ParamField path="en_US" type="string">
英語(米国)
</ParamField>
<ParamField path="zh_Hans" type="string">
簡体字中国語
</ParamField>
<ParamField path="ja_JP" type="string">
日本語
</ParamField>
<ParamField path="pt_BR" type="string">
ポルトガル語(ブラジル)
</ParamField>
#### ProviderConfig
`ProviderConfig`は共通のプロバイダーフォーム構造で、`Tool`と`Endpoint`の両方に適用されます
<ParamField path="name" type="string">
フォーム項目名
</ParamField>
<ParamField path="label" type="I18nObject" required>
[IETF BCP 47](https://tools.ietf.org/html/bcp47)標準に準拠した表示ラベル
</ParamField>
<ParamField path="type" type="provider_config_type" required>
フォームフィールドタイプ - UIでフィールドがどのようにレンダリングされるかを決定します
</ParamField>
<ParamField path="scope" type="provider_config_scope">
オプションの範囲指定、`type`の値に基づいて異なります
</ParamField>
<ParamField path="required" type="boolean">
フィールドが空であってはならないかどうか
</ParamField>
<ParamField path="default" type="any">
デフォルト値、基本型のみサポート:`float`、`int`、`string`
</ParamField>
<ParamField path="options" type="array[provider_config_option]">
利用可能なオプション、typeが`select`の場合のみ使用
</ParamField>
<ParamField path="helper" type="object">
ヘルプドキュメントリンクラベル、[IETF BCP 47](https://tools.ietf.org/html/bcp47)に準拠
</ParamField>
<ParamField path="url" type="string">
ヘルプドキュメントリンク
</ParamField>
<ParamField path="placeholder" type="object">
複数言語でのプレースホルダーテキスト、[IETF BCP 47](https://tools.ietf.org/html/bcp47)に準拠
</ParamField>
#### ProviderConfigOption(object)
<ParamField path="value" type="string" required>
オプションの値
</ParamField>
<ParamField path="label" type="object" required>
オプションの表示ラベル、[IETF BCP 47](https://tools.ietf.org/html/bcp47)に準拠
</ParamField>
#### ProviderConfigType(string)
<ParamField path="secret-input" type="string">
暗号化される設定情報
</ParamField>
<ParamField path="text-input" type="string">
プレーンテキスト入力フィールド
</ParamField>
<ParamField path="select" type="string">
ドロップダウン選択フィールド
</ParamField>
<ParamField path="boolean" type="boolean">
スイッチ/トグルコントロール
</ParamField>
<ParamField path="model-selector" type="object">
モデル設定セレクター、プロバイダー名、モデル名、モデルパラメータなどを含む
</ParamField>
<ParamField path="app-selector" type="object">
アプリケーションIDセレクター
</ParamField>
<ParamField path="tool-selector" type="object">
ツール設定セレクター、ツールプロバイダー、名前、パラメータなどを含む
</ParamField>
<ParamField path="dataset-selector" type="string">
データセットセレクターTBD
</ParamField>
#### ProviderConfigScope(string)
`type`が`model-selector`の場合:
<ParamField path="all" type="string">
すべてのモデルタイプ
</ParamField>
<ParamField path="llm" type="string">
大規模言語モデルのみ
</ParamField>
<ParamField path="text-embedding" type="string">
テキスト埋め込みモデルのみ
</ParamField>
<ParamField path="rerank" type="string">
リランキングモデルのみ
</ParamField>
<ParamField path="tts" type="string">
テキスト読み上げモデルのみ
</ParamField>
<ParamField path="speech2text" type="string">
音声テキスト変換モデルのみ
</ParamField>
<ParamField path="moderation" type="string">
コンテンツモデレーションモデルのみ
</ParamField>
<ParamField path="vision" type="string">
ビジョンモデルのみ
</ParamField>
`type`が`app-selector`の場合:
<ParamField path="all" type="string">
すべてのアプリケーションタイプ
</ParamField>
<ParamField path="chat" type="string">
チャットアプリケーションのみ
</ParamField>
<ParamField path="workflow" type="string">
ワークフローアプリケーションのみ
</ParamField>
<ParamField path="completion" type="string">
補完アプリケーションのみ
</ParamField>
`type`が`tool-selector`の場合:
<ParamField path="all" type="string">
すべてのツールタイプ
</ParamField>
<ParamField path="plugin" type="string">
プラグインツールのみ
</ParamField>
<ParamField path="api" type="string">
APIツールのみ
</ParamField>
<ParamField path="workflow" type="string">
ワークフローツールのみ
</ParamField>
#### ModelConfig
<ParamField path="provider" type="string">
plugin_idを含むモデルプロバイダー名、`langgenius/openai/openai`の形式
</ParamField>
<ParamField path="model" type="string">
特定のモデル名
</ParamField>
<ParamField path="model_type" type="enum">
モデルタイプの列挙、[モデル設計ルール](/ja/develop-plugin/features-and-specs/plugin-types/model-designing-rules#modeltype)ドキュメントを参照
</ParamField>
#### NodeResponse
<ParamField path="inputs" type="dict">
最終的にノードに入力される変数
</ParamField>
<ParamField path="outputs" type="dict">
ノードの出力結果
</ParamField>
<ParamField path="process_data" type="dict">
ノード実行中に生成されるデータ
</ParamField>
#### ToolSelector
<ParamField path="provider_id" type="string">
ツールプロバイダー名
</ParamField>
<ParamField path="tool_name" type="string">
ツール名
</ParamField>
<ParamField path="tool_description" type="string">
ツールの説明
</ParamField>
<ParamField path="tool_configuration" type="dict[string, any]">
ツール設定情報
</ParamField>
<ParamField path="tool_parameters" type="dict[string, dict]">
LLM推論が必要なパラメータ
<ParamField path="name" type="string">
パラメータ名
</ParamField>
<ParamField path="type" type="string">
パラメータタイプ
</ParamField>
<ParamField path="required" type="boolean">
パラメータが必須かどうか
</ParamField>
<ParamField path="description" type="string">
パラメータの説明
</ParamField>
<ParamField path="default" type="any">
デフォルト値
</ParamField>
<ParamField path="options" type="array[string]">
パラメータで利用可能なオプション
</ParamField>
</ParamField>
## 関連リソース
- [プラグイン開発の基本概念](/ja/develop-plugin/getting-started/getting-started-dify-plugin) - Difyプラグイン開発の包括的な理解
- [開発者チートシート](/ja/develop-plugin/getting-started/cli) - プラグイン開発における一般的なコマンドと概念のクイックリファレンス
- [ツールプラグイン開発の詳細](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin) - プラグイン情報の定義方法とツールプラグイン開発プロセスの理解
- [モデル設計ルール](/ja/develop-plugin/features-and-specs/plugin-types/model-designing-rules) - モデル設定の標準の理解
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集](https://github.com/langgenius/dify-docs/edit/main/ja/develop-plugin/features-and-specs/plugin-types/general-specifications.mdx) | [問題を報告](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,573 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Model Specs
language: ja
title: モデル仕様
description: このドキュメントでは、Difyモデルプラグイン開発のコア概念と構造について詳細に定義しています。モデルプロバイダーProvider、AIモデルエンティティAIModelEntity、モデルタイプModelType、設定方法ConfigurateMethod、モデル機能ModelFeature、パラメータルールParameterRule、価格設定PriceConfig、および各種認証情報モードの詳細なデータ構造仕様が含まれます。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/plugin-types/model-designing-rules)を参照してください。</Note>
* モデルプロバイダールールは [Provider](#provider) エンティティに基づいています。
* モデルルールは [AIModelEntity](#aimodelentity) エンティティに基づいています。
> 以下のすべてのエンティティは `Pydantic BaseModel` に基づいており、`entities` モジュールで確認できます。
### Provider
<ParamField path="provider" type="string">
プロバイダー識別子、例:`openai`
</ParamField>
<ParamField path="label" type="object">
プロバイダー表示名、i18n、`en_US`(英語)と `zh_Hans`(中国語)の両方の言語を設定可能
<ParamField path="zh_Hans" type="string">
中国語ラベル、設定されていない場合はデフォルトで `en_US` を使用
</ParamField>
<ParamField path="en_US" type="string" required>
英語ラベル
</ParamField>
</ParamField>
<ParamField path="description" type="object">
プロバイダーの説明、i18n
<ParamField path="zh_Hans" type="string">
中国語の説明
</ParamField>
<ParamField path="en_US" type="string" required>
英語の説明
</ParamField>
</ParamField>
<ParamField path="icon_small" type="object">
プロバイダーの小アイコン、対応するプロバイダー実装ディレクトリ下の `_assets` ディレクトリに保存
<ParamField path="zh_Hans" type="string">
中国語アイコン
</ParamField>
<ParamField path="en_US" type="string" required>
英語アイコン
</ParamField>
</ParamField>
<ParamField path="icon_large" type="object">
プロバイダーの大アイコン、対応するプロバイダー実装ディレクトリ下の `_assets` ディレクトリに保存
<ParamField path="zh_Hans" type="string">
中国語アイコン
</ParamField>
<ParamField path="en_US" type="string" required>
英語アイコン
</ParamField>
</ParamField>
<ParamField path="background" type="string">
背景色の値、例:#FFFFFF、空の場合はフロントエンドのデフォルト色値が表示されます
</ParamField>
<ParamField path="help" type="object">
ヘルプ情報
<ParamField path="title" type="object">
ヘルプタイトル、i18n
<ParamField path="zh_Hans" type="string">
中国語タイトル
</ParamField>
<ParamField path="en_US" type="string" required>
英語タイトル
</ParamField>
</ParamField>
<ParamField path="url" type="object">
ヘルプリンク、i18n
<ParamField path="zh_Hans" type="string">
中国語リンク
</ParamField>
<ParamField path="en_US" type="string" required>
英語リンク
</ParamField>
</ParamField>
</ParamField>
<ParamField path="supported_model_types" type="array[ModelType]" required>
サポートされるモデルタイプ
</ParamField>
<ParamField path="configurate_methods" type="array[ConfigurateMethod]" required>
設定方法
</ParamField>
<ParamField path="provider_credential_schema" type="ProviderCredentialSchema" required>
プロバイダー認証情報仕様
</ParamField>
<ParamField path="model_credential_schema" type="ModelCredentialSchema">
モデル認証情報仕様
</ParamField>
### AIModelEntity
<ParamField path="model" type="string" required>
モデル識別子、例:`gpt-3.5-turbo`
</ParamField>
<ParamField path="label" type="object">
モデル表示名、i18n、`en_US`(英語)と `zh_Hans`(中国語)の両方の言語を設定可能
<ParamField path="zh_Hans" type="string">
中国語ラベル
</ParamField>
<ParamField path="en_US" type="string" required>
英語ラベル
</ParamField>
</ParamField>
<ParamField path="model_type" type="ModelType" required>
モデルタイプ
</ParamField>
<ParamField path="features" type="array[ModelFeature]">
サポートされる機能のリスト
</ParamField>
<ParamField path="model_properties" type="object" required>
モデルプロパティ
<ParamField path="mode" type="LLMMode">
モード(モデルタイプ `llm` で利用可能)
</ParamField>
<ParamField path="context_size" type="integer">
コンテキストサイズ(モデルタイプ `llm` および `text-embedding` で利用可能)
</ParamField>
<ParamField path="max_chunks" type="integer">
最大チャンク数(モデルタイプ `text-embedding` および `moderation` で利用可能)
</ParamField>
<ParamField path="file_upload_limit" type="integer">
最大ファイルアップロード制限、単位MBモデルタイプ `speech2text` で利用可能)
</ParamField>
<ParamField path="supported_file_extensions" type="string">
サポートされるファイル拡張子形式、例mp3,mp4モデルタイプ `speech2text` で利用可能)
</ParamField>
<ParamField path="default_voice" type="string">
デフォルト音声、必須alloy,echo,fable,onyx,nova,shimmerモデルタイプ `tts` で利用可能)
</ParamField>
<ParamField path="voices" type="array">
利用可能な音声のリスト(モデルタイプ `tts` で利用可能)
<ParamField path="mode" type="string">
音声モデル
</ParamField>
<ParamField path="name" type="string">
音声モデルの表示名
</ParamField>
<ParamField path="language" type="string">
音声モデルでサポートされる言語
</ParamField>
</ParamField>
<ParamField path="word_limit" type="integer">
単一変換の単語制限、デフォルトは段落分割(モデルタイプ `tts` で利用可能)
</ParamField>
<ParamField path="audio_type" type="string">
サポートされるオーディオファイル拡張子形式、例mp3,wavモデルタイプ `tts` で利用可能)
</ParamField>
<ParamField path="max_workers" type="integer">
テキストからオーディオへの変換でサポートされる同時タスク数(モデルタイプ `tts` で利用可能)
</ParamField>
<ParamField path="max_characters_per_chunk" type="integer">
チャンクあたりの最大文字数(モデルタイプ `moderation` で利用可能)
</ParamField>
</ParamField>
<ParamField path="parameter_rules" type="array[ParameterRule]">
モデル呼び出しパラメータルール
</ParamField>
<ParamField path="pricing" type="PriceConfig">
価格情報
</ParamField>
<ParamField path="deprecated" type="boolean">
非推奨かどうか。非推奨の場合、モデルリストには表示されなくなりますが、すでに設定されているものは引き続き使用できます。デフォルトはFalseです。
</ParamField>
### ModelType
<ParamField path="llm" type="string">
テキスト生成モデル
</ParamField>
<ParamField path="text-embedding" type="string">
テキスト埋め込みモデル
</ParamField>
<ParamField path="rerank" type="string">
リランクモデル
</ParamField>
<ParamField path="speech2text" type="string">
音声からテキスト
</ParamField>
<ParamField path="tts" type="string">
テキストから音声
</ParamField>
<ParamField path="moderation" type="string">
コンテンツモデレーション
</ParamField>
### ConfigurateMethod
<ParamField path="predefined-model" type="string">
事前定義モデル - ユーザーは統一されたプロバイダー認証情報を設定するだけで、プロバイダー下の事前定義モデルを使用できることを示します。
</ParamField>
<ParamField path="customizable-model" type="string">
カスタマイズ可能モデル - ユーザーは各モデルの認証情報設定を追加する必要があります。
</ParamField>
<ParamField path="fetch-from-remote" type="string">
リモートから取得 - `predefined-model` 設定方法と同様に、統一されたプロバイダー認証情報のみが必要ですが、モデルは認証情報を使用してプロバイダーから取得されます。
</ParamField>
### ModelFeature
<ParamField path="agent-thought" type="string">
エージェント推論、一般的に70B以上のモデルには思考連鎖機能があります。
</ParamField>
<ParamField path="vision" type="string">
ビジョン、すなわち:画像理解。
</ParamField>
<ParamField path="tool-call" type="string">
ツール呼び出し
</ParamField>
<ParamField path="multi-tool-call" type="string">
複数ツール呼び出し
</ParamField>
<ParamField path="stream-tool-call" type="string">
ストリーミングツール呼び出し
</ParamField>
### FetchFrom
<ParamField path="predefined-model" type="string">
事前定義モデル
</ParamField>
<ParamField path="fetch-from-remote" type="string">
リモートモデル
</ParamField>
### LLMMode
<ParamField path="completion" type="string">
テキスト補完
</ParamField>
<ParamField path="chat" type="string">
チャット
</ParamField>
### ParameterRule
<ParamField path="name" type="string" required>
モデル呼び出しの実際のパラメータ名
</ParamField>
<ParamField path="use_template" type="string">
テンプレートを使用
</ParamField>
> テンプレートの使用方法の詳細については、[新しいモデルプロバイダーの作成](/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider)の例を参照してください。
デフォルトで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` を参照できます。
<ParamField path="label" type="object">
ラベル、i18n
<ParamField path="zh_Hans" type="string">
中国語ラベル
</ParamField>
<ParamField path="en_US" type="string" required>
英語ラベル
</ParamField>
</ParamField>
<ParamField path="type" type="string">
パラメータタイプ
<ParamField path="int" type="string">
整数
</ParamField>
<ParamField path="float" type="string">
浮動小数点
</ParamField>
<ParamField path="string" type="string">
文字列
</ParamField>
<ParamField path="boolean" type="string">
ブール値
</ParamField>
</ParamField>
<ParamField path="help" type="object">
ヘルプ情報
<ParamField path="zh_Hans" type="string">
中国語ヘルプ情報
</ParamField>
<ParamField path="en_US" type="string" required>
英語ヘルプ情報
</ParamField>
</ParamField>
<ParamField path="required" type="boolean">
必須かどうか、デフォルトはFalse
</ParamField>
<ParamField path="default" type="int/float/string/boolean">
デフォルト値
</ParamField>
<ParamField path="min" type="int/float">
最小値、数値タイプのみに適用
</ParamField>
<ParamField path="max" type="int/float">
最大値、数値タイプのみに適用
</ParamField>
<ParamField path="precision" type="integer">
精度、保持する小数桁数、数値タイプのみに適用
</ParamField>
<ParamField path="options" type="array[string]">
ドロップダウンオプション値、`type` が `string` の場合のみ適用、設定されていないか null の場合、オプション値は制限されません
</ParamField>
### PriceConfig
<ParamField path="input" type="float">
入力単価、すなわちプロンプト単価
</ParamField>
<ParamField path="output" type="float">
出力単価、すなわち返されるコンテンツの単価
</ParamField>
<ParamField path="unit" type="float">
価格単位、例えば1Mトークンあたりの価格の場合、単価に対応する単位トークン数は `0.000001` です
</ParamField>
<ParamField path="currency" type="string">
通貨単位
</ParamField>
### ProviderCredentialSchema
<ParamField path="credential_form_schemas" type="array[CredentialFormSchema]" required>
認証情報フォーム仕様
</ParamField>
### ModelCredentialSchema
<ParamField path="model" type="object" required>
モデル識別子、デフォルト変数名は `model`
<ParamField path="label" type="object" required>
モデルフォーム項目の表示名
<ParamField path="en_US" type="string" required>
英語
</ParamField>
<ParamField path="zh_Hans" type="string">
中国語
</ParamField>
</ParamField>
<ParamField path="placeholder" type="object" required>
モデルプロンプトコンテンツ
<ParamField path="en_US" type="string" required>
英語
</ParamField>
<ParamField path="zh_Hans" type="string">
中国語
</ParamField>
</ParamField>
</ParamField>
<ParamField path="credential_form_schemas" type="array[CredentialFormSchema]" required>
認証情報フォーム仕様
</ParamField>
### CredentialFormSchema
<ParamField path="variable" type="string" required>
フォーム項目変数名
</ParamField>
<ParamField path="label" type="object" required>
フォーム項目ラベル
<ParamField path="en_US" type="string" required>
英語
</ParamField>
<ParamField path="zh_Hans" type="string">
中国語
</ParamField>
</ParamField>
<ParamField path="type" type="FormType" required>
フォーム項目タイプ
</ParamField>
<ParamField path="required" type="boolean">
必須かどうか
</ParamField>
<ParamField path="default" type="string">
デフォルト値
</ParamField>
<ParamField path="options" type="array[FormOption]">
`select` または `radio` に固有のフォーム項目属性、ドロップダウンコンテンツを定義
</ParamField>
<ParamField path="placeholder" type="object">
`text-input` に固有のフォーム項目属性、フォーム項目プレースホルダー
<ParamField path="en_US" type="string" required>
英語
</ParamField>
<ParamField path="zh_Hans" type="string">
中国語
</ParamField>
</ParamField>
<ParamField path="max_length" type="integer">
`text-input` に固有のフォーム項目属性、最大入力長を定義、0は制限なしを意味
</ParamField>
<ParamField path="show_on" type="array[FormShowOnObject]">
他のフォーム項目の値が条件を満たすときに表示、空の場合は常に表示
</ParamField>
#### FormType
<ParamField path="text-input" type="string">
テキスト入力コンポーネント
</ParamField>
<ParamField path="secret-input" type="string">
パスワード入力コンポーネント
</ParamField>
<ParamField path="select" type="string">
単一選択ドロップダウン
</ParamField>
<ParamField path="radio" type="string">
ラジオコンポーネント
</ParamField>
<ParamField path="switch" type="string">
スイッチコンポーネント、`true` と `false` のみサポート
</ParamField>
#### FormOption
<ParamField path="label" type="object" required>
ラベル
<ParamField path="en_US" type="string" required>
英語
</ParamField>
<ParamField path="zh_Hans" type="string">
中国語
</ParamField>
</ParamField>
<ParamField path="value" type="string" required>
ドロップダウンオプション値
</ParamField>
<ParamField path="show_on" type="array[FormShowOnObject]">
他のフォーム項目の値が条件を満たすときに表示、空の場合は常に表示
</ParamField>
#### FormShowOnObject
<ParamField path="variable" type="string" required>
他のフォーム項目変数名
</ParamField>
<ParamField path="value" type="string" required>
他のフォーム項目変数値
</ParamField>
## 関連リソース
- [モデルアーキテクチャの詳細](/ja/develop-plugin/features-and-specs/plugin-types/model-schema) - モデルプラグインのアーキテクチャ仕様の詳細
- [新しいモデルをすばやく統合する](/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider) - これらのルールを適用して新しいモデルを追加する方法を学ぶ
- [一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - プラグインマニフェストファイルの設定を理解する
- [新しいモデルプロバイダーを作成する](/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider) - まったく新しいモデルプロバイダープラグインを開発する
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/plugin-types/model-designing-rules.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Multilingual README
language: en
title: 多言語README
description: この記事では、Difyプラグインの多言語READMEのファイル仕様と、Dify Marketplaceでの表示ルールについて紹介します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/plugin-types/multilingual-readme)を参照してください。</Note>
プラグイン用の多言語READMEを作成できます。これは[Dify Marketplace](https://marketplace.dify.ai)やその他の場所で、ユーザーの優先言語に基づいて表示されます。
### README **ファイル仕様**
| **言語** | 必須 | ファイル名 | パス | **説明** |
| :------------------ | :------- | :-------------------------- | :----------------------------------------------------- | :--------------------------------------------------------------- |
| **英語** | はい | `README.md` | プラグインルートディレクトリ | / |
| **その他の言語** | いいえ | `README_<language_code>.md` | プラグインルートディレクトリ下の`readme`フォルダ内 | 現在、日本語、ポルトガル語、簡体字中国語をサポートしています。 |
以下はディレクトリ構造の例です:
```bash
...
├── main.py
├── manifest.yaml
├── readme
│ ├── README_ja_JP.md
│ ├── README_pt_BR.md
│ └── README_zh_Hans.md
├── README.md
...
```
### 多言語READMEの**Marketplaceでの表示方法**
プラグインにユーザーの優先言語のREADMEがある場合、Dify Marketplaceのプラグイン詳細ページにはその言語バージョンのREADMEが表示されます。
![](/images/plugin_details_page_en.jpeg)
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/plugin-types/multilingual-readme.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,162 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Persistent Storage KV
language: ja
title: 永続ストレージ
description: 組み込みのキーバリューデータベースを使用して、Difyプラグインで永続ストレージを実装し、インタラクション間で状態を維持する方法を学びます。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/plugin-types/persistent-storage-kv)を参照してください。</Note>
## 概要
ほとんどのプラグインツールとエンドポイントは、ステートレスな単一ラウンドのインタラクションモデルで動作します:
1. リクエストを受信
2. データを処理
3. レスポンスを返却
4. インタラクションを終了
しかし、多くの実際のアプリケーションでは、複数のインタラクション間で状態を維持する必要があります。ここで**永続ストレージ**が不可欠になります。
<Info>
永続ストレージメカニズムにより、プラグインは同じワークスペース内でデータを永続的に保存でき、ステートフルなアプリケーションやメモリ機能を実現できます。
</Info>
Difyは現在、プラグイン用のキーバリューKVストレージシステムを提供しており、開発者のニーズに基づいて、将来的にはより柔軟で強力なストレージインターフェースを導入する予定です。
## ストレージへのアクセス
すべてのストレージ操作は、プラグインのセッションで利用可能な`storage`オブジェクトを通じて実行されます:
```python
# Access the storage interface
storage = self.session.storage
```
## ストレージ操作
### データの保存
`set`メソッドでデータを保存します:
```python
def set(self, key: str, val: bytes) -> None:
"""
Store data in persistent storage
Parameters:
key: Unique identifier for your data
val: Binary data to store (bytes)
"""
pass
```
<Warning>
値は`bytes`形式である必要があります。これにより、ファイルを含むさまざまな種類のデータを柔軟に保存できます。
</Warning>
#### 例:さまざまなデータ型の保存
```python
# String data (must convert to bytes)
storage.set("user_name", "John Doe".encode('utf-8'))
# JSON data
import json
user_data = {"name": "John", "age": 30, "preferences": ["AI", "NLP"]}
storage.set("user_data", json.dumps(user_data).encode('utf-8'))
# File data
with open("image.jpg", "rb") as f:
image_data = f.read()
storage.set("profile_image", image_data)
```
### データの取得
`get`メソッドで保存されたデータを取得します:
```python
def get(self, key: str) -> bytes:
"""
Retrieve data from persistent storage
Parameters:
key: Unique identifier for your data
Returns:
The stored data as bytes, or None if key doesn't exist
"""
pass
```
#### 例:データの取得と変換
```python
# Retrieving string data
name_bytes = storage.get("user_name")
if name_bytes:
name = name_bytes.decode('utf-8')
print(f"Retrieved name: {name}")
# Retrieving JSON data
import json
user_data_bytes = storage.get("user_data")
if user_data_bytes:
user_data = json.loads(user_data_bytes.decode('utf-8'))
print(f"User preferences: {user_data['preferences']}")
```
### データの削除
`delete`メソッドで保存されたデータを削除します:
```python
def delete(self, key: str) -> None:
"""
Delete data from persistent storage
Parameters:
key: Unique identifier for the data to delete
"""
pass
```
## ベストプラクティス
<CardGroup cols={2}>
<Card title="説明的なキーを使用する" icon="key">
競合を避け、コードをより保守しやすくするために、キーに一貫した命名規則を作成してください。
</Card>
<Card title="欠損キーを処理する" icon="triangle-exclamation">
キーが見つからない可能性があるため、処理前にデータが存在するかどうかを常に確認してください。
</Card>
<Card title="複雑なデータをシリアライズする" icon="code">
保存前に複雑なオブジェクトをJSONまたは他のシリアライズ形式に変換してください。
</Card>
<Card title="エラーハンドリングを実装する" icon="shield">
潜在的なエラーを適切に処理するために、ストレージ操作をtry/exceptブロックでラップしてください。
</Card>
</CardGroup>
## 一般的なユースケース
- **ユーザー設定**:セッション間でユーザーの設定やプリファレンスを保存
- **会話履歴**:以前の会話からのコンテキストを維持
- **APIトークン**:認証トークンを安全に保存
- **キャッシュデータ**API呼び出しを減らすために頻繁にアクセスされるデータを保存
- **ファイルストレージ**:ユーザーがアップロードしたファイルや生成されたコンテンツを保存
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/plugin-types/persistent-storage-kv.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,253 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Plugin info by Manifest
language: ja
title: Manifest
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/plugin-types/plugin-info-by-manifest)を参照してください。</Note>
Manifestは、**プラグイン**の最も基本的な情報を定義するYAML準拠のファイルです。プラグイン名、作成者、含まれるツール、モデルなどが含まれますが、これらに限定されません。プラグインの全体的なアーキテクチャについては、[プラグイン開発の基本概念](/ja/develop-plugin/getting-started/getting-started-dify-plugin)と[開発者チートシート](/ja/develop-plugin/dev-guides-and-walkthroughs/cheatsheet)を参照してください。
このファイルのフォーマットが正しくない場合、プラグインの解析とパッケージングプロセスは失敗します。
### コード例
以下はManifestファイルの簡単な例です。各データ項目の意味と機能については後で説明します。
他のプラグインの参照コードについては、[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"
```
### 構造
<ParamField path="version" type="version" required>
プラグインのバージョン。
</ParamField>
<ParamField path="type" type="string" required>
プラグインタイプ。現在は`plugin`のみサポートされており、将来的に`bundle`がサポートされる予定です。
</ParamField>
<ParamField path="author" type="string" required>
作成者。Marketplaceでは組織名として定義されます。
</ParamField>
<ParamField path="label" type="object" required>
多言語名。
</ParamField>
<ParamField path="created_at" type="RFC3339" required>
作成時刻。Marketplaceでは現在時刻より後であってはなりません。
</ParamField>
<ParamField path="icon" type="string" required>
アイコンパス。
</ParamField>
<ParamField path="resource" type="object">
申請するリソース。
<ParamField path="memory" type="int64">
最大メモリ使用量。主にSaaS上のAWS Lambdaリソース申請に関連します。単位はバイトです。
</ParamField>
<ParamField path="permission" type="object">
権限申請。
<ParamField path="tool" type="object">
ツールの逆呼び出し権限。
<ParamField path="enabled" type="boolean">
ツール権限を有効にするかどうか。
</ParamField>
</ParamField>
<ParamField path="model" type="object">
モデルの逆呼び出し権限。
<ParamField path="enabled" type="boolean">
モデル権限を有効にするかどうか。
</ParamField>
<ParamField path="llm" type="boolean">
大規模言語モデル権限を有効にするかどうか。
</ParamField>
<ParamField path="text_embedding" type="boolean">
テキスト埋め込みモデル権限を有効にするかどうか。
</ParamField>
<ParamField path="rerank" type="boolean">
rerankモデル権限を有効にするかどうか。
</ParamField>
<ParamField path="tts" type="boolean">
テキスト読み上げモデル権限を有効にするかどうか。
</ParamField>
<ParamField path="speech2text" type="boolean">
音声テキスト変換モデル権限を有効にするかどうか。
</ParamField>
<ParamField path="moderation" type="boolean">
コンテンツモデレーションモデル権限を有効にするかどうか。
</ParamField>
</ParamField>
<ParamField path="node" type="object">
ノードの逆呼び出し権限。
<ParamField path="enabled" type="boolean">
ノード権限を有効にするかどうか。
</ParamField>
</ParamField>
<ParamField path="endpoint" type="object">
`endpoint`を登録する権限。
<ParamField path="enabled" type="boolean">
endpoint権限を有効にするかどうか。
</ParamField>
</ParamField>
<ParamField path="app" type="object">
`app`の逆呼び出し権限。
<ParamField path="enabled" type="boolean">
app権限を有効にするかどうか。
</ParamField>
</ParamField>
<ParamField path="storage" type="object">
永続ストレージを申請する権限。
<ParamField path="enabled" type="boolean">
ストレージ権限を有効にするかどうか。
</ParamField>
<ParamField path="size" type="int64">
許可される最大永続メモリサイズ。単位はバイトです。
</ParamField>
</ParamField>
</ParamField>
</ParamField>
<ParamField path="plugins" type="object" required>
プラグインによって拡張される特定の機能の`yaml`ファイルのリスト。プラグインパッケージ内の絶対パスです。例えば、モデルを拡張する必要がある場合、`openai.yaml`のようなファイルを定義し、ここにファイルパスを記入する必要があります。このパスにファイルが実際に存在しない場合、パッケージングは失敗します。
<Warning>
ツールとモデルを同時に拡張することは許可されていません。
</Warning>
<Warning>
拡張がないことは許可されていません。
</Warning>
<Warning>
モデルとEndpointsを同時に拡張することは許可されていません。
</Warning>
<Warning>
現在、各タイプの拡張では1つのプロバイダーのみがサポートされています。
</Warning>
<ParamField path="tools" type="array[string]">
[ツール](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)プロバイダーのプラグイン拡張。
</ParamField>
<ParamField path="models" type="array[string]">
[モデル](/ja/develop-plugin/features-and-specs/plugin-types/model-designing-rules)プロバイダーのプラグイン拡張。
</ParamField>
<ParamField path="endpoints" type="array[string]">
[Endpoints](/ja/develop-plugin/dev-guides-and-walkthroughs/develop-a-slack-bot-plugin)プロバイダーのプラグイン拡張。
</ParamField>
<ParamField path="agent_strategies" type="array[string]">
[エージェント戦略](/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation)プロバイダーのプラグイン拡張。
</ParamField>
</ParamField>
<ParamField path="meta" type="object" required>
プラグインのメタデータ。
<ParamField path="version" type="version" required>
`manifest`フォーマットバージョン。初期バージョンは`0.0.1`です。
</ParamField>
<ParamField path="arch" type="array[string]" required>
サポートされるアーキテクチャ。現在は`amd64`と`arm64`のみサポートされています。
</ParamField>
<ParamField path="runner" type="object" required>
ランタイム設定。
<ParamField path="language" type="string" required>
プログラミング言語。現在はPythonのみサポートされています。
</ParamField>
<ParamField path="version" type="string" required>
言語バージョン。現在は`3.12`のみサポートされています。
</ParamField>
<ParamField path="entrypoint" type="string" required>
プログラムエントリポイント。Pythonでは`main`である必要があります。
</ParamField>
</ParamField>
</ParamField>
<ParamField path="privacy" type="string">
プラグインのプライバシーポリシーファイルの相対パスまたはURLを指定します。例`"./privacy.md"`または`"https://your-web/privacy"`。プラグインをDify Marketplaceに掲載する予定がある場合、明確なユーザーデータの使用とプライバシーに関する声明を提供するために**このフィールドは必須**です。詳細な記入ガイドラインについては、[プラグインプライバシーデータ保護ガイドライン](/ja/develop-plugin/publishing/standards/privacy-protection-guidelines)を参照してください。
</ParamField>
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/plugin-types/plugin-info-by-manifest.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,33 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Remote Debug a Plugin
language: en
title: プラグインのデバッグ
description: このドキュメントでは、Difyのリモートデバッグ機能を使用してプラグインをテストする方法を紹介します。デバッグ情報の取得、環境変数ファイルの設定、プラグインのリモートデバッグの開始、プラグインのインストール状態の確認について詳細な手順を提供します。この方法により、開発者はローカルで開発しながら、Dify環境でリアルタイムにプラグインをテストできます。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin)を参照してください。</Note>
プラグイン開発が完了したら、次のステップはプラグインが正常に機能するかどうかをテストすることです。Difyは、テスト環境でプラグインの機能を素早く検証するための便利なリモートデバッグ方法を提供しています。
[「プラグイン管理」](https://cloud.dify.ai/plugins)ページに移動して、リモートサーバーアドレスとデバッグKeyを取得します。
![リモートデバッグプラグイン](https://assets-docs.dify.ai/2024/12/053415ef127f1f4d6dd85dd3ae79626a.png)
プラグインプロジェクトに戻り、`.env.example`ファイルをコピーして`.env`にリネームし、取得したリモートサーバーアドレスとデバッグKey情報を入力します。
`.env`ファイル:
```bash
INSTALL_METHOD=remote
REMOTE_INSTALL_URL=debug.dify.ai:5003
REMOTE_INSTALL_KEY=********-****-****-****-************
```
`python -m main`コマンドを実行してプラグインを起動します。プラグインページで、プラグインがワークスペースにインストールされていることが確認でき、チームの他のメンバーもプラグインにアクセスできます。
![ワークスペースにインストールされたプラグイン](https://assets-docs.dify.ai/2024/12/ec26e5afc57bbfeb807719638f603807.png)

View File

@@ -0,0 +1,393 @@
---
dimensions:
type:
primary: reference
detail: core
level: beginner
standard_title: Tool
language: ja
title: ツールの戻り値
description: このドキュメントでは、Difyプラグインにおけるツールのデータ構造と使用方法について詳しく紹介します。さまざまな種類のメッセージ画像URL、リンク、テキスト、ファイル、JSONの返し方、変数およびストリーミング変数メッセージの作成方法、ワークフローで参照するためのツール出力変数スキーマの定義方法について説明します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/features-and-specs/plugin-types/tool)を参照してください。</Note>
## 概要
<Note>
詳細なインターフェースドキュメントに入る前に、Difyプラグインのツール統合プロセスについて全般的な理解があることを確認してください。
</Note>
<CardGroup cols={2}>
<Card title="メッセージタイプ" icon="comment-dots" href="#message-return">
テキスト、リンク、画像、JSONなど、さまざまな種類のメッセージを返す
</Card>
<Card title="変数" icon="code-branch" href="#variable">
ワークフロー統合のための変数を作成および操作する
</Card>
<Card title="出力スキーマ" icon="diagram-project" href="#returning-custom-variables">
ワークフロー参照用のカスタム出力変数を定義する
</Card>
</CardGroup>
## データ構造
### メッセージの戻り値
<Info>
Difyは `text`、`links`、`images`、`file BLOBs`、`JSON` など、さまざまなメッセージタイプをサポートしています。これらのメッセージは専用のインターフェースを通じて返すことができます。
</Info>
デフォルトでは、ワークフロー内のツールの出力には `files`、`text`、`json` の3つの固定変数が含まれます。以下のメソッドを使用して、これらの変数に適切なコンテンツを設定できます。
<Tip>
`create_image_message` などのメソッドを使用して画像を返すことができますが、ツールはカスタム出力変数もサポートしており、ワークフロー内で特定のデータを参照するのに便利です。
</Tip>
### メッセージタイプ
<CodeGroup>
```python Image URL
def create_image_message(self, image: str) -> ToolInvokeMessage:
"""
Return an image URL message
Dify will automatically download the image from the provided URL
and display it to the user.
Args:
image: URL to an image file
Returns:
ToolInvokeMessage: Message object for the tool response
"""
pass
```
```python Link
def create_link_message(self, link: str) -> ToolInvokeMessage:
"""
Return a clickable link message
Args:
link: URL to be displayed as a clickable link
Returns:
ToolInvokeMessage: Message object for the tool response
"""
pass
```
```python Text
def create_text_message(self, text: str) -> ToolInvokeMessage:
"""
Return a text message
Args:
text: Text content to be displayed
Returns:
ToolInvokeMessage: Message object for the tool response
"""
pass
```
```python File
def create_blob_message(self, blob: bytes, meta: dict = None) -> ToolInvokeMessage:
"""
Return a file blob message
For returning raw file data such as images, audio, video,
or documents (PPT, Word, Excel, etc.)
Args:
blob: Raw file data in bytes
meta: File metadata dictionary. Include 'mime_type' to specify
the file type, otherwise 'octet/stream' will be used
Returns:
ToolInvokeMessage: Message object for the tool response
"""
pass
```
```python JSON
def create_json_message(self, json: dict) -> ToolInvokeMessage:
"""
Return a formatted JSON message
Useful for data transmission between workflow nodes.
In agent mode, most LLMs can read and understand JSON data.
Args:
json: Python dictionary to be serialized as JSON
Returns:
ToolInvokeMessage: Message object for the tool response
"""
pass
```
</CodeGroup>
<Accordion title="パラメータ">
<ParamField path="image" type="string" required>
ダウンロードして表示される画像のURL
</ParamField>
<ParamField path="link" type="string" required>
クリック可能なリンクとして表示されるURL
</ParamField>
<ParamField path="text" type="string" required>
表示されるテキストコンテンツ
</ParamField>
<ParamField path="blob" type="bytes" required>
バイト形式の生ファイルデータ
</ParamField>
<ParamField path="meta" type="dict">
以下を含むファイルメタデータ:
- `mime_type`ファイルのMIMEタイプ"image/png"
- ファイルに関連するその他のメタデータ
</ParamField>
<ParamField path="json" type="dict" required>
JSONとしてシリアライズされるPython辞書
</ParamField>
</Accordion>
<Tip>
ファイルBLOBを扱う際は、ファイルが正しく処理されるように、`meta` 辞書に常に `mime_type` を指定してください。例:`{"mime_type": "image/png"}`。
</Tip>
### 変数
<CodeGroup>
```python Standard Variable
from typing import Any
def create_variable_message(self, variable_name: str, variable_value: Any) -> ToolInvokeMessage:
"""
Create a named variable for workflow integration
For non-streaming output variables. If multiple instances with the
same name are created, the latest one overrides previous values.
Args:
variable_name: Name of the variable to create
variable_value: Value of the variable (any Python data type)
Returns:
ToolInvokeMessage: Message object for the tool response
"""
pass
```
```python Streaming Variable
def create_stream_variable_message(
self, variable_name: str, variable_value: str
) -> ToolInvokeMessage:
"""
Create a streaming variable with typewriter effect
When referenced in an answer node in a chatflow application,
the text will be output with a typewriter effect.
Args:
variable_name: Name of the variable to create
variable_value: String value to stream (only strings supported)
Returns:
ToolInvokeMessage: Message object for the tool response
"""
pass
```
</CodeGroup>
<Accordion title="パラメータ">
<ParamField path="variable_name" type="string" required>
作成または更新される変数の名前
</ParamField>
<ParamField path="variable_value" type="Any/string" required>
変数に割り当てる値:
- 標準変数の場合任意のPythonデータ型
- ストリーミング変数の場合:文字列データのみ
</ParamField>
</Accordion>
<Warning>
ストリーミング変数メソッド(`create_stream_variable_message`)は現在、文字列データのみをサポートしています。複雑なデータ型はタイプライター効果でストリーミングできません。
</Warning>
## カスタム出力変数
<Info>
ワークフローアプリケーションでツールの出力変数を参照するには、どの変数が出力される可能性があるかを定義する必要があります。これはツールのマニフェストで [JSON Schema](https://json-schema.org/) 形式を使用して行います。
</Info>
### 出力スキーマの定義
<CodeGroup>
```yaml Tool Manifest with Output Schema
identity:
author: example_author
name: example_tool
label:
en_US: Example Tool
zh_Hans: 示例工具
ja_JP: ツール例
pt_BR: Ferramenta de exemplo
description:
human:
en_US: A simple tool that returns a name
zh_Hans: 返回名称的简单工具
ja_JP: 名前を返す簡単なツール
pt_BR: Uma ferramenta simples que retorna um nome
llm: A simple tool that returns a name variable
output_schema:
type: object
properties:
name:
type: string
description: "The name returned by the tool"
age:
type: integer
description: "The age returned by the tool"
profile:
type: object
properties:
interests:
type: array
items:
type: string
location:
type: string
```
</CodeGroup>
<Accordion title="スキーマ構造">
<ParamField path="output_schema" type="object" required>
ツールの出力スキーマを定義するルートオブジェクト
</ParamField>
<ParamField path="type" type="string" required>
ツール出力スキーマでは "object" である必要があります
</ParamField>
<ParamField path="properties" type="object" required>
すべての可能な出力変数の辞書
</ParamField>
<ParamField path="properties.[variable_name]" type="object">
各出力変数の定義(型と説明を含む)
</ParamField>
</Accordion>
<Warning>
出力スキーマを定義しても、実装コードで `create_variable_message()` を使用して実際に変数を返す必要があります。そうしないと、ワークフローはその変数に対して `None` を受け取ります。
</Warning>
### 実装例
<CodeGroup>
```python Basic Variable Example
def run(self, inputs):
# Process inputs and generate a name
generated_name = "Alice"
# Return the name as a variable that matches the output_schema
return self.create_variable_message("name", generated_name)
```
```python Complex Structure Example
def run(self, inputs):
# Generate complex structured data
user_data = {
"name": "Bob",
"age": 30,
"profile": {
"interests": ["coding", "reading", "hiking"],
"location": "San Francisco"
}
}
# Return individual variables
self.create_variable_message("name", user_data["name"])
self.create_variable_message("age", user_data["age"])
self.create_variable_message("profile", user_data["profile"])
# Also return a text message for display
return self.create_text_message(f"User {user_data['name']} processed successfully")
```
</CodeGroup>
<Tip>
複雑なワークフローの場合、複数の出力変数を定義してすべてを返すことができます。これにより、ワークフロー設計者がツールを使用する際の柔軟性が向上します。
</Tip>
## 例
### 完全なツール実装
<CodeGroup>
```python Weather Forecast Tool
import requests
from typing import Any
class WeatherForecastTool:
def run(self, inputs: dict) -> Any:
# Get location from inputs
location = inputs.get("location", "London")
try:
# Call weather API (example only)
weather_data = self._get_weather_data(location)
# Create variables for workflow use
self.create_variable_message("temperature", weather_data["temperature"])
self.create_variable_message("conditions", weather_data["conditions"])
self.create_variable_message("forecast", weather_data["forecast"])
# Create a JSON message for data transmission
self.create_json_message(weather_data)
# Create an image message for the weather map
self.create_image_message(weather_data["map_url"])
# Return a formatted text response
return self.create_text_message(
f"Weather in {location}: {weather_data['temperature']}°C, {weather_data['conditions']}. "
f"Forecast: {weather_data['forecast']}"
)
except Exception as e:
# Handle errors gracefully
return self.create_text_message(f"Error retrieving weather data: {str(e)}")
def _get_weather_data(self, location: str) -> dict:
# Mock implementation - in a real tool, this would call a weather API
return {
"location": location,
"temperature": 22,
"conditions": "Partly Cloudy",
"forecast": "Sunny with occasional showers tomorrow",
"map_url": "https://example.com/weather-map.png"
}
```
</CodeGroup>
<Tip>
ツールを設計する際は、直接出力(ユーザーが見るもの)と変数出力(他のワークフローノードが使用できるもの)の両方を考慮してください。この分離により、ツールの使用方法に柔軟性が生まれます。
</Tip>
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/features-and-specs/plugin-types/tool.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,156 @@
---
dimensions:
type:
primary: conceptual
detail: architecture
level: beginner
standard_title: CLI
language: en
title: CLI
description: Difyプラグイン開発用コマンドラインインターフェース
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/getting-started/cli)を参照してください。</Note>
コマンドラインインターフェースCLIを使用してDifyプラグインのセットアップとパッケージ化を行います。CLIは、初期化からパッケージ化まで、プラグイン開発ワークフローを効率的に管理する方法を提供します。
このガイドでは、Difyプラグイン開発におけるCLIの使用方法について説明します。
## 前提条件
始める前に、以下がインストールされていることを確認してください:
- Pythonバージョン ≥ 3.12
- Dify CLI
- HomebrewMacユーザーの場合
## Difyプラグインプロジェクトの作成
<Tabs>
<Tab title="Mac">
```bash
brew tap langgenius/dify
brew install dify
```
</Tab>
<Tab title="Linux">
[Dify GitHubリリースページ](https://github.com/langgenius/dify-plugin-daemon/releases)から最新のDify CLIを取得してください
```bash
# Download dify-plugin-darwin-arm64
chmod +x dify-plugin-darwin-arm64
mv dify-plugin-darwin-arm64 dify
sudo mv dify /usr/local/bin/
```
</Tab>
</Tabs>
これでDify CLIのインストールが完了しました。以下のコマンドを実行してインストールを確認できます
<CodeGroup>
```bash
dify version
```
</CodeGroup>
以下のコマンドを使用して新しいDifyプラグインプロジェクトを作成できます
```bash
dify plugin init
```
プロンプトが表示されたら、必要なフィールドを入力してください:
```bash
Edit profile of the plugin
Plugin name (press Enter to next step): hello-world
Author (press Enter to next step): langgenius
Description (press Enter to next step): hello world example
Repository URL (Optional) (press Enter to next step): Repository URL (Optional)
Enable multilingual README: [✔] English is required by default
Languages to generate:
English: [✔] (required)
→ 简体中文 (Simplified Chinese): [✔]
日本語 (Japanese): [✘]
Português (Portuguese - Brazil): [✘]
Controls:
↑/↓ Navigate • Space/Tab Toggle selection • Enter Next step
```
`python`を選択してEnterキーを押し、Pythonプラグインテンプレートで続行します。
```bash
Select the type of plugin you want to create, and press `Enter` to continue
Before starting, here's some basic knowledge about Plugin types in Dify:
- Tool: Tool Providers like Google Search, Stable Diffusion, etc. Used to perform specific tasks.
- Model: Model Providers like OpenAI, Anthropic, etc. Use their models to enhance AI capabilities.
- Endpoint: Similar to Service API in Dify and Ingress in Kubernetes. Extend HTTP services as endpoints with custom logi
- Agent Strategy: Implement your own agent strategies like Function Calling, ReAct, ToT, CoT, etc.
Based on the ability you want to extend, Plugins are divided into four types: Tool, Model, Extension, and Agent Strategy
- Tool: A tool provider that can also implement endpoints. For example, building a Discord Bot requires both Sending and
- Model: Strictly for model providers, no other extensions allowed.
- Extension: For simple HTTP services that extend functionality.
- Agent Strategy: Implement custom agent logic with a focused approach.
We've provided templates to help you get started. Choose one of the options below:
-> tool
agent-strategy
llm
text-embedding
rerank
tts
speech2text
moderation
extension
```
デフォルトのdifyバージョンを入力します。空白のままにすると最新バージョンが使用されます
```bash
Edit minimal Dify version requirement, leave it blank by default
Minimal Dify version (press Enter to next step):
```
準備完了ですCLIは指定したプラグイン名で新しいディレクトリを作成し、プラグインの基本構造をセットアップします。
```bash
cd hello-world
```
## プラグインの実行
hello-worldディレクトリにいることを確認してください
```bash
cp .env.example .env
```
`.env`ファイルを編集して、APIキーやその他の設定などのプラグインの環境変数を設定します。これらの変数はDifyダッシュボードで確認できます。Dify環境にログインし、右上の「プラグイン」アイコンをクリックしてから、デバッグアイコンまたは虫のようなものをクリックします。ポップアップウィンドウで「APIキー」と「ホストアドレス」をコピーします。キーとホストアドレスの取得インターフェースを示すローカルの対応するスクリーンショットを参照してください
```bash
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=debug-plugin.dify.dev
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=********-****-****-****-************
```
以下のコマンドを使用して、プラグインをローカルで実行できます:
```bash
pip install -r requirements.txt
python -m main
```
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/getting-started/cli.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,108 @@
---
dimensions:
type:
primary: conceptual
detail: introduction
level: beginner
standard_title: Getting Started with Dify Plugin Development
language: en
title: Dify プラグイン
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/getting-started/getting-started-dify-plugin)を参照してください。</Note>
Dify プラグインは、AI アプリケーションに追加機能を提供するモジュラーコンポーネントです。外部サービス、カスタム機能、特殊なツールを Dify で構築した AI アプリケーションに統合することができます。
<Frame caption="Marketplace">
<img src="/images/marketplace.png" />
</Frame>
プラグインを通じて、AI アプリケーションは以下のことが可能になります:
- 外部 API への接続
- 様々なタイプのデータ処理
- 特殊な計算の実行
- 実世界でのアクションの実行
## プラグインの種類
<AccordionGroup cols={3}>
<Accordion
title="モデル"
icon="microchip"
href="/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider"
>
AI モデルをプラグインとしてパッケージ化して管理
<a href="/ja/develop-plugin/dev-guides-and-walkthroughs/creating-new-model-provider" className="text-primary">詳細を見る</a>
</Accordion>
<Accordion
title="ツール"
icon="toolbox"
href="/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin"
>
エージェントとワークフロー向けの特殊な機能を構築
<a href="/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin" className="text-primary">詳細を見る</a>
</Accordion>
<Accordion
title="エージェント戦略"
icon="brain"
href="/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation"
>
自律型エージェント向けのカスタム推論戦略を作成
<a href="/ja/develop-plugin/features-and-specs/advanced-development/reverse-invocation" className="text-primary">詳細を見る</a>
</Accordion>
<Accordion
title="拡張機能"
icon="puzzle-piece"
href="/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint"
>
HTTP Webhook を通じた外部サービスとの統合を実装
<a href="/ja/develop-plugin/dev-guides-and-walkthroughs/endpoint" className="text-primary">詳細を見る</a>
</Accordion>
</AccordionGroup>
## その他のリソース
<CardGroup cols={2}>
<Card
title="開発とデバッグ"
icon="code"
href="/ja/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin"
>
効率的なプラグイン開発のためのツールとテクニック
</Card>
<Card
title="公開とマーケットプレイス"
icon="shop"
href="/ja/develop-plugin/publishing/marketplace-listing/release-overview"
>
プラグインをパッケージ化して Dify コミュニティと共有
</Card>
<Card
title="API & SDK リファレンス"
icon="book-open"
href="/ja/develop-plugin/features-and-specs/plugin-types/general-specifications"
>
技術仕様とドキュメント
</Card>
<Card
title="コミュニティと貢献"
icon="users"
href="/ja/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct"
>
他の開発者とコミュニケーションを取り、エコシステムに貢献
</Card>
</CardGroup>
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/getting-started/getting-started-dify-plugin.mdx) | [問題を報告](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,49 @@
---
dimensions:
type:
primary: operational
detail: maintenance
level: beginner
todo: Developers (Contributors) should thoroughly test before releasing; debugging
should not be the user's (Dify User / Consumer) responsibility.
standard_title: Faq
language: en
title: よくある質問
description: このドキュメントでは、Difyプラグインの開発とインストールに関するよくある質問に回答します。プラグインのアップロード失敗の解決方法authorフィールドの修正やプラグインインストール時の検証例外の処理方法FORCE_VERIFYING_SIGNATURE環境変数の設定などを含みます。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/faq/faq)を参照してください。</Note>
## インストール時にプラグインのアップロードが失敗した場合はどうすればよいですか?
**エラー詳細**: `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にリスト審査されていないすべてのプラグインのインストールを許可するようになりますが、これはセキュリティリスクをもたらす可能性があります。
まずテスト/サンドボックス環境でプラグインをインストールし、安全性を確認してから本番環境にインストールすることをお勧めします。
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/faq/faq.mdx) | [問題を報告](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,317 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: beginner
standard_title: Plugin Auto Publish PR
language: ja
title: PRによるプラグインの自動公開
description: このドキュメントでは、GitHub Actionsを使用してDifyプラグインのリリースプロセスを自動化する方法について説明します。設定手順、パラメータの説明、使用方法を含み、プラグイン開発者が手動操作なしでリリースプロセスを効率化できるようサポートします。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/marketplace-listing/plugin-auto-publish-pr)を参照してください。</Note>
### 背景
他のユーザーが積極的に使用しているプラグインを更新するのは面倒な作業です。従来は、コードの修正、バージョンの更新、変更のプッシュ、ブランチの作成、ファイルのパッケージング、PRの手動送信が必要でした。この繰り返しのプロセスは開発を遅らせます。
そこで、**Plugin Auto-PR**を作成しました。これはプロセス全体を自動化するGitHub Actionsワークフローです。これにより、パッケージング、プッシュ、PRの作成を1つのアクションで行え、優れたプラグインの構築に集中できます。
### コンセプト
#### GitHub Actions
GitHub Actionsは、GitHub上の開発タスクを自動化します。
**仕組み**: トリガー(例:コードのプッシュ)が発生すると、クラウドベースの仮想マシンでワークフローが実行され、ビルドからデプロイまですべてが自動的に処理されます。
![Workflow](https://assets-docs.dify.ai/2025/04/60534de8e220f860947b32a8329a8349.png)
**制限**:
* パブリックリポジトリ: 無制限
* プライベートリポジトリ: 月2000分
#### Plugin Auto-PR
**仕組み**:
1. プラグインソースリポジトリのメインブランチにコードをプッシュするとワークフローがトリガーされます
2. ワークフローが`manifest.yaml`ファイルからプラグイン情報を読み取ります
3. プラグインを`.difypkg`ファイルとして自動的にパッケージングします
4. パッケージングされたファイルをフォークした`dify-plugins`リポジトリにプッシュします
5. 新しいブランチを作成し、変更をコミットします
6. 上流リポジトリにマージするためのPRを自動的に作成します
### 前提条件
#### リポジトリ
* 自分のプラグインソースコードリポジトリがすでにあること(例:`your-name/plugin-source`
* 自分のフォークしたプラグインリポジトリがすでにあること(例:`your-name/dify-plugins`
* フォークしたリポジトリにすでにプラグインディレクトリ構造があること:
```
dify-plugins/
└── your-author-name
└── plugin-name
```
#### 権限
このワークフローが機能するには適切な権限が必要です:
* 十分な権限を持つGitHub Personal Access Token (PAT)を作成する必要があります
* PATはフォークしたリポジトリにコードをプッシュする権限が必要です
* PATは上流リポジトリにPRを作成する権限が必要です
### パラメータと設定
#### セットアップ要件
自動公開を開始するには、2つの主要なコンポーネントが必要です:
**manifest.yamlファイル**: このファイルが自動化プロセスを駆動します:
* `name`: プラグイン名(パッケージ名とブランチ名に影響します)
* `version`: セマンティックバージョン番号(リリースごとに増加)
* `author`: GitHubユーザー名リポジトリパスを決定します
**PLUGIN\_ACTION Secret**: このシークレットをプラグインソースリポジトリに追加する必要があります:
* 値: 十分な権限を持つPersonal Access Token (PAT)である必要があります
* 権限: フォークしたリポジトリにブランチをプッシュし、上流リポジトリにPRを作成する能力
#### 自動生成されるパラメータ
セットアップが完了すると、ワークフローは以下のパラメータを自動的に処理します:
* GitHubユーザー名: `manifest.yaml`の`author`フィールドから読み取り
* 作者フォルダ名: `author`フィールドと一致
* プラグイン名: `manifest.yaml`の`name`フィールドから読み取り
* ブランチ名: `bump-{plugin-name}-plugin-{version}`
* パッケージファイル名: `{plugin-name}-{version}.difypkg`
* PRタイトルと内容: プラグイン名とバージョンに基づいて自動生成
### ステップバイステップガイド
<Steps>
<Step title="リポジトリの準備">
公式の`dify-plugins`リポジトリをフォークし、自分のプラグインソースリポジトリがあることを確認してください。
</Step>
<Step title="Secretの設定">
プラグインソースリポジトリに移動し、**Settings > Secrets and variables > Actions > New repository secret**をクリックして、GitHub Secretを作成します:
* 名前: `PLUGIN_ACTION`
* 値: ターゲットリポジトリ(`your-name/dify-plugins`への書き込み権限を持つGitHub Personal Access Token (PAT)
<img src="https://assets-docs.dify.ai/2025/04/8abd72b677dd24752910c304c76f1c26.png" alt="Create Secrets" />
</Step>
<Step title="ワークフローファイルの作成">
リポジトリに`.github/workflows/`ディレクトリを作成し、このディレクトリに`plugin-publish.yml`という名前のファイルを作成して、以下の内容をファイルにコピーしてください:
```yaml
# .github/workflows/auto-pr.yml
name: Auto Create PR on Main Push
on:
push:
branches: [ main ] # Trigger on push to main
jobs:
create_pr: # Renamed job for clarity
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Print working directory # Kept for debugging
run: |
pwd
ls -la
- name: Download CLI tool
run: |
# Create bin directory in runner temp
mkdir -p $RUNNER_TEMP/bin
cd $RUNNER_TEMP/bin
# Download CLI tool
wget https://github.com/langgenius/dify-plugin-daemon/releases/latest/download/dify-plugin-linux-amd64
chmod +x dify-plugin-linux-amd64
# Show download location and file
echo "CLI tool location:"
pwd
ls -la dify-plugin-linux-amd64
- name: Get basic info from manifest # Changed step name and content
id: get_basic_info
run: |
PLUGIN_NAME=$(grep "^name:" manifest.yaml | cut -d' ' -f2)
echo "Plugin name: $PLUGIN_NAME"
echo "plugin_name=$PLUGIN_NAME" >> $GITHUB_OUTPUT
VERSION=$(grep "^version:" manifest.yaml | cut -d' ' -f2)
echo "Plugin version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
# If the author's name is not your github username, you can change the author here
AUTHOR=$(grep "^author:" manifest.yaml | cut -d' ' -f2)
echo "Plugin author: $AUTHOR"
echo "author=$AUTHOR" >> $GITHUB_OUTPUT
- name: Package Plugin
id: package
run: |
# Use the downloaded CLI tool to package
cd $GITHUB_WORKSPACE
# Use variables for package name
PACKAGE_NAME="${{ steps.get_basic_info.outputs.plugin_name }}-${{ steps.get_basic_info.outputs.version }}.difypkg"
# Use CLI from runner temp
$RUNNER_TEMP/bin/dify-plugin-linux-amd64 plugin package . -o "$PACKAGE_NAME"
# Show packaging result
echo "Package result:"
ls -la "$PACKAGE_NAME"
echo "package_name=$PACKAGE_NAME" >> $GITHUB_OUTPUT
# Show full file path and directory structure (kept for debugging)
echo "\\nFull file path:"
pwd
echo "\\nDirectory structure:"
tree || ls -R
- name: Checkout target repo
uses: actions/checkout@v3
with:
# Use author variable for repository
repository: ${{steps.get_basic_info.outputs.author}}/dify-plugins
path: dify-plugins
token: ${{ secrets.PLUGIN_ACTION }}
fetch-depth: 1 # Fetch only the last commit to speed up checkout
persist-credentials: true # Persist credentials for subsequent git operations
- name: Prepare and create PR
run: |
# Debug info (kept)
echo "Debug: Current directory $(pwd)"
# Use variable for package name
PACKAGE_NAME="${{ steps.get_basic_info.outputs.plugin_name }}-${{ steps.get_basic_info.outputs.version }}.difypkg"
echo "Debug: Package name: $PACKAGE_NAME"
ls -la
# Move the packaged file to the target directory using variables
mkdir -p dify-plugins/${{ steps.get_basic_info.outputs.author }}/${{ steps.get_basic_info.outputs.plugin_name }}
mv "$PACKAGE_NAME" dify-plugins/${{ steps.get_basic_info.outputs.author }}/${{ steps.get_basic_info.outputs.plugin_name }}/
# Enter the target repository directory
cd dify-plugins
# Configure git
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
# Ensure we are on the latest main branch
git fetch origin main
git checkout main
git pull origin main
# Create and switch to a new branch using variables and new naming convention
BRANCH_NAME="bump-${{ steps.get_basic_info.outputs.plugin_name }}-plugin-${{ steps.get_basic_info.outputs.version }}"
git checkout -b "$BRANCH_NAME"
# Add and commit changes (using git add .)
git add .
git status # for debugging
# Use variables in commit message
git commit -m "bump ${{ steps.get_basic_info.outputs.plugin_name }} plugin to version ${{ steps.get_basic_info.outputs.version }}"
# Push to remote (use force just in case the branch existed before from a failed run)
git push -u origin "$BRANCH_NAME" --force
# Confirm branch has been pushed and wait for sync (GitHub API might need a moment)
git branch -a
echo "Waiting for branch to sync..."
sleep 10 # Wait 10 seconds for branch sync
- name: Create PR via GitHub API
env:
GH_TOKEN: ${{ secrets.PLUGIN_ACTION }} # Use the provided token for authentication
run: |
gh pr create \
--repo langgenius/dify-plugins \
--head "${{ steps.get_basic_info.outputs.author }}:${{ steps.get_basic_info.outputs.plugin_name }}-${{ steps.get_basic_info.outputs.version }}" \
--base main \
--title "bump ${{ steps.get_basic_info.outputs.plugin_name }} plugin to version ${{ steps.get_basic_info.outputs.version }}" \
--body "bump ${{ steps.get_basic_info.outputs.plugin_name }} plugin package to version ${{ steps.get_basic_info.outputs.version }}
Changes:
- Updated plugin package file" || echo "PR already exists or creation skipped." # Handle cases where PR already exists
- name: Print environment info # Kept for debugging
run: |
echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE"
echo "Current directory contents:"
ls -R
```
</Step>
<Step title="manifest.yamlの更新">
以下のフィールドが正しく設定されていることを確認してください:
```yaml
version: 0.0.x # Version number
author: your-github-username # GitHub username/Author name
name: your-plugin-name # Plugin name
```
</Step>
</Steps>
### 使用ガイド
#### 初回セットアップ
自動公開ワークフローを初めてセットアップする際は、以下の手順を完了してください:
1. 公式の`dify-plugins`リポジトリをフォークしていることを確認します
2. プラグインソースリポジトリの構造が正しいことを確認します
3. プラグインソースリポジトリに`PLUGIN_ACTION Secret`をセットアップします
4. ワークフローファイル`.github/workflows/plugin-publish.yml`を作成します
5. `manifest.yaml`ファイルの`name`と`author`フィールドが正しく設定されていることを確認します
#### その後の更新
セットアップ後に新しいバージョンを公開するには:
1. コードを修正します
2. `manifest.yaml`の`version`フィールドを更新します
![Release](https://assets-docs.dify.ai/2025/04/9eed2b9110e91e18008b399e58198f03.png)
3. すべての変更をメインブランチにプッシュします
4. GitHub Actionsがパッケージング、ブランチ作成、PR送信を完了するのを待ちます
### 結果
プラグインソースリポジトリのメインブランチにコードをプッシュすると、GitHub Actionsが自動的に公開プロセスを実行します:
* プラグインを`{plugin-name}-{version}.difypkg`形式でパッケージング
* パッケージングされたファイルをターゲットリポジトリにプッシュ
* フォークリポジトリにマージするためのPRを作成
![Outcome](https://assets-docs.dify.ai/2025/04/60d5de910c6ce2482c67ddec3320311f.png)
### サンプルリポジトリ
設定とベストプラクティスを理解するには、[サンプルリポジトリ](https://github.com/Yevanchen/exa-in-dify)を参照してください。
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[このページを編集](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/marketplace-listing/plugin-auto-publish-pr.mdx) | [問題を報告](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,75 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: intermediate
standard_title: Release by File
language: en
title: ローカルファイルとしてパッケージ化して共有
description: このドキュメントでは、Difyプラグインプロジェクトをローカルファイルとしてパッケージ化し、他のユーザーと共有する方法について詳細な手順を提供します。プラグインのパッケージ化前の準備作業、Difyプラグイン開発ツールを使用したパッケージ化コマンドの実行方法、生成された.difypkgファイルのインストール方法、および他のユーザーとプラグインファイルを共有する方法について説明します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/marketplace-listing/release-by-file)を参照してください。</Note>
プラグイン開発が完了したら、プラグインプロジェクトをローカルファイルとしてパッケージ化し、他のユーザーと共有できます。プラグインファイルを入手した後、Dify Workspaceにインストールできます。まだプラグインを開発していない場合は、[プラグイン開発Hello Worldガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)を参照してください。
* **特徴**
* オンラインプラットフォームに依存せず、**迅速で柔軟**なプラグイン共有方法。
* **プライベートプラグイン**や**内部テスト**に適しています。
* **公開プロセス**
* プラグインプロジェクトをローカルファイルとしてパッケージ化。
* Difyプラグインページでファイルをアップロードしてプラグインをインストール。
この記事では、プラグインプロジェクトをローカルファイルとしてパッケージ化する方法と、ローカルファイルを使用してプラグインをインストールする方法を紹介します。
### 前提条件
* **Difyプラグイン開発ツール**、詳細な手順については[開発ツールの初期化](/ja/develop-plugin/getting-started/cli)を参照してください。
設定後、ターミナルで`dify version`コマンドを入力し、バージョン情報が出力されることを確認して、必要な開発ツールがインストールされていることを確認してください。
### プラグインのパッケージ化
> プラグインをパッケージ化する前に、プラグインの`manifest.yaml`ファイルと`/provider`パス下の`.yaml`ファイルの`author`フィールドがGitHub IDと一致していることを確認してください。マニフェストファイルの詳細については、[一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications)を参照してください。
プラグインプロジェクトの開発が完了したら、[リモートデバッグテスト](/ja/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin)が完了していることを確認してください。プラグインプロジェクトの上位ディレクトリに移動し、以下のプラグインパッケージ化コマンドを実行します:
```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リポジトリに公開](/ja/develop-plugin/publishing/marketplace-listing/release-to-individual-github-repo) - GitHubを通じてプラグインを共有
2. [Dify Marketplaceに公開](/ja/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace) - 公式マーケットプレイスにプラグインを公開
## 関連リソース
- [プラグインの公開](/ja/develop-plugin/publishing/marketplace-listing/release-overview) - さまざまな公開方法について学ぶ
- [開発ツールの初期化](/ja/develop-plugin/getting-started/cli) - プラグイン開発環境の設定
- [プラグインのリモートデバッグ](/ja/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin) - プラグインのデバッグ方法を学ぶ
- [一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - プラグインメタデータの定義
- [プラグイン開発Hello Worldガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin) - ゼロからプラグインを開発
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/marketplace-listing/release-by-file.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,96 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: beginner
standard_title: Release Overview
language: en
title: プラグインの公開
description: このドキュメントでは、Difyプラグインを公開する3つの方法公式マーケットプレイス、オープンソースGitHubリポジトリ、ローカルプラグインファイルパッケージを紹介します。各方法の特徴、公開プロセス、適用シナリオを詳しく説明し、さまざまな開発者のニーズに対応するための具体的な公開推奨事項を提供します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/marketplace-listing/release-overview)を参照してください。</Note>
### 公開方法
さまざまな開発者の公開ニーズに対応するため、Difyは以下の3つのプラグイン公開方法を提供しています。公開する前に、プラグインの開発とテストが完了していること、および[プラグイン開発の基本概念](/ja/develop-plugin/getting-started/getting-started-dify-plugin)と[プラグイン開発者ガイドライン](/ja/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct)を読んでいることを確認してください。
#### **1. マーケットプレイス**
**概要**: Difyが提供する公式プラグインマーケットプレイスで、ユーザーはさまざまなプラグインを閲覧、検索し、ワンクリックでインストールできます。
**特徴**:
* プラグインは公開前に審査され、**安全で信頼性が高い**ことが保証されます。
* 個人またはチームの**ワークスペース**に直接インストールできます。
**公開プロセス**:
* プラグインプロジェクトを**Difyマーケットプレイス**の[コードリポジトリ](https://github.com/langgenius/dify-plugins)に提出します。
* 公式審査後、プラグインはマーケットプレイスで公開され、他のユーザーがインストールして使用できるようになります。
詳細な手順については、以下を参照してください:
[Difyマーケットプレイスへの公開](/ja/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace)
#### 2. **GitHubリポジトリ**
**概要**: **GitHub**でプラグインをオープンソース化またはホストし、他のユーザーが閲覧、ダウンロード、インストールできるようにします。
**特徴**:
* **バージョン管理**と**オープンソース共有**に便利です。
* ユーザーはプラグインリンクから直接インストールでき、プラットフォームの審査は不要です。
**公開プロセス**:
* プラグインコードをGitHubリポジトリにプッシュします。
* リポジトリリンクを共有し、ユーザーはリンクを通じてプラグインを**Difyワークスペース**に統合できます。
詳細な手順については、以下を参照してください:
[個人のGitHubリポジトリへの公開](/ja/develop-plugin/publishing/marketplace-listing/release-to-individual-github-repo)
#### 3. プラグインファイルパッケージ(ローカルインストール)
**概要**: プラグインをローカルファイル(`.difypkg`形式など)としてパッケージ化し、他のユーザーがインストールできるように共有します。
**特徴**:
* オンラインプラットフォームに依存せず、**迅速で柔軟な**プラグイン共有方法です。
* **プライベートプラグイン**や**内部テスト**に適しています。
**公開プロセス**:
* プラグインプロジェクトをローカルファイルとしてパッケージ化します。
* Difyプラグインページで**プラグインをアップロード**をクリックし、ローカルファイルを選択してプラグインをインストールします。
プラグインプロジェクトをローカルファイルとしてパッケージ化し、他のユーザーと共有できます。プラグインページでファイルをアップロードすると、Difyワークスペースにプラグインをインストールできます。
詳細な手順については、以下を参照してください:
[ローカルファイルとしてパッケージ化して共有](/ja/develop-plugin/publishing/marketplace-listing/release-by-file)
### **公開の推奨事項**
* **プラグインを宣伝したい場合** → **マーケットプレイスの使用を推奨**、公式審査によりプラグインの品質を確保し、露出を増やします。
* **オープンソース共有プロジェクト** → **GitHubの使用を推奨**、バージョン管理とコミュニティコラボレーションに便利です。
* **迅速な配布または内部テスト** → **プラグインファイルの使用を推奨**、シンプルで効率的なインストールと共有方法です。
## 関連リソース
- [プラグイン開発の基本概念](/ja/develop-plugin/getting-started/getting-started-dify-plugin) - Difyプラグイン開発を包括的に理解する
- [プラグイン開発者ガイドライン](/ja/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct) - プラグイン提出の基準を理解する
- [プラグインプライバシーデータ保護ガイド](/ja/develop-plugin/publishing/standards/privacy-protection-guidelines) - プライバシーポリシー作成の要件を理解する
- [一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - プラグインマニフェストファイルの設定を理解する
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/marketplace-listing/release-overview.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,113 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: intermediate
standard_title: Release to Dify Marketplace
language: en
title: Dify Marketplaceへの公開
description: このガイドでは、Dify Marketplaceへのプラグイン公開の完全なプロセスについて、PRの提出、レビュープロセス、リリース後のメンテナンス、その他の重要なステップと考慮事項を含めて詳細に説明します。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace)を参照してください。</Note>
Dify Marketplaceは、パートナーやコミュニティ開発者からのプラグイン提出を歓迎します。皆様の貢献は、Difyプラグインの可能性をさらに豊かにします。このガイドでは、明確な公開プロセスとベストプラクティスの推奨事項を提供し、プラグインがスムーズに公開され、コミュニティに価値をもたらすことを支援します。まだプラグインを開発していない場合は、[プラグイン開発Hello Worldガイド](/ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin)を参照してください。
以下の手順に従って、プラグインのPull RequestPRを[GitHubリポジトリ](https://github.com/langgenius/dify-plugins)に提出し、レビューを受けてください。承認後、プラグインはDify Marketplaceに正式に公開されます。
### プラグイン公開プロセス
Dify Marketplaceへのプラグイン公開には、以下のステップが含まれます
1. [プラグイン開発者ガイドライン](/ja/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct)に従って、プラグインの開発とテストを完了する;
2. [プラグインプライバシーデータ保護ガイド](/ja/develop-plugin/publishing/standards/privacy-protection-guidelines)に従ってプラグインのプライバシーポリシーを作成し、プライバシーポリシーのファイルパスまたはURLをプラグインの[一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications)に含める;
3. プラグインのパッケージングを完了する;
4. [Dify Plugins](https://github.com/langgenius/dify-plugins)コードリポジトリをフォークする;
5. リポジトリに個人または組織のフォルダを作成し、パッケージ化された`.difypkg`ファイルをフォルダにアップロードする;
6. GitHubのPRテンプレート形式に従ってPull RequestPRを提出し、レビューを待つ
7. レビューが承認されると、プラグインコードがMainブランチにマージされ、プラグインは自動的に[Dify Marketplace](https://marketplace.dify.ai/)に公開されます。
プラグインの提出、レビュー、公開のフローチャート:
![プラグインアップロードのプロセス](https://assets-docs.dify.ai/2025/01/05df333acfaf662e99316432db23ba9f.png)
> **注意**上記の図のContributor Agreement貢献者同意書は、[プラグイン開発者ガイドライン](/ja/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct)を指します。
***
### Pull RequestPRレビュー中
レビュアーの質問やフィードバックに積極的に対応してください:
* **14日以内**に解決されないPRコメントは、stale古いとしてマークされます再開可能
* **30日以内**に解決されないPRコメントは、クローズされます再開不可、新しいPRを作成する必要があります
***
### **Pull RequestPR承認後**
**1. 継続的なメンテナンス**
* ユーザーから報告された問題や機能リクエストに対応する。
* 重大なAPI変更が発生した場合はプラグインを移行する
* Difyは事前に変更通知と移行手順を公開します。
* Difyエンジニアが移行サポートを提供できます。
**2. Marketplaceパブリックベータテスト段階での制限**
* 既存のプラグインに破壊的変更を導入しないでください。
***
### レビュープロセス
**1. レビュー順序**
* PRは**先着順**で処理されます。レビューは1週間以内に開始されます。遅延がある場合、レビュアーはコメントを通じてPR作成者に通知します。
**2. レビューの焦点**
* プラグイン名、説明、セットアップ手順が明確で説明的かどうかを確認する。
* プラグインの[一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications)が形式基準を満たし、有効な作成者連絡先情報が含まれているかを確認する。
**3. プラグインの機能と関連性**
* [プラグイン開発ガイド](/ja/develop-plugin/getting-started/getting-started-dify-plugin)に従ってプラグインをテストする。
* プラグインがDifyエコシステムで合理的な目的を持っていることを確認する。
[Dify.AI](https://dify.ai/)は、プラグイン提出を承認または拒否する権利を留保します。
***
### よくある質問
1. **プラグインがユニークかどうかをどのように判断しますか?**
多言語バージョンのみを追加するGoogle検索プラグインは、既存プラグインの最適化と見なすべきです。ただし、プラグインが重要な機能改善最適化されたバッチ処理やエラーハンドリングなどを実装している場合は、新しいプラグインとして提出できます。
2. **PRがstaleまたはクローズとしてマークされた場合はどうすればよいですか**
staleとマークされたPRは、フィードバックに対応した後に再開できます。クローズされたPR30日以上は、新しいPRを作成する必要があります。
3. **ベータテスト段階中にプラグインを更新できますか?**
はい、ただし破壊的変更は避けるべきです。
## 関連リソース
- [プラグインの公開](/ja/develop-plugin/publishing/marketplace-listing/release-overview) - さまざまな公開方法について学ぶ
- [プラグイン開発者ガイドライン](/ja/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct) - プラグイン提出基準
- [プラグインプライバシーデータ保護ガイド](/ja/develop-plugin/publishing/standards/privacy-protection-guidelines) - プライバシーポリシー作成要件
- [ローカルファイルとしてパッケージ化して共有](/ja/develop-plugin/publishing/marketplace-listing/release-by-file) - プラグインのパッケージング方法
- [一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - プラグインメタデータの定義
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,92 @@
---
dimensions:
type:
primary: operational
detail: deployment
level: intermediate
standard_title: Release to Individual GitHub Repo
language: en
title: 個人GitHubリポジトリへの公開
description: このドキュメントでは、Difyプラグインを個人のGitHubリポジトリに公開する方法について、準備作業、ローカルプラグインリポジトリの初期化、リモートリポジトリへの接続、プラグインファイルのアップロード、プラグインコードのパッケージング、およびGitHub経由でのプラグインインストールの完全なプロセスを含む詳細な手順を提供します。この方法により、開発者は自分のプラグインコードと更新を完全に管理できます。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/marketplace-listing/release-to-individual-github-repo)を参照してください。</Note>
### 公開方法
開発者のさまざまな公開ニーズに対応するため、Difyは3つのプラグイン公開方法を提供しています
#### **1. マーケットプレイス**
**概要**: Dify公式プラグインマーケットプレイスでは、ユーザーがさまざまなプラグインを閲覧、検索し、ワンクリックでインストールできます。
**特徴**:
* プラグインは審査を通過した後に利用可能になり、**信頼性**と**高品質**が保証されます。
* 個人またはチームの**ワークスペース**に直接インストールできます。
**公開プロセス**:
* プラグインプロジェクトを**Dify Marketplace**の[コードリポジトリ](https://github.com/langgenius/dify-plugins)に提出します。
* 公式審査の後、プラグインはマーケットプレイスで公開され、他のユーザーがインストールして使用できるようになります。
詳細な手順については、以下を参照してください:
<Card title="Dify Marketplaceへの公開" icon="link" href="/en/plugins/publish-plugins/publish-to-dify-marketplace">
</Card>
#### 2. **GitHubリポジトリ**
**概要**: プラグインを**GitHub**でオープンソース化またはホストすることで、他のユーザーが簡単に閲覧、ダウンロード、インストールできます。
**特徴**:
* **バージョン管理**と**オープンソース共有**に便利です。
* ユーザーはプラットフォームの審査を経ずに、リンクから直接プラグインをインストールできます。
**公開プロセス**:
* プラグインコードをGitHubリポジトリにプッシュします。
* リポジトリリンクを共有し、ユーザーはリンクを通じてプラグインを**Difyワークスペース**に統合できます。
詳細な手順については、以下を参照してください:
<Card title="個人GitHubリポジトリでのプラグイン公開" icon="link" href="/en/plugins/publish-plugins/publish-plugin-on-personal-github-repo">
</Card>
#### プラグインファイル(ローカルインストール)
**概要**: プラグインをローカルファイル(例:`.difypkg`形式)としてパッケージ化し、他のユーザーがインストールできるように共有します。
**特徴**:
* オンラインプラットフォームに依存せず、**迅速かつ柔軟**にプラグインを共有できます。
* **プライベートプラグイン**や**内部テスト**に適しています。
**公開プロセス**:
* プラグインプロジェクトをローカルファイルとしてパッケージ化します。
* Difyプラグインページで**プラグインをアップロード**をクリックし、ローカルファイルを選択してプラグインをインストールします。
プラグインプロジェクトをローカルファイルとしてパッケージ化し、他のユーザーと共有できます。プラグインページでファイルをアップロードすると、プラグインをDifyワークスペースにインストールできます。
詳細な手順については、以下を参照してください:
<Card title="プラグインファイルのパッケージ化と公開" icon="link" href="/en/plugins/publish-plugins/package-plugin-file-and-publish">
</Card>
### **公開に関する推奨事項**
* **プラグインを宣伝したい場合** → **マーケットプレイスの使用を推奨**、公式審査によりプラグインの品質を確保し、露出を増やせます。
* **オープンソース共有プロジェクト** → **GitHubの使用を推奨**、バージョン管理とコミュニティコラボレーションに便利です。
* **迅速な配布または内部テスト** → **プラグインファイルの使用を推奨**、シンプルで効率的なインストールと共有が可能です。
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/marketplace-listing/release-to-individual-github-repo.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,173 @@
---
dimensions:
type:
primary: operational
detail: setup
level: intermediate
standard_title: Contributor Covenant Code of Conduct
language: en
title: プラグイン開発ガイドライン
description: Dify Marketplaceのすべてのプラグインの品質を確保し、Dify Marketplaceユーザーに一貫した高品質な体験を提供するため、プラグインを審査に提出する際には、これらのプラグイン開発ガイドラインに記載されているすべての要件を遵守する必要があります。プラグインを提出することにより、**以下のすべての条項を読み、理解し、遵守することに同意したものとみなされます**。これらのガイドラインに従うことで、プラグインの審査がより迅速に行われます。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct)を参照してください。</Note>
## 1. プラグインの価値と独自性
- **生成AIに焦点を当てる**: プラグインのコア機能が生成AI領域に焦点を当て、Difyユーザーに明確で重要な価値を提供することを確認してください。これには以下が含まれます
- 新しいモデル、ツール、またはサービスの統合。
- AIアプリケーションを強化するための独自のデータソースまたは処理機能の提供。
- Difyプラットフォームでのワークフローの簡素化または自動化。
- AIアプリケーション開発のための革新的なサポート機能の提供。
- **機能の重複を避ける**: 提出されるプラグインは、Marketplace内の既存のプラグインと重複または類似しては**なりません**。公開される各プラグインは、ユーザーに最高の体験を提供するために、独自で独立したものでなければなりません。
- **意味のある更新**: プラグインの更新では、現在のバージョンにはない**新しい機能やサービス**が導入されていることを確認してください。
- **PRの提出に関するアドバイス**: プルリクエストには、新しいプラグインが必要な理由を明確にする簡単な説明を含めることを**推奨**します。
## 2. プラグイン機能チェックリスト
- **ユニークな名前**: 事前にプラグインディレクトリを検索して、プラグイン名がユニークであることを確認してください。
- **ブランドの整合性**: プラグイン名はプラグインのブランディングと一致する必要があります。
- **機能の検証**: 提出前にプラグインを徹底的にテストし、意図したとおりに動作することを確認してください。詳細については、[プラグインのリモートデバッグ](/ja/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin)を参照してください。プラグインは本番環境に対応している必要があります。
- **README要件**:
- セットアップ手順と使用ガイダンス。
- プラグインに接続するために必要なコード、API、認証情報、または情報。
- 無関係なコンテンツやリンクを含めては**なりません**。
- 誇大な宣伝文句や検証不可能な主張を使用しては**なりません**。
- いかなる種類の広告も含めては**なりません**(自己宣伝やディスプレイ広告を含む)。
- 誤解を招く、攻撃的な、または名誉毀損的なコンテンツを含めては**なりません**。
- スクリーンショットに実際のユーザー名やデータを公開しては**なりません**。
- 404ページやエラーを返すページへのリンクを含めては**なりません**。
- 過度なスペルミスや句読点の誤りを避けてください。
- **ユーザーデータの使用**: 収集したデータは、サービスへの接続とプラグイン機能の改善のためにのみ使用してください。
- **エラーの明確さ**: 必須フィールドをマークし、ユーザーが問題を理解するのに役立つ明確なエラーメッセージを提供してください。
- **認証設定**: 認証が必要な場合は、完全な設定手順を含めてください—省略しないでください。
- **プライバシーポリシー**: [プライバシーガイドライン](/ja/develop-plugin/publishing/standards/privacy-protection-guidelines)に従って、プライバシーポリシードキュメントまたはオンラインURLを準備してください。
- **パフォーマンス**: プラグインは効率的に動作する必要があり、Difyやユーザーシステムのパフォーマンスを低下させてはなりません。
- **認証情報のセキュリティ**: APIキーやその他の認証情報は、安全に保存および送信する必要があります。ハードコーディングしたり、権限のない第三者に公開したりしないでください。
## 3. 言語要件
- **英語を主要言語とする**: Dify Marketplaceはグローバルなユーザーにサービスを提供しているため、すべてのユーザー向けテキストプラグイン名、説明、フィールド名、ラベル、ヘルプテキスト、エラーメッセージの**主要言語は英語**でなければなりません。
- **多言語サポートを推奨**: 複数言語のサポートを推奨します。
## 4. 禁止および制限されるプラグイン
- **禁止: 誤解を招くまたは悪意のある行為**
プラグインはユーザーを誤解させてはなりません。スパム、フィッシング、または迷惑メッセージの送信を目的としたプラグインを作成しないでください。審査プロセスを欺こうとしたり、ユーザーデータを盗んだり、ユーザーになりすましたりする試みは、削除および将来の提出禁止につながる可能性があります。
- **禁止: 攻撃的なコンテンツ**
プラグインには、暴力的なコンテンツ、ヘイトスピーチ、差別、またはグローバルな文化、宗教、ユーザーに対する不敬を含めてはなりません。
- **禁止: 金融取引**
プラグインは、金融取引、資産移転、または決済処理を促進してはなりません。これには、ブロックチェーン/暗号アプリケーションにおけるトークンまたは資産の所有権移転が含まれます。
- **制限: 頻繁な欠陥を持つプラグイン**
重大なバグを避けるために、プラグインを徹底的にテストしてください。欠陥のある提出を繰り返すと、遅延やペナルティにつながる可能性があります。
- **制限: 不必要なプラグイン分割**
各プラグインが明確にスタンドアロンの製品またはサービスでない限り、同じAPIと認証を共有する機能のために複数のプラグインを作成しないでください。機能を1つの高レベルプラグインに統合することを推奨します。
- **制限: 重複提出**
本質的に同一のプラグインを繰り返し提出することは避けてください。そうすると、審査が遅れたり、拒否されたりする可能性があります。
## 5. プラグインの収益化
- **Dify Marketplaceは現在、**無料**のプラグインのみをサポートしています。
- **将来のポリシー**: 収益化と価格モデルに関するポリシーは、将来発表される予定です。
## 6. 商標と知的財産
- **許可が必要**: 提出するロゴや商標を使用する権利があることを確認してください。
- **検証権**: サードパーティのロゴが使用されている場合—特に明らかに有名なブランドに属している場合—許可があることを証明するよう求める場合があります。
- **違反の結果**: 無許可の使用が発見された場合、Difyは変更を求めるか、プラグインを削除する権利を留保します。権利者からの苦情も削除につながる可能性があります。
- **Difyロゴの使用禁止**: Dify自体のロゴを使用することはできません。
- **画像の基準**: 低品質、歪んだ、またはトリミングが不適切な画像を提出しないでください。審査チームは交換を求める場合があります。
- **アイコンの制限**: アイコンには、誤解を招く、攻撃的な、または悪意のあるビジュアルを含めてはなりません。
## 7. プラグインの更新とバージョン管理
- **責任ある更新**: 説明または外部チャネルGitHub Release Notesを通じて、破壊的な変更を明確に伝えてください。
- **メンテナンスの推奨**: バグの修正、Difyプラットフォームの変更への対応、またはサードパーティサービスからの更新への対応—特にセキュリティに関して—のために定期的に更新してください。
- **廃止通知**: プラグインを廃止する場合は、事前にユーザーに通知し(例:プラグインの説明にタイムラインと計画を記載)、利用可能な場合は代替案を提案してください。
## 8. プラグインのメンテナンスとサポート
- **オーナーの責任**: プラグインオーナーは、技術サポートとメンテナンスに責任を負います。
- **サポートチャネルが必要**: オーナーは、審査および公開中のフィードバックのために、**少なくとも1つ**のサポートチャネルGitHubリポジトリまたはメールを提供する必要があります。
- **メンテナンスされていないプラグインの処理**: プラグインにメンテナンスがなく、オーナーが合理的な通知後も応答しない場合、Difyは以下を行う可能性があります
- 「メンテナンス不足」または「潜在的リスク」タグを追加する。
- 新規インストールを制限する。
- 最終的にプラグインを非公開にする。
## 9. プライバシーとデータコンプライアンス
- **開示が必要**: プラグインがユーザーの個人データを収集するかどうかを**宣言する必要があります**。[プライバシーガイドライン](/ja/develop-plugin/publishing/standards/privacy-protection-guidelines)を参照してください。
- **シンプルなデータリスト**: データを収集する場合は、種類を簡潔にリストしてくださいユーザー名、メール、デバイスID、位置情報。網羅的な詳細は必要ありません。
- **プライバシーポリシー**: 以下を記載したプライバシーポリシーリンクを**提供する必要があります**
- どのような情報が収集されるか。
- どのように使用されるか。
- 第三者と何が共有されるか(該当する場合は、そのプライバシーリンクも含む)。
- **審査の焦点**:
- **形式チェック**: 収集するデータを宣言していることを確認します。
- **機密データスキャン**: 機密データ(例:健康、金融、子供の情報)を収集するプラグインには追加の精査が必要です。
- **悪意のある行為のスキャン**: プラグインは、同意なしにユーザーデータを収集またはアップロードしてはなりません。
---
## 10. 審査と裁量
- **拒否/削除の権利**: 要件、プライバシー基準、または関連ポリシーが満たされていない場合、Difyはプラグインを拒否または削除する可能性があります。これには、審査プロセスの悪用やデータの誤用が含まれます。
- **適時な審査**: Dify審査チームは、ボリュームと複雑さに応じて、妥当な時間内にプラグインを審査することを目指します。
- **コミュニケーション**: 提供されたサポートチャネルを通じて連絡する場合があります—アクティブであることを確認してください。
## 関連リソース
- [プラグイン開発の基本概念](/ja/develop-plugin/getting-started/getting-started-dify-plugin) - プラグイン開発の基本を学ぶ
- [プラグインの公開](/ja/develop-plugin/publishing/marketplace-listing/release-overview) - プラグイン公開プロセスの概要
- [プラグインプライバシーデータ保護ガイド](/ja/develop-plugin/publishing/standards/privacy-protection-guidelines) - プライバシーポリシー作成ガイド
- [Dify Marketplaceへの公開](/ja/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace) - 公式マーケットプレイスでプラグインを公開
- [プラグインのリモートデバッグ](/ja/develop-plugin/features-and-specs/plugin-types/remote-debug-a-plugin) - プラグインデバッグガイド
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,102 @@
---
dimensions:
type:
primary: operational
detail: setup
level: intermediate
standard_title: Privacy Protection Guidelines
language: en
title: プラグインプライバシーポリシーガイドライン
description: このドキュメントは、開発者がDify Marketplaceにプラグインを提出する際のプライバシーポリシーの書き方に関するガイドラインを説明します。収集する個人データの種類直接識別情報、間接識別情報、組み合わせ情報の特定とリストアップ方法、プラグインプライバシーポリシーの記入方法、Manifestファイルへのプライバシーポリシー声明の含め方、および関連するよくある質問への回答が含まれています。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/standards/privacy-protection-guidelines)を参照してください。</Note>
プラグインをDify Marketplaceに提出する際は、ユーザーデータの取り扱い方法について透明性を持つ必要があります。以下のガイドラインは、プラグインのプライバシー関連の質問とユーザーデータ処理への対応方法に焦点を当てています。
プライバシーポリシーは以下のポイントを中心に作成してください:
**プラグインはユーザーの個人データを収集・使用しますか?** 収集する場合は、収集するデータの種類をリストアップしてください。
> 「個人データ」とは、特定の個人を識別できる情報を指します。単独で、または他のデータと組み合わせることで、特定の個人を特定、連絡、またはターゲットにするために使用される情報です。
#### 1. 収集するデータの種類をリストアップする
**タイプA** **直接識別子**
* 氏名(例:フルネーム、名、姓)
* メールアドレス
* 電話番号
* 自宅住所またはその他の物理的住所
* 政府発行の識別番号(例:社会保障番号、パスポート番号、運転免許証番号)
**タイプB**: **間接識別子**
* デバイス識別子IMEI、MACアドレス、デバイスID
* IPアドレス
* 位置データGPS座標、市区町村、地域
* オンライン識別子クッキー、広告ID
* ユーザー名
* プロフィール写真
* 生体データ(例:指紋、顔認識データ)
* ウェブ閲覧履歴
* 購入履歴
* 健康情報
* 財務情報
**タイプC: 他のデータと組み合わせて個人を識別できるデータ:**
* 年齢
* 性別
* 職業
* 興味・関心
プラグインが個人情報を収集しない場合でも、プラグイン内でのサードパーティサービスの使用がデータ収集や処理を伴う可能性があることを確認する必要があります。プラグイン開発者として、サードパーティサービスによって実行されるものを含め、プラグインに関連するすべてのデータ収集活動を開示する責任があります。したがって、サードパーティサービスのプライバシーポリシーを十分に読み、プラグインによって収集されるデータが提出時に申告されていることを確認してください。
例えば、開発中のプラグインがSlackサービスを使用する場合は、プラグインのプライバシーポリシー声明で[Slackのプライバシーポリシー](https://slack.com/trust/privacy/privacy-policy)を参照し、データ収集の慣行を明確に開示してください。
#### **2. プラグインの最新のプライバシーポリシーを提出する**
**プライバシーポリシー**には以下を含める必要があります:
* 収集するデータの種類
* 収集したデータの使用方法
* データがサードパーティと共有されるかどうか、共有される場合はそのサードパーティを特定し、そのプライバシーポリシーへのリンクを提供する
* プライバシーポリシーの書き方がわからない場合は、Difyチームが発行したプラグインのプライバシーポリシーを参考にすることもできます。
#### 3. プラグインManifestファイル内にプライバシーポリシー声明を導入する
特定のフィールドの記入に関する詳細な手順については、[一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications)ドキュメントを参照してください。
**よくある質問**
1. **ユーザーの個人データに関する「収集と使用」とはどういう意味ですか?プラグインで個人データが収集・使用される一般的な例はありますか?**
ユーザーデータの「収集と使用」とは、一般的にユーザーデータの収集、送信、使用、または共有を指します。製品が個人データまたは機密ユーザーデータを処理する一般的な例には以下が含まれます:
* 個人を特定できる情報を収集するフォームの使用
* サードパーティ認証サービスを使用する場合でも、ログイン機能の実装
* 個人を特定できる情報を含む可能性のある入力やリソースに関する情報の収集
* ユーザーの行動、インタラクション、使用パターンを追跡するアナリティクスの実装
* メッセージ、チャットログ、メールアドレスなどの通信データの保存
* 接続されたソーシャルメディアアカウントからのユーザープロフィールやデータへのアクセス
* 活動レベル、心拍数、医療情報などの健康・フィットネスデータの収集
* 検索クエリの保存やブラウジング行動の追跡
* 銀行口座情報、信用スコア、取引履歴などの財務情報の処理
## 関連リソース
- [公開の概要](/ja/develop-plugin/publishing/marketplace-listing/release-overview) - プラグイン公開プロセスを理解する
- [Dify Marketplaceへの公開](/ja/develop-plugin/publishing/marketplace-listing/release-to-dify-marketplace) - 公式マーケットプレイスへのプラグイン提出方法を学ぶ
- [プラグイン開発者ガイドライン](/ja/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct) - プラグイン提出ガイドラインを理解する
- [一般仕様](/ja/develop-plugin/features-and-specs/plugin-types/general-specifications) - プラグインメタデータ設定
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/standards/privacy-protection-guidelines.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)

View File

@@ -0,0 +1,120 @@
---
dimensions:
type:
primary: operational
detail: setup
level: intermediate
standard_title: Third-Party Signature Verification
language: ja
title: サードパーティ署名検証用のプラグイン署名
description: このドキュメントでは、Dify Community Editionでサードパーティ署名検証機能を有効化して使用する方法について説明します。キーペアの生成、プラグインの署名と検証、環境設定の手順を含み、管理者がDify Marketplaceで入手できないプラグインを安全にインストールできるようにします。
---
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/publishing/standards/third-party-signature-verification)を参照してください。</Note>
---
title:
---
<Warning>この機能はDify Community Editionでのみ利用可能です。サードパーティ署名検証は現在Dify Cloud Editionではサポートされていません。</Warning>
サードパーティ署名検証により、Dify管理者は署名検証を完全に無効化することなく、Dify Marketplaceに掲載されていないプラグインのインストールを安全に承認できます。これは例えば以下のシナリオをサポートします
* Dify管理者は、開発者から送信されたプラグインを承認後、署名を追加できます。
* プラグイン開発者は、自分のプラグインに署名を追加し、署名検証を無効化できないDify管理者向けに公開鍵と一緒に公開できます。
Dify管理者とプラグイン開発者の両方が、事前に生成されたキーペアを使用してプラグインに署名を追加できます。さらに、管理者はプラグインのインストール時に特定の公開鍵を使用した署名検証を強制するようにDifyを設定できます。
## 署名と検証用のキーペア生成
プラグインの署名を追加および検証するための新しいキーペアを以下のコマンドで生成します:
```bash
dify signature generate -f your_key_pair
```
このコマンドを実行すると、現在のディレクトリに2つのファイルが生成されます
* **秘密鍵**: `your_key_pair.private.pem`
* **公開鍵**: `your_key_pair.public.pem`
秘密鍵はプラグインの署名に使用し、公開鍵はプラグインの署名検証に使用します。
<Warning>秘密鍵は安全に保管してください。漏洩した場合、攻撃者が任意のプラグインに有効な署名を追加でき、Difyのセキュリティが侵害される可能性があります。</Warning>
## プラグインへの署名追加と検証
以下のコマンドを実行してプラグインに署名を追加します。**署名するプラグインファイル**と**秘密鍵**を指定する必要があることに注意してください:
```bash
dify signature sign your_plugin_project.difypkg -p your_key_pair.private.pem
```
コマンドを実行すると、同じディレクトリに元のファイル名に`signed`が追加された新しいプラグインファイルが生成されます:`your_plugin_project.signed.difypkg`
このコマンドを使用して、プラグインが正しく署名されていることを検証できます。ここでは、**署名済みプラグインファイル**と**公開鍵**を指定する必要があります:
```bash
dify signature verify your_plugin_project.signed.difypkg -p your_key_pair.public.pem
```
<Info>公開鍵引数を省略した場合、検証にはDify Marketplace公開鍵が使用されます。その場合、Dify Marketplaceからダウンロードされていないプラグインファイルでは署名検証が失敗します。</Info>
## サードパーティ署名検証の有効化
Dify管理者は、プラグインをインストールする前に、事前承認された公開鍵を使用した署名検証を強制できます。
### 公開鍵の配置
署名に使用した秘密鍵に対応する**公開鍵**を、プラグインデーモンがアクセスできる場所に配置します。
例えば、`docker/volumes/plugin_daemon`の下に`public_keys`ディレクトリを作成し、公開鍵ファイルをそこにコピーします:
```bash
mkdir docker/volumes/plugin_daemon/public_keys
cp your_key_pair.public.pem docker/volumes/plugin_daemon/public_keys
```
### 環境変数の設定
`plugin_daemon`コンテナで、以下の環境変数を設定します:
* `THIRD_PARTY_SIGNATURE_VERIFICATION_ENABLED`
* サードパーティ署名検証を有効にします。
* 機能を有効にするには`true`に設定します。
* `THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS`
* 署名検証に使用する公開鍵ファイルのパスを指定します。
* カンマで区切って複数の公開鍵ファイルをリストできます。
以下は、これらの変数を設定するDocker Composeオーバーライドファイル`docker-compose.override.yaml`)の例です:
```yaml
services:
plugin_daemon:
environment:
FORCE_VERIFYING_SIGNATURE: true
THIRD_PARTY_SIGNATURE_VERIFICATION_ENABLED: true
THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS: /app/storage/public_keys/your_key_pair.public.pem
```
<Info>`docker/volumes/plugin_daemon`は`plugin_daemon`コンテナ内の`/app/storage`にマウントされることに注意してください。`THIRD_PARTY_SIGNATURE_VERIFICATION_PUBLIC_KEYS`で指定するパスがコンテナ内のパスに対応していることを確認してください。</Info>
これらの変更を適用するには、Difyサービスを再起動します
```bash
cd docker
docker compose down
docker compose up -d
```
サービスを再起動すると、現在のCommunity Edition環境でサードパーティ署名検証機能が有効になります。
{/*
Contributing Section
DO NOT edit this section!
It will be automatically generated by the script.
*/}
---
[Edit this page](https://github.com/langgenius/dify-docs/edit/main/en/develop-plugin/publishing/standards/third-party-signature-verification.mdx) | [Report an issue](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)