CommunityRecherche & Datenanalysegithub.com

SystemTce/dify-skills

Vollständiger Leitfaden zur Dify-Plugin-Entwicklung, der die vier Plugin-Typen Werkzeug, Modell, Datenquelle und Erweiterung abdeckt.

Was ist dify-skills?

Dieses SKILL bietet eine umfassende Anleitung zur Entwicklung von Plugins für die Dify-Plattform. Es erklärt die innovative Beehive-Architektur (Bienenstock-Architektur), die auf dezentraler Orchestrierung, Master-Wahl und Selbstheilung basiert, und unterstützt die drei Laufzeitmodi: Lokal, Debug und Serverless. Entwickler erhalten detaillierte Anweisungen zur Erstellung der vier Plugin-Typen – Tool, Model, Datasource und Extension – von der ersten Initialisierung über die Implementierung bis hin zum Debugging und Deployment. Die Anleitung behandelt Schlüsselkonzepte wie die Plugin-Struktur mit `manifest.yaml` und `main.py`, die Integration von OAuth 2.0 für Authentifizierung, bewährte Methoden für Sicherheit und Leistung sowie die Migration bestehender APIs in Plugins. Der Leitfaden richtet sich an Entwickler, die die Fähigkeiten von Dify erweitern und nahtlos mit externen Diensten und LLMs verbinden möchten, und bietet sowohl theoretische Grundlagen als auch praktische Codebeispiele in Python.

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

Installed? Explore more Recherche & Datenanalyse skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Dify Plugin-Entwicklung SKILL

Überblick

Das Dify Plugin-System verwendet die innovative Beehive-Architektur (Bienenstock-Architektur) und unterstützt drei Laufzeitmodi. Es bietet vier Plugin-Typen und bietet Entwicklern leistungsstarke Erweiterungsmöglichkeiten. Dieses SKILL bietet einen vollständigen Leitfaden zur Plugin-Entwicklung vom Anfänger bis zum Fortgeschrittenen.

Anwendungsszenarien

Verwenden Sie dieses SKILL in den folgenden Szenarien:

  • Entwicklung von Dify-Plugins: Die vier Typen Werkzeug, Modell, Datenquelle und Erweiterung
  • Integration von Drittanbieterdiensten: API-Wrapper, OAuth-Autorisierung
  • Implementierung benutzerdefinierter Werkzeuge: Erweiterung der KI-Fähigkeiten
  • Erweiterung der Dify-Plattformfunktionen: Trigger, Agent-Strategien
  • Migration bestehender APIs zu Plugins: API-zu-Plugin-Konvertierung
  • Debugging und Optimierung der Plugin-Leistung: Leistungsoptimierung und Fehlerbehebung

Kernwerte

  • Beehive-Architektur: Dezentrale Orchestrierung, Master-Wahl, Selbstheilung
  • Mehrere Laufzeitmodi: Lokal, Debug, Serverless – drei Modi
  • Vollständige Toolchain: dify CLI, Python SDK, Debug-Laufzeit
  • Reichhaltiges Ökosystem: 70+ Modell-Plugins, 20+ Werkzeug-Plugins, 18+ Datenquellen-Plugins
  • Produktionsqualität: OAuth 2.0, Zugriffskontrolle, Monitoring und Tracing

Kurzanleitung

1. Umgebungsvorbereitung

# Installieren Sie Python 3.12+
python --version  # Stellen Sie sicher, dass >= 3.12

# Installieren Sie den uv-Paketmanager (empfohlen)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Installieren Sie die dify CLI
pip install dify-cli

# Überprüfen Sie die Installation
dify --version

2. Erstellen des ersten Plugins

# Initialisieren Sie ein Plugin-Projekt
dify plugin init

# Wählen Sie den Plugin-Typ
? Select plugin type: Tool
? Plugin name: my_first_tool
? Author: your_name
? Description: My first Dify tool plugin

# Wechseln Sie in das Projektverzeichnis
cd my_first_tool

# Installieren Sie Abhängigkeiten
uv pip install -r requirements.txt

3. Implementieren der Plugin-Logik

Bearbeiten Sie 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]:
        """
        Werkzeugaufruf-Einstiegspunkt
        """
        # Parameter abrufen
        text = tool_parameters.get("text", "")

        # Verarbeitungslogik
        result = f"Verarbeitungsergebnis: {text.upper()}"

        # Ergebnis zurückgeben
        yield self.create_text_message(result)

4. Lokales Debugging

# Debug-Laufzeit starten
dify plugin run

# Plugin in der Dify-Oberfläche testen
# Zugriff unter http://localhost:5001

5. Paketieren und Bereitstellen

# Plugin paketieren
dify plugin package

# Erzeugt die Datei my_first_tool.difypkg
# Hochladen in den Dify Marketplace oder zur privaten Bereitstellung

Kernkonzepte

Beehive-Architektur

Das Dify Plugin-System verwendet die Beehive-Architektur mit den folgenden Kernmerkmalen:

  1. Dezentrale Orchestrierung: Jeder Daemon-Knoten verwaltet lokale Plugins unabhängig
  2. Master-Wahl: Automatische Master-Wahl über Redis Distributed Lock
  3. Zustandssynchronisation: Der Zustand aller Knoten wird in Redis gespeichert und ermöglicht knotenübergreifenden Zugriff
  4. Selbstheilung: Bei Knotenausfall werden Plugins automatisch neu zugewiesen

Eine detaillierte Architekturbeschreibung finden Sie unter: types/architecture.md

Drei Laufzeitmodi

LaufzeitmodusAnwendungsszenarioKommunikationsmethodeVorteileNachteile
Local RuntimeLokale Entwicklung, kleine BereitstellungenSTDIN/STDOUTNiedrige Latenz, RessourcenisolierungHoher Speicherverbrauch, begrenzte Skalierbarkeit
Debug RuntimeRemote-Debugging, EntwicklungsumgebungTCP VollduplexEntwicklerfreundlich, flexible BereitstellungNetzwerkabhängigkeit, komplexe Zustandsverwaltung
Serverless RuntimeGroße ProduktionsumgebungenHTTP/SSEAutomatische Skalierung, KostenoptimierungKaltstart-Latenz, komplexes Debugging

Ein detaillierter Vergleich finden Sie unter: development/runtime-modes.md

Vier Plugin-Typen

1. Tool (Werkzeug-Plugin)

Werkzeuge zur Erweiterung der KI-Fähigkeiten, z. B. Übersetzung, Suche, Datenverarbeitung.

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

Anwendungsszenarien:

  • API-Wrapper (REST API → Tool)
  • Datenverarbeitung (Formatkonvertierung, Berechnung)
  • Integration externer Dienste (Suche, Übersetzung)

2. Model (Modell-Plugin)

Anbindung von LLM-Anbietern wie Anthropic, OpenAI, Gemini usw.

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

Anwendungsszenarien:

  • Anbindung neuer LLM-Anbieter
  • Benutzerdefinierte Modellkonfiguration
  • Unterstützung multimodaler Modelle

3. Datasource (Datenquellen-Plugin)

Anbindung von Speichersystemen wie S3, Google Drive, Notion usw.

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

Anwendungsszenarien:

  • Cloud-Speicher-Integration
  • Verbindung zu Dokumentenplattformen
  • Datenbankzugriff

4. Extension (Erweiterungs-Plugin)

Erweiterung der Plattformfunktionen, z. B. Integration von Drittanbieterplattformen wie Slack, WeChat Work.

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

Anwendungsszenarien:

  • Integration von Drittanbieterplattformen
  • Implementierung von Triggern
  • Benutzerdefinierte Agent-Strategien

Eine detaillierte Typbeschreibung finden Sie unter: types/


Projektstruktur

Die Standardstruktur eines Dify Plugin-Projekts:

my_plugin/
├── manifest.yaml           # Plugin-Manifest (erforderlich)
├── main.py                 # Einstiegspunkt (erforderlich)
├── requirements.txt        # Python-Abhängigkeiten
├── pyproject.toml         # Projektkonfiguration
├── README.md              # Plugin-Beschreibung
├── PRIVACY.md             # Datenschutzerklärung (falls OAuth erforderlich)
├── .env.example           # Beispiel für Umgebungsvariablen
│
├── _assets/               # Ressourcendateien
│   └── icon.svg          # Plugin-Symbol
│
├── provider/              # Anbieterkonfiguration
│   ├── provider_name.yaml # Konfigurationsdatei des Anbieters
│   └── provider_name.py   # Implementierung des Anbieters
│
└── tools/                 # Werkzeugimplementierung (Tool-Plugin)
    ├── tool_name.yaml    # Werkzeugkonfigurationsdatei
    └── tool_name.py      # Werkzeugimplementierung

Beschreibung der Kerndateien

manifest.yaml

Die Plugin-Manifestdatei definiert die grundlegenden Informationen und die Konfiguration des Plugins:

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  # 1 MB = 1048576 Bytes
  permission:
    tool:
      enabled: true
    model:
      enabled: true
      llm: true

tags:
  - utilities

Eine detaillierte Konfigurationsbeschreibung finden Sie unter: development/manifest.md

main.py

Plugin-Einstiegspunkt:

from dify_plugin import Plugin, DifyPluginEnv

# Plugin-Instanz erstellen
plugin = Plugin(DifyPluginEnv(MAX_REQUEST_TIMEOUT=120))

if __name__ == '__main__':
    # Plugin starten
    plugin.run()

Entwicklungsleitfaden

Entwicklung von Tool-Plugins

1. Erstellen eines Anbieters

Bearbeiten Sie 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

Bearbeiten Sie 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:
        """
        Anmeldeinformationen validieren (falls erforderlich)
        """
        try:
            # API-Schlüssel oder andere Anmeldeinformationen validieren
            api_key = credentials.get("api_key")
            if not api_key:
                raise ToolProviderCredentialValidationError("API Key is required")

            # Gültigkeit der Anmeldeinformationen testen
            MyTool().invoke(
                tool_parameters={"text": "test"}
            )
        except Exception as e:
            raise ToolProviderCredentialValidationError(str(e))

2. Erstellen eines Werkzeugs

Bearbeiten Sie 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

Bearbeiten Sie 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]:
        """
        Werkzeugaufruf-Einstiegspunkt

        Args:
            tool_parameters: Dictionary der Werkzeugparameter

        Yields:
            ToolInvokeMessage: Werkzeugaufruf-Nachricht
        """
        # 1. Parameter abrufen
        text = tool_parameters.get("text", "")

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

        try:
            # 2. Verarbeitungslogik
            result = self._process_text(text)

            # 3. Ergebnis zurückgeben
            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:
        """
        Spezifische Logik zur Textverarbeitung
        """
        return text.upper()

Eine detaillierte Entwicklungsanleitung finden Sie unter: development/tool.md


OAuth 2.0-Integration

OAuth-Ablauf Übersicht

Dify unterstützt den vollständigen OAuth 2.0-Autorisierungsablauf:

  1. Autorisierungs-URL abrufen: Der Benutzer klickt auf die Autorisierungsschaltfläche
  2. Benutzerautorisierung: Weiterleitung zur Autorisierungsseite des Drittanbieters
  3. Autorisierungscode abrufen: Nach der Autorisierung des Benutzers wird der Autorisierungscode zurückgegeben
  4. Access-Token austauschen: Verwendung des Autorisierungscodes zum Austausch gegen ein Access-Token
  5. Token aktualisieren: Bei Ablauf des Access-Tokens wird das Refresh-Token verwendet, um ein neues Token zu erhalten

Konfigurieren des OAuth-Schemas

Fügen Sie in provider/my_provider.yaml die OAuth-Konfiguration hinzu:

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: 刷新令牌

Implementieren eines OAuth-Anbieters

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-Anmeldeinformationen validieren
        """
        access_token = credentials.get("access_token")
        if not access_token:
            raise ToolProviderCredentialValidationError(
                "Access token is required"
            )

        # Gültigkeit des Access-Tokens testen
        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)}"
            )

Verwenden von OAuth-Tokens

Verwenden von OAuth-Tokens in einem Tool:

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

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

        yield self.create_text_message(response.text)

Eine vollständige Anleitung zur OAuth-Integration finden Sie unter: development/oauth-integration.md


Testen und Debugging

Unit-Tests

Schreiben von Unit-Tests mit 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

Tests ausführen:

pytest tests/

Integrationstests

Testen der Integration des Plugins mit dem Dify-System:

# tests/test_integration.py
def test_plugin_integration():
    # Plugin-Installation testen
    # Werkzeugaufruf testen
    # OAuth-Ablauf testen
    pass

Debuggen mit der Debug-Laufzeit

Starten der Debug-Laufzeit für Remote-Debugging:

# Debug-Laufzeit starten
dify plugin run --debug

# In der Dify-Oberfläche testen
# Live-Logs und Fehlermeldungen anzeigen

Fehlerbehebung bei häufigen Problemen

Plugin-Start fehlgeschlagen

  • Python-Version überprüfen (3.12+ erforderlich)
  • Abhängigkeitsinstallation überprüfen (requirements.txt)
  • manifest.yaml-Konfiguration überprüfen
  • Pfad der Einstiegspunktdatei überprüfen (main.py)

Berechtigungsvalidierung fehlgeschlagen

  • credentials-Konfiguration überprüfen
  • Überprüfen, ob OAuth-Token abgelaufen ist
  • Überprüfen, ob der API-Schlüssel gültig ist
  • Berechtigungsdeklaration überprüfen (resource.permission)

Laufzeitfehler

  • Timeout-Wert anpassen (MAX_REQUEST_TIMEOUT)
  • Speichernutzung optimieren (resource.memory)
  • Netzwerkverbindung überprüfen
  • Rückrufberechtigungen überprüfen

Eine detaillierte Anleitung zur Fehlerbehebung finden Sie unter: testing/troubleshooting.md


Migration von APIs zu Plugins

Migrationsstrategie

  1. API-Wrapper-Modus: REST-API als Tool-Plugin kapseln
  2. SDK-Integrationsmodus: Verwendung eines Python SDK eines Drittanbieters
  3. OAuth-Migration: Implementierung des OAuth 2.0-Autorisierungsablaufs
  4. Batch-Verarbeitungsoptimierung: Verwendung von Streaming-Antworten für große Datenmengen

Migrationsschritte

  1. Vorhandene API analysieren

    • API-Endpunkte und Parameter
    • Authentifizierungsmethode (API-Key / OAuth)
    • Antwortformat und Fehlerbehandlung
  2. Plugin-Typ auswählen

    • REST API → Tool-Plugin
    • LLM API → Model-Plugin
    • Storage API → Datasource-Plugin
  3. Plugin-Projekt erstellen

    dify plugin init
    
  4. API-Aufruf implementieren

    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. Authentifizierung konfigurieren

    • API-Key: credentials in provider.yaml konfigurieren
    • OAuth: oauth_schema konfigurieren
  6. Fehlerbehandlung hinzufügen

    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. Tests schreiben

    def test_api_wrapper():
        tool = APIWrapperTool()
        result = list(tool.invoke(tool_parameters={...}))
        assert result[0].message
    
  8. Paketieren und bereitstellen

    dify plugin package
    

Praxisbeispiele

  • REST API → Tool: Google Translate (keine Authentifizierung)
  • OAuth API → Tool: Google Contacts (OAuth 2.0)
  • LLM API → Model: Anthropic Claude (API-Key)
  • Storage API → Datasource: AWS S3 (IAM-Authentifizierung)

Eine detaillierte Migrationsanleitung finden Sie unter: development/migration-guide.md


Bewährte Methoden

Code-Organisation

  1. Einzelverantwortung: Jedes Tool macht nur eine Sache
  2. Fehlerbehandlung: Alle Ausnahmen abfangen und benutzerfreundliche Fehlermeldungen zurückgeben
  3. Parametervalidierung: Alle Parameter zu Beginn von _invoke validieren
  4. Protokollierung: Strukturierte Protokollierung für kritische Vorgänge

Leistungsoptimierung

  1. Streaming-Antworten: Verwendung von Generator für Streaming großer Datenmengen
  2. Cache-Strategie: Häufig abgerufene Daten zwischenspeichern
  3. Asynchrone Verarbeitung: Verwendung von async/await für I/O-intensive Vorgänge
  4. Ressourcenbeschränkungen: resource.memory angemessen konfigurieren

Sicherheitsaspekte

  1. Eingabevalidierung: Alle Benutzereingaben validieren
  2. Sensible Daten: Verwendung von secret-input für die Speicherung sensibler Informationen
  3. Zugriffskontrolle: Prinzip der minimalen Berechtigung, nur notwendige Berechtigungen deklarieren
  4. Fehlermeldungen: Keine sensiblen Daten in Fehlermeldungen preisgeben

Benutzererfahrung

  1. Klare Beschreibungen: Bereitstellung detaillierter description und help
  2. Sinnvolle Standardwerte: Bereitstellung sinnvoller Standardwerte für Parameter
  3. Mehrsprachige Unterstützung: Mindestens en_US und zh_Hans unterstützen
  4. Benutzerfreundliche Fehler: Rückgabe von für den Benutzer verständlichen Fehlermeldungen

Bereitstellung und Betrieb

Auswahl des Laufzeitmodus

SzenarioEmpfohlener ModusGrund
Lokale EntwicklungLocal RuntimeNiedrige Latenz, einfaches Debugging
Remote-DebuggingDebug RuntimeFlexibel, Remote-Unterstützung
Kleine ProduktionLocal RuntimeEinfach, geringe Kosten
Große ProduktionServerless RuntimeAutomatische Skalierung, hohe Verfügbarkeit

Serverless-Bereitstellung

Bereitstellung auf AWS Lambda:

# 1. Plugin paketieren
dify plugin package

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

# 3. Umgebungsvariablen konfigurieren
aws lambda update-function-configuration \
  --function-name my-plugin \
  --environment Variables={...}

Überwachung und Protokollierung

  1. Strukturierte Protokollierung: Verwendung von JSON-Format für Logs
  2. Metriken erfassen: Latenz, Fehlerrate, Speichernutzung
  3. Alarme einrichten: Alarme für anormales Verhalten konfigurieren
  4. Tracing verteilter Systeme: Implementierung von verteiltem Tracing für komplexe Workflows

Anhang

Referenzen

API-Referenz

Beispiele

Individual skills in this repo

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

Verwandte Skills