CommunityPesquisa e Análise de Dadosgithub.com

SystemTce/dify-skills

Guia completo para desenvolvimento de plugins Dify, abrangendo os quatro tipos de plugins: ferramenta, modelo, fonte de dados e extensão.

O que é dify-skills?

Este skill fornece um guia completo e detalhado para o desenvolvimento de plugins na plataforma Dify, cobrindo desde a configuração inicial do ambiente até tópicos avançados como integração OAuth 2.0 e implantação Serverless. O Dify utiliza a arquitetura inovadora Beehive (favo de mel), que suporta três modos de execução (Local, Debug e Serverless) e oferece quatro tipos de plugins: Ferramenta (Tool), Modelo (Model), Fonte de Dados (Datasource) e Extensão (Extension). O guia inclui instruções passo a passo para criar, depurar e empacotar plugins usando o CLI `dify`, além de exemplos práticos de código em Python para implementar a lógica, configurar a autenticação OAuth 2.0 e realizar testes. É um recurso essencial para desenvolvedores que desejam estender as capacidades do Dify, integrar serviços de terceiros ou migrar APIs existentes para o ecossistema de plugins, seguindo as melhores práticas de segurança, desempenho e organização de código.

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

Installed? Explore more Pesquisa e Análise de Dados skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

SKILL DE DESENVOLVIMENTO DE PLUGINS DIFY

Visão Geral

O sistema de plugins do Dify adota a arquitetura inovadora Beehive (Favo de Mel), suportando três modos de execução e oferecendo quatro tipos de plugins, fornecendo aos desenvolvedores poderosas capacidades de extensão. Este SKILL oferece um guia completo de desenvolvimento de plugins, do básico ao avançado.

Cenários de Uso

Use este SKILL quando precisar dos seguintes cenários:

  • Desenvolver plugins Dify: Quatro tipos: Ferramenta, Modelo, Fonte de Dados, Extensão
  • Integrar serviços de terceiros: Wrapper de API, autorização OAuth
  • Implementar ferramentas personalizadas: Expandir capacidades de IA
  • Estender funcionalidades da plataforma Dify: Gatilhos, estratégias de Agente
  • Migrar APIs existentes para plugins: Conversão de API para plugin
  • Depurar e otimizar o desempenho de plugins: Ajuste de desempenho e solução de problemas

Valor Principal

  • Arquitetura Beehive: Escalonamento descentralizado, eleição líder-seguidor, autocura de falhas
  • Suporte a múltiplos runtimes: Três modos: Local, Debug, Serverless
  • Conjunto completo de ferramentas: CLI dify, SDK Python, runtime de depuração
  • Ecossistema rico: Mais de 70 plugins de modelo, 20+ plugins de ferramenta, 18+ plugins de fonte de dados
  • Qualidade de produção: OAuth 2.0, controle de permissão, monitoramento e rastreamento

Início Rápido

1. Preparação do Ambiente

# Instalar Python 3.12+
python --version  # Garantir >= 3.12

# Instalar o gerenciador de pacotes uv (recomendado)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Instalar o CLI do Dify
pip install dify-cli

# Verificar a instalação
dify --version

2. Criar o Primeiro Plugin

# Inicializar o projeto do plugin
dify plugin init

# Selecionar o tipo de plugin
? Select plugin type: Tool
? Plugin name: my_first_tool
? Author: your_name
? Description: Meu primeiro plugin de ferramenta Dify

# Entrar no diretório do projeto
cd my_first_tool

# Instalar dependências
uv pip install -r requirements.txt

3. Implementar a Lógica do 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]:
        """
        Ponto de entrada da chamada da ferramenta
        """
        # Obter parâmetros
        text = tool_parameters.get("text", "")

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

        # Retornar resultado
        yield self.create_text_message(result)

4. Depuração Local

# Iniciar o Debug Runtime
dify plugin run

# Testar o plugin na interface do Dify
# Acessar http://localhost:5001

5. Empacotar e Implantar

# Empacotar o plugin
dify plugin package

# Gera o arquivo my_first_tool.difypkg
# Fazer upload para o Dify Marketplace ou implantação privada

Conceitos Principais

Arquitetura Beehive

O sistema de plugins do Dify adota a arquitetura Beehive (Favo de Mel), com características principais:

  1. Escalonamento Descentralizado: Cada nó do processo daemon gerencia plugins locais de forma independente
  2. Eleição Líder-Seguidor: Usa bloqueio distribuído do Redis para eleição automática do nó líder
  3. Sincronização de Estado: O estado de todos os nós é armazenado no Redis, suportando acesso entre nós
  4. Autocura de Falhas: Quando um nó cai, os plugins são automaticamente redistribuídos

Para uma descrição detalhada da arquitetura, consulte: types/architecture.md

Três Modos de Runtime

Modo de RuntimeCenário de UsoMétodo de ComunicaçãoVantagensDesvantagens
Local RuntimeDesenvolvimento local, implantação de pequena escalaSTDIN/STDOUTBaixa latência, isolamento de recursosAlto consumo de memória, escalabilidade limitada
Debug RuntimeDepuração remota, ambiente de desenvolvimentoTCP full-duplexAmigável para desenvolvimento, implantação flexívelDependência de rede, gerenciamento de estado complexo
Serverless RuntimeAmbiente de produção em larga escalaHTTP/SSEEscalonamento automático, otimização de custosLatência de inicialização a frio, depuração complexa

Para uma comparação detalhada, consulte: development/runtime-modes.md

Quatro Tipos de Plugins

1. Tool (Plugin de Ferramenta)

Ferramentas que expandem as capacidades de IA, como tradução, pesquisa, processamento de dados, etc.

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

Cenários de Uso:

  • Wrapper de API (REST API → Tool)
  • Processamento de dados (conversão de formato, cálculos)
  • Integração de serviços externos (pesquisa, tradução)

2. Model (Plugin de Modelo)

Conectar provedores de LLM, como Anthropic, OpenAI, Gemini, etc.

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

Cenários de Uso:

  • Conectar novos provedores de LLM
  • Configuração personalizada de modelo
  • Suporte a modelos multimodais

3. Datasource (Plugin de Fonte de Dados)

Conectar sistemas de armazenamento, como S3, Google Drive, Notion, etc.

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

Cenários de Uso:

  • Integração com armazenamento em nuvem
  • Conexão com plataformas de documentos
  • Acesso a bancos de dados

4. Extension (Plugin de Extensão)

Extensões de funcionalidades da plataforma, como integração com plataformas de terceiros (Slack, WeCom, etc.).

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

Cenários de Uso:

  • Integração com plataformas de terceiros
  • Implementação de gatilhos
  • Estratégias personalizadas de Agente

Para descrições detalhadas dos tipos, consulte: types/


Estrutura do Projeto

Estrutura padrão de um projeto de plugin Dify:

my_plugin/
├── manifest.yaml           # Manifesto do plugin (obrigatório)
├── main.py                 # Arquivo de entrada (obrigatório)
├── requirements.txt        # Dependências Python
├── pyproject.toml         # Configuração do projeto
├── README.md              # Descrição do plugin
├── PRIVACY.md             # Política de privacidade (se necessário OAuth)
├── .env.example           # Exemplo de variáveis de ambiente
│
├── _assets/               # Arquivos de recursos
│   └── icon.svg          # Ícone do plugin
│
├── provider/              # Configuração do provedor
│   ├── provider_name.yaml # Arquivo de configuração do provedor
│   └── provider_name.py   # Implementação do provedor
│
└── tools/                 # Implementação da ferramenta (Plugin Tool)
    ├── tool_name.yaml    # Arquivo de configuração da ferramenta
    └── tool_name.py      # Implementação da ferramenta

Descrição dos Arquivos Principais

manifest.yaml

Arquivo de manifesto do plugin, definindo as informações básicas e configuração:

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

Para configuração detalhada, consulte: development/manifest.md

main.py

Arquivo de entrada do plugin:

from dify_plugin import Plugin, DifyPluginEnv

# Criar instância do plugin
plugin = Plugin(DifyPluginEnv(MAX_REQUEST_TIMEOUT=120))

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

Guia de Desenvolvimento

Desenvolvimento de Plugin Tool

1. Criar o Provider

Edite 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

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 credenciais (se necessário)
        """
        try:
            # Validar chave de API ou outras credenciais
            api_key = credentials.get("api_key")
            if not api_key:
                raise ToolProviderCredentialValidationError("API Key é obrigatória")

            # Testar a validade das credenciais
            MyTool().invoke(
                tool_parameters={"text": "teste"}
            )
        except Exception as e:
            raise ToolProviderCredentialValidationError(str(e))

2. Criar a Tool

Edite 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

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]:
        """
        Ponto de entrada da chamada da ferramenta

        Args:
            tool_parameters: Dicionário de parâmetros da ferramenta

        Yields:
            ToolInvokeMessage: Mensagem de chamada da ferramenta
        """
        # 1. Obter parâmetros
        text = tool_parameters.get("text", "")

        if not text:
            yield self.create_text_message("Erro: parâmetro 'text' é obrigatório")
            return

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

            # 3. Retornar resultado
            yield self.create_text_message(result)

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

    def _process_text(self, text: str) -> str:
        """
        Lógica específica para processar o texto
        """
        return text.upper()

Para um guia de desenvolvimento detalhado, consulte: development/tool.md


Integração OAuth 2.0

Visão Geral do Fluxo OAuth

O Dify suporta o fluxo de autorização OAuth 2.0 completo:

  1. Obter URL de Autorização: O usuário clica no botão de autorização
  2. Autorização do Usuário: Redireciona para a página de autorização do serviço de terceiros
  3. Obter Código de Autorização: Após a autorização do usuário, retorna o código de autorização
  4. Trocar por Token de Acesso: Usa o código de autorização para trocar por um token de acesso
  5. Atualizar Token: Quando o token de acesso expira, usa o token de atualização para obter um novo token

Configurar o Schema OAuth

Adicione a configuração OAuth em provider/my_provider.yaml:

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

Implementar um 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 credenciais OAuth
        """
        access_token = credentials.get("access_token")
        if not access_token:
            raise ToolProviderCredentialValidationError(
                "Token de acesso é obrigatório"
            )

        # Testar a validade do token de acesso
        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 acesso inválido: {str(e)}"
            )

Usar Token OAuth em uma Tool

Use o token OAuth dentro da Tool:

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

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

        yield self.create_text_message(response.text)

Para um guia completo de integração OAuth, consulte: development/oauth-integration.md


Testes e Depuração

Testes Unitários

Use pytest para escrever testes unitários:

# 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

Execute os testes:

pytest tests/

Testes de Integração

Teste a integração do plugin com o sistema Dify:

# tests/test_integration.py
def test_plugin_integration():
    # Testar instalação do plugin
    # Testar chamada da ferramenta
    # Testar fluxo OAuth
    pass

Depuração com Debug Runtime

Inicie o Debug Runtime para depuração remota:

# Iniciar o Debug Runtime
dify plugin run --debug

# Testar na interface do Dify
# Ver logs e mensagens de erro em tempo real

Solução de Problemas Comuns

Falha ao Iniciar o Plugin

  • Verificar a versão do Python (precisa ser 3.12+)
  • Verificar a instalação das dependências (requirements.txt)
  • Verificar a configuração do manifest.yaml
  • Verificar o caminho do arquivo de entrada (main.py)

Falha na Validação de Permissão

  • Verificar a configuração de credentials
  • Verificar se o token OAuth expirou
  • Verificar se a chave de API é válida
  • Verificar a declaração de permissão (resource.permission)

Erros em Tempo de Execução

  • Ajustar o tempo limite (MAX_REQUEST_TIMEOUT)
  • Otimizar o uso de memória (resource.memory)
  • Verificar a conexão de rede
  • Verificar a permissão de chamada reversa

Para um guia detalhado de solução de problemas, consulte: testing/troubleshooting.md


Migração de API para Plugin

Estratégia de Migração

  1. Modo Wrapper de API: Empacotar uma REST API como um plugin Tool
  2. Modo de Integração com SDK: Usar SDK Python de terceiros
  3. Migração OAuth: Implementar o fluxo de autorização OAuth 2.0
  4. Otimização de Operações em Lote: Usar respostas em streaming para processar grandes volumes de dados

Etapas da Migração

  1. Analisar a API Existente

    • Endpoints e parâmetros da API
    • Método de autenticação (API Key / OAuth)
    • Formato de resposta e tratamento de erros
  2. Selecionar o Tipo de Plugin

    • REST API → Plugin Tool
    • API de LLM → Plugin Model
    • API de Armazenamento → Plugin Datasource
  3. Criar o Projeto do Plugin

    dify plugin init
    
  4. Implementar a Chamada à 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 Autenticação

    • Chave de API: Configurar credentials em provider.yaml
    • OAuth: Configurar oauth_schema
  6. Adicionar Tratamento de Erros

    try:
        response = requests.post(...)
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        yield self.create_text_message(f"Erro na API: {str(e)}")
    
  7. Escrever Testes

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

    dify plugin package
    

Exemplos Práticos

  • REST API → Tool: Google Translate (sem autenticação)
  • API OAuth → Tool: Google Contacts (OAuth 2.0)
  • API de LLM → Model: Anthropic Claude (Chave de API)
  • API de Armazenamento → Datasource: AWS S3 (autenticação IAM)

Para um guia detalhado de migração, consulte: development/migration-guide.md


Melhores Práticas

Organização do Código

  1. Responsabilidade Única: Cada Tool faz apenas uma coisa
  2. Tratamento de Erros: Capture todas as exceções e retorne mensagens de erro amigáveis
  3. Validação de Parâmetros: Valide todos os parâmetros no início do _invoke
  4. Registro em Log: Use logs estruturados para registrar operações críticas

Otimização de Desempenho

  1. Respostas em Streaming: Use Generator para retornar grandes dados em streaming
  2. Estratégia de Cache: Armazene em cache dados acessados com frequência
  3. Processamento Assíncrono: Use async/await para operações intensivas de I/O
  4. Limites de Recursos: Configure resource.memory adequadamente

Considerações de Segurança

  1. Validação de Entrada: Valide todas as entradas do usuário
  2. Dados Sensíveis: Use o tipo secret-input para armazenar informações confidenciais
  3. Controle de Permissão: Princípio do menor privilégio, declare apenas as permissões necessárias
  4. Mensagens de Erro: Não vaze dados sensíveis em mensagens de erro

Experiência do Usuário

  1. Descrições Claras: Forneça description e help detalhados
  2. Valores Padrão Razoáveis: Forneça valores padrão adequados para os parâmetros
  3. Suporte a Múltiplos Idiomas: Suporte pelo menos en_US e zh_Hans
  4. Erros Amigáveis: Retorne mensagens de erro compreensíveis para o usuário

Implantação e Operação

Escolha do Modo de Runtime

CenárioModo RecomendadoMotivo
Desenvolvimento localLocal RuntimeBaixa latência, fácil depuração
Depuração remotaDebug RuntimeFlexível, suporta remoto
Produção de pequena escalaLocal RuntimeSimples, baixo custo
Produção em larga escalaServerless RuntimeEscalonamento automático, alta disponibilidade

Implantação Serverless

Implantação no AWS Lambda:

# 1. Empacotar o plugin
dify plugin package

# 2. Criar função Lambda
aws lambda create-function \
  --function-name my-plugin \
  --runtime python3.12 \
  --handler main.handler \
  --zip-file fileb://my_plugin.difypkg

# 3. Configurar variáveis de ambiente
aws lambda update-function-configuration \
  --function-name my-plugin \
  --environment Variab

…

[truncado para tradução]

Individual skills in this repo

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

Habilidades Relacionadas