mirror of
https://github.com/langgenius/dify-docs.git
synced 2026-03-27 13:28:32 +07:00
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:
164
ja/develop-plugin/dev-guides-and-walkthroughs/cheatsheet.mdx
Normal file
164
ja/develop-plugin/dev-guides-and-walkthroughs/cheatsheet.mdx
Normal 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)
|
||||
@@ -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` タイプのプラグインテンプレートを選択します。このテンプレートは、モデル統合のための完全なコード構造を提供します。
|
||||
|
||||

|
||||
|
||||
### プラグイン権限の設定
|
||||
|
||||
モデルプロバイダープラグインには、以下の必須権限を設定します:
|
||||
|
||||
* **Models** - モデル操作の基本権限
|
||||
* **LLM** - 大規模言語モデル機能の権限
|
||||
* **Storage** - ファイル操作の権限(必要な場合)
|
||||
|
||||

|
||||
|
||||
### ディレクトリ構造の概要
|
||||
|
||||
初期化後、プラグインプロジェクトは以下のようなディレクトリ構造になります(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)
|
||||
@@ -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
|
||||
|
||||
データソースタイプとデータソースプラグインタイプの関係を以下に示します。
|
||||
|
||||

|
||||
|
||||
## データソースプラグインの開発
|
||||
|
||||
### データソースプラグインの作成
|
||||
|
||||
スキャフォールディングコマンドラインツールを使用して、`datasource`タイプを選択することでデータソースプラグインを作成できます。セットアップが完了すると、コマンドラインツールが自動的にプラグインプロジェクトコードを生成します。
|
||||
|
||||
```powershell
|
||||
dify plugin init
|
||||
```
|
||||
|
||||

|
||||
|
||||
<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)
|
||||
@@ -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** 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をゼロから作成し、デプロイするワークスペースを選択します。
|
||||
|
||||

|
||||
|
||||
1. **Webhooksを有効にする:**
|
||||
|
||||

|
||||
|
||||
2. **Slackワークスペースにアプリをインストールする:**
|
||||
|
||||

|
||||
|
||||
3. 将来のプラグイン開発のために**OAuthトークンを取得する**:
|
||||
|
||||

|
||||
|
||||
### 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)を参照してください。
|
||||
|
||||

|
||||
|
||||
#### 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プラットフォームに移動し、プラグインのリモートデバッグアドレスとキーを取得します。
|
||||
|
||||

|
||||
|
||||
プラグインプロジェクトに戻り、`.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を有効にする**
|
||||

|
||||
|
||||
上記で生成したPOSTリクエストURLを貼り付けます。
|
||||

|
||||
|
||||
2. **必要な権限を付与する**
|
||||

|
||||
|
||||
---
|
||||
|
||||
### 3. プラグインの検証
|
||||
|
||||
コード内で、`self.session.app.chat.invoke`がDifyアプリケーションを呼び出すために使用され、`app_id`や`query`などのパラメータを渡します。応答はSlack Botに返されます。`python -m main`を再度実行してプラグインをデバッグ用に再起動し、SlackがDify Appの応答を正しく表示するかどうかを確認します:
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
### 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)
|
||||
@@ -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>
|
||||
|
||||
## ステップ1:Dify 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)
|
||||
@@ -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
|
||||
```
|
||||
|
||||
## ステップ3:Wordエクスポートツールの定義
|
||||
|
||||
`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: 导出文档的名称(无需扩展名)
|
||||
```
|
||||
|
||||
## ステップ4:PDFエクスポートツールの定義
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
## ステップ6:Wordエクスポート機能の実装
|
||||
|
||||
`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>
|
||||
|
||||
## ステップ7:PDFエクスポート機能の実装
|
||||
|
||||
`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)
|
||||
128
ja/develop-plugin/dev-guides-and-walkthroughs/endpoint.mdx
Normal file
128
ja/develop-plugin/dev-guides-and-walkthroughs/endpoint.mdx
Normal 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` を作成する際、以下の設定を入力する必要がある場合があります。
|
||||
|
||||

|
||||
|
||||
`Endpoint Name` の他に、グループの設定情報を記述することで新しいフォーム項目を追加できます。保存をクリックすると、含まれる複数のインターフェースが表示され、それらは同じ設定情報を使用します。
|
||||
|
||||

|
||||
|
||||
#### **構造**
|
||||
|
||||
* `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)
|
||||
382
ja/develop-plugin/dev-guides-and-walkthroughs/tool-oauth.mdx
Normal file
382
ja/develop-plugin/dev-guides-and-walkthroughs/tool-oauth.mdx
Normal file
@@ -0,0 +1,382 @@
|
||||
---
|
||||
title: "ツールプラグインにOAuthサポートを追加する"
|
||||
---
|
||||
|
||||
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/tool-oauth)を参照してください。</Note>
|
||||
|
||||

|
||||
|
||||
このガイドでは、ツールプラグインに[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. 必要なAPI(例:Gmail 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)
|
||||
387
ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin.mdx
Normal file
387
ja/develop-plugin/dev-guides-and-walkthroughs/tool-plugin.mdx
Normal 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 Provider
|
||||
- Tool A
|
||||
- Tool B
|
||||
```
|
||||
|
||||

|
||||
|
||||
この記事では、`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)ガイドを参照して、さまざまなタイプのプラグインの開発を完了できます。
|
||||
|
||||

|
||||
|
||||
#### プラグイン権限の設定
|
||||
|
||||
プラグインは、Difyプラットフォームから読み取る権限も必要です。このサンプルプラグインに以下の権限を付与します:
|
||||
|
||||
- Tools
|
||||
- Apps
|
||||
- 永続ストレージStorageを有効にし、デフォルトサイズのストレージを割り当てる
|
||||
- Endpointsの登録を許可
|
||||
|
||||
> ターミナルの矢印キーを使用して権限を選択し、「Tab」ボタンを使用して権限を付与します。
|
||||
|
||||
すべての権限項目をチェックした後、Enterを押してプラグインの作成を完了します。システムは自動的にプラグインプロジェクトコードを生成します。
|
||||
|
||||

|
||||
|
||||
### ツールプラグインの開発
|
||||
|
||||
#### 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)ページに移動して、リモートサーバーアドレスとデバッグキーを取得します。
|
||||
|
||||

|
||||
|
||||
プラグインプロジェクトに戻り、`.env.example`ファイルをコピーして`.env`に名前変更し、取得したリモートサーバーアドレスとデバッグキー情報を入力します。
|
||||
|
||||
`.env`ファイル:
|
||||
|
||||
```bash
|
||||
INSTALL_METHOD=remote
|
||||
REMOTE_INSTALL_URL=debug.dify.ai:5003
|
||||
REMOTE_INSTALL_KEY=********-****-****-****-************
|
||||
```
|
||||
|
||||
`python -m main`コマンドを実行してプラグインを起動します。プラグインページで、プラグインがワークスペースにインストールされていることを確認でき、チームの他のメンバーもプラグインにアクセスできます。
|
||||
|
||||

|
||||
|
||||
### プラグインのパッケージング(オプション)
|
||||
|
||||
プラグインが正常に実行できることを確認した後、以下のコマンドラインツールを使用してプラグインをパッケージ化して名前を付けることができます。実行後、現在のフォルダに`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)
|
||||
665
ja/develop-plugin/dev-guides-and-walkthroughs/trigger-plugin.mdx
Normal file
665
ja/develop-plugin/dev-guides-and-walkthroughs/trigger-plugin.mdx
Normal file
@@ -0,0 +1,665 @@
|
||||
---
|
||||
title: "トリガープラグイン"
|
||||
---
|
||||
|
||||
<Note> ⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/develop-plugin/dev-guides-and-walkthroughs/trigger-plugin)を参照してください。</Note>
|
||||
|
||||
## トリガープラグインとは?
|
||||
|
||||
トリガーは Dify v1.10.0 で新しいタイプの開始ノードとして導入されました。コード、ツール、ナレッジベース検索などの機能ノードとは異なり、トリガーの目的は**サードパーティのイベントを Dify が認識して処理できる入力形式に変換すること**です。
|
||||
|
||||

|
||||
|
||||
例えば、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)
|
||||
@@ -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文字で、文字、数字、ハイフン、アンダースコアのみを含めることができます。
|
||||
|
||||

|
||||
|
||||
情報を入力してEnterを押すと、Bundleプラグインプロジェクトディレクトリが自動的に作成されます。
|
||||
|
||||

|
||||
|
||||
#### 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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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(プラットフォーム内の他のツールプラグインの呼び出し)、Node(Chatflow/ワークフローアプリケーション内のノードの呼び出し)。
|
||||
---
|
||||
|
||||
<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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
1263
ja/develop-plugin/features-and-specs/plugin-types/model-schema.mdx
Normal file
1263
ja/develop-plugin/features-and-specs/plugin-types/model-schema.mdx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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が表示されます。
|
||||
|
||||

|
||||
|
||||
{/*
|
||||
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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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を取得します。
|
||||
|
||||

|
||||
|
||||
プラグインプロジェクトに戻り、`.env.example`ファイルをコピーして`.env`にリネームし、取得したリモートサーバーアドレスとデバッグKey情報を入力します。
|
||||
|
||||
`.env`ファイル:
|
||||
|
||||
```bash
|
||||
INSTALL_METHOD=remote
|
||||
REMOTE_INSTALL_URL=debug.dify.ai:5003
|
||||
REMOTE_INSTALL_KEY=********-****-****-****-************
|
||||
```
|
||||
|
||||
`python -m main`コマンドを実行してプラグインを起動します。プラグインページで、プラグインがワークスペースにインストールされていることが確認でき、チームの他のメンバーもプラグインにアクセスできます。
|
||||
|
||||

|
||||
393
ja/develop-plugin/features-and-specs/plugin-types/tool.mdx
Normal file
393
ja/develop-plugin/features-and-specs/plugin-types/tool.mdx
Normal 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)
|
||||
156
ja/develop-plugin/getting-started/cli.mdx
Normal file
156
ja/develop-plugin/getting-started/cli.mdx
Normal 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
|
||||
- Homebrew(Macユーザーの場合)
|
||||
|
||||
## 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)
|
||||
@@ -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)
|
||||
49
ja/develop-plugin/publishing/faq/faq.mdx
Normal file
49
ja/develop-plugin/publishing/faq/faq.mdx
Normal 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)
|
||||
@@ -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上の開発タスクを自動化します。
|
||||
|
||||
**仕組み**: トリガー(例:コードのプッシュ)が発生すると、クラウドベースの仮想マシンでワークフローが実行され、ビルドからデプロイまですべてが自動的に処理されます。
|
||||
|
||||

|
||||
|
||||
**制限**:
|
||||
|
||||
* パブリックリポジトリ: 無制限
|
||||
* プライベートリポジトリ: 月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`フィールドを更新します
|
||||
|
||||

|
||||
|
||||
3. すべての変更をメインブランチにプッシュします
|
||||
4. GitHub Actionsがパッケージング、ブランチ作成、PR送信を完了するのを待ちます
|
||||
|
||||
### 結果
|
||||
|
||||
プラグインソースリポジトリのメインブランチにコードをプッシュすると、GitHub Actionsが自動的に公開プロセスを実行します:
|
||||
|
||||
* プラグインを`{plugin-name}-{version}.difypkg`形式でパッケージング
|
||||
* パッケージングされたファイルをターゲットリポジトリにプッシュ
|
||||
* フォークリポジトリにマージするためのPRを作成
|
||||
|
||||

|
||||
|
||||
### サンプルリポジトリ
|
||||
|
||||
設定とベストプラクティスを理解するには、[サンプルリポジトリ](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)
|
||||
@@ -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`拡張子のファイルが生成されます。
|
||||
|
||||

|
||||
|
||||
### プラグインのインストール
|
||||
|
||||
Difyプラグイン管理ページにアクセスし、右上の**プラグインをインストール** → **ローカルファイルから**をクリックしてインストールするか、プラグインファイルをページの空白部分にドラッグ&ドロップしてプラグインをインストールします。
|
||||
|
||||

|
||||
|
||||
### プラグインの公開
|
||||
|
||||
プラグインファイルを他のユーザーと共有したり、インターネットにアップロードして他のユーザーがダウンロードできるようにできます。プラグインをより広く共有したい場合は、以下を検討してください:
|
||||
|
||||
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)
|
||||
@@ -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)
|
||||
@@ -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 Request(PR)を[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 Request(PR)を提出し、レビューを待つ;
|
||||
7. レビューが承認されると、プラグインコードがMainブランチにマージされ、プラグインは自動的に[Dify Marketplace](https://marketplace.dify.ai/)に公開されます。
|
||||
|
||||
プラグインの提出、レビュー、公開のフローチャート:
|
||||
|
||||

|
||||
|
||||
> **注意**:上記の図のContributor Agreement(貢献者同意書)は、[プラグイン開発者ガイドライン](/ja/develop-plugin/publishing/standards/contributor-covenant-code-of-conduct)を指します。
|
||||
|
||||
***
|
||||
|
||||
### Pull Request(PR)レビュー中
|
||||
|
||||
レビュアーの質問やフィードバックに積極的に対応してください:
|
||||
|
||||
* **14日以内**に解決されないPRコメントは、stale(古い)としてマークされます(再開可能)。
|
||||
* **30日以内**に解決されないPRコメントは、クローズされます(再開不可、新しいPRを作成する必要があります)。
|
||||
|
||||
***
|
||||
|
||||
### **Pull Request(PR)承認後**
|
||||
|
||||
**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は、フィードバックに対応した後に再開できます。クローズされたPR(30日以上)は、新しい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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user