mirror of
https://github.com/langgenius/dify-docs.git
synced 2026-03-27 13:28:32 +07:00
387 lines
21 KiB
Plaintext
387 lines
21 KiB
Plaintext
---
|
||
dimensions:
|
||
type:
|
||
primary: implementation
|
||
detail: standard
|
||
level: intermediate
|
||
standard_title: Tool Plugin
|
||
language: ja
|
||
title: Tool プラグイン
|
||
description: このドキュメントでは、Difyのツールプラグインを開発する方法を詳しく説明します。Google Searchを例に、プラグインの初期化、テンプレートの選択、ツールプロバイダー設定ファイルの定義、サードパーティサービス認証情報の追加、ツール機能コードの実装、デバッグ、パッケージ化と公開までの完全なツールプラグイン開発フローを紹介します。
|
||
---
|
||
|
||
ツールとは、Chatflow / Workflow / Agent タイプのアプリケーションから呼び出すことができるサードパーティサービスを指し、Difyアプリケーションの能力を強化するための完全なAPI実装機能を提供します。例えば、アプリケーションにオンライン検索や画像生成などの追加機能を追加します。
|
||
|
||

|
||
|
||
この記事では、**「ツールプラグイン」** とは、ツールプロバイダーファイル、機能コードなどの構造を含む完全なプロジェクトを指します。1つのツールプロバイダーには複数のツール(個々のツール内で提供される追加機能と理解できます)を含めることができ、構造は以下の通りです。
|
||
|
||
```
|
||
- ツールプロバイダー
|
||
- Tool A
|
||
- Tool B
|
||
```
|
||
|
||

|
||
|
||
この記事では、`Google Search` を例に、ツールプラグインを迅速に開発する方法を紹介します。
|
||
|
||
### 事前準備
|
||
|
||
- Difyプラグインスキャフォールドツール
|
||
- Python環境、バージョン ≥ 3.12
|
||
|
||
プラグイン開発用のスキャフォールドツールの準備方法については、[開発ツールの初期化](/plugin-dev-ja/0221-initialize-development-tools)を参照してください。初めてプラグインを開発する場合は、まず[Difyプラグイン開発:Hello Worldガイド](/plugin-dev-ja/0211-getting-started-dify-tool)を読むことをお勧めします。
|
||
|
||
### 新規プロジェクトの作成
|
||
|
||
スキャフォールドコマンドラインツールを実行し、新しいDifyプラグインプロジェクトを作成します。
|
||
|
||
```bash
|
||
./dify-plugin-darwin-arm64 plugin init
|
||
```
|
||
|
||
このバイナリファイルを `dify` にリネームし、`/usr/local/bin` パスにコピーした場合、以下のコマンドを実行して新しいプラグインプロジェクトを作成できます。
|
||
|
||
```bash
|
||
dify plugin init
|
||
```
|
||
|
||
> 以下では、コマンドラインの例として `dify` を使用します。問題が発生した場合は、`dify` コマンドをコマンドラインツールの実際のパスに置き換えてください。
|
||
|
||
### プラグインタイプとテンプレートの選択
|
||
|
||
スキャフォールドツール内のすべてのテンプレートは、完全なコードプロジェクトを提供しています。この記事の例では、`Tool` プラグインを選択します。
|
||
|
||
> プラグイン開発に慣れている場合は、テンプレートを使用せずに、[一般仕様](/plugin-dev-ja/0411-general-specifications)のガイドラインを参照して、さまざまなタイプのプラグイン開発を完了できます。
|
||
|
||

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

|
||
|
||
### ツールプラグインの開発
|
||
|
||
#### 1. ツールプロバイダーファイルの作成
|
||
|
||
ツールプロバイダーファイルはYAML形式のファイルで、ツールプラグインの基本設定エントリと理解でき、ツールに必要な認証情報を提供するために使用されます。
|
||
|
||
プラグインテンプレートプロジェクトの `/provider` パスに移動し、そこにあるyamlファイルを `google.yaml` にリネームします。この `yaml` ファイルには、ツールプロバイダーの情報(プロバイダー名、アイコン、作成者などの詳細)が含まれます。この情報はプラグインのインストール時に表示されます。
|
||
|
||
**コード例**
|
||
|
||
```yaml
|
||
identity: # ツールプロバイダーの基本情報
|
||
author: Your-name # 作成者
|
||
name: google # 名称、一意であり、他のプロバイダーと重複することはできません
|
||
label: # ラベル、フロントエンド表示用
|
||
en_US: Google # 英語ラベル
|
||
zh_Hans: Google # 中国語ラベル
|
||
description: # 説明、フロントエンド表示用
|
||
en_US: Google # 英語の説明
|
||
zh_Hans: Google # 中国語の説明
|
||
icon: icon.svg # ツールアイコン、_assetsフォルダに配置する必要があります
|
||
tags: # タグ、フロントエンド表示用
|
||
- search
|
||
```
|
||
|
||
このファイルパスが `/tools` ディレクトリに配置されるようにしてください。完全なパスは次のとおりです。
|
||
|
||
```yaml
|
||
plugins:
|
||
tools:
|
||
- 'google.yaml'
|
||
```
|
||
|
||
`google.yaml`ファイルは、プラグインプロジェクトにおける絶対パスを使用する必要があります。この例では、プロジェクトのルートディレクトリにあります。YAMLファイル内のidentityフィールドは次のように説明されます:`identity`には、作成者、名前、ラベル、説明、アイコンなど、ツールプロバイダーの基本情報が含まれます。
|
||
|
||
- アイコンは添付リソースに属する必要があり、プロジェクトのルートディレクトリにある `_assets` フォルダに配置する必要があります。
|
||
- タグは、ユーザーがカテゴリ別にプラグインをすばやく見つけるのに役立ちます。以下は現在サポートされているすべてのタグです。
|
||
|
||
```python
|
||
class ToolLabelEnum(Enum):
|
||
SEARCH = 'search'
|
||
IMAGE = 'image'
|
||
VIDEOS = 'videos'
|
||
WEATHER = 'weather'
|
||
FINANCE = 'finance'
|
||
DESIGN = 'design'
|
||
TRAVEL = 'travel'
|
||
SOCIAL = 'social'
|
||
NEWS = 'news'
|
||
MEDICAL = 'medical'
|
||
PRODUCTIVITY = 'productivity'
|
||
EDUCATION = 'education'
|
||
BUSINESS = 'business'
|
||
ENTERTAINMENT = 'entertainment'
|
||
UTILITIES = 'utilities'
|
||
OTHER = 'other'
|
||
```
|
||
|
||
#### **2. サードパーティサービス認証情報の補完**
|
||
|
||
開発を容易にするため、サードパーティサービス `SerpApi` が提供する Google Search API を採用することを選択します。`SerpApi` は使用にあたって API Key の入力を要求するため、`yaml` ファイル内に `credentials_for_provider` フィールドを追加する必要があります。
|
||
|
||
完全なコードは以下の通りです。
|
||
|
||
```yaml
|
||
identity:
|
||
author: Dify
|
||
name: google
|
||
label:
|
||
en_US: Google
|
||
zh_Hans: Google
|
||
pt_BR: Google
|
||
description:
|
||
en_US: Google
|
||
zh_Hans: GoogleSearch
|
||
pt_BR: Google
|
||
icon: icon.svg
|
||
tags:
|
||
- search
|
||
credentials_for_provider: # credentials_for_provider フィールドを追加
|
||
serpapi_api_key:
|
||
type: secret-input
|
||
required: true
|
||
label:
|
||
en_US: SerpApi API key
|
||
zh_Hans: SerpApi APIキー
|
||
placeholder:
|
||
en_US: Please input your SerpApi API key
|
||
zh_Hans: SerpApi APIキーを入力してください
|
||
help:
|
||
en_US: Get your SerpApi API key from SerpApi
|
||
zh_Hans: SerpApiからSerpApi APIキーを取得します
|
||
url: https://serpapi.com/manage-api-key
|
||
tools:
|
||
- tools/google_search.yaml
|
||
extra:
|
||
python:
|
||
source: google.py
|
||
```
|
||
|
||
- `credentials_for_provider` の子構造は、[一般仕様](/plugin-dev-ja/0411-general-specifications)の要件を満たす必要があります。
|
||
- このプロバイダーにどのツールが含まれているかを指定する必要があります。この例では、`tools/google_search.yaml` ファイルのみが含まれています。
|
||
- プロバイダーとして、基本情報を定義するだけでなく、そのコードロジックの一部を実装する必要があるため、その実装ロジックを指定する必要があります。この例では、機能のコードファイルを `google.py` に配置しましたが、一時的に実装せず、まず `google_search` のコードを作成します。
|
||
|
||
#### 3. ツールyamlファイルの記入
|
||
|
||
1つのツールプラグインには複数のツール機能を含めることができ、各ツール機能には、ツール機能の基本情報、パラメータ、出力などを含む `yaml` ファイルで記述する必要があります。
|
||
|
||
引き続き `GoogleSearch` ツールを例に、`/tools` フォルダ内に新しい `google_search.yaml` ファイルを作成します。
|
||
|
||
```yaml
|
||
identity:
|
||
name: google_search
|
||
author: Dify
|
||
label:
|
||
en_US: GoogleSearch
|
||
zh_Hans: Google検索
|
||
pt_BR: GoogleSearch
|
||
description:
|
||
human:
|
||
en_US: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
|
||
zh_Hans: Google SERP検索を実行し、スニペットとウェブページを抽出するためのツールです。入力は検索クエリである必要があります。
|
||
pt_BR: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
|
||
llm: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
|
||
parameters:
|
||
- name: query
|
||
type: string
|
||
required: true
|
||
label:
|
||
en_US: Query string
|
||
zh_Hans: クエリ文
|
||
pt_BR: Query string
|
||
human_description:
|
||
en_US: used for searching
|
||
zh_Hans: ウェブコンテンツの検索に使用
|
||
pt_BR: used for searching
|
||
llm_description: key words for searching
|
||
form: llm
|
||
extra:
|
||
python:
|
||
source: tools/google_search.py
|
||
```
|
||
|
||
- `identity` には、ツールの基本情報(名前、作成者、ラベル、説明など)が含まれます。
|
||
- `parameters` パラメータリスト
|
||
- `name` (必須)パラメータ名、一意であり、他のパラメータと重複することはできません。
|
||
- `type` (必須)パラメータタイプ。現在、`string`(文字列)、`number`(数値)、`boolean`(ブール値)、`select`(ドロップダウンリスト)、`secret-input`(暗号化入力フィールド)の5種類をサポートしています。機密情報には`secret-input`タイプを使用してください。
|
||
- `label`(必須)パラメータラベル、フロントエンド表示用。
|
||
- `form` (必須)フォームタイプ。現在、`llm`、`form`の2種類をサポートしています。
|
||
- Agentアプリケーションでは、`llm` はLLMが自身で推論するパラメータを示し、`form` はこのツールを使用するために事前に設定できるパラメータを示します。
|
||
- Workflowアプリケーションでは、`llm` と `form` の両方をフロントエンドで入力する必要がありますが、`llm` のパラメータはツールノードの入力変数として機能します。
|
||
- `required` 必須かどうか
|
||
- `llm` モードでは、パラメータが必須の場合、Agentはこのパラメータを推論する必要があります。
|
||
- `form` モードでは、パラメータが必須の場合、ユーザーは対話開始前にフロントエンドでこのパラメータを入力する必要があります。
|
||
- `options` パラメータオプション
|
||
- `llm` モードでは、DifyはすべてのオプションをLLMに渡し、LLMはこれらのオプションに基づいて推論できます。
|
||
- `form` モードで `type` が `select` の場合、フロントエンドはこれらのオプションを表示します。
|
||
- `default` デフォルト値。
|
||
- `min` 最小値、パラメータタイプが `number` の場合に設定できます。
|
||
- `max` 最大値、パラメータタイプが `number` の場合に設定できます。
|
||
- `human_description` フロントエンド表示用の説明、多言語対応。
|
||
- `placeholder` フィールド入力ボックスのヒントテキスト。フォームタイプが`form`で、パラメータタイプが`string`、`number`、`secret-input`の場合に設定でき、多言語対応です。
|
||
- `llm_description` LLMに渡す説明。LLMがこのパラメータをよりよく理解できるように、ここにこのパラメータに関するできるだけ詳細な情報を記述してください。
|
||
|
||
#### 4. ツールコードの準備
|
||
|
||
ツールの設定情報を入力した後、ツールの機能コードの作成を開始し、ツールの論理的な目的を実現できます。`/tools`ディレクトリに`google_search.py`を作成し、内容は以下の通りです。
|
||
|
||
```python
|
||
from collections.abc import Generator
|
||
from typing import Any
|
||
|
||
import requests
|
||
|
||
from dify_plugin import Tool
|
||
from dify_plugin.entities.tool import ToolInvokeMessage
|
||
|
||
SERP_API_URL = "https://serpapi.com/search"
|
||
|
||
class GoogleSearchTool(Tool):
|
||
def _parse_response(self, response: dict) -> dict:
|
||
result = {}
|
||
if "knowledge_graph" in response:
|
||
result["title"] = response["knowledge_graph"].get("title", "")
|
||
result["description"] = response["knowledge_graph"].get("description", "")
|
||
if "organic_results" in response:
|
||
result["organic_results"] = [
|
||
{
|
||
"title": item.get("title", ""),
|
||
"link": item.get("link", ""),
|
||
"snippet": item.get("snippet", ""),
|
||
}
|
||
for item in response["organic_results"]
|
||
]
|
||
return result
|
||
|
||
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
|
||
params = {
|
||
"api_key": self.runtime.credentials["serpapi_api_key"],
|
||
"q": tool_parameters["query"],
|
||
"engine": "google",
|
||
"google_domain": "google.com",
|
||
"gl": "us",
|
||
"hl": "en",
|
||
}
|
||
|
||
response = requests.get(url=SERP_API_URL, params=params, timeout=5)
|
||
response.raise_for_status()
|
||
valuable_res = self._parse_response(response.json())
|
||
|
||
yield self.create_json_message(valuable_res)
|
||
```
|
||
|
||
この例の意味は、`serpapi` にリクエストを送信し、`self.create_json_message` を使用して `json` 形式のフォーマット済みデータを返すことです。返されるデータ型の詳細については、[プラグインのリモートデバッグ](/plugin-dev-ja/0411-remote-debug-a-plugin)および[永続ストレージKV](/plugin-dev-ja/0411-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` コマンドを実行してプラグインを起動します。プラグインページで、このプラグインがWorkspaceにインストールされていることが確認でき、チームの他のメンバーもこのプラグインにアクセスできます。
|
||
|
||

|
||
|
||
### プラグインのパッケージ化(オプション)
|
||
|
||
プラグインが正常に動作することを確認した後、以下のコマンドラインツールを使用してプラグインをパッケージ化し、名前を付けることができます。実行後、現在のフォルダに `google.difypkg` ファイルが見つかります。これは最終的なプラグインパッケージです。
|
||
|
||
```bash
|
||
# ./google をプラグインプロジェクトの実際のパスに置き換えてください
|
||
|
||
dify plugin package ./google
|
||
```
|
||
|
||
おめでとうございます、これでツールタイププラグインの完全な開発、デバッグ、パッケージ化プロセスを完了しました!
|
||
|
||
### プラグインの公開(オプション)
|
||
|
||
プラグインをDify Marketplaceに公開したい場合は、プラグインが[Difyマーケットプレイスへの公開](/plugin-dev-ja/0322-release-to-dify-marketplace)の仕様に従っていることを確認してください。審査に合格すると、コードはメインブランチにマージされ、自動的に[Dify Marketplace](https://marketplace.dify.ai/)に公開されます。
|
||
|
||
[公開概要](/plugin-dev-ja/0321-release-overview)
|
||
|
||
### さらに探る
|
||
|
||
#### **クイックスタート:**
|
||
|
||
- [Extensionプラグインの開発](/plugin-dev-ja/9231-extension-plugin)
|
||
- [Modelプラグインの開発](/plugin-dev-ja/0211-getting-started-new-model)
|
||
- [Bundleプラグイン:複数のプラグインをパッケージ化](/plugin-dev-ja/9241-bundle)
|
||
|
||
#### **プラグインインターフェースドキュメント:**
|
||
|
||
- [一般仕様定義](/plugin-dev-ja/0411-general-specifications) - Manifest構造とツール仕様
|
||
- [エンドポイント](/plugin-dev-ja/0432-endpoint) - Endpoint詳細定義
|
||
- [リバースコール](/plugin-dev-ja/9241-reverse-invocation) - Dify機能のリバースコール
|
||
- [モデルスキーマ](/plugin-dev-ja/0412-model-schema) - モデル
|
||
- [Agentプラグイン](/plugin-dev-ja/9232-agent) - Agent戦略の拡張
|
||
|
||
## 次のステップ
|
||
|
||
- [プラグインのリモートデバッグ](/plugin-dev-ja/0411-remote-debug-a-plugin) - より高度なデバッグテクニックを学ぶ
|
||
- [永続ストレージ](/plugin-dev-ja/0411-persistent-storage-kv) - プラグインでデータストレージを使用する方法を学ぶ
|
||
- [Slackボットプラグイン開発例](/plugin-dev-ja/0432-develop-a-slack-bot-plugin) - より複雑なプラグイン開発事例を見る
|
||
- [ツールプラグイン](/plugin-dev-ja/0411-tool) - ツールプラグインの高度な機能を探る
|
||
|
||
{/*
|
||
Contributing Section
|
||
DO NOT edit this section!
|
||
It will be automatically generated by the script.
|
||
*/}
|
||
|
||
---
|
||
|
||
[このページを編集する](https://github.com/langgenius/dify-docs/edit/main/plugin-dev-ja/0222-tool-plugin.mdx) | [問題を報告する](https://github.com/langgenius/dify-docs/issues/new?template=docs.yml)
|
||
|