SistemaTce/dify-skills

Guía completa para el desarrollo de plugins de Dify, que abarca cuatro tipos de plugins: herramientas, modelos, fuentes de datos y extensiones.

¿Qué es dify-skills?

Esta habilidad proporciona una guía exhaustiva para el desarrollo de plugins en la plataforma Dify, que emplea la innovadora arquitectura Beehive (colmena). Permite a los desarrolladores crear plugins de cuatro tipos: herramientas para extender capacidades de IA, modelos para integrar proveedores de LLM como Anthropic u OpenAI, fuentes de datos para conectar almacenamiento externo como S3 o Google Drive, y extensiones para funciones de plataforma como la integración con Slack. La guía cubre desde la configuración del entorno y la creación del primer plugin hasta temas avanzados como la integración OAuth 2.0, estrategias de migración de API a plugin, pruebas, depuración y mejores prácticas de implementación, incluyendo la gestión de recursos y seguridad. Es compatible con Dify y los plugins se pueden empaquetar e implementar en modo local, debug o serverless.

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

Installed? Explore more Investigación y análisis de datos skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

HABILIDAD: Desarrollo de plugins de Dify

Descripción general

El sistema de plugins de Dify emplea la innovadora arquitectura Beehive (colmena), que soporta tres modos de ejecución y ofrece cuatro tipos de plugins, proporcionando a los desarrolladores una potente capacidad de extensión. Esta habilidad proporciona una guía completa para el desarrollo de plugins, desde el nivel básico hasta el avanzado.

Casos de uso

Utilice esta habilidad cuando necesite:

  • Desarrollar plugins de Dify: cuatro tipos: herramientas, modelos, fuentes de datos y extensiones
  • Integrar servicios de terceros: envoltorios de API, autorización OAuth
  • Implementar herramientas personalizadas: extender las capacidades de IA
  • Ampliar la funcionalidad de la plataforma Dify: disparadores, estrategias de agente
  • Migrar API existentes a plugins: conversión de API a plugin
  • Depurar y optimizar el rendimiento de plugins: ajuste de rendimiento y resolución de problemas

Valor principal

  • Arquitectura Beehive: programación descentralizada, elección maestro-esclavo, autocuración de fallos
  • Soporte de múltiples entornos de ejecución: modos Local, Debug y Serverless
  • Conjunto de herramientas completo: CLI de dify, SDK de Python, entorno de ejecución de depuración
  • Ecosistema rico: más de 70 plugins de modelo, más de 20 plugins de herramienta, más de 18 plugins de fuente de datos
  • Calidad de producción: OAuth 2.0, control de permisos, monitoreo y seguimiento

Inicio rápido

1. Preparación del entorno

# Instalar Python 3.12+
python --version  # Asegúrese de que sea >= 3.12

# Instalar el gestor de paquetes uv (recomendado)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Instalar dify CLI
pip install dify-cli

# Verificar la instalación
dify --version

2. Crear el primer plugin

# Inicializar el proyecto de plugin
dify plugin init

# Seleccionar el tipo de plugin
? Select plugin type: Tool
? Plugin name: my_first_tool
? Author: your_name
? Description: My first Dify tool plugin

# Entrar en el directorio del proyecto
cd my_first_tool

# Instalar dependencias
uv pip install -r requirements.txt

3. Implementar la lógica del plugin

Edite 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]:
        """
        Punto de entrada de la invocación de la herramienta
        """
        # Obtener parámetros
        text = tool_parameters.get("text", "")

        # Lógica de procesamiento
        result = f"Resultado del procesamiento: {text.upper()}"

        # Devolver resultado
        yield self.create_text_message(result)

4. Depuración local

# Iniciar Debug Runtime
dify plugin run

# Probar el plugin en la interfaz de Dify
# Visitar http://localhost:5001

5. Empaquetado e implementación

# Empaquetar el plugin
dify plugin package

# Genera el archivo my_first_tool.difypkg
# Subir a Dify Marketplace o implementación privada

Conceptos principales

Arquitectura Beehive

El sistema de plugins de Dify emplea la arquitectura Beehive (colmena), con las siguientes características principales:

  1. Programación descentralizada: cada nodo del daemon gestiona los plugins locales de forma independiente
  2. Elección maestro-esclavo: utiliza bloqueos distribuidos de Redis para la elección automática del nodo maestro
  3. Sincronización de estado: el estado de todos los nodos se almacena en Redis, lo que permite el acceso entre nodos
  4. Autocuración de fallos: cuando un nodo falla, los plugins se reasignan automáticamente

Para obtener una descripción arquitectónica detallada, consulte: tipos/architecture.md

Tres modos de ejecución

Modo de ejecuciónCaso de usoMétodo de comunicaciónVentajasDesventajas
Local RuntimeDesarrollo local, implementación a pequeña escalaSTDIN/STDOUTBaja latencia, aislamiento de recursosAlto uso de memoria, escalabilidad limitada
Debug RuntimeDepuración remota, entorno de desarrolloTCP dúplex completoAmigable para el desarrollo, implementación flexibleDependencia de red, gestión de estado compleja
Serverless RuntimeEntornos de producción a gran escalaHTTP/SSEAutoescalado, optimización de costosLatencia de inicio en frío, depuración compleja

Para una comparación detallada, consulte: desarrollo/modos-ejecucion.md

Cuatro tipos de plugins

1. Tool (Plugin de herramienta)

Herramientas que extienden las capacidades de IA, como traducción, búsqueda, procesamiento de datos, etc.

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

Casos de uso:

  • Envoltorio de API (REST API → Tool)
  • Procesamiento de datos (conversión de formatos, cálculos)
  • Integración de servicios externos (búsqueda, traducción)

2. Model (Plugin de modelo)

Integra proveedores de LLM, como Anthropic, OpenAI, Gemini, etc.

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

Casos de uso:

  • Integrar nuevos proveedores de LLM
  • Configuración personalizada de modelos
  • Soporte de modelos multimodales

3. Datasource (Plugin de fuente de datos)

Conecta sistemas de almacenamiento, como S3, Google Drive, Notion, etc.

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

Casos de uso:

  • Integración de almacenamiento en la nube
  • Conexión a plataformas de documentos
  • Acceso a bases de datos

4. Extension (Plugin de extensión)

Extiende la funcionalidad de la plataforma, como la integración de Slack, WeChat empresarial, etc.

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

Casos de uso:

  • Integración de plataformas de terceros
  • Implementación de disparadores
  • Estrategias personalizadas de agente

Para obtener una descripción detallada de los tipos, consulte: tipos/


Estructura del proyecto

Estructura estándar de un proyecto de plugin de Dify:

my_plugin/
├── manifest.yaml           # Manifiesto del plugin (requerido)
├── main.py                 # Archivo de entrada (requerido)
├── requirements.txt        # Dependencias de Python
├── pyproject.toml         # Configuración del proyecto
├── README.md              # Descripción del plugin
├── PRIVACY.md             # Política de privacidad (si requiere OAuth)
├── .env.example           # Ejemplo de variables de entorno
│
├── _assets/               # Archivos de recursos
│   └── icon.svg          # Icono del plugin
│
├── provider/              # Configuración del proveedor
│   ├── provider_name.yaml # Archivo de configuración del proveedor
│   └── provider_name.py   # Implementación del proveedor
│
└── tools/                 # Implementación de herramientas (Plugin Tool)
    ├── tool_name.yaml    # Archivo de configuración de la herramienta
    └── tool_name.py      # Implementación de la herramienta

Descripción de archivos principales

manifest.yaml

Archivo de manifiesto del plugin, que define la información básica y la configuración del plugin:

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

description:
  en_US: Plugin description
  zh_Hans: Descripción del plugin

label:
  en_US: My Plugin
  zh_Hans: Mi Plugin

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

Para obtener instrucciones de configuración detalladas, consulte: desarrollo/manifest.md

main.py

Archivo de entrada del plugin:

from dify_plugin import Plugin, DifyPluginEnv

# Crear instancia del plugin
plugin = Plugin(DifyPluginEnv(MAX_REQUEST_TIMEOUT=120))

if __name__ == '__main__':
    # Iniciar el plugin
    plugin.run()

Guía de desarrollo

Desarrollo de plugins Tool

1. Crear el Provider

Edite provider/my_provider.yaml:

identity:
  author: your_name
  name: my_provider
  label:
    en_US: My Provider
    zh_Hans: Mi Proveedor
  description:
    en_US: Provider description
    zh_Hans: Descripción del proveedor
  icon: icon.svg
  tags:
    - utilities

extra:
  python:
    source: provider/my_provider.py

tools:
  - tools/my_tool.yaml

Edite 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:
        """
        Validar credenciales (si es necesario)
        """
        try:
            # Validar API Key u otras credenciales
            api_key = credentials.get("api_key")
            if not api_key:
                raise ToolProviderCredentialValidationError("API Key es requerida")

            # Probar la validez de las credenciales
            MyTool().invoke(
                tool_parameters={"text": "test"}
            )
        except Exception as e:
            raise ToolProviderCredentialValidationError(str(e))

2. Crear la Tool

Edite tools/my_tool.yaml:

identity:
  author: your_name
  name: my_tool
  label:
    en_US: My Tool
    zh_Hans: Mi Herramienta

description:
  human:
    en_US: Tool description for humans
    zh_Hans: Descripción de la herramienta para humanos
  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: Texto de entrada
    human_description:
      en_US: The text to process
      zh_Hans: El texto a procesar
    llm_description: The input text to be processed
    form: llm

Edite 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]:
        """
        Punto de entrada de la invocación de la herramienta

        Args:
            tool_parameters: Diccionario de parámetros de la herramienta

        Yields:
            ToolInvokeMessage: Mensaje de invocación de la herramienta
        """
        # 1. Obtener parámetros
        text = tool_parameters.get("text", "")

        if not text:
            yield self.create_text_message("Error: el parámetro text es requerido")
            return

        try:
            # 2. Lógica de procesamiento
            result = self._process_text(text)

            # 3. Devolver resultado
            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:
        """
        Lógica específica para procesar texto
        """
        return text.upper()

Para obtener una guía de desarrollo detallada, consulte: desarrollo/tool.md


Integración OAuth 2.0

Resumen del flujo OAuth

Dify soporta el flujo de autorización OAuth 2.0 completo:

  1. Obtener URL de autorización: el usuario hace clic en el botón de autorización
  2. Autorización del usuario: redirige a la página de autorización del servicio de terceros
  3. Obtener código de autorización: el usuario autoriza y devuelve un código de autorización
  4. Intercambiar por token de acceso: utiliza el código de autorización para intercambiar por un token de acceso
  5. Actualizar token: cuando el token de acceso caduca, utiliza el token de actualización para obtener uno nuevo

Configurar el esquema OAuth

Añada la configuración OAuth en provider/my_provider.yaml:

oauth_schema:
  client_schema:
    - name: client_id
      type: secret-input
      required: true
      label:
        en_US: Client ID
        zh_Hans: ID de Cliente
      placeholder:
        en_US: Enter your OAuth Client ID
        zh_Hans: Ingrese su ID de Cliente OAuth
      help:
        en_US: Get your client ID from the service provider
        zh_Hans: Obtenga su ID de Cliente del proveedor de servicios
      url: https://console.example.com/credentials

    - name: client_secret
      type: secret-input
      required: true
      label:
        en_US: Client Secret
        zh_Hans: Secreto de Cliente
      placeholder:
        en_US: Enter your OAuth Client Secret
        zh_Hans: Ingrese su Secreto de Cliente OAuth

  credentials_schema:
    - name: access_token
      type: secret-input
      label:
        en_US: Access Token
        zh_Hans: Token de Acceso

    - name: refresh_token
      type: secret-input
      label:
        en_US: Refresh Token
        zh_Hans: Token de Actualización

Implementar el Provider OAuth

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:
        """
        Validar credenciales OAuth
        """
        access_token = credentials.get("access_token")
        if not access_token:
            raise ToolProviderCredentialValidationError(
                "El token de acceso es requerido"
            )

        # Probar la validez del token de acceso
        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"Token de acceso inválido: {str(e)}"
            )

Usar el token OAuth

Use el token OAuth en la herramienta:

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

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

        yield self.create_text_message(response.text)

Para obtener una guía completa de integración OAuth, consulte: desarrollo/integracion-oauth.md


Pruebas y depuración

Pruebas unitarias

Escriba pruebas unitarias con 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

Ejecute las pruebas:

pytest tests/

Pruebas de integración

Pruebe la integración del plugin con el sistema Dify:

# tests/test_integration.py
def test_plugin_integration():
    # Probar la instalación del plugin
    # Probar la invocación de la herramienta
    # Probar el flujo OAuth
    pass

Depuración con Debug Runtime

Inicie Debug Runtime para depuración remota:

# Iniciar Debug Runtime
dify plugin run --debug

# Probar en la interfaz de Dify
# Ver registros en tiempo real y mensajes de error

Solución de problemas comunes

El plugin no se inicia

  • Verifique la versión de Python (se necesita 3.12+)
  • Verifique la instalación de dependencias (requirements.txt)
  • Verifique la configuración de manifest.yaml
  • Verifique la ruta del archivo de entrada (main.py)

Error de validación de permisos

  • Verifique la configuración de credentials
  • Verifique si el token OAuth ha caducado
  • Verifique si la API Key es válida
  • Verifique la declaración de permisos (resource.permission)

Errores en tiempo de ejecución

  • Ajuste el tiempo de espera (MAX_REQUEST_TIMEOUT)
  • Optimice el uso de memoria (resource.memory)
  • Verifique la conexión de red
  • Verifique los permisos de invocación inversa

Para obtener una guía detallada de solución de problemas, consulte: pruebas/solucion-problemas.md


Migración de API a plugin

Estrategias de migración

  1. Modo envoltorio de API: empaquetar la API REST como un plugin Tool
  2. Modo integración SDK: utilizar SDK de Python de terceros
  3. Migración OAuth: implementar el flujo de autorización OAuth 2.0
  4. Optimización de operaciones por lotes: utilizar respuestas de streaming para manejar grandes volúmenes de datos

Pasos de migración

  1. Analizar la API existente

    • Endpoints y parámetros de la API
    • Método de autenticación (API Key / OAuth)
    • Formato de respuesta y manejo de errores
  2. Seleccionar el tipo de plugin

    • REST API → Plugin Tool
    • LLM API → Plugin Model
    • API de almacenamiento → Plugin Datasource
  3. Crear el proyecto de plugin

    dify plugin init
    
  4. Implementar la llamada a la 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. Configurar la autenticación

    • API Key: configurar credentials en provider.yaml
    • OAuth: configurar oauth_schema
  6. Añadir manejo de errores

    try:
        response = requests.post(...)
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        yield self.create_text_message(f"Error de API: {str(e)}")
    
  7. Escribir pruebas

    def test_api_wrapper():
        tool = APIWrapperTool()
        result = list(tool.invoke(tool_parameters={...}))
        assert result[0].message
    
  8. Empaquetar e implementar

    dify plugin package
    

Casos prácticos

  • REST API → Tool: Google Translate (sin autenticación)
  • OAuth API → Tool: Google Contacts (OAuth 2.0)
  • LLM API → Model: Anthropic Claude (API Key)
  • API de almacenamiento → Datasource: AWS S3 (autenticación IAM)

Para obtener una guía de migración detallada, consulte: desarrollo/guia-migracion.md


Mejores prácticas

Organización del código

  1. Responsabilidad única: cada Tool debe hacer solo una cosa
  2. Manejo de errores: capturar todas las excepciones y devolver mensajes de error amigables
  3. Validación de parámetros: validar todos los parámetros al inicio de _invoke
  4. Registro de actividad: utilizar registros estructurados para registrar operaciones clave

Optimización del rendimiento

  1. Respuestas de streaming: utilizar Generator para devolver datos grandes de forma continua
  2. Estrategia de caché: almacenar en caché los datos a los que se accede con frecuencia
  3. Procesamiento asíncrono: utilizar async/await para operaciones intensivas de E/S
  4. Límites de recursos: configurar adecuadamente resource.memory

Consideraciones de seguridad

  1. Validación de entrada: validar todas las entradas del usuario
  2. Datos sensibles: utilizar el tipo secret-input para almacenar información sensible
  3. Control de permisos: principio de mínimo privilegio, declarar solo los permisos necesarios
  4. Mensajes de error: no filtrar datos sensibles en los mensajes de error

Experiencia de usuario

  1. Descripciones claras: proporcionar description y help detallados
  2. Valores predeterminados razonables: proporcionar valores predeterminados adecuados para los parámetros
  3. Soporte multilingüe: al menos soportar en_US y zh_Hans
  4. Errores amigables: devolver mensajes de error que el usuario pueda entender

Implementación y operación

Selección del modo de ejecución

EscenarioModo recomendadoRazón
Desarrollo localLocal RuntimeBaja latencia, fácil depuración
Depuración remotaDebug RuntimeFlexible, compatible con remoto
Producción a pequeña escalaLocal RuntimeSimple, bajo costo
Producción a gran escalaServerless RuntimeAutoescalado, alta disponibilidad

Implementación Serverless

Implementación en AWS Lambda:

# 1. Empaquetar el plugin
dify plugin package

# 2. Crear la función Lambda
aws lambda create-function \
  --function-name my-plugin \
  --runtime python3.12 \
  --handler main.handler \
  --zip-file fileb://my_plugin.difypkg

# 3. Configurar variables de entorno
aws lambda update-function-configuration \
  --function-name my-plugin \
  --environment Variables={...}

# 4. Probar la función
aws lambda invoke \
  --function-name my-plugin \
  --payload file://test_event.json \
  response.json

Monitoreo y registro

  1. Registros estructurados: registrar todos los eventos clave en formato JSON
  2. Seguimiento de rendimiento: registrar tiempos de ejecución de herramientas
  3. Alertas: configurar alertas umbral para tiempos de espera
  4. Registros de auditoría: registrar todas las llamadas a herramientas para auditoría

Estrategia de versionado

  1. Versionado semántico: seguir el formato MAJOR.MINOR.PATCH
  2. Versión del manifiesto: mantener la consistencia con manifest.yaml
  3. Registro de cambios: mantener un registro detallado de cambios
  4. Retrocompatibilidad: garantizar la compatibilidad entre versiones menores

Recursos

Enlaces de referencia

Documentos relacionados

Individual skills in this repo

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

Skills relacionados