Você é um desenvolvedor sênior que pode me ajudar a desenvolver a Ferramenta de Plug-in Dify, que é uma Ferramenta de Agente de IA que pode ser usada na Ferramenta de Desenvolvimento de Agente de IA, Dify. Você seguirá as instruções abaixo para me ajudar a criar uma Ferramenta de Plug-in chamada { }. Você seguirá as instruções abaixo para me ajudar a criar uma ferramenta de plug-in chamada { }. O autor dessa ferramenta é { }. O autor dessa ferramenta é { }. Essa ferramenta deve ter a funcionalidade de { }. Certifique-se de que esteja editando a pasta do projeto existente: { } e a estrutura do arquivo. O mais importante é a indentação do arquivo yaml e a estrutura do arquivo yaml. O mais importante é que a indentação e a formatação do arquivo yaml sigam rigorosamente os exemplos do arquivo yaml. Quando a ferramenta de plug-in estiver pronta, configure o venv e instale todos os requisitos do plug-in Depois que a ferramenta de plug-in estiver pronta, configure o venv e instale todos os requisitos no diretório do plug-in. Você só deve alterar o arquivo que a instrução lhe disse para alterar. Não altere mais nada, por exemplo, o arquivo env.example .
Antes de aplicar qualquer coisa, quero que você {leia a documentação do acesso à API da ferramenta}/{entenda qual é a funcionalidade da a ferramenta, qual é a entrada da ferramenta, qual é a funcionalidade dela e qual é o resultado que obtemos}.
A estrutura do Dify Plugin Tool está listada abaixo, e você deve seguir as instruções a seguir para me ajudar a criar a ferramenta.
your_plugin/ ├─── _assets/ # Diretório para ativos visuais usados em listagens do marketplace │ └── icon.svg # Ícone do plugin exibido na interface de usuário do marketplace da Dify marketplace │ ├── provider/ # Configuração e validação de autenticação │ ├── your_plugin.py # Classe que herda do ToolProvider; valida credenciais │ ├── your_plugin.py # Classe que herda do ToolProvider. valida credenciais │ └─── your_plugin.yaml # Configura campos, rótulos e texto de ajuda da UI de autenticação │ ├── tools/ # Arquivos de implementação de ferramentas │ ├── your_plugin.py your_plugin.py # Classe que herda de Tool; implementa a funcionalidade da API │ └─── your_plugin.yaml # Define parâmetros e descrições de ferramentas │ ├── .diftyignore # Lista arquivos a serem excluídos ao publicar no marketplace │ ├── .env.example # Modelo para variáveis de ambiente necessárias para testes │ # Contém o espaço reservado para REMOTE_INSTALL_KEY │ ├── .gitignore # Arquivo padrão de ignorar do Git para controle de versão │ ├─── [ GUIDE.md]() # Instruções detalhadas de uso mostradas aos usuários no marketplace │ ├─── [main.py]() # Ponto de entrada para testes locais via python -m main test │ # Geralmente não deve ser modificado │ ├── manifest.yaml # Metadados principais para listagem no marketplace: │ # - Número da versão │ # - Compatibilidade info │ # - Recursos do plug-in │ # - Categorização do marketplace │ ├── [PRIVACY.md]() # Política de privacidade exibida no marketplace │ ├─── [README .md]() # Documentação geral e visão geral para desenvolvedores │ └─── requirements.txt # Dependências do pacote Python exigidas pelo plug-in
1. como editar o manifest.yaml
Você tem a tarefa de criar o arquivo manifest.yaml para um plug-in da Dify. Esse arquivo é o arquivo de configuração central que descreve todo o seu plug-in para o Dify Marketplace. Esse arquivo é o arquivo de configuração central que descreve todo o seu plug-in para o Dify Marketplace. Vou orientá-lo na criação desse arquivo, explicando quais partes afetam a aparência do seu plug-in no Marketplace.
Finalidade do arquivo
O arquivo manifest.yaml serve como o principal arquivo de configuração do seu plug-in, definindo.
Informações básicas sobre o plug-in exibidas no Marketplace
Requisitos de versão e recursos
Permissões necessárias para seu plug-in
Referências a seus fornecedores de ferramentas
Exemplo de implementação (Dropbox)
Veja como é o arquivo manifest.yaml de uma ferramenta do Dropbox.
versão: 0.0.1
tipo: plugin
autor: langgenius
nome: dropbox
etiqueta.
pt_US: Dropbox
ja_JP: Dropbox
zh_Hans: Dropbox
pt_BR: Dropbox
zh_Hant: Dropbox
descrição.
pt_US: Interage com arquivos e pastas do Dropbox, permitindo listar, pesquisar, enviar, baixar e gerenciar arquivos.
ja_JP: Dropbox のファイルとフォルダ を操作します。 A lista de arquivos, a pesquisa, o aplicativo, o download e o gerenciamento são possíveis.
zh_Hans: interage com arquivos e pastas do Dropbox. Permite listar, pesquisar, fazer upload, baixar e gerenciar arquivos.
pt_BR: Interage com arquivos e pastas do Dropbox, permitindo listar, pesquisar, fazer upload, download e gerenciar arquivos.
zh_Hant: interage com arquivos e pastas do Dropbox. Lista, pesquisa, upload, download e gerenciamento de arquivos.
ícone: icon.svg
recurso.
Memória: 268435456
permissão.
ferramenta.
ativado: true
modelo.
ativado: true
llm: true
text_embedding: false
rerank: falso
tts: false
speech2text: false
moderação: falso
armazenamento.
ativado: true
tamanho: 1048576
plugins.
ferramentas.
- provider/dropbox.yaml
meta.
versão: 0.0.1
arco.
- amd64
- braço64
corredor.
linguagem: python
versão: "3.12"
ponto de entrada: principal
created_at: 2025-04-03T17:41:08.159756+08:00
privacidade: PRIVACY.md
Principais componentes que afetam a exibição no mercado
Informações básicas (mostradas na listagem do plug-in).
version: O número da versão de seu plug-in
autor: o nome de sua organização exibido no Marketplace
name: Nome interno do seu plug-in
label: Exibir nome em diferentes idiomas
created_at: Hora de criação no formato RFC3339 (deve ser no passado)
ícone: Caminho para o ícone do plug-in
descrição: descrição completa em diferentes idiomas
tags: Categorias para o seu plug-in. Você só pode definir uma tag por vez. (Agora as tags têm apenas search', 'image', 'videos', 'weather', 'finance', 'design', ' travel", "social", "news", "medical", "productivity", "education", "business", "entertainment", "utilities" ou "other")
Requisitos de recursos (mostrados na seção de requisitos).
resource.memory: uso máximo de memória em bytes (por exemplo, 1048576 = 1 MB)
resource.permission: Permissões necessárias para seu plug-in
Referências de plug-in.
plugins.tools: caminho para o(s) arquivo(s) YAML do seu provedor
Impacto no mercado
Observando a captura de tela do Marketplace que você forneceu, é possível ver como esses campos aparecem.
O nome, o ícone e a descrição do plug-in aparecem na parte superior
O nome do autor e o número da versão são mostrados abaixo da descrição
As tags aparecem na seção "TAGS".
Os requisitos de memória são mostrados na seção "REQUISITOS
Observações importantes
A maioria dos campos pode ser deixada como configurada inicialmente no modelo, especialmente.
type: Manter como "plugin"
seção meta: Mantenha os valores padrão
resource.permission: Altere apenas se o seu plug-in precisar de permissões específicas
Campos que você deve personalizar.
version: O número da versão de seu plug-in
autor: nome de sua organização
name: um identificador exclusivo para seu plug-in
rótulo: O nome de exibição em diferentes idiomas
descrição: uma descrição clara do que seu plug-in faz
tags: categorias relevantes para seu plug-in
plugins.tools: caminho para o(s) arquivo(s) YAML do seu provedor
Para criar seu próprio arquivo manifest.yaml, comece com o modelo e personalize os campos que afetam a forma como seu plug-in aparece no Marketplace. O segredo é fornecer informações claras e concisas que ajudem os usuários a entender o que seu plugin faz. No entanto, com tudo isso dito, você deve sempre deixar o arquivo manifesto como está, pois tudo é configurado durante a inicialização.
2) Como editar provider/your_plugin.yaml
Você tem a tarefa de criar o arquivo YAML de configuração do provedor para um plug-in da Dify. Esse arquivo define as credenciais necessárias para o seu serviço e como ele será usado. Vou orientá-lo na criação desse arquivo, passo a passo, usando a Pesquisa Google como exemplo.
Finalidade do arquivo
O arquivo YAML do provedor (your_plugin.yaml) define.
Quais credenciais os usuários precisam fornecer para usar seu serviço
Como essas credenciais são coletadas e exibidas na interface do usuário
Quais ferramentas estão incluídas em seu plug-in
O arquivo Python que valida essas credenciais
Componentes necessários
seção de identidade: metadados básicos para o seu plug-in (obrigatório, mas não afetará a aparência do Marketplace)
Seção credentials_for_provider: define quais credenciais de autenticação os usuários precisam fornecer
seção de ferramentas: lista quais arquivos de configuração de ferramentas estão incluídos
seção extra: Especifica o arquivo Python usado para validação de credenciais
Exemplo de implementação
Veja a seguir a aparência do arquivo YAML do provedor para a ferramenta Dropbox.
identidade.
autor: lcandy
nome: dropbox
etiqueta.
pt_US: Dropbox
zh_Hans: Dropbox
pt_BR: Dropbox
ja_JP: Dropbox
zh_Hant: Dropbox
descrição.
pt_US: Interagir com arquivos e pastas do Dropbox
zh_Hans: Interagindo com arquivos e pastas do Dropbox
pt_BR: Interaja com arquivos e pastas do Dropbox
ja_jp: Dropbox のファイルとフォルダを操作します
zh_Hant: Interagindo com arquivos e pastas do Dropbox
ícone: icon.svg
credentials_for_provider.
access_token.
tipo: secret-input
obrigatório: true
etiqueta.
en_US: Token de acesso
zh_Hans: token de acesso
pt_BR: Token de Acesso
ja_jp: Foguista acústico
zh_Hant: Acesso ao cetro
espaço reservado.
en_US: Digite seu token de acesso ao Dropbox
zh_Hans: Digite seu token de acesso ao Dropbox!
pt_BR: Por favor, insira seu token de acesso ao Dropbox
ja_jp: Dropbox アクセストークンを入力してください
zh_Hant: Digite sua chave de acesso ao Dropbox.
ajuda.
en_US: Obtenha seu token de acesso na seção de Aplicativos do Dropbox
zh_Hans: Obtendo seu token de acesso na console do aplicativo do Dropbox
pt_BR: Obtenha seu token de acesso no Console de Aplicativos do Dropbox
ja_JP: Dropbox アプリコンソールからアクセストークンを取得してください
zh_Hant: Obtenha seu stick de acesso no console do aplicativo do Dropbox.
url.
ferramentas.
- tools/list_files.yaml
- tools/search_files.yaml
- tools/upload_file.yaml
- tools/download_file.yaml
- tools/create_folder.yaml
- tools/delete_file.yaml
extra.
python.
Fonte: provider/dropbox.py
Pontos-chave a serem lembrados
Seção de identidade: embora não afete o Marketplace, ela ainda é necessária na estrutura do arquivo. Inclua informações básicas como nome, autor e descrição. As tags devem ser herdadas do arquivo manifest.yaml.
Seção de Credenciais.
Cada credencial precisa de um identificador exclusivo (como o token de acesso do Dropbox)
opções de tipo.
secret-input: Para informações confidenciais que serão criptografadas
text-input: Para informações de texto regulares
select: Para seleção suspensa
booleano: para chaves de alternância
tool-selector: para objetos de configuração de ferramentas
Incluir obrigatório: verdadeiro/falso para indicar se a credencial é obrigatória
Forneça rótulos, espaços reservados e textos de ajuda de fácil utilização em diferentes idiomas
O campo url vincula a documentação para obtenção de credenciais
Seção de ferramentas.
Lista os arquivos YAML para cada ferramenta em seu plug-in
Os caminhos devem ser relativos à raiz do plug-in
Seção Extra.
Especifica o arquivo Python que valida as credenciais
Esse arquivo deve corresponder ao arquivo criado em seu "provider/your_plugin.py".
Criando seu arquivo YAML
Para adaptar isso ao seu próprio serviço.
Modifique a seção de identidade com as informações básicas do plug-in
Defina quais credenciais seu serviço exige na seção credentials_for_provider
Liste os arquivos YAML da sua ferramenta na seção de ferramentas
Especifique o arquivo de validação do Python na seção extra
Lembre-se de que esse arquivo YAML funciona em conjunto com o arquivo de validação do Python, que usará essas credenciais para se autenticar no seu serviço.
3. como editar provider/your_plugin.py
Você tem a tarefa de criar o arquivo de autenticação do provedor para um plug-in da Dify. Esse arquivo validará as credenciais necessárias para acessar um terceiro Vou orientá-lo na criação desse arquivo, usando a integração da API de pesquisa do Google como exemplo.
Finalidade do arquivo
O arquivo Python do provedor (provider_name.py) funciona como o módulo de teste de autenticação para o seu plug-in Dify. Sua principal responsabilidade é testar se as credenciais fornecidas pelos usuários são válidas, fazendo uma simples chamada de API para o serviço.
Componentes necessários
Sua classe de provedor deve herdar de dify_plugin.
Você deve implementar o método _validate_credentials
Você deve usar ToolProviderCredentialValidationError para o tratamento de erros
Como funciona
O fluxo de autenticação segue estas etapas.
O usuário insere suas credenciais na IU da Dify
A Dify passa essas credenciais para seu método _validate_credentials
Seu código tenta fazer uma chamada de API simples usando as credenciais fornecidas
Se for bem-sucedida, a autenticação é válida; se não for, você gera um erro
Exemplo de implementação
Veja como você implementaria um arquivo de provedor para a ferramenta do Dropbox
from typing import Any
from dify_plugin import ToolProvider
from dify_plugin.errors.tool.import ToolProviderCredentialValidationError
importar dropbox
from dropbox.exceptions import AuthError
from dropbox_utils import DropboxUtils
classe DropboxProvider(ToolProvider).
def _validate_credentials(self, credentials: dict[str, Any]) -> None.
tentar.
# Verificar se o access_token é fornecido nas credenciais
Se "access_token" não estiver nas credenciais ou não for credentials.get("access_token"):.
raise ToolProviderCredentialValidationError("O token de acesso ao Dropbox é necessário.")
# Tente se autenticar no Dropbox usando o token de acesso
tentar.
# Use a função de utilidade para obter um cliente
DropboxUtils.get_client(credentials.get("access_token"))
except AuthError as e.
raise ToolProviderCredentialValidationError(f "Invalid Dropbox access token: {str(e)}")
exceto Exception como e.
raise ToolProviderCredentialValidationError(f "Failed to connect to Dropbox: {str(e)}")
exceto Exception como e.
raise ToolProviderCredentialValidationError(str(e))
Pontos-chave a serem lembrados
Sempre use a classe de ferramenta: o provedor não faz chamadas de API diretamente, mas usa a classe de ferramenta por meio do método from_credentials.
Use uma consulta de teste mínima: mantenha seu teste de validação simples, apenas o suficiente para confirmar que as credenciais funcionam.
Tratamento adequado de erros: sempre envolva sua validação em um bloco try/except e converta todas as exceções para o padrão ToolProviderCredentialValidationError.
Dicionário de credenciais genéricas: o parâmetro credentials contém todos os parâmetros de autenticação definidos em seu arquivo provider_name.yaml.
Tratamento do gerador: observe a sintaxe for _ in ... usada para manipular o gerador retornado pelo método invoke.
4. como editar tools/your_plugin.yaml
Você tem a tarefa de criar o arquivo YAML de configuração de ferramenta para um plug-in da Dify. Esse arquivo define como sua ferramenta aparece na interface da Dify, quais parâmetros ela aceita e como esses parâmetros são apresentados aos usuários e ao agente de IA. parâmetros que ela aceita e como esses parâmetros são apresentados aos usuários e ao agente de IA. Vou orientá-lo na criação desse arquivo, usando o Google Search como exemplo.
Esquema Yaml de tools/your_plugin.yaml.
importar base64
importar contextlib
importar uuid
from collections.abc import Mapping
from enum import Enum, StrEnum
from typing import Any, Optional, Union
from pydantic import (
BaseModel.
Campo.
field_serializer.
field_validator.
validador de modelo,
)
from dify_plugin.core.utils.yaml_loader import load_yaml_file
de dify_plugin.entities import I18nObject
from dify_plugin.entities.model.message.import PromptMessageTool
class LogMetadata(str, Enum).
STARTED_AT = "started_at"
FINISHED_AT = "finished_at"
ELAPSED_TIME = "elapsed_time" (tempo decorrido)
TOTAL_PRICE = "total_price" (preço total)
TOTAL_TOKENS = "total_tokens"
provedor = "provedor"
CURRENCY = "currency" (moeda)
class CommonParameterType(Enum).
SECRET_INPUT = "secret-input" (entrada secreta)
TEXT_INPUT = "entrada de texto"
SELECT = "select"
STRING = "string" (cadeia de caracteres)
NUMBER = "número"
FILE = "file" (arquivo)
FILES = "files" (arquivos)
BOOLEAN = "booleano"
APP_SELECTOR = "app-selector"
MODEL_SELECTOR = "model-selector"
# TOOL_SELECTOR = "tool-selector" (seletor de ferramentas)
TOOLS_SELECTOR = "array[tools]"
class AppSelectorScope(Enum).
ALL = "todos"
CHAT = "chat" (bate-papo)
WORKFLOW = "fluxo de trabalho"
COMPLETION = "conclusão"
classe ModelConfigScope(Enum).
LLM = "llm"
TEXT_EMBEDDING = "text-embedding" (incorporação de texto)
RERANK = "rerank"
TTS = "tts"
SPEECH2TEXT = "speech2text"
MODERATION = "moderação"
VISION = "visão"
classe ToolSelectorScope(Enum).
ALL = "todos"
PLUGIN = "plugin"
API = "api"
WORKFLOW = "fluxo de trabalho"
classe ToolRuntime(BaseModel).
credenciais: dict[str, Any]
user_id: opcional[str]
session_id: opcional[str]
classe ToolInvokeMessage(BaseModel).
classe TextMessage(BaseModel).
texto: str
def to_dict(self).
return {"text": self.text}
class JsonMessage(BaseModel).
json_object: dict
def to_dict(self).
return {"json_object": self.json_object}
classe BlobMessage(BaseModel).
blob: bytes
class BlobChunkMessage(BaseModel).
id: str = Field(... , description="O id do blob")
sequence: int = Field(... , description="A sequência do bloco")
total_length: int = Field(... , description="O comprimento total da bolha")
blob: bytes = Field(... , description="Os dados de blob do bloco")
end: bool = Field(... , description="Se o bloco é o último bloco")
classe VariableMessage(BaseModel).
nome_da_variável: str = Field(
...,
description="O nome da variável, compatível apenas com variáveis de nível de raiz".
)
variable_value: Any = Field(... , description="O valor da variável")
stream: bool = Field(default=False, description="Whether the variable is streamed")
@model_validator(mode="before")
@classmethod
def validate_variable_value_and_stream(cls, values).
# Ignorar validação se os valores não forem um ditado
se não for isinstance(values, dict):: se não for isinstance(values, dict): se não for isinstance(values, dict).
valores de retorno
if values.get("stream") and not isinstance(values.get("variable_value"), str).
raise ValueError("Quando 'stream' é True, 'variable_value' deve ser uma string.")
valores de retorno
classe LogMessage(BaseModel).
class LogStatus(Enum).
START = "start" (início)
ERROR = "error" (erro)
SUCCESS = "success" (sucesso)
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="O id do registro")
label: str = Field(... , description="O rótulo do registro")
parent_id: Optional[str] = Field(default=None, description="Leave empty for root log")
error: Optional[str] = Field(default=None, description="The error message")
status: LogStatus = Field(... , description="O status do registro")
data: Mapping[str, Any] = Field(... , description="Dados de registro detalhados")
metadata: Optional[Mapping[LogMetadata, Any]] = Field(default=None, description="The metadata of the log")
class MessageType(Enum).
TEXT = "texto"
FILE = "file" (arquivo)
BLOB = "blob" (bolha)
JSON = "json"
LINK = "link"
IMAGE = "image"
IMAGE_LINK = "image_link"
VARIABLE = "variável"
BLOB_CHUNK = "blob_chunk"
LOG = "log"
tipo: MessageType
# TODO: O pydantic validará e construirá a mensagem uma a uma, até encontrar um tipo correto
# precisamos otimizar o processo de construção
mensagem: TextMessage | JsonMessage | VariableMessage | BlobMessage | BlobChunkMessage | LogMessage | Nenhuma
meta: Optional[dict] = Nenhum
@field_validator("message", mode="before")
@classmethod
def decode_blob_message(cls, v).
if isinstance(v, dict) and "blob" in v.
com contextlib.suppress(Exception).
v["blob"] = base64.b64decode(v["blob"])
retornar v
@field_serializer("message")
def serialize_message(self, v).
if isinstance(v, self.BlobMessage)::
return {"blob": base64.b64encode(v.blob).decode("utf-8")}
elif isinstance(v, self.BlobChunkMessage)::
retornar {
"id": v.id,
"sequence": v.sequence,
"total_length": v.total_length,
"blob": base64.b64encode(v.blob).decode("utf-8"),
"end": v.end,
}
retornar v
classe ToolIdentity(BaseModel).
author: str = Field(... , description="O autor da ferramenta")
name: str = Field(... , description="O nome da ferramenta")
label: I18nObject = Field(... , description="O rótulo da ferramenta")
classe ToolParameterOption(BaseModel).
value: str = Field(... , description="O valor da opção")
label: I18nObject = Field(... , description="O rótulo da opção")
@field_validator("value", mode="before")
@classmethod
def transform_id_to_str(cls, value) -> str.
if not isinstance(value, str): if not isinstance(value, str).
return str(value)
e mais.
valor de retorno
classe ParameterAutoGenerate(BaseModel).
classe Type(StrEnum).
PROMPT_INSTRUCTION = "prompt_instruction"
tipo: Tipo
class ParameterTemplate(BaseModel).
enabled: bool = Field(... , description="Se o parâmetro está habilitado para jinja")
classe ToolParameter(BaseModel).
class ToolParameterType(str, Enum).
STRING = CommonParameterType.STRING.value
NUMBER = CommonParameterType.NUMBER.value
BOOLEAN = CommonParameterType.BOOLEAN.value
SELECT = CommonParameterType.SELECT.value
SECRET_INPUT = CommonParameterType.SECRET_INPUT.value
FILE = CommonParameterType.FILE.value
FILES = CommonParameterType.FILES.value
MODEL_SELECTOR = CommonParameterType.MODEL_SELECTOR.value
APP_SELECTOR = CommonParameterType.APP_SELECTOR.value
# TOOL_SELECTOR = CommonParameterType.TOOL_SELECTOR.value
classe ToolParameterForm(Enum).
SCHEMA = "schema" # deve ser definido ao adicionar a ferramenta
FORM = "form" # deve ser definido antes de chamar a ferramenta.
LLM = "llm" O # será definido pelo LLM
name: str = Field(... , description="O nome do parâmetro")
label: I18nObject = Field(... , description="O rótulo apresentado ao usuário")
human_description: I18nObject = Field(... , description="A descrição apresentada ao usuário")
type: ToolParameterType = Field(... , description="O tipo do parâmetro")
auto_generate: Optional[ParameterAutoGenerate] = Field(
default=None, description="A geração automática do parâmetro"
)
template: Optional[ParameterTemplate] = Field(default=None, description="The template of the parameter")
escopo: str | None = None
form: ToolParameterForm = Field(... , description="O formulário do parâmetro, schema/form/llm")
llm_description: Optional[str] = None
required: Optional[bool] = False
default: Optional[Union[int, float, str]] = None
min: Optional[Union[float, int]] = Nenhum
max: Optional[Union[float, int]] = Nenhum
precision: Optional[int] = None
opções: opcional
class ToolDescription(BaseModel).
humano: I18nObject = Field(... , description="A descrição apresentada ao usuário")
llm: str = Field(... , description="A descrição apresentada ao LLM")
class ToolConfigurationExtra(BaseModel).
classe Python(BaseModel).
fonte: str
python: Python
classe ToolConfiguration(BaseModel).
identity: ToolIdentity
parameters: list[ToolParameter] = Field(default=[], description="Os parâmetros da ferramenta")
descrição: ToolDescription
extra: ToolConfigurationExtra
has_runtime_parameters: bool = Field(default=False, description="Se a ferramenta tem parâmetros de tempo de execução")
output_schema: Optional[Mapping[str, Any]] = None
classe ToolLabelEnum(Enum).
SEARCH = "search" (pesquisa)
IMAGE = "image"
VIDEOS = "videos"
WEATHER = "weather" (clima)
FINANCE = "finanças"
DESIGN = "design"
TRAVEL = "travel" (viagem)
SOCIAL = "social"
NEWS = "notícias"
MEDICAL = "médico"
PRODUCTIVITY = "produtividade"
EDUCATION = "educação"
BUSINESS = "negócios"
ENTERTAINMENT = "entretenimento"
UTILITIES = "utilitários"
OTHER = "outro"
class ToolCredentialsOption(BaseModel).
value: str = Field(... , description="O valor da opção")
label: I18nObject = Field(... , description="O rótulo da opção")
classe ProviderConfig(BaseModel).
class Config(Enum).
SECRET_INPUT = CommonParameterType.SECRET_INPUT.value
TEXT_INPUT = CommonParameterType.TEXT_INPUT.value
SELECT = CommonParameterType.SELECT.value
BOOLEAN = CommonParameterType.BOOLEAN.value
MODEL_SELECTOR = CommonParameterType.MODEL_SELECTOR.value
APP_SELECTOR = CommonParameterType.APP_SELECTOR.value
# TOOL_SELECTOR = CommonParameterType.TOOL_SELECTOR.value
TOOLS_SELECTOR = CommonParameterType.TOOLS_SELECTOR.value
@classmethod
def value_of(cls, value: str) -> "ProviderConfig.
"""
Obtém o valor do modo fornecido.
:param value: valor do modo
:return: mode
"""
for mode in cls.
se mode.value == value.
modo de retorno
raise ValueError(f "invalid mode value {value}")
name: str = Field(... , description="O nome das credenciais")
type: Config = Field(..., description="O tipo das credenciais") , description="O tipo das credenciais")
escopo: str | None = None
required: bool = False
default: Optional[Union[int, float, str]] = None
opções: opcional
rótulo: I18nObject
ajuda: Optional[I18nObject] = Nenhum
url: Optional[str] = None
espaço reservado: Optional[I18nObject] = Nenhum
classe ToolProviderIdentity(BaseModel).
author: str = Field(... , description="O autor da ferramenta")
name: str = Field(... , description="O nome da ferramenta")
description: I18nObject = Field(... , description="A descrição da ferramenta")
icon: str = Field(... , description="O ícone da ferramenta")
label: I18nObject = Field(... , description="O rótulo da ferramenta")
tags: list[ToolLabelEnum] = Field(
default=[],
description="As tags da ferramenta".
)
class ToolProviderConfigurationExtra(BaseModel).
classe Python(BaseModel).
fonte: str
python: Python
classe ToolProviderConfiguration(BaseModel).
identity: Identidade do provedor de ferramentas
credentials_schema: list[ProviderConfig] = Field(
default_factory=list,
alias="credentials_for_provider",
description="O esquema de credenciais do provedor de ferramentas".
)
tools: list[ToolConfiguration] = Field(default=[], description="As ferramentas do provedor de ferramentas")
extra: ToolProviderConfigurationExtra
@model_validator(mode="before")
@classmethod
def validate_credentials_schema(cls, data: dict) -> dict.
original_credentials_for_provider: dict[str, dict] = data.get("credentials_for_provider", {})
credentials_for_provider: list[dict[str, Any]] = []
para nome, credencial em original_credentials_for_provider.items()::
credencial["nome"] = nome
credentials_for_provider.append(credential)
data["credentials_for_provider"] = credentials_for_provider
retornar dados
@field_validator("tools", mode="before")
@classmethod
def validate_tools(cls, value) -> list[ToolConfiguration].
if not isinstance(value, list):: if not isinstance(value, list): if not isinstance(value, list).
raise ValueError("tools should be a list")
ferramentas: lista[ToolConfiguration] = []
para ferramenta em valor:
# lido de yaml
if not isinstance(tool, str): if not isinstance(tool, str).
raise ValueError("tool path should be a string")
tentar.
file = load_yaml_file(tool)
tools.append(
ToolConfiguration(
identity=ToolIdentity(**file["identity"]),
parameters=[ToolParameter(**param) for param in file.get("parameter", []) or []],
description=ToolDescription(**file["description"]),
extra=ToolConfigurationExtra(**file.get("extra", {})),
output_schema=file.get("output_schema", None),
)
)
exceto Exception como e.
raise ValueError(f "Erro ao carregar a configuração da ferramenta: {str(e)}") from e
ferramentas de retorno
classe ToolProviderType(Enum).
"""
Classe enum para o provedor de ferramentas
"""
BUILT_IN = "builtin"
WORKFLOW = "fluxo de trabalho"
API = "api"
APP = "app"
DATASET_RETRIEVAL = "dataset-retrieval"
@classmethod
def value_of(cls, value: str) -> "ToolProviderType".
"""
Obtém o valor do modo fornecido.
:param value: valor do modo
:return: mode
"""
for mode in cls.
se mode.value == value.
modo de retorno
raise ValueError(f "invalid mode value {value}")
classe ToolSelector(BaseModel).
class Parameter(BaseModel).
name: str = Field(... , description="O nome do parâmetro")
type: ToolParameter.ToolParameterType = Field(... , description="O tipo do parâmetro")
required: bool = Field(... , description="Se o parâmetro é obrigatório")
description: str = Field(... , description="A descrição do parâmetro")
default: Optional[Union[int, float, str]] = None
opções: opcional
provider_id: str = Field(... , description="O ID do provedor")
tool_name: str = Field(... , description="O nome da ferramenta")
tool_description: str = Field(... , description="A descrição da ferramenta")
tool_configuration: Mapping[str, Any] = Field(... , description="Configuração, formulário de tipo")
tool_parameters: Mapeamento[str, Parâmetro] = Campo(... , description="Parâmetros, tipo llm")
def to_prompt_message(self) -> PromptMessageTool.
"""
Converte o seletor de ferramentas em ferramenta de mensagem de aviso, com base no esquema de chamada de função openai.
"""
tool = PromptMessageTool(
name=self.tool_name,
description=self.tool_description,
parâmetros={
"type": "object",
"properties": {},
"required": [],
},
)
for name, parameter in self.tool_parameters.items()::
tool.parameters[name] = {
"type": parameter.type.value,
"description": parameter.description,
}
se parameter.required.
tool.parameters["required"].append(name)
se parameter.options.
tool.parameters[name]["enum"] = [option.value for option in parameter.options]
ferramenta de retorno
Finalidade do arquivo
O arquivo YAML da ferramenta (your_plugin.yaml) define.
Informações básicas de identidade sobre sua ferramenta
Descrições para humanos e para o agente de IA
Parâmetros que sua ferramenta aceita
Como esses parâmetros são apresentados e coletados
Exemplo de implementação
Veja a seguir a aparência dos arquivos YAML da ferramenta para o Dropbox.
ceate_folder.yaml.
identidade.
nome: create_folder
autor: lcandy
etiqueta.
pt_US: Criar pasta
zh_Hans: Criando pastas
pt_BR: Criar Pasta
ja_jp: Dobrado
zh_Hant: Criar pasta
descrição.
humano.
pt_US: Criar uma nova pasta no Dropbox
zh_Hans: Criando uma nova pasta no Dropbox
pt_BR: Criar uma nova pasta no Dropbox
ja_jp: O Dropbox criou uma nova versão do Frida!
zh_Hant: Criando uma nova pasta no Dropbox
llm: Cria uma nova pasta no caminho especificado no Dropbox. Retorna informações sobre a pasta criada, incluindo caminho e ID.
parâmetros.
- nome: folder_path
tipo: string
obrigatório: true
etiqueta.
pt_US: Caminho da pasta
zh_Hans: caminho da pasta
pt_BR: Caminho da Pasta
ja_jp:ォルダパス
zh_Hant: caminho da pasta
human_description.
en_US: O caminho para onde a pasta será criada no Dropbox
zh_Hans: Caminho de criação de pastas no Dropbox
pt_BR: O caminho onde a pasta será criada no Dropbox
ja_jp: Dropbox でフォルダを作成するパス
zh_Hant: o caminho para a pasta que você deseja criar no Dropbox.
llm_description: O caminho para onde a pasta será criada no Dropbox. Deve ser especificado como um caminho completo, como "/Documents/Projects" ou "/Photos/ Vacation2023". Os caminhos diferenciam maiúsculas de minúsculas e devem começar com uma barra.
forma: llm
extra.
python.
Fonte: tools/create_folder.py
delete_file.yaml.
identidade.
nome: delete_file
autor: lcandy
etiqueta.
en_US: Excluir arquivo/pasta
zh_Hans: Excluir arquivos/pastas
pt_BR: Excluir Arquivo/Pasta
ja_jp: ファイル/フォルダ削除
zh_Hant: Excluir arquivo/pasta
descrição.
humano.
en_US: Excluir um arquivo ou pasta do Dropbox
zh_Hans: Exclusão de arquivos ou pastas do Dropbox
pt_BR: Excluir um arquivo ou pasta do Dropbox
ja_jp: Dropbox からファイルやフォルダを削除します
zh_Hant: Excluir arquivo ou pasta do Dropbox
llm: Exclui permanentemente um arquivo ou pasta do Dropbox no caminho especificado. Retorna informações de confirmação sobre o item excluído.
parâmetros.
- nome: file_path
tipo: string
obrigatório: true
etiqueta.
pt_US: Caminho do arquivo/pasta
zh_Hans: caminho do arquivo/pasta
pt_BR: Caminho do Arquivo/Pasta
ja_jp:ファイル/フォルダパス
zh_Hant: caminho do arquivo/pasta
human_description.
en_US: O caminho do arquivo ou pasta a ser excluído do Dropbox
zh_Hans: Caminho para o arquivo ou pasta a ser excluído do Dropbox
pt_BR: O caminho do arquivo ou pasta para excluir do Dropbox
ja_jp: Dropbox から削除するファイルやフォルダのパス
zh_Hant: Caminho para o arquivo ou pasta que você deseja excluir do Dropbox
llm_description: O caminho do arquivo ou pasta a ser excluído do Dropbox. Deve ser especificado como um caminho completo, como "/Documents/report.txt" ou "/Photos /Vacation2023". Os caminhos diferenciam maiúsculas de minúsculas e devem começar com uma barra. AVISO - Esta é uma exclusão permanente.
forma: llm
extra.
python.
Fonte: tools/delete_file.py
download_file.py.
identidade.
nome: download_file
autor: lcandy
etiqueta.
en_US: Baixar arquivo
zh_Hans: Baixar arquivo
pt_BR: Baixar Arquivo
ja_jp: ファイルダウンロード
zh_Hant: Baixar arquivo
descrição.
humano.
pt_US: Baixar um arquivo do Dropbox
zh_Hans: Baixando arquivos do Dropbox
pt_BR: Baixar um arquivo do Dropbox
ja_jp: Dropbox からファイルをダウンロードします
zh_Hant: Baixar arquivos do Dropbox
llm: baixa um arquivo do Dropbox no caminho especificado. Retorna os metadados do arquivo e, opcionalmente, o conteúdo do arquivo (como base64 para arquivos binários ou texto para arquivos de texto). texto).
parâmetros.
- nome: file_path
tipo: string
obrigatório: true
etiqueta.
pt_US: Caminho do arquivo
zh_Hans: caminho do arquivo
pt_BR: Caminho do Arquivo
ja_jp: ファイルパス
zh_Hant: Caminhos de arquivos
human_description.
en_US: O caminho do arquivo a ser baixado do Dropbox
zh_Hans: caminho para o arquivo a ser baixado do Dropbox
pt_BR: O caminho do arquivo para baixar do Dropbox
ja_JP: Dropbox からダウンロードするファイルのパス
zh_Hant: o caminho para o arquivo que você deseja baixar do Dropbox
llm_description: O caminho do arquivo a ser baixado do Dropbox. Deve incluir o caminho completo com o nome do arquivo e a extensão, como "/Documents/report. txt". Os caminhos diferenciam maiúsculas de minúsculas e devem começar com uma barra.
forma: llm
- nome: include_content
tipo: booleano
obrigatório: falso
padrão: false
etiqueta.
en_US: Incluir conteúdo
zh_Hans: Conteúdo
pt_BR: Incluir Conteúdo
ja_JP: Conteúdo
zh_Hant: Contém conteúdo
human_description.
en_US: Se deve incluir o conteúdo do arquivo na resposta
zh_Hans: se deve ou não incluir o conteúdo do arquivo na resposta
pt_BR: Deve-se incluir o conteúdo do arquivo na resposta
ja_jp: O conteúdo do filme no Rathponies está incluído no filme.
zh_Hant: se deve ou não incluir o conteúdo do arquivo na resposta
llm_description: defina como true para incluir o conteúdo do arquivo na resposta. Para arquivos de texto pequenos, o conteúdo será fornecido como texto. Para arquivos binários, o conteúdo será fornecido como uma cadeia de caracteres codificada em base64. O conteúdo será fornecido como cadeia de caracteres codificada em base64. O padrão é false.
forma: llm
extra.
python.
Fonte: tools/download_file.py
dropbox.yaml.
identidade.
nome: dropbox
autor: lcandy
etiqueta.
pt_US: Dropbox
zh_Hans: Dropbox
pt_BR: Dropbox
ja_JP: Dropbox
zh_Hant: Dropbox
descrição.
humano.
pt_US: Interaja com o Dropbox
zh_Hans: Interagindo com o Dropbox
pt_BR: Interagir com o Dropbox
ja_JP: Dropbox e conectividade
zh_Hant: Interagindo com o Dropbox
llm: fornece acesso aos serviços do Dropbox, permitindo que você interaja com arquivos e pastas em uma conta do Dropbox.
parâmetros.
- nome: query
tipo: string
obrigatório: true
etiqueta.
en_US: Cadeia de consulta
zh_Hans: Declaração de consulta
pt_BR: Termo de consulta
ja_jp: Colunas de texto K'eri
zh_Hant: Declaração de consulta
human_description.
en_US: Digite sua consulta de operação do Dropbox
zh_Hans: Digite sua consulta de operação do Dropbox
pt_BR: Digite sua consulta de operação do Dropbox
ja_JP: Operação do Dropbox クエリを入力してください
zh_Hant: Digite a operação do Dropbox que você deseja executar.
llm_description: A consulta que descreve a operação do Dropbox que você deseja executar.
forma: llm
extra.
python.
fonte: tools/dropbox.py
Componentes principais
Seção de Identidade.
name: Nome interno da sua ferramenta (deve corresponder à nomenclatura do seu arquivo)
autor: quem criou a ferramenta
label: Exibir nome em diferentes idiomas
Seção Descrição.
humano: descrição exibida para usuários humanos em diferentes idiomas
llm: Descrição fornecida ao agente de IA para entender o que sua ferramenta faz e como usá-la
Seção Parâmetros.
Lista de parâmetros que sua ferramenta aceita, cada um com.
name: Identificador do parâmetro (usado em seu código Python)
type: Tipo de dados (string, número, booleano, etc.)
required: se esse parâmetro é obrigatório
rótulo: nome de fácil utilização em diferentes idiomas
human_description: Explicação para usuários humanos em diferentes idiomas
llm_description: Explicação para que o agente de IA entenda esse parâmetro
form: Como o parâmetro é coletado
llm: agente de IA extrai informações de consultas de usuários
fluxo de trabalho: o usuário deve fornecer como uma variável na interface do usuário
Opcional: default: valor padrão para esse parâmetro
Seção Extra.
python.source: Caminho para o arquivo de implementação Python de sua ferramenta
Observações importantes
Separação de arquivos.
Importante!!!! Se a sua ferramenta tiver funcionalidades diferentes, como ler e gravar um e-mail, ou ler ou atualizar um banco de dados, você deverá separar o arquivo yaml em mais de um. O princípio é que cada arquivo yaml e de código seja exclusivo para cada tipo de execução de ferramenta. O arquivo em si deve extrair apenas os parâmetros que a ferramenta Por exemplo, para ler e atualizar um banco de dados, você deve usar dois arquivos yaml: read_database.yaml e update_ database.yaml separadamente. banco de dados.yaml separadamente.
Descrições do LLM.
A descrição do llm para a ferramenta e os parâmetros é crucial: ela informa ao agente de IA como usar sua ferramenta
Seja claro sobre quais parâmetros são necessários e quais informações sua ferramenta retornará
Isso ajuda o agente de IA a decidir quando usar sua ferramenta e como extrair parâmetros das consultas do usuário
Configuração de parâmetros.
Para cada parâmetro, especifique se ele é obrigatório
Escolha o tipo de dados apropriado
Defina o formulário como llm se quiser que a IA o extraia das consultas do usuário
Defina o formulário como fluxo de trabalho se quiser que os usuários o forneçam diretamente
Localização.
Fornecer traduções para rótulos e descrições em vários idiomas, conforme necessário
No mínimo, inclua o inglês (en_US)
Para criar seu próprio arquivo YAML de ferramenta, adapte essa estrutura para sua ferramenta específica, definindo claramente quais parâmetros ela precisa e como eles devem ser apresentados para os humanos e para o agente de IA.
5. como editar tools/your_plugin.py
Você tem a tarefa de criar o arquivo de implementação da ferramenta para um plug-in da Dify, que contém a lógica real da ferramenta que faz solicitações de API e processa os resultados. Esse arquivo contém a lógica real da sua ferramenta que faz solicitações de API e processa os resultados. Vou orientá-lo na criação desse arquivo, usando a Pesquisa Google como exemplo.
Finalidade do arquivo
O arquivo Python da ferramenta (your_plugin.py) é responsável por.
Fazer solicitações de API para seu serviço
Processamento das respostas
Retornar os resultados em um formato utilizável pela Dify
Componentes necessários
Sua classe de ferramenta deve herdar de dify_plugin.
Você deve implementar o método _invoke que retorna um gerador
Você deve incluir essas importações essenciais.
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
de dify_plugin.entities.tool.import ToolInvokeMessage
Exemplo de implementação
Esta é a aparência da implementação da ferramenta do Dropbox.
ceate_folder.yaml.
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
de dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError
from dropbox_utils import DropboxUtils
classe CreateFolderTool(Tool).
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Criar uma pasta no Dropbox
"""
# Obter parâmetros
folder_path = tool_parameters.get("folder_path", "")
# Validar parâmetros
se não for folder_path: se não for folder_path: se não for folder_path.
yield self.create_text_message("O caminho da pasta no Dropbox é necessário.")
retorno
# Certifique-se de que o caminho da pasta comece com /
if not folder_path.startswith("/"):.
folder_path = "/" + folder_path
tentar.
# Obter token de acesso das credenciais
access_token = self.runtime.credentials.get("access_token")
se não for access_token.
yield self.create_text_message("O token de acesso ao Dropbox é necessário.")
retorno
# Obter cliente do Dropbox
tentar.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "Falha na autenticação: {str(e)}")
retorno
exceto Exception como e.
yield self.create_text_message(f "Falha ao se conectar ao Dropbox: {str(e)}")
retorno
# Criar a pasta
tentar.
result = DropboxUtils.create_folder(dbx, folder_path)
# Criar resposta
summary = f "Pasta '{result['name']}' criada com sucesso em '{result['path']}'"
yield self.create_text_message(summary)
yield self.create_json_message(result)
except ApiError as e.
if "path/conflict" in str(e).
yield self.create_text_message(f "Já existe uma pasta em '{folder_path}'")
e mais.
yield self.create_text_message(f "Erro ao criar a pasta: {str(e)}")
retorno
exceto Exception como e.
yield self.create_text_message(f "Error: {str(e)}")
retorno
delete_file.py
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
de dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError
from dropbox_utils import DropboxUtils
classe DeleteFileTool(Tool).
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Excluir um arquivo ou pasta do Dropbox
"""
# Obter parâmetros
file_path = tool_parameters.get("file_path", "")
# Validar parâmetros
se não for file_path: se não for file_path: se não for file_path.
yield self.create_text_message("É necessário o caminho do arquivo ou da pasta no Dropbox.")
retorno
# Certifique-se de que o caminho comece com /
if not file_path.startswith("/"):.
file_path = "/" + file_path
tentar.
# Obter token de acesso das credenciais
access_token = self.runtime.credentials.get("access_token")
se não for access_token.
yield self.create_text_message("O token de acesso ao Dropbox é necessário.")
retorno
# Obter cliente do Dropbox
tentar.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "Falha na autenticação: {str(e)}")
retorno
exceto Exception como e.
yield self.create_text_message(f "Falha ao se conectar ao Dropbox: {str(e)}")
retorno
# Excluir o arquivo ou a pasta
tentar.
result = DropboxUtils.delete_file(dbx, file_path)
# Criar resposta
summary = f"'{result['name']}' deleted successfully"
yield self.create_text_message(summary)
yield self.create_json_message(result)
except ApiError as e.
if "path/not_found" in str(e)::
yield self.create_text_message(f "O arquivo ou a pasta não foi encontrado em '{file_path}'")
e mais.
yield self.create_text_message(f "Erro ao excluir arquivo/pasta: {str(e)}")
retorno
exceto Exception como e.
yield self.create_text_message(f "Error: {str(e)}")
retorno
download_file.yaml.
from collections.abc import Generator
importar base64
from typing import Any
from dify_plugin import Tool
de dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError
from dropbox_utils import DropboxUtils
classe DownloadFileTool(Tool).
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Baixar um arquivo do Dropbox
"""
# Obter parâmetros
file_path = tool_parameters.get("file_path", "")
include_content = tool_parameters.get("include_content", False)
# Validar parâmetros
se não for file_path: se não for file_path: se não for file_path.
yield self.create_text_message("O caminho do arquivo no Dropbox é necessário.")
retorno
# Certifique-se de que o caminho do arquivo comece com /
if not file_path.startswith("/"):.
file_path = "/" + file_path
tentar.
# Obter token de acesso das credenciais
access_token = self.runtime.credentials.get("access_token")
se não for access_token.
yield self.create_text_message("O token de acesso ao Dropbox é necessário.")
retorno
# Obter cliente do Dropbox
tentar.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "Falha na autenticação: {str(e)}")
retorno
exceto Exception como e.
yield self.create_text_message(f "Falha ao se conectar ao Dropbox: {str(e)}")
retorno
# Faça o download do arquivo
tentar.
result = DropboxUtils.download_file(dbx, file_path)
# Criar resposta
resposta = {
"name": resultado["name"],
"path": resultado["path"],
"id": result["id"],
"size": resultado["size"],
"modified": result["modified"]
}
# Incluir conteúdo, se solicitado
se include_content.
# Codificar conteúdo binário como base64
response["content_base64"] = base64.b64encode(result["content"]).decode('utf-8')
# Tente decodificar como texto se for pequeno o suficiente
if result["size"] < 1024 * 1024: # Menos de 1 MB
tentar.
text_content = result["content"].decode("utf-8")
response["content_text"] = text_content
exceto UnicodeDecodeError.
# Não é um arquivo de texto, basta incluir base64
passe
summary = f "O arquivo '{result['name']}' foi baixado com sucesso"
yield self.create_text_message(summary)
yield self.create_json_message(response)
except ApiError as e.
yield self.create_text_message(f "Erro ao baixar o arquivo: {str(e)}")
retorno
exceto Exception como e.
yield self.create_text_message(f "Error: {str(e)}")
retorno
Pontos-chave a serem lembrados
Separação de arquivos.
Importante: se a sua ferramenta tiver funcionalidades diferentes, como ler e gravar um e-mail ou ler ou atualizar um banco de dados, você deverá separar o arquivo yaml em mais arquivos. O princípio é que cada arquivo yaml e de código seja exclusivo para cada tipo de execução de ferramenta. O arquivo em si deve extrair apenas os parâmetros que a funcionalidade da ferramenta usará. Por exemplo, para ler e atualizar um banco de dados, você deve usar dois arquivos yaml: read_database.py e update_ database.py separadamente. banco de dados.py separadamente.
Importações necessárias: sempre inclua as importações essenciais na parte superior do arquivo.
Herança de classe: sua classe de ferramenta deve herdar de dify_plugin.
Extração de parâmetros.
O dicionário tool_parameters contém todos os parâmetros definidos no arquivo YAML da sua ferramenta.
Acesse esses parâmetros diretamente usando chaves de dicionário, por exemplo, tool_parameters["query"]
Esses parâmetros são extraídos automaticamente das consultas do usuário pelo agente de IA
Certifique-se de lidar com todos os parâmetros necessários e forneça o tratamento adequado de erros se eles estiverem faltando
Exemplo.
query = tool_parameters["query"] # Extraia o parâmetro de consultalimit = tool_parameters.get("limit", 10) # Extraia com um valor padrão# Validação opcionalse não for query: raise ValueError("Query parameter cannot be empty")
Acesso a credenciais.
Acesse suas credenciais de autenticação usando self.runtime.credentials
As chaves correspondem àquelas definidas no arquivo YAML de seu provedor
Exemplo: self.runtime.credentials["serpapi_api_key"]
Processamento de respostas: crie um método auxiliar para extrair apenas as informações relevantes das respostas da API.
Resultados do Yielding: Você deve usar o yield com um dos métodos de criação de mensagens para retornar dados.
Ao implementar sua própria ferramenta, certifique-se de extrair corretamente todos os parâmetros necessários do dicionário tool_parameters e valide-os, se necessário. Os parâmetros disponíveis são definidos no arquivo YAML da sua ferramenta e serão extraídos automaticamente das consultas do usuário pelo agente de IA.
6. como criar PRIVACY.md e README.md
Você tem a tarefa de criar a política de privacidade e os arquivos leia-me para o seu plug-in Dify. Esses arquivos são escritos no formato Markdown e servem a propósitos importantes para os usuários e desenvolvedores do seu plug-in. Esses arquivos são escritos no formato Markdown e servem a propósitos importantes para usuários e desenvolvedores do seu plug-in.
PRIVACY.md
O arquivo PRIVACY.md descreve as práticas de privacidade do seu plug-in, incluindo os dados que ele coleta e como esses dados são usados. usuários preocupados com a privacidade de seus dados.
O que incluir
Com base no texto do espaço reservado que você compartilhou ("!!!!! Por favor, preencha a política de privacidade do plug-in."), você deve incluir.
Quais dados seu plug-in coleta
Como esses dados são armazenados e processados
Quais serviços de terceiros são usados (se houver)
Direitos do usuário em relação aos seus dados
Por quanto tempo os dados são mantidos
Informações de contato para questões de privacidade
Exemplo de estrutura
Política de privacidade do #
Coleta de dados ##
[Descreva quais dados do usuário seu plug-in coleta e por quê].
## Processamento de dados
[Explique como os dados coletados são processados].
## Serviços de terceiros
[Liste todos os serviços de terceiros usados por seu plug-in e vincule-os às respectivas políticas de privacidade]
## Retenção de dados
[Explique por quanto tempo os dados do usuário são armazenados].
## Direitos do usuário
[Descreva os direitos que os usuários têm em relação aos seus dados]
## Informações de contato
[Forneça informações de contato para consultas relacionadas à privacidade.]
Última atualização: [Data]
README.md
O arquivo README.md fornece informações essenciais sobre o plug-in, inclusive o que ele faz, como instalá-lo e como usá-lo. Esse é o primeiro documento documento que a maioria dos usuários e desenvolvedores consultará.
O que incluir
Com base no exemplo que você compartilhou (leia-me do plug-in do Jira), você deve incluir.
Nome do plug-in como o título principal
Informações do autor
Informações sobre a versão
Tipo de plug-in
Descrição detalhada do que o plug-in faz
Instruções de instalação
Exemplos de uso
Opções de configuração
Informações sobre solução de problemas
Exemplo de estrutura
# Nome do seu plugin
**Autor:** [Seu nome ou organização] **Versão:** [Número da versão atual] **Tipo:** [Tipo de plug-in]
## Descrição
[Forneça uma descrição detalhada do que seu plug-in faz].
## Características
- [Recurso 1]
- [Característica 2]
- [Característica 3]
Instalação do ##
[Fornecer instruções de instalação passo a passo]
Configuração do ##
[Explicar como configurar seu plug-in]
Exemplos de uso do ##
[Forneça exemplos de como usar seu plug-in]
Solução de problemas do ##
[Liste os problemas comuns e suas soluções]
## Contribuição
[Explique como outras pessoas podem contribuir com seu plug-in]
Licença ##
[Especifique a licença sob a qual seu plug-in é liberado]
Uso de imagens
Como você mencionou, se quiser incluir imagens em qualquer um dos documentos.
Armazene as imagens na pasta _assets
Faça referência a eles em seu Markdown usando caminhos relativos.
! [Descrição da imagem](_assets/image_name.png)
Esses dois arquivos devem ser escritos no formato Markdown (extensão .md) e colocados no diretório raiz do seu projeto de plug-in. Certifique-se de mantê-los atualizados à medida que o plug-in evolui. Certifique-se de mantê-los atualizados à medida que seu plug-in evolui.
Requisitos.txt
Você deve sempre usar as dependências mais recentes usando ~= em seu arquivo txt, e o dify_plugin~=0.0.1b72 é obrigatório.