Community研究與資料分析github.com

SystemTce/dify-skills

Dify 插件開發完整指南,涵蓋工具、模型、資料來源和擴充四種插件類型

dify-skills 是什麼?

此技能提供完整的 Dify 插件開發指南,涵蓋從環境建置到部署維運的完整流程。它詳細說明了創新的 Beehive(蜂巢)架構,支援 Local、Debug 和 Serverless 三種執行模式,並提供工具、模型、資料來源和擴充這四種插件類型的開發範例。技能中包含了實際的程式碼片段、YAML 設定檔、CLI 命令和最佳實踐,協助開發者快速上手。無論您是將現有 API 遷移為插件,還是從頭建立新的整合,此技能都提供了清晰的指引,讓您能在 Dify 生態系統中擴充 AI 功能。

相容平台✓Claude Code✓Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/SystemTce/dify-skills/tree/main/02-plugin

Installed? Explore more 研究與資料分析 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Dify 插件開發 SKILL

概述

Dify 插件系統採用創新的 Beehive(蜂巢)架構,支援三種執行時期模式,提供四種插件類型,為開發者提供強大的擴充能力。本 SKILL 提供從入門到精通的完整插件開發指南。

適用場景

當你需要以下場景時使用本 SKILL:

  • 開發 Dify 插件:工具、模型、資料來源、擴充四種類型
  • 整合第三方服務:API 包裝、OAuth 授權
  • 實作自訂工具:擴充 AI 能力
  • 擴充 Dify 平台功能:觸發器、Agent 策略
  • 將現有 API 遷移為插件:API 到插件的轉換
  • 除錯和最佳化插件效能:效能調校和問題排查

核心價值

  • Beehive 架構:去中心化排程、主從選舉、故障自癒
  • 多執行時期支援:Local、Debug、Serverless 三種模式
  • 完整工具鏈:dify CLI、Python SDK、除錯執行時期
  • 豐富生態:70+ 模型插件、20+ 工具插件、18+ 資料來源插件
  • 生產級品質:OAuth 2.0、權限控制、監控追蹤

快速開始

1. 環境準備

# 安裝 Python 3.12+
python --version  # 確保 >= 3.12

# 安裝 uv 套件管理器(推薦)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 安裝 dify CLI
pip install dify-cli

# 驗證安裝
dify --version

2. 建立第一個插件

# 初始化插件專案
dify plugin init

# 選擇插件類型
? Select plugin type: Tool
? Plugin name: my_first_tool
? Author: your_name
? Description: My first Dify tool plugin

# 進入專案目錄
cd my_first_tool

# 安裝依賴
uv pip install -r requirements.txt

3. 實作插件邏輯

編輯 tools/my_tool.py:

from typing import Any, Generator
from dify_plugin.entities.tool import ToolInvokeMessage
from dify_plugin import Tool


class MyTool(Tool):
    def _invoke(
        self, tool_parameters: dict[str, Any]
    ) -> Generator[ToolInvokeMessage, None, None]:
        """
        工具呼叫進入點
        """
        # 取得參數
        text = tool_parameters.get("text", "")

        # 處理邏輯
        result = f"處理結果: {text.upper()}"

        # 回傳結果
        yield self.create_text_message(result)

4. 本地除錯

# 啟動 Debug Runtime
dify plugin run

# 在 Dify 介面中測試插件
# 存取 http://localhost:5001

5. 打包部署

# 打包插件
dify plugin package

# 產生 my_first_tool.difypkg 檔案
# 上傳到 Dify Marketplace 或私有部署

核心概念

Beehive 架構

Dify 插件系統採用 Beehive(蜂巢)架構,核心特點:

  1. 去中心化排程:每個守護行程節點獨立管理本地插件
  2. 主從選舉:透過 Redis 分散式鎖定實現自動主節點選舉
  3. 狀態同步:所有節點狀態儲存在 Redis,支援跨節點存取
  4. 故障自癒:節點當機時自動重新分配插件

詳細架構說明請參考:types/architecture.md

三種執行時期模式

執行時期模式適用場景通訊方式優勢劣勢
Local Runtime本地開發、小規模部署STDIN/STDOUT低延遲、資源隔離記憶體佔用高、擴充性有限
Debug Runtime遠端除錯、開發環境TCP 全雙工開發友善、靈活部署網路依賴、狀態管理複雜
Serverless Runtime大規模生產環境HTTP/SSE自動擴充、成本最佳化冷啟動延遲、除錯複雜

詳細對比請參考:development/runtime-modes.md

四種插件類型

1. Tool(工具插件)

擴充 AI 能力的工具,如翻譯、搜尋、資料處理等。

# 範例:Google Translate
type: plugin
plugins:
  tools:
    - provider/google_translate.yaml

使用場景:

  • API 包裝(REST API → Tool)
  • 資料處理(格式轉換、計算)
  • 外部服務整合(搜尋、翻譯)

2. Model(模型插件)

接入 LLM 提供商,如 Anthropic、OpenAI、Gemini 等。

# 範例:Anthropic Claude
type: plugin
plugins:
  models:
    - provider/anthropic.yaml

使用場景:

  • 接入新的 LLM 提供商
  • 自訂模型配置
  • 多模態模型支援

3. Datasource(資料來源插件)

連線儲存系統,如 S3、Google Drive、Notion 等。

# 範例:AWS S3
type: plugin
plugins:
  datasources:
    - provider/aws_s3.yaml

使用場景:

  • 雲端儲存整合
  • 文件平台連線
  • 資料庫存取

4. Extension(擴充插件)

平台功能擴充,如 Slack、企業微信等第三方平台整合。

# 範例:Slack
type: plugin
plugins:
  extensions:
    - provider/slack.yaml

使用場景:

  • 第三方平台整合
  • 觸發器實作
  • 自訂 Agent 策略

詳細類型說明請參考:types/


專案結構

標準的 Dify 插件專案結構:

my_plugin/
├── manifest.yaml           # 插件清單(必需)
├── main.py                 # 進入點檔案(必需)
├── requirements.txt        # Python 依賴
├── pyproject.toml         # 專案配置
├── README.md              # 插件說明
├── PRIVACY.md             # 隱私政策(如需 OAuth)
├── .env.example           # 環境變數範例
│
├── _assets/               # 資源檔案
│   └── icon.svg          # 插件圖示
│
├── provider/              # 提供者配置
│   ├── provider_name.yaml # 提供者設定檔
│   └── provider_name.py   # 提供者實作
│
└── tools/                 # 工具實作(Tool 插件)
    ├── tool_name.yaml    # 工具設定檔
    └── tool_name.py      # 工具實作

核心檔案說明

manifest.yaml

插件清單檔案,定義插件的基本資訊和配置:

author: your_name
name: my_plugin
version: 0.0.1
type: plugin

description:
  en_US: Plugin description
  zh_Hans: 插件描述

label:
  en_US: My Plugin
  zh_Hans: 我的插件

icon: icon.svg

meta:
  version: 0.0.1
  arch:
    - amd64
    - arm64
  runner:
    language: python
    version: '3.12'
    entrypoint: main

plugins:
  tools:
    - provider/my_provider.yaml

resource:
  memory: 1048576  # 1MB = 1048576 bytes
  permission:
    tool:
      enabled: true
    model:
      enabled: true
      llm: true

tags:
  - utilities

詳細配置說明請參考:development/manifest.md

main.py

插件進入點檔案:

from dify_plugin import Plugin, DifyPluginEnv

# 建立插件實例
plugin = Plugin(DifyPluginEnv(MAX_REQUEST_TIMEOUT=120))

if __name__ == '__main__':
    # 啟動插件
    plugin.run()

開發指南

Tool 插件開發

1. 建立 Provider

編輯 provider/my_provider.yaml:

identity:
  author: your_name
  name: my_provider
  label:
    en_US: My Provider
    zh_Hans: 我的提供者
  description:
    en_US: Provider description
    zh_Hans: 提供者描述
  icon: icon.svg
  tags:
    - utilities

extra:
  python:
    source: provider/my_provider.py

tools:
  - tools/my_tool.yaml

編輯 provider/my_provider.py:

from typing import Any
from dify_plugin.errors.tool import ToolProviderCredentialValidationError
from dify_plugin import ToolProvider
from tools.my_tool import MyTool


class MyProvider(ToolProvider):
    def _validate_credentials(self, credentials: dict[str, Any]) -> None:
        """
        驗證憑證(如果需要)
        """
        try:
            # 驗證 API Key 或其他憑證
            api_key = credentials.get("api_key")
            if not api_key:
                raise ToolProviderCredentialValidationError("API Key is required")

            # 測試憑證有效性
            MyTool().invoke(
                tool_parameters={"text": "test"}
            )
        except Exception as e:
            raise ToolProviderCredentialValidationError(str(e))

2. 建立 Tool

編輯 tools/my_tool.yaml:

identity:
  author: your_name
  name: my_tool
  label:
    en_US: My Tool
    zh_Hans: 我的工具

description:
  human:
    en_US: Tool description for humans
    zh_Hans: 給人類看的工具描述
  llm: Tool description for LLM

extra:
  python:
    source: tools/my_tool.py

parameters:
  - name: text
    type: string
    required: true
    label:
      en_US: Input Text
      zh_Hans: 輸入文字
    human_description:
      en_US: The text to process
      zh_Hans: 要處理的文字
    llm_description: The input text to be processed
    form: llm

編輯 tools/my_tool.py:

from typing import Any, Generator
from dify_plugin.entities.tool import ToolInvokeMessage
from dify_plugin import Tool


class MyTool(Tool):
    def _invoke(
        self, tool_parameters: dict[str, Any]
    ) -> Generator[ToolInvokeMessage, None, None]:
        """
        工具呼叫進入點

        Args:
            tool_parameters: 工具參數字典

        Yields:
            ToolInvokeMessage: 工具呼叫訊息
        """
        # 1. 取得參數
        text = tool_parameters.get("text", "")

        if not text:
            yield self.create_text_message("Error: text parameter is required")
            return

        try:
            # 2. 處理邏輯
            result = self._process_text(text)

            # 3. 回傳結果
            yield self.create_text_message(result)

        except Exception as e:
            yield self.create_text_message(f"Error: {str(e)}")

    def _process_text(self, text: str) -> str:
        """
        處理文字的具體邏輯
        """
        return text.upper()

詳細開發指南請參考:development/tool.md


OAuth 2.0 整合

OAuth 流程概述

Dify 支援完整的 OAuth 2.0 授權流程:

  1. 取得授權 URL:使用者點擊授權按鈕
  2. 使用者授權:跳轉到第三方服務授權頁面
  3. 取得授權碼:使用者授權後回傳授權碼
  4. 交換存取權杖:使用授權碼交換存取權杖
  5. 重新整理權杖:存取權杖過期時使用重新整理權杖取得新權杖

配置 OAuth Schema

在 provider/my_provider.yaml 中加入 OAuth 配置:

oauth_schema:
  client_schema:
    - name: client_id
      type: secret-input
      required: true
      label:
        en_US: Client ID
        zh_Hans: 客戶端 ID
      placeholder:
        en_US: Enter your OAuth Client ID
        zh_Hans: 輸入您的 OAuth 客戶端 ID
      help:
        en_US: Get your client ID from the service provider
        zh_Hans: 從服務提供者取得客戶端 ID
      url: https://console.example.com/credentials

    - name: client_secret
      type: secret-input
      required: true
      label:
        en_US: Client Secret
        zh_Hans: 客戶端金鑰
      placeholder:
        en_US: Enter your OAuth Client Secret
        zh_Hans: 輸入您的 OAuth 客戶端金鑰

  credentials_schema:
    - name: access_token
      type: secret-input
      label:
        en_US: Access Token
        zh_Hans: 存取權杖

    - name: refresh_token
      type: secret-input
      label:
        en_US: Refresh Token
        zh_Hans: 重新整理權杖

實作 OAuth Provider

from typing import Any
from dify_plugin import ToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError
import requests


class MyOAuthProvider(ToolProvider):
    def _validate_credentials(self, credentials: dict[str, Any]) -> None:
        """
        驗證 OAuth 憑證
        """
        access_token = credentials.get("access_token")
        if not access_token:
            raise ToolProviderCredentialValidationError(
                "Access token is required"
            )

        # 測試存取權杖有效性
        try:
            response = requests.get(
                "https://api.example.com/user",
                headers={"Authorization": f"Bearer {access_token}"}
            )
            response.raise_for_status()
        except Exception as e:
            raise ToolProviderCredentialValidationError(
                f"Invalid access token: {str(e)}"
            )

使用 OAuth 權杖

在 Tool 中使用 OAuth 權杖:

class MyOAuthTool(Tool):
    def _invoke(
        self, tool_parameters: dict[str, Any]
    ) -> Generator[ToolInvokeMessage, None, None]:
        # 取得 OAuth 憑證
        credentials = self.runtime.credentials
        access_token = credentials.get("access_token")

        # 呼叫 API
        response = requests.get(
            "https://api.example.com/data",
            headers={"Authorization": f"Bearer {access_token}"}
        )

        yield self.create_text_message(response.text)

完整 OAuth 整合指南請參考:development/oauth-integration.md


測試和除錯

單元測試

使用 pytest 編寫單元測試:

# tests/test_my_tool.py
import pytest
from tools.my_tool import MyTool


def test_my_tool():
    tool = MyTool()
    result = list(tool.invoke(tool_parameters={"text": "hello"}))

    assert len(result) == 1
    assert "HELLO" in result[0].message

執行測試:

pytest tests/

整合測試

測試插件與 Dify 系統的整合:

# tests/test_integration.py
def test_plugin_integration():
    # 測試插件安裝
    # 測試工具呼叫
    # 測試 OAuth 流程
    pass

Debug Runtime 除錯

啟動 Debug Runtime 進行遠端除錯:

# 啟動 Debug Runtime
dify plugin run --debug

# 在 Dify 介面中測試
# 檢視即時日誌和錯誤資訊

常見問題排查

插件啟動失敗

  • 檢查 Python 版本(需要 3.12+)
  • 檢查依賴安裝(requirements.txt)
  • 檢查 manifest.yaml 配置
  • 檢查進入點檔案路徑(main.py)

權限驗證失敗

  • 檢查 credentials 配置
  • 檢查 OAuth 權杖是否過期
  • 檢查 API Key 是否有效
  • 檢查權限宣告(resource.permission)

執行時期錯誤

  • 調整逾時時間(MAX_REQUEST_TIMEOUT)
  • 最佳化記憶體使用(resource.memory)
  • 檢查網路連線
  • 檢查反向呼叫權限

詳細排查指南請參考:testing/troubleshooting.md


從 API 到插件遷移

遷移策略

  1. API 包裝模式:將 REST API 包裝為 Tool 插件
  2. SDK 整合模式:使用第三方 Python SDK
  3. OAuth 遷移:實作 OAuth 2.0 授權流程
  4. 批次操作最佳化:使用串流回應處理大資料

遷移步驟

  1. 分析現有 API

    • API 端點和參數
    • 認證方式(API Key / OAuth)
    • 回應格式和錯誤處理
  2. 選擇插件類型

    • REST API → Tool 插件
    • LLM API → Model 插件
    • 儲存 API → Datasource 插件
  3. 建立插件專案

    dify plugin init
    
  4. 實作 API 呼叫

    import requests
    
    class APIWrapperTool(Tool):
        def _invoke(self, tool_parameters: dict[str, Any]):
            response = requests.post(
                "https://api.example.com/endpoint",
                json=tool_parameters,
                headers={"Authorization": f"Bearer {api_key}"}
            )
            yield self.create_text_message(response.text)
    
  5. 配置認證

    • API Key:在 provider.yaml 中配置 credentials
    • OAuth:配置 oauth_schema
  6. 加入錯誤處理

    try:
        response = requests.post(...)
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        yield self.create_text_message(f"API Error: {str(e)}")
    
  7. 編寫測試

    def test_api_wrapper():
        tool = APIWrapperTool()
        result = list(tool.invoke(tool_parameters={...}))
        assert result[0].message
    
  8. 打包部署

    dify plugin package
    

實際案例

  • REST API → Tool:Google Translate(無認證)
  • OAuth API → Tool:Google Contacts(OAuth 2.0)
  • LLM API → Model:Anthropic Claude(API Key)
  • 儲存 API → Datasource:AWS S3(IAM 認證)

詳細遷移指南請參考:development/migration-guide.md


最佳實踐

程式碼組織

  1. 單一職責:每個 Tool 只做一件事
  2. 錯誤處理:捕獲所有例外並回傳友善錯誤資訊
  3. 參數驗證:在 _invoke 開始時驗證所有參數
  4. 日誌記錄:使用結構化日誌記錄關鍵操作

效能最佳化

  1. 串流回應:對於大資料使用 Generator 串流回傳
  2. 快取策略:快取頻繁存取的資料
  3. 非同步處理:使用 async/await 處理 I/O 密集型操作
  4. 資源限制:合理配置 resource.memory

安全考量

  1. 輸入驗證:驗證所有使用者輸入
  2. 敏感資料:使用 secret-input 類型儲存敏感資訊
  3. 權限控制:最小權限原則,只宣告必需的權限
  4. 錯誤資訊:不要在錯誤資訊中洩露敏感資料

使用者體驗

  1. 清晰的描述:提供詳細的 description 和 help
  2. 合理的預設值:為參數提供合理的預設值
  3. 多語言支援:至少支援 en_US 和 zh_Hans
  4. 友善的錯誤:回傳使用者可理解的錯誤資訊

部署和維運

執行時期模式選擇

場景推薦模式理由
本地開發Local Runtime低延遲、易除錯
遠端除錯Debug Runtime靈活、支援遠端
小規模生產Local Runtime簡單、成本低
大規模生產Serverless Runtime自動擴充、高可用

Serverless 部署

部署到 AWS Lambda:

# 1. 打包插件
dify plugin package

# 2. 建立 Lambda 函數
aws lambda create-function \
  --function-name my-plugin \
  --runtime python3.12 \
  --handler main.handler \
  --zip-file fileb://my_plugin.difypkg

# 3. 配置環境變數
aws lambda update-function-configuration \
  --function-name my-plugin \
  --environment Variables={
      REDIS_URL=redis://...
  }

# 4. 設定 API Gateway 觸發器
aws api-gateway create-rest-api \
  --name my-plugin-api

監控和日誌

  1. Prometheus 指標:監控插件效能
  2. 結構化日誌:使用 JSON 格式輸出日誌
  3. 錯誤追蹤:整合 Sentry 等錯誤追蹤服務
  4. 效能分析:使用 OpenTelemetry 進行分散式追蹤

生態系統

Marketplace

Dify 插件可發布到官方 Marketplace:

# 發布插件
dify plugin publish

# 需要通過審核
# 支援版本管理

社群貢獻


參考資源

官方文檔

工具和 SDK

社群資源


本 SKILL 基於 Dify 插件開發文檔和實踐經驗整理,持續更新中。

Individual skills in this repo

This repo contains 5 individual skills — each has its own dedicated page.

相關技能