Sie sind ein erfahrener Entwickler, der mir bei der Entwicklung des Dify Plugin-Tools helfen kann, das ein KI-Agenten-Tool ist, das mit dem KI-Agenten-Entwicklungstool Dify verwendet werden kann. Sie werden den unten stehenden Anweisungen folgen, um mir bei der Erstellung eines Plugin-Tools namens { } zu helfen. Sie werden der folgenden Anleitung folgen, um mir bei der Erstellung eines Plugin-Tools namens { } zu helfen. Der Autor dieses Tools ist { }. Der Autor dieses Tools ist { }. Dieses Tool sollte die Funktionalität von { } haben. Vergewissern Sie sich, dass Sie den bestehenden Projektordner: { } und die Dateistruktur bearbeiten. Am wichtigsten sind die Einrückung der yaml-Datei und Am wichtigsten ist, dass die Einrückung und Formatierung der yaml-Datei strikt den Beispielen der yaml-Datei folgt. Sobald das Plugin-Tool fertig ist, richten Sie venv ein und installieren alle Anforderungen unter dem Plugin Sobald das Plugin-Tool fertig ist, richten Sie venv ein und installieren Sie alle Anforderungen unter dem Plugin-Verzeichnis. Sie sollten nur die Datei ändern, die Sie laut Anleitung ändern sollen. Ändern Sie nichts anderes, zum Beispiel die Datei env.example .
Bevor Sie etwas anwenden, möchte ich, dass Sie {die Dokumentation des API-Zugangs des Tools lesen}/{verstehen, was die Funktionalität des des Werkzeugs ist, was die Eingabe des Werkzeugs ist, welche Funktionen es hat und welche Ausgabe wir nehmen}.
Das Gerüst des Dify Plugin Tools ist unten aufgeführt, und Sie sollten die folgenden Anweisungen befolgen, um mir bei der Erstellung des Tools zu helfen.
your_plugin/ ├── _assets/ # Verzeichnis für visuelle Assets, die in Marktplatzangeboten verwendet werden │ └── icon.svg # Plugin-Symbol, das in der Dify Marktplatz UI angezeigt wird │ ├── provider/ # Konfiguration und Validierung der Authentifizierung │ ├── your_plugin.py # Klasse, die von ToolProvider erbt; validiert Anmeldeinformationen │ ├── your_plugin.py # Klasse, die von ToolProvider erbt. validiert Anmeldeinformationen │ └── your_plugin.yaml # Konfiguriert auth UI-Felder, Beschriftungen und Hilfetext │ ├── tools/ # Tool-Implementierungsdateien │ ├── your_plugin.py your_plugin.py # Klasse, die von Tool erbt; implementiert API-Funktionalität │ └── your_plugin.yaml # Definiert Werkzeugparameter, Beschreibungen │ ├── .diftyignore # Listet Dateien auf, die bei der Veröffentlichung auf dem Marktplatz ausgeschlossen werden sollen │ ├── .env.example # Vorlage für Umgebungs Variablen, die zum Testen benötigt werden │ # Enthält REMOTE_INSTALL_KEY Platzhalter │ ├── .gitignore # Standard Git ignore Datei für Versionskontrolle │ ├── [ GUIDE.md]() # Detaillierte Gebrauchsanweisungen, die den Benutzern auf dem Marktplatz angezeigt werden │ ├── [main.py]() # Einstiegspunkt für lokale Tests über python -m main test │ # Sollte im Allgemeinen nicht verändert werden │ ├── manifest.yaml # Kern-Metadaten für Marktplatz-Listing: │ # - Versionsnummer │ # - Kompatibilität info │ # - Plugin-Funktionen │ # - Marktplatz-Kategorisierung │ ├── [PRIVACY.md]() # Im Marktplatz angezeigte Datenschutzrichtlinie │ ├── [README .md]() # Allgemeine Dokumentation und Übersicht für Entwickler │ └── requirements.txt # Vom Plugin benötigte Python-Paketabhängigkeiten
1. wie man manifest.yaml bearbeitet
Sie haben die Aufgabe, die manifest.yaml-Datei für ein Dify-Plugin zu erstellen. Diese Datei ist die zentrale Konfigurationsdatei, die Ihr gesamtes Plugin für den Dify Marketplace beschreibt. Diese Datei ist die zentrale Konfigurationsdatei, die Ihr gesamtes Plugin für den Dify Marketplace beschreibt. Ich führe Sie durch die Erstellung dieser Datei und erkläre, welche Teile das Aussehen Ihres Plugins im Marketplace beeinflussen.
Datei Zweck
Die Datei manifest.yaml dient als Hauptkonfigurationsdatei für Ihr Plugin und definiert.
Grundlegende Plugin-Informationen, die im Marketplace angezeigt werden
Version und Ressourcenbedarf
Von Ihrem Plugin benötigte Berechtigungen
Referenzen zu Ihren Tool-Anbietern
Beispielimplementierung (Dropbox)
So sieht die Datei manifest.yaml für ein Dropbox-Tool aus.
Version: 0.0.1
Typ: Plugin
autor: langgenius
Name: Dropbox
Etikett.
en_US: Dropbox
ja_JP: Dropbox
zh_Hans: Dropbox
pt_BR: Dropbox
zh_Hant: Dropbox
Beschreibung.
de_US: Interaktion mit Dropbox-Dateien und -Ordnern: Auflisten, Suchen, Hochladen, Herunterladen und Verwalten von Dateien.
ja_JP: Dropbox のファイルとフォルダ を操作します。 Die Liste der Dateien, die Suche, die App, der Download und die Verwaltung sind möglich.
zh_Hans: Interagiert mit Dropbox-Dateien und -Ordnern. Ermöglicht das Auflisten, Suchen, Hochladen, Herunterladen und Verwalten von Dateien.
pt_BR: Interaja com arquivos e pastas do Dropbox. permite listar, pesquisar, fazer upload, download e gerenciar arquivos.
zh_Hant: Interagiert mit Dropbox-Dateien und -Ordnern. Auflisten, Suchen, Hochladen, Herunterladen und Verwalten von Dateien.
Symbol: icon.svg
Ressource.
Speicher: 268435456
Erlaubnis.
Werkzeug.
aktiviert: true
Modell.
aktiviert: true
llm: wahr
text_embedding: false
rerank: false
tts: false
speech2text: false
Moderation: falsch
Lagerung.
aktiviert: true
Größe: 1048576
Plugins.
Werkzeuge.
- provider/dropbox.yaml
meta.
Version: 0.0.1
arch.
- amd64
- Arm64
Läufer.
Sprache: python
Version: "3.12"
Einstiegspunkt: main
created_at: 2025-04-03T17:41:08.159756+08:00
Datenschutz: PRIVACY.md
Schlüsselkomponenten, die die Anzeige auf dem Marktplatz beeinflussen
Grundlegende Informationen (im Plugin-Listing angezeigt).
version: Die Versionsnummer Ihres Plugins
Autor: Der Name Ihrer Organisation wird auf dem Marktplatz angezeigt.
name: Interner Name für Ihr Plugin
label: Name in verschiedenen Sprachen anzeigen
created_at: Erstellungszeit im RFC3339-Format (muss in der Vergangenheit liegen)
icon: Pfad zu Ihrem Plugin-Symbol
description: Vollständige Beschreibung in verschiedenen Sprachen
Tags: Kategorien für Ihr Plugin. Sie können jeweils nur ein Tag festlegen (derzeit gibt es nur die Tags 'Suche', 'Bild', 'Videos', 'Wetter', 'Finanzen', 'Design', ' Reisen', 'Soziales', 'Nachrichten', 'Medizin', 'Produktivität', 'Bildung', 'Business', 'Unterhaltung', 'Versorgungsunternehmen' oder 'Sonstiges')
Ressourcenanforderungen (siehe Abschnitt "Anforderungen").
resource.memory: Maximale Speichernutzung in Bytes (z. B. 1048576 = 1MB)
resource.permission: Erforderliche Berechtigungen für Ihr Plugin
Plugin-Referenzen.
plugins.tools: Pfad zu den YAML-Dateien Ihres Anbieters
Auswirkungen auf den Marktplatz
Auf dem von Ihnen zur Verfügung gestellten Marketplace-Screenshot können Sie sehen, wie diese Felder aussehen.
Der Name des Plugins, das Symbol und die Beschreibung erscheinen oben
Der Name des Autors und die Versionsnummer werden unterhalb der Beschreibung angezeigt.
Tags erscheinen im Abschnitt "TAGS".
Die Speicheranforderungen sind im Abschnitt "VORAUSSETZUNGEN" aufgeführt.
Wichtige Hinweise
Die meisten Felder können so belassen werden, wie sie ursprünglich in der Vorlage konfiguriert wurden.
Typ: als "Plugin" beibehalten
meta section: Behalten Sie die Standardwerte bei
resource.permission: Nur ändern, wenn Ihr Plugin bestimmte Berechtigungen benötigt
Felder, die Sie anpassen sollten.
version: Die Versionsnummer Ihres Plugins
Autor: Name Ihrer Organisation
name: Ein eindeutiger Bezeichner für Ihr Plugin
label: Der Anzeigename in verschiedenen Sprachen
description: Eine klare Beschreibung, was Ihr Plugin macht
Tags: Relevante Kategorien für Ihr Plugin
plugins.tools: Pfad zu den YAML-Dateien Ihres Anbieters
Um Ihre eigene manifest.yaml-Datei zu erstellen, beginnen Sie mit der Vorlage und passen Sie die Felder an, die beeinflussen, wie Ihr Plugin im Marketplace erscheint. Der Schlüssel ist ist es, klare, prägnante Informationen zu liefern, die den Nutzern helfen zu verstehen, was Ihr Plugin tut. Trotzdem sollten Sie die Manifestdatei so belassen, wie sie ist, da alles bei der Initialisierung eingerichtet wird.
2. wie man provider/your_plugin.yaml bearbeitet
Sie haben die Aufgabe, die YAML-Datei für die Providerkonfiguration eines Dify-Plugins zu erstellen. Diese Datei definiert die für Ihren Dienst erforderlichen Anmeldedaten und die Art der Anmeldung. Ich werde Sie Schritt für Schritt durch die Erstellung dieser Datei am Beispiel der Google-Suche führen.
Datei Zweck
Die YAML-Datei des Anbieters (your_plugin.yaml) definiert.
Welche Berechtigungsnachweise die Nutzer für die Nutzung Ihres Dienstes angeben müssen
Wie diese Anmeldeinformationen gesammelt und in der Benutzeroberfläche angezeigt werden
Welche Tools sind in Ihrem Plugin enthalten?
Die Python-Datei, die diese Anmeldeinformationen validiert
Erforderliche Komponenten
Identitätsabschnitt: Grundlegende Metadaten für Ihr Plugin (erforderlich, hat aber keinen Einfluss auf das Erscheinungsbild des Marktplatzes)
Abschnitt credentials_for_provider: Legt fest, welche Authentifizierungsdaten die Benutzer angeben müssen
Abschnitt tools: Listet auf, welche Werkzeugkonfigurationsdateien enthalten sind
extra section: Gibt die Python-Datei an, die für die Validierung der Anmeldeinformationen verwendet wird
Beispielhafte Umsetzung
So sieht die YAML-Datei des Anbieters für das Dropbox-Tool aus.
Identität.
Autor: lcandy
Name: Dropbox
Etikett.
en_US: Dropbox
zh_Hans: Dropbox
pt_BR: Dropbox
ja_JP: Dropbox
zh_Hant: Dropbox
Beschreibung.
en_US: Interaktion mit Dropbox-Dateien und -Ordnern
zh_Hans: Interaktion mit Dropbox-Dateien und -Ordnern
pt_BR: Interaktion mit Dokumenten und Dateien in Dropbox
ja_jp: Dropbox のファイルとフォルダを操作します
zh_Hant: Interaktion mit Dropbox-Dateien und -Ordnern
Symbol: icon.svg
credentials_for_provider.
zugangs_token.
Typ: Geheim-Eingang
erforderlich: true
Etikett.
en_US: Zugangstoken
zh_Hans: Zugangstoken
pt_BR: Erlaubnismarke (Token de Acesso)
ja_jp: akustischer Heizer
zh_Hant: Zugang zum Zepter
Platzhalter.
en_US: Bitte geben Sie Ihr Dropbox-Zugangs-Token ein
zh_Hans: Bitte geben Sie Ihr Dropbox-Zugangs-Token ein!
pt_BR: Por favor, insira seu token de acesso do Dropbox
ja_jp: Dropbox アクセストークンを入力してください
zh_Hant: Bitte geben Sie Ihren Dropbox-Zugangsschlüssel ein.
helfen.
en_US: Holen Sie sich Ihr Zugriffstoken von der Dropbox App Console
zh_Hans: Abrufen des Zugriffstokens aus der Dropbox-App-Konsole
pt_BR: Obtenha seu token de acesso no Console de Aplicativos do Dropbox
ja_JP: Dropbox アプリコンソールからアクセストークンを取得してください
zh_Hant: Bitte holen Sie sich Ihren Zugangsstick über die Dropbox-App-Konsole.
url.
Werkzeuge.
- tools/list_files.yaml
- tools/search_files.yaml
- tools/upload_file.yaml
- tools/download_file.yaml
- tools/erstellen_ordner.yaml
- tools/delete_file.yaml
extra.
python.
Quelle: provider/dropbox.py
Wichtige Punkte zur Erinnerung
Identity Section: Obwohl sie den Marketplace nicht beeinflusst, ist sie dennoch in der Dateistruktur erforderlich. Enthält grundlegende Informationen wie Name, Autor und Beschreibung. Die Tags sollten von der Datei manifest.yaml geerbt werden.
Abschnitt Berechtigungsnachweise.
Jeder Berechtigungsnachweis benötigt einen eindeutigen Bezeichner (wie Dropbox-Zugangs-Token)
Typ Optionen.
secret-input: Für sensible Informationen, die verschlüsselt werden sollen
text-input: Für regelmäßige Textinformationen
select: Für Dropdown-Auswahl
boolean: Für Kippschalter
tool-selector: Für Werkzeugkonfigurationsobjekte
Erforderlich einschließen: true/false, um anzugeben, ob der Nachweis obligatorisch ist
Bereitstellung von benutzerfreundlichen Beschriftungen, Platzhaltern und Hilfetexten in verschiedenen Sprachen
Das Feld url verweist auf die Dokumentation für den Erhalt von Anmeldeinformationen
Abschnitt Werkzeuge.
Listet die YAML-Dateien für jedes Werkzeug in Ihrem Plugin auf
Die Pfade sollten relativ zum Stammverzeichnis des Plugins sein
Extra Abschnitt.
Gibt die Python-Datei an, die die Anmeldeinformationen validiert
Diese Datei sollte mit der Datei übereinstimmen, die Sie in Ihrer "provider/your_plugin.py" erstellt haben.
Erstellen Ihrer YAML-Datei
Um dies für Ihren eigenen Dienst anzupassen.
Ändern Sie den Abschnitt Identität mit Ihren grundlegenden Plugin-Informationen
Definieren Sie im Abschnitt credentials_for_provider, welche Anmeldeinformationen Ihr Dienst benötigt
Listen Sie Ihre Werkzeug-YAML-Dateien im Bereich Werkzeuge auf
Geben Sie Ihre Python-Validierungsdatei im Abschnitt extra an
Denken Sie daran, dass diese YAML-Datei mit Ihrer Python-Validierungsdatei zusammenarbeitet, die diese Anmeldedaten für die Authentifizierung bei Ihrem Dienst verwenden wird.
3. wie man provider/your_plugin.py bearbeitet
Sie haben die Aufgabe, die Anbieter-Authentifizierungsdatei für ein Dify-Plugin zu erstellen. Diese Datei validiert die Anmeldedaten, die für den Zugriff auf ein Drittanbieter-Plugin benötigt werden. Ich werde Sie bei der Erstellung dieser Datei am Beispiel der Google Search API-Integration anleiten.
Datei Zweck
Die Python-Datei provider (provider_name.py) dient als Testmodul für die Authentifizierung Ihres Dify-Plugins. Ihre Hauptaufgabe besteht darin, zu testen ob die von den Benutzern angegebenen Anmeldeinformationen gültig sind, indem sie einen einfachen API-Aufruf an den Dienst richten.
Erforderliche Komponenten
Ihre Providerklasse muss von dify_plugin erben.
Sie müssen die Methode _validate_credentials implementieren
Sie müssen ToolProviderCredentialValidationError für die Fehlerbehandlung verwenden
Wie es funktioniert
Der Ablauf der Authentifizierung erfolgt in folgenden Schritten.
Der Benutzer gibt seine Anmeldedaten in der Dify-Benutzeroberfläche ein
Dify übergibt diese Anmeldedaten an Ihre _validate_credentials-Methode
Ihr Code versucht einen einfachen API-Aufruf unter Verwendung der angegebenen Anmeldeinformationen
Wenn die Authentifizierung erfolgreich war, ist sie gültig; wenn nicht, wird ein Fehler ausgegeben.
Beispielhafte Umsetzung
So würden Sie eine Anbieterdatei für das Dropbox-Tool implementieren
from typing import Any
von dify_plugin importieren ToolProvider
from dify_plugin.errors.tool.import ToolProviderCredentialValidationError
Dropbox importieren
from dropbox.exceptions import AuthError
from dropbox_utils import DropboxUtils
class DropboxProvider(ToolProvider).
def _validate_credentials(self, credentials: dict[str, Any]) -> None.
versuchen.
# Prüfung, ob access_token in den Anmeldeinformationen angegeben ist
if "access_token" nicht in credentials oder nicht credentials.get("access_token"):.
raise ToolProviderCredentialValidationError("Dropbox-Zugangstoken ist erforderlich.")
# Versuchen Sie, sich bei Dropbox mit dem Zugriffstoken zu authentifizieren
versuchen.
# Verwenden Sie die Utility-Funktion, um einen Client zu erhalten
DropboxUtils.get_client(credentials.get("access_token"))
except AuthError as e.
raise ToolProviderCredentialValidationError(f "Ungültiges Dropbox-Zugangs-Token: {str(e)}")
außer Ausnahme wie e.
raise ToolProviderCredentialValidationError(f "Verbindung zu Dropbox fehlgeschlagen: {str(e)}")
außer Ausnahme wie e.
raise ToolProviderCredentialValidationError(str(e))
Wichtige Punkte zur Erinnerung
Verwenden Sie immer die Toolklasse: Der Anbieter führt keine direkten API-Aufrufe durch, sondern verwendet die Toolklasse über die Methode from_credentials.
Verwenden Sie eine minimale Testabfrage: Halten Sie Ihren Validierungstest einfach - gerade genug, um zu bestätigen, dass die Anmeldedaten funktionieren.
Korrekte Fehlerbehandlung: Wickeln Sie Ihre Validierung immer in einen try/except-Block ein und wandeln Sie alle Ausnahmen in den Standard ToolProviderCredentialValidationError.
Generic credentials dictionary: Der credentials-Parameter enthält alle Authentifizierungsparameter, die in Ihrer provider_name.yaml-Datei definiert sind.
Handhabung des Generators: Beachten Sie die for _ in ... Syntax, die verwendet wird, um den von der invoke-Methode zurückgegebenen Generator zu behandeln.
4. wie man tools/your_plugin.yaml bearbeitet
Sie haben die Aufgabe, die YAML-Datei für die Werkzeugkonfiguration eines Dify-Plugins zu erstellen. Diese Datei definiert, wie Ihr Werkzeug in der Dify-Oberfläche erscheint, welche Parameter es akzeptiert und wie diese Parameter sowohl dem Benutzer als auch dem AI-Agenten präsentiert werden. Parameter es akzeptiert und wie diese Parameter sowohl den Nutzern als auch dem KI-Agenten präsentiert werden. Ich werde Sie durch die Erstellung dieser Datei am Beispiel von Google Suche als Beispiel.
Yaml-Schema von tools/your_plugin.yaml.
base64 importieren
importieren contextlib
uuid importieren
from collections.abc import Mapping
from enum import Enum, StrEnum
from typing import Any, Optional, Union
von pydantic importieren (
BaseModel.
Feld.
field_serializer.
field_validator.
model_validator,
)
from dify_plugin.core.utils.yaml_loader import load_yaml_file
from 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 = "abgelaufene_Zeit"
GESAMTPREIS = "gesamt_preis"
TOTAL_TOKENS = "total_tokens"
Anbieter = "Anbieter"
CURRENCY = "Währung"
class CommonParameterType(Enum).
SECRET_INPUT = "Geheimeingabe"
TEXT_INPUT = "Texteingabe"
SELECT = "auswählen"
STRING = "Zeichenfolge"
NUMBER = "Zahl"
FILE = "Datei"
FILES = "Dateien"
BOOLEAN = "boolesch"
APP_SELECTOR = "app-selector"
MODEL_SELECTOR = "Modell-Selektor"
# TOOL_SELECTOR = "Werkzeug-Selektor"
TOOLS_SELECTOR = "array[tools]"
class AppSelectorScope(Enum).
ALL = "alle"
CHAT = "Chat"
WORKFLOW = "Arbeitsablauf"
COMPLETION = "Abschluss"
class ModelConfigScope(Enum).
LLM = "llm"
TEXT_EMBEDDING = "text-embedding"
RERANK = "rerank"
TTS = "tts"
SPEECH2TEXT = "speech2text"
MODERATION = "Mäßigung"
VISION = "Weitblick"
class ToolSelectorScope(Enum).
ALL = "alle"
PLUGIN = "Plugin"
API = "api"
WORKFLOW = "Arbeitsablauf"
class ToolRuntime(BaseModel).
credentials: dict[str, Any]
user_id: Optional[str]
session_id: Optional[str]
class ToolInvokeMessage(BaseModel).
class TextMessage(BaseModel).
text: 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}
class BlobMessage(BaseModel).
blob: bytes
class BlobChunkMessage(BaseModel).
id: str = Feld(... , description="Die ID des Blob")
sequence: int = Feld(... , description="Die Sequenz des Chunks")
total_length: int = Field(... , description="Die Gesamtlänge des BLOBs")
blob: bytes = Field(... , description="Die Blobdaten des Chunks")
end: bool = Field(... , description="Ob der Chunk der letzte Chunk ist")
class VariableMessage(BaseModel).
variable_name: str = Feld(
...,
description="Der Name der Variablen, unterstützt nur Root-Level-Variablen".
)
variable_value: Any = Feld(... , description="Der Wert der Variablen")
stream: bool = Field(default=False, description="Ob die Variable gestreamt wird")
@model_validator(mode="before")
@classmethod
def validate_variable_wert_und_strom(cls, werte).
# Überspringen der Validierung, wenn values kein dict ist
if not isinstance(values, dict):: if not isinstance(values, dict): if not isinstance(values, dict).
Rückgabewerte
if values.get("stream") and not isinstance(values.get("variable_value"), str).
raise ValueError("Wenn 'stream' True ist, muss 'variable_value' ein String sein.")
Rückgabewerte
class LogMessage(BaseModel).
class LogStatus(Enum).
START = "Start"
ERROR = "Fehler"
SUCCESS = "Erfolg"
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Die ID des Protokolls")
label: str = Field(... , description="Die Bezeichnung des Protokolls")
parent_id: Optional[str] = Field(default=None, description="Leer lassen für Wurzelprotokoll")
error: Optional[str] = Field(default=None, description="Die Fehlermeldung")
status: LogStatus = Feld(... , description="Der Status des Protokolls")
data: Mapping[str, Any] = Feld(... , description="Detaillierte Protokolldaten")
metadata: Optional[Mapping[LogMetadata, Any]] = Field(default=None, description="Die Metadaten des Protokolls")
class MessageType(Enum).
TEXT = "Text"
FILE = "Datei"
BLOB = "Klecks"
JSON = "json"
LINK = "Verknüpfung"
IMAGE = "Bild"
IMAGE_LINK = "image_link"
VARIABLE = "Variable"
BLOB_CHUNK = "blob_chunk"
LOG = "Protokoll"
Typ: MessageType
# TODO: pydantic validiert und konstruiert die Nachricht eine nach der anderen, bis es auf einen korrekten Typ trifft
# wir müssen den Bauprozess optimieren
Nachricht: TextMessage | JsonMessage | VariableMessage | BlobMessage | BlobChunkMessage | LogMessage | Keine
meta: Optional[dict] = Keine
@field_validator("message", mode="before")
@classmethod
def decode_blob_message(cls, v).
if isinstance(v, dict) und "blob" in v.
mit contextlib.suppress(Exception).
v["blob"] = base64.b64decode(v["blob"])
Rückgabe v
@field_serializer("Nachricht")
def serialize_message(self, v).
if isinstance(v, self.BlobMessage)::
return {"blob": base64.b64encode(v.blob).decode("utf-8")}
elif isinstance(v, self.BlobChunkMessage)::
zurück {
"id": v.id,
"Sequenz": v.sequence,
"Gesamtlänge": v.total_length,
"blob": base64.b64encode(v.blob).decode("utf-8"),
"Ende": v.end,
}
Rückgabe v
class ToolIdentity(BaseModel).
author: str = Field(... , description="Der Autor des Tools")
name: str = Feld(... , description="Der Name des Werkzeugs")
label: I18nObject = Field(... , description="Die Bezeichnung des Werkzeugs")
class ToolParameterOption(BaseModel).
value: str = Feld(... , description="Der Wert der Option")
label: I18nObject = Field(... , description="Die Bezeichnung der Option")
@field_validator("value", mode="before")
@classmethod
def transform_id_to_str(cls, value) -> str.
if not isinstance(wert, str): if not isinstance(wert, str).
return str(Wert)
sonst.
Rückgabewert
class ParameterAutoGenerate(BaseModel).
class Type(StrEnum).
PROMPT_INSTRUCTION = "prompt_instruction"
Typ: Typ
class ParameterTemplate(BaseModel).
enabled: bool = Field(... , description="Ob der Parameter Jinja aktiviert ist")
class 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
class ToolParameterForm(Enum).
SCHEMA = "schema" # sollte beim Hinzufügen des Werkzeugs gesetzt werden
FORM = "form" # sollte vor dem Aufrufen des Werkzeugs gesetzt werden.
LLM = "llm" # wird durch LLM gesetzt
name: str = Feld(... , description="Der Name des Parameters")
label: I18nObject = Field(... , description="Die Bezeichnung, die dem Benutzer angezeigt wird")
human_description: I18nObject = Field(... , description="Die Beschreibung, die dem Benutzer präsentiert wird")
type: ToolParameterType = Feld(... , description="Der Typ des Parameters")
auto_generate: Optional[ParameterAutoGenerate] = Feld(
default=None, description="Die automatische Generierung des Parameters"
)
template: Optional[ParameterTemplate] = Field(default=None, description="Die Vorlage für den Parameter")
Geltungsbereich: str | None = None
form: ToolParameterForm = Field(... , description="Die Form des Parameters, schema/form/llm")
llm_description: Optional[str] = Keine
erforderlich: Optional[bool] = False
Standard: Optional[Union[int, float, str]] = Keine
min: Optional[Union[float, int]] = Keine
max: Optional[Union[float, int]] = Keine
Genauigkeit: Optional[int] = Keine
Optionen: Optional
class ToolDescription(BaseModel).
human: I18nObject = Field(... , description="Die Beschreibung, die dem Benutzer präsentiert wird")
llm: str = Feld(... , description="Die dem LLM vorgelegte Beschreibung")
class ToolConfigurationExtra(BaseModel).
class Python(BaseModel).
Quelle: str
python: Python
class ToolConfiguration(BaseModel).
Identität: ToolIdentity
parameters: list[ToolParameter] = Field(default=[], description="Die Parameter des Werkzeugs")
Beschreibung: ToolDescription
extra: WerkzeugkonfigurationExtra
has_runtime_parameters: bool = Field(default=False, description="Ob das Werkzeug Laufzeitparameter hat")
output_schema: Optional[Mapping[str, Any]] = Keine
class ToolLabelEnum(Enum).
SEARCH = "Suche"
IMAGE = "Bild"
VIDEOS = "Videos"
WEATHER = "Wetter"
FINANCE = "Finanzen"
DESIGN = "Entwurf"
TRAVEL = "Reisen"
SOCIAL = "sozial"
NEWS = "Nachrichten"
MEDICAL = "medizinisch"
PRODUCTIVITY = "Produktivität"
EDUCATION = "Bildung"
BUSINESS = "Geschäft"
ENTERTAINMENT = "Unterhaltung"
UTILITIES = "Dienstprogramme"
OTHER = "sonstiges"
class ToolCredentialsOption(BaseModel).
value: str = Feld(... , description="Der Wert der Option")
label: I18nObject = Field(... , description="Die Bezeichnung der Option")
class 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.
"""
Ermittelt den Wert des angegebenen Modus.
:param Wert: Modus Wert
:return: Modus
"""
for mode in cls.
wenn Modus.Wert == Wert.
Rückkehrmodus
raise ValueError(f "ungültiger Moduswert {Wert}")
name: str = Feld(... , description="Der Name des Berechtigungsnachweises")
type: Config = Field(..., description="Die Art des Berechtigungsnachweises") , description="Die Art des Berechtigungsnachweises")
Geltungsbereich: str | None = None
erforderlich: bool = False
Standard: Optional[Union[int, float, str]] = Keine
Optionen: Optional
Bezeichnung: I18nObject
Hilfe: Optional[I18nObject] = Keine
url: Optional[str] = Keine
Platzhalter: Optional[I18nObject] = Keine
class ToolProviderIdentity(BaseModel).
author: str = Field(... , description="Der Autor des Tools")
name: str = Feld(... , description="Der Name des Werkzeugs")
description: I18nObject = Field(... , description="Die Beschreibung des Werkzeugs")
icon: str = Field(... , description="Das Symbol des Werkzeugs")
label: I18nObject = Field(... , description="Die Bezeichnung des Werkzeugs")
tags: list[ToolLabelEnum] = Feld(
default=[],
description="Die Tags des Tools".
)
class ToolProviderConfigurationExtra(BaseModel).
class Python(BaseModel).
Quelle: str
python: Python
class ToolProviderConfiguration(BaseModel).
Identität: ToolProviderIdentität
credentials_schema: list[ProviderConfig] = Feld(
default_factory=list,
alias="credentials_for_provider",
description="Das Schema der Anmeldeinformationen des Toolanbieters".
)
tools: list[ToolConfiguration] = Field(default=[], description="Die Werkzeuge des Werkzeuganbieters")
extra: ToolProviderKonfigurationExtra
@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]] = []
for name, credential in original_credentials_for_provider.items()::
credential["name"] = name
credentials_for_provider.append(credential)
data["credentials_for_provider"] = credentials_for_provider
Rückgabedaten
@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("Werkzeuge sollten eine Liste sein")
Werkzeuge: list[Werkzeugkonfiguration] = []
für Werkzeug im Wert:
# aus yaml lesen
if not isinstance(tool, str): if not isinstance(tool, str).
raise ValueError("Werkzeugpfad sollte ein String sein")
versuchen.
Datei = load_yaml_file(Werkzeug)
tools.append(
WerkzeugKonfiguration(
identity=ToolIdentity(**file["identity"]),
parameters=[ToolParameter(**param) for param in file.get("parameter", []) oder []],
description=ToolDescription(**file["description"]),
extra=ToolConfigurationExtra(**file.get("extra", {})),
output_schema=file.get("output_schema", None),
)
)
außer Ausnahme wie e.
raise ValueError(f "Fehler beim Laden der Werkzeugkonfiguration: {str(e)}") from e
Rückholwerkzeuge
class ToolProviderType(Enum).
"""
Enum-Klasse für Werkzeuganbieter
"""
BUILT_IN = "eingebaut"
WORKFLOW = "Arbeitsablauf"
API = "api"
APP = "app"
DATASET_RETRIEVAL = "Datensatz-Wiederherstellung"
@classmethod
def value_of(cls, value: str) -> "ToolProviderType".
"""
Ermittelt den Wert des angegebenen Modus.
:param Wert: Modus Wert
:return: Modus
"""
for mode in cls.
wenn Modus.Wert == Wert.
Rückkehrmodus
raise ValueError(f "ungültiger Moduswert {Wert}")
class ToolSelector(BaseModel).
class Parameter(BaseModel).
name: str = Feld(... , description="Der Name des Parameters")
type: ToolParameter.ToolParameterType = Field(... , description="Der Typ des Parameters")
required: bool = Field(... , description="Ob der Parameter erforderlich ist")
description: str = Feld(... , description="Die Beschreibung des Parameters")
Standard: Optional[Union[int, float, str]] = Keine
Optionen: Optional
provider_id: str = Feld(... , description="Die ID des Anbieters")
tool_name: str = Field(... , description="Der Name des Werkzeugs")
tool_description: str = Field(... , description="Die Beschreibung des Werkzeugs")
tool_configuration: Mapping[str, Any] = Feld(... , description="Konfiguration, Typ Formular")
tool_parameters: Mapping[str, Parameter] = Feld(... , description="Parameter, Typ llm")
def to_prompt_message(self) -> PromptMessageTool.
"""
Umwandlung des Werkzeugselektors in ein Werkzeug für die Eingabeaufforderung, basierend auf dem Aufrufschema der openai-Funktion.
"""
tool = PromptMessageTool(
name=self.tool_name,
description=self.tool_description,
parameter={
"Typ": "Objekt",
"Eigenschaften": {},
"erforderlich": [],
},
)
for name, parameter in self.tool_parameters.items()::
tool.parameters[name] = {
"Typ": Parameter.Typ.Wert,
"Beschreibung": parameter.description,
}
wenn parameter.required.
tool.parameters["required"].append(name)
wenn Parameter.Optionen.
tool.parameters[name]["enum"] = [option.value for option in parameter.options]
Rückholwerkzeug
Datei Zweck
Die YAML-Datei des Tools (your_plugin.yaml) definiert.
Grundlegende Informationen zur Identität Ihres Werkzeugs
Beschreibungen für Menschen und den KI-Agenten
Parameter, die Ihr Werkzeug akzeptiert
Wie diese Parameter dargestellt und erfasst werden
Beispielhafte Umsetzung
So sehen die YAML-Dateien des Tools für Dropbox aus.
ceate_folder.yaml.
Identität.
Name: create_folder
Autor: lcandy
Etikett.
en_US: Ordner erstellen
zh_Hans: Erstellen von Ordnern
pt_BR: Criar Teigwaren
ja_jp: Gefaltet
zh_Hant: Ordner erstellen
Beschreibung.
menschlich.
en_US: Erstellen eines neuen Ordners in Dropbox
zh_Hans: Erstellen eines neuen Ordners in Dropbox
pt_BR: Eine neue Nudel in Dropbox erstellen
ja_jp: Dropbox macht eine neue Version von Frida!
zh_Hant: Erstellen eines neuen Ordners in Dropbox
llm: Erstellt einen neuen Ordner unter dem angegebenen Pfad in Dropbox und gibt Informationen über den erstellten Ordner einschließlich Pfad und ID zurück.
Parameter.
- name: ordner_pfad
Typ: Zeichenkette
erforderlich: true
Etikett.
en_US: Ordnerpfad
zh_Hans: Ordnerpfad
pt_BR: Caminho da Pasta
ja_jp:ォルダパス
zh_Hant: Ordnerpfad
human_description.
en_US: Der Pfad, unter dem der Ordner in Dropbox erstellt wird
zh_Hans: Pfad zur Ordnererstellung in Dropbox
pt_BR: Der Weg, auf dem die Nudeln in Dropbox gefunden werden
ja_jp: Dropbox でフォルダを作成するパス
zh_Hant: Der Pfad zu dem Ordner, den Sie in Dropbox erstellen möchten.
llm_description: Der Pfad, unter dem der Ordner in Dropbox erstellt wird, sollte als vollständiger Pfad angegeben werden, z. B. '/Documents/Projects' oder '/Photos/ Urlaub2023". Bei Pfaden wird die Groß- und Kleinschreibung beachtet und sie müssen mit einem Schrägstrich beginnen.
Form: llm
extra.
python.
Quelle: tools/create_folder.py
delete_file.yaml.
Identität.
Name: delete_file
Autor: lcandy
Etikett.
en_US: Datei/Ordner löschen
zh_Hans: Dateien/Ordner löschen
pt_BR: Ausschluss von Nudeln/Pasta
ja_jp: ファイル/フォルダ削除
zh_Hant: Datei/Ordner löschen
Beschreibung.
menschlich.
en_US: Löschen einer Datei oder eines Ordners aus Dropbox
zh_Hans: Löschen von Dateien oder Ordnern aus Dropbox
pt_BR: Ausschluss eines Dokuments oder einer Datei aus Dropbox
ja_jp: Dropbox からファイルやフォルダを削除します
zh_Hant: Datei oder Ordner aus Dropbox löschen
llm: Löscht eine Datei oder einen Ordner unter dem angegebenen Pfad dauerhaft aus Dropbox und gibt Bestätigungsinformationen über das gelöschte Element zurück.
Parameter.
- Name: file_path
Typ: Zeichenkette
erforderlich: true
Etikett.
en_US: Datei-/Ordnerpfad
zh_Hans: Datei-/Ordnerpfad
pt_BR: Caminho do Arquivo/Pasta
ja_jp:ファイル/フォルダパス
zh_Hant: Datei-/Ordnerpfad
human_description.
en_US: Der Pfad der Datei oder des Ordners, der aus Dropbox gelöscht werden soll
zh_Hans: Pfad zu der Datei oder dem Ordner, der aus Dropbox gelöscht werden soll
pt_BR: O caminho do arquivo ou pasta para excluir do Dropbox
ja_jp: Dropbox から削除するファイルやフォルダのパス
zh_Hant: Pfad zu der Datei oder dem Ordner, den Sie aus Dropbox löschen möchten
llm_description: Der Pfad der Datei oder des Ordners, die/das aus Dropbox gelöscht werden soll, sollte als vollständiger Pfad angegeben werden, z. B. "/Documents/report.txt" oder "/Photos /Urlaub2023'. Pfade unterscheiden Groß- und Kleinschreibung und müssen mit einem Schrägstrich beginnen. WARNUNG - Dies ist eine dauerhafte Löschung.
Form: llm
extra.
python.
Quelle: tools/delete_file.py
download_file.py.
Identität.
Name: download_file
Autor: lcandy
Etikett.
en_US: Datei herunterladen
zh_Hans: Datei herunterladen
pt_BR: Abfrage der Daten
ja_jp: ファイルダウンロード
zh_Hant: Datei herunterladen
Beschreibung.
menschlich.
en_US: Herunterladen einer Datei von Dropbox
zh_Hans: Herunterladen von Dateien aus Dropbox
pt_BR: Abrufen von Daten aus Dropbox
ja_JP: Dropbox からファイルをダウンロードします
zh_Hant: Dateien von Dropbox herunterladen
llm: Lädt eine Datei von Dropbox unter dem angegebenen Pfad herunter. Gibt die Metadaten der Datei und optional den Inhalt der Datei zurück (als base64 für Binärdateien oder Text für Textdateien). Dateien).
Parameter.
- Name: file_path
Typ: Zeichenkette
erforderlich: true
Etikett.
en_US: Dateipfad
zh_Hans: Dateipfad
pt_BR: Caminho do Arquivo
ja_jp: ファイルパス
zh_Hant: Dateipfade
human_description.
en_US: Der Pfad der Datei, die von Dropbox heruntergeladen werden soll
zh_Hans: Pfad zur Datei, die von Dropbox heruntergeladen werden soll
pt_BR: O caminho do arquivo para baixar do Dropbox
ja_JP: Dropbox からダウンロードするファイルのパス
zh_Hant: der Pfad zu der Datei, die Sie von Dropbox herunterladen möchten
llm_description: Der Pfad der Datei, die von Dropbox heruntergeladen werden soll, sollte den vollständigen Pfad mit Dateinamen und Erweiterung enthalten, z. B. "/Documents/report. txt'. Bei Pfaden wird die Groß- und Kleinschreibung beachtet und sie müssen mit einem Schrägstrich beginnen.
Form: llm
- Name: include_content
Typ: boolesch
erforderlich: false
Voreinstellung: false
Etikett.
en_US: Inhalt einbeziehen
zh_Hans: Inhalt
pt_BR: Einbeziehen von Inhalten
ja_JP: Inhalt
zh_Hant: Enthält Inhalt
human_description.
en_US: Angabe, ob der Inhalt der Datei in die Antwort aufgenommen werden soll
zh_Hans: ob der Inhalt der Datei in die Antwort aufgenommen werden soll oder nicht
pt_BR: Se deve incluir o conteúdo do arquivo na resposta
ja_jp: Die Inhalte des Films in den Rathponies sind im Film enthalten.
zh_Hant: ob der Dateiinhalt in die Antwort aufgenommen werden soll oder nicht
llm_description: Wird auf true gesetzt, um den Inhalt der Datei in die Antwort einzuschließen. Bei kleinen Textdateien wird der Inhalt als Text geliefert. Bei Binärdateien wird der Inhalt als base64-kodierter String geliefert. content wird als base64-kodierte Zeichenkette bereitgestellt. Standardwert ist false.
Form: llm
extra.
python.
Quelle: tools/download_file.py
dropbox.yaml.
Identität.
Name: Dropbox
Autor: lcandy
Etikett.
en_US: Dropbox
zh_Hans: Dropbox
pt_BR: Dropbox
ja_JP: Dropbox
zh_Hant: Dropbox
Beschreibung.
menschlich.
en_US: Interaktion mit Dropbox
zh_Hans: Interaktion mit Dropbox
pt_BR: Interagieren mit Dropbox
ja_JP: Dropbox und Konnektivität
zh_Hant: Interaktion mit Dropbox
llm: Ermöglicht den Zugriff auf Dropbox-Dienste, so dass Sie mit Dateien und Ordnern in einem Dropbox-Konto interagieren können.
Parameter.
- Name: Abfrage
Typ: Zeichenkette
erforderlich: true
Etikett.
en_US: Abfrage-String
zh_Hans: Abfrageanweisung
pt_BR: Begriff der Beratung
ja_jp: K'eri Textspalten
zh_Hant: Erklärung zur Anfrage
human_description.
en_US: Geben Sie Ihre Dropbox-Betriebsabfrage ein
zh_Hans: Geben Sie Ihre Dropbox-Betriebsabfrage ein
pt_BR: Stellen Sie Ihre Dropbox-Bedienungsanleitung ein
ja_JP: Dropbox-Betrieb クエリを入力してください
zh_Hant: Bitte geben Sie den Dropbox-Vorgang ein, den Sie ausführen möchten.
llm_description: Die Abfrage, die den Dropbox-Vorgang beschreibt, den Sie durchführen möchten.
Form: llm
extra.
python.
Quelle: tools/dropbox.py
Wichtige Komponenten
Abschnitt "Identität".
name: Interner Name für Ihr Tool (sollte mit Ihrer Dateibenennung übereinstimmen)
Autor: Wer hat das Tool erstellt?
label: Name in verschiedenen Sprachen anzeigen
Beschreibung Abschnitt.
menschlich: Beschreibung für menschliche Benutzer in verschiedenen Sprachen
llm: Beschreibung, die dem KI-Agenten zur Verfügung gestellt wird, um zu verstehen, was Ihr Werkzeug tut und wie es zu verwenden ist
Abschnitt Parameter.
Liste der Parameter, die Ihr Werkzeug akzeptiert, jeweils mit.
name: Bezeichner des Parameters (wird in Ihrem Python-Code verwendet)
type: Datentyp (Zeichenkette, Zahl, Boolescher Wert, usw.)
required: Ob dieser Parameter obligatorisch ist
Etikett: Benutzerfreundlicher Name in verschiedenen Sprachen
human_description: Erläuterung für menschliche Benutzer in verschiedenen Sprachen
llm_description: Erklärung für den KI-Agenten zum Verständnis dieses Parameters
form: Wie der Parameter erfasst wird
llm: KI-Agent extrahiert aus Nutzeranfragen
Workflow: Benutzer muss als Variable in der UI angeben
Optional: default: Standardwert für diesen Parameter
Extra Abschnitt.
python.source: Pfad zur Python-Implementierungsdatei Ihres Tools
Wichtige Hinweise
Dateitrennung.
Wichtig!!!! Wenn Ihr Tool verschiedene Funktionen hat, wie z.B. das Lesen und Schreiben einer E-Mail oder das Lesen oder Aktualisieren einer Datenbank, sollten Sie die yaml-Datei in mehrere Dateien aufteilen. Das Prinzip ist, dass jede yaml- und Code-Datei ausschließlich für die jeweilige Art der Tool-Ausführung bestimmt ist. Die Datei selbst sollte nur Parameter extrahieren, die das Tool Die Datei selbst sollte nur die Parameter extrahieren, die von der Funktionalität des Werkzeugs verwendet werden. Um zum Beispiel eine Datenbank zu lesen und zu aktualisieren, sollten Sie zwei separate yaml-Dateien verwenden: read_database.yaml und update_ database.yaml. database.yaml getrennt verwenden.
LLM-Beschreibungen.
Die llm-Beschreibung sowohl für das Werkzeug als auch für die Parameter ist von entscheidender Bedeutung - sie sagt dem KI-Agenten, wie er Ihr Werkzeug verwenden soll.
Seien Sie sich darüber im Klaren, welche Parameter benötigt werden und welche Informationen Ihr Tool zurückgeben wird
Dies hilft dem KI-Agenten zu entscheiden, wann er Ihr Tool verwenden und wie er Parameter aus Benutzeranfragen extrahieren soll.
Parameter Konfiguration.
Geben Sie für jeden Parameter an, ob er erforderlich ist
Wählen Sie den entsprechenden Datentyp
Setzen Sie das Formular auf llm, wenn Sie möchten, dass die KI es aus Benutzerabfragen extrahiert
Setzen Sie das Formular auf Workflow, wenn Sie möchten, dass die Benutzer es direkt eingeben
Lokalisierung.
Bereitstellung von Übersetzungen für Etiketten und Beschreibungen in mehreren Sprachen nach Bedarf
Mindestens Englisch (en_US) einschließen
Um eine eigene YAML-Datei für Ihr Tool zu erstellen, passen Sie diese Struktur an Ihr spezifisches Tool an, indem Sie klar definieren, welche Parameter es benötigt und wie diese Menschen und dem KI-Agenten präsentiert werden sollen.
5 Wie bearbeitet man tools/your_plugin.py?
Sie haben die Aufgabe, die Tool-Implementierungsdatei für ein Dify-Plugin zu erstellen. Diese Datei enthält die eigentliche Logik für Ihr Tool, das API-Anfragen stellt und die Ergebnisse verarbeitet. Diese Datei enthält die eigentliche Logik für Ihr Tool, das API-Anfragen stellt und die Ergebnisse verarbeitet. Ich werde Sie durch die Erstellung dieser Datei am Beispiel der Google-Suche führen.
Datei Zweck
Die Python-Datei des Tools (your_plugin.py) ist verantwortlich für.
API-Anfragen an Ihren Dienst stellen
Verarbeitung der Antworten
Rückgabe der Ergebnisse in einem von Dify verwendbaren Format
Erforderliche Komponenten
Ihre Werkzeugklasse muss von dify_plugin erben.
Sie müssen die Methode _invoke implementieren, die einen Generator zurückgibt
Sie müssen diese wesentlichen Einfuhren berücksichtigen.
from collections.abc import Generator
from typing import Any
from dify_plugin importieren Werkzeug
from dify_plugin.entities.tool.import ToolInvokeMessage
Beispielhafte Umsetzung
So sieht die Tool-Implementierung für das Dropbox-Tool aus.
ceate_folder.yaml.
from collections.abc import Generator
from typing import Any
from dify_plugin importieren Werkzeug
from dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError
from dropbox_utils import DropboxUtils
class CreateFolderTool(Tool).
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Einen Ordner in Dropbox erstellen
"""
# Parameter erhalten
ordner_pfad = tool_parameters.get("ordner_pfad", "")
# Parameter validieren
if not folder_path: if not folder_path: if not folder_path.
yield self.create_text_message("Ordnerpfad in Dropbox ist erforderlich.")
return
# Stellen Sie sicher, dass der Ordnerpfad mit / beginnt.
if not folder_path.startswith("/"):.
ordner_pfad = "/" + ordner_pfad
versuchen.
# Zugriffstoken aus Anmeldeinformationen abrufen
access_token = self.runtime.credentials.get("access_token")
wenn nicht access_token.
yield self.create_text_message("Dropbox-Zugangstoken ist erforderlich.")
return
# Dropbox-Client herunterladen
versuchen.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "Authentifizierung fehlgeschlagen: {str(e)}")
return
außer Ausnahme wie e.
yield self.create_text_message(f "Verbindung zu Dropbox fehlgeschlagen: {str(e)}")
return
# Erstellen Sie den Ordner
versuchen.
Ergebnis = DropboxUtils.create_folder(dbx, folder_path)
# Antwort erstellen
summary = f "Ordner '{result['name']}' erfolgreich erstellt unter '{result['path']}'"
yield self.create_text_message(Zusammenfassung)
yield self.create_json_message(result)
except ApiError as e.
if "Pfad/Konflikt" in str(e).
yield self.create_text_message(f "Ein Ordner existiert bereits unter '{Ordner_pfad}'")
sonst.
yield self.create_text_message(f "Fehler beim Erstellen des Ordners: {str(e)}")
return
außer Ausnahme wie e.
yield self.create_text_message(f "Fehler: {str(e)}")
return
delete_file.py
from collections.abc import Generator
from typing import Any
from dify_plugin importieren Werkzeug
from dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError
from dropbox_utils import DropboxUtils
class DeleteFileTool(Tool).
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Löschen einer Datei oder eines Ordners aus Dropbox
"""
# Parameter erhalten
file_path = tool_parameters.get("file_path", "")
# Parameter validieren
if not file_path: if not file_path: if not file_path.
yield self.create_text_message("Datei- oder Ordnerpfad in Dropbox ist erforderlich.")
return
# Stellen Sie sicher, dass der Pfad mit / beginnt.
if not file_path.startswith("/"):.
file_path = "/" + file_path
versuchen.
# Zugriffstoken aus Anmeldeinformationen abrufen
access_token = self.runtime.credentials.get("access_token")
wenn nicht access_token.
yield self.create_text_message("Dropbox-Zugangstoken ist erforderlich.")
return
# Dropbox-Client herunterladen
versuchen.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "Authentifizierung fehlgeschlagen: {str(e)}")
return
außer Ausnahme wie e.
yield self.create_text_message(f "Verbindung zu Dropbox fehlgeschlagen: {str(e)}")
return
# Löschen Sie die Datei oder den Ordner
versuchen.
Ergebnis = DropboxUtils.delete_file(dbx, file_path)
# Antwort erstellen
summary = f"'{result['name']}' erfolgreich gelöscht"
yield self.create_text_message(Zusammenfassung)
yield self.create_json_message(result)
except ApiError as e.
if "path/not_found" in str(e)::
yield self.create_text_message(f "Datei oder Ordner nicht gefunden unter '{file_path}'")
sonst.
yield self.create_text_message(f "Fehler beim Löschen von Dateien/Ordnern: {str(e)}")
return
außer Ausnahme wie e.
yield self.create_text_message(f "Fehler: {str(e)}")
return
download_file.yaml.
from collections.abc import Generator
base64 importieren
from typing import Any
from dify_plugin importieren Werkzeug
from dify_plugin.entities.tool.import ToolInvokeMessage
from dropbox.exceptions import ApiError, AuthError
from dropbox_utils import DropboxUtils
class DownloadFileTool(Tool).
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage, None, None].
"""
Eine Datei von Dropbox herunterladen
"""
# Parameter erhalten
file_path = tool_parameters.get("file_path", "")
include_content = tool_parameters.get("include_content", False)
# Parameter validieren
if not file_path: if not file_path: if not file_path.
yield self.create_text_message("Dateipfad in Dropbox ist erforderlich.")
return
# Stellen Sie sicher, dass der Dateipfad mit / beginnt.
if not file_path.startswith("/"):.
file_path = "/" + file_path
versuchen.
# Zugriffstoken aus Anmeldeinformationen abrufen
access_token = self.runtime.credentials.get("access_token")
wenn nicht access_token.
yield self.create_text_message("Dropbox-Zugangstoken ist erforderlich.")
return
# Dropbox-Client herunterladen
versuchen.
dbx = DropboxUtils.get_client(access_token)
except AuthError as e.
yield self.create_text_message(f "Authentifizierung fehlgeschlagen: {str(e)}")
return
außer Ausnahme wie e.
yield self.create_text_message(f "Verbindung zu Dropbox fehlgeschlagen: {str(e)}")
return
# Herunterladen der Datei
versuchen.
Ergebnis = DropboxUtils.download_file(dbx, file_path)
# Antwort erstellen
Antwort = {
"Name": Ergebnis["Name"],
"Pfad": Ergebnis["Pfad"],
"id": Ergebnis["id"],
"Größe": Ergebnis["Größe"],
"geändert": result["geändert"]
}
# Inhalt einfügen, wenn gewünscht
wenn include_content.
# Kodierung von Binärinhalten als base64
response["content_base64"] = base64.b64encode(result["content"]).decode('utf-8')
# Versuch der Dekodierung als Text, wenn klein genug
if result["size"] < 1024 * 1024: # Weniger als 1MB
versuchen.
text_inhalt = ergebnis["inhalt"].decode('utf-8')
response["content_text"] = text_content
except UnicodeDecodeError.
# Keine Textdatei, nur base64 einschließen
Pass
summary = f "Datei '{result['name']}' erfolgreich heruntergeladen"
yield self.create_text_message(Zusammenfassung)
yield self.create_json_message(response)
except ApiError as e.
yield self.create_text_message(f "Fehler beim Herunterladen der Datei: {str(e)}")
return
außer Ausnahme wie e.
yield self.create_text_message(f "Fehler: {str(e)}")
return
Wichtige Punkte zur Erinnerung
Dateitrennung.
Wichtig: Wenn Ihr Tool verschiedene Funktionen hat, wie z.B. das Lesen und Schreiben einer E-Mail oder das Lesen oder Aktualisieren einer Datenbank, sollten Sie die yaml-Datei in mehrere Dateien aufteilen. Das Prinzip ist, dass jede yaml- und Code-Datei ausschließlich für die jeweilige Art der Tool-Ausführung bestimmt ist. Die Datei selbst sollte nur die Parameter extrahieren, die die Funktionalität des Tools verwenden wird. Zum Beispiel, um eine Datenbank zu lesen und zu aktualisieren, sollten Sie zwei yaml-Dateien verwenden: read_database.py und update_ database.py. database.py getrennt verwenden.
Erforderliche Importe: Fügen Sie die wichtigsten Importe immer an den Anfang Ihrer Datei.
Klassenvererbung: Ihre Werkzeugklasse muss von dify_plugin erben.
Parameter extrahieren.
Das tool_parameters-Wörterbuch enthält alle Parameter, die in der YAML-Datei Ihres Werkzeugs definiert sind.
Direkter Zugriff auf diese Parameter über Wörterbuchschlüssel, z. B. tool_parameters["query"]
Diese Parameter werden vom KI-Agenten automatisch aus Benutzeranfragen extrahiert
Vergewissern Sie sich, dass Sie alle erforderlichen Parameter behandeln und bei fehlenden Parametern eine entsprechende Fehlerbehandlung vorsehen.
Beispiel.
query = tool_parameters["query"] # Extrahieren der Abfrage parameterlimit = tool_parameters.get("limit", 10) # Extrahieren mit einem Standardwert# Optionale Validierungwenn keine Abfrage: raise ValueError("Abfrageparameter darf nicht leer sein")
Zugriff auf Anmeldeinformationen.
Zugriff auf Ihre Authentifizierungsdaten mit self.runtime.credentials
Die Schlüssel entsprechen denen, die in der YAML-Datei Ihres Anbieters definiert sind
Beispiel: self.runtime.credentials["serpapi_api_key"]
Antwortverarbeitung: Erstellen Sie eine Hilfsmethode, um nur die relevanten Informationen aus API-Antworten zu extrahieren.
Yielding Results: Sie müssen yield mit einer der Methoden zur Nachrichtenerstellung verwenden, um Daten zurückzugeben.
Wenn Sie Ihr eigenes Tool implementieren, stellen Sie sicher, dass Sie alle benötigten Parameter korrekt aus dem tool_parameters-Wörterbuch extrahieren und sie gegebenenfalls validieren. Die verfügbaren Parameter sind in der YAML-Datei Ihres Tools definiert und werden vom KI-Agenten automatisch aus Benutzeranfragen extrahiert.
6. wie man PRIVACY.md und README.md erstellt
Sie sollen die Datenschutzrichtlinien und die Readme-Dateien für Ihr Dify-Plugin erstellen. Diese Dateien sind im Markdown-Format geschrieben und dienen wichtigen Diese Dateien sind im Markdown-Format geschrieben und dienen wichtigen Zwecken für Benutzer und Entwickler Ihres Plugins.
PRIVACY.md
Die Datei PRIVACY.md beschreibt die Datenschutzpraktiken Ihres Plugins, einschließlich der Daten, die es sammelt und wie diese Daten verwendet werden. Nutzer, die sich um ihren Datenschutz sorgen.
Was man einbeziehen sollte
Basierend auf dem von Ihnen geteilten Platzhaltertext ("!!!!! Bitte geben Sie die Datenschutzrichtlinien des Plugins an.") sollten Sie diese einfügen.
Welche Daten Ihr Plugin sammelt
Wie diese Daten gespeichert und verarbeitet werden
Welche Dienste von Drittanbietern werden genutzt (falls vorhanden)?
Rechte der Nutzer in Bezug auf ihre Daten
Wie lange werden die Daten gespeichert?
Kontaktinformationen für Datenschutzbelange
Beispiel Struktur
# Datenschutzrichtlinie
## Datenerhebung
[Beschreiben Sie, welche Nutzerdaten Ihr Plugin sammelt und warum]
## Datenverarbeitung
[Erläutern Sie, wie die erhobenen Daten verarbeitet werden]
## Dienste von Dritten
[Führen Sie alle Dienste von Drittanbietern auf, die von Ihrem Plugin verwendet werden, und verlinken Sie auf deren Datenschutzrichtlinien]
## Datenaufbewahrung
[Erläutern Sie, wie lange die Benutzerdaten gespeichert werden]
## Benutzerrechte
[Darlegen, welche Rechte die Nutzer in Bezug auf ihre Daten haben]
## Kontaktinformationen
[Geben Sie Kontaktinformationen für datenschutzbezogene Anfragen an]
Zuletzt aktualisiert: [Datum]
README.md
Die Datei README.md enthält wichtige Informationen über Ihr Plugin, einschließlich seiner Funktionen, seiner Installation und seiner Verwendung. Dies ist das erste Dokument, auf das sich die meisten Benutzer und Entwickler beziehen werden.
Was man einbeziehen sollte
Anhand des von Ihnen geteilten Beispiels (Jira-Plugin-Readme) sollten Sie Folgendes einschließen.
Plugin-Name als Hauptüberschrift
Informationen zum Autor
Informationen zur Version
Art des Plugins
Ausführliche Beschreibung der Funktionen des Plugins
Einbauanleitung
Beispiele für den Gebrauch
Optionen zur Konfiguration
Informationen zur Fehlersuche
Beispiel Struktur
# Ihr Plugin-Name
**Autor:** [Ihr Name oder Ihre Organisation] **Version:** [Aktuelle Versionsnummer] **Typ:** [Plugin-Typ]
## Beschreibung
[Geben Sie eine ausführliche Beschreibung der Funktionen Ihres Plugins]
## Merkmale
- [Merkmal 1]
- [Merkmal 2]
- [Merkmal 3]
## Einbau
[Schritt-für-Schritt-Installationsanweisungen bereitstellen]
## Konfiguration
[Erläutern Sie, wie Sie Ihr Plugin konfigurieren].
## Verwendungsbeispiele
[Geben Sie Beispiele für die Verwendung Ihres Plugins].
## Fehlerbehebung
[Auflistung gemeinsamer Probleme und ihrer Lösungen]
## Beitragend
[Erklären Sie, wie andere zu Ihrem Plugin beitragen können]
## Lizenz
[Geben Sie die Lizenz an, unter der Ihr Plugin veröffentlicht wird]
Bilder verwenden
Wie Sie bereits erwähnt haben, können Sie Bilder in beide Dokumente aufnehmen.
Speichern Sie die Bilder im Ordner _assets
Verweisen Sie in Ihrem Markdown auf sie mit relativen Pfaden.
! [Beschreibung des Bildes](_assets/image_name.png)
Beide Dateien sollten im Markdown-Format (.md-Erweiterung) geschrieben und im Stammverzeichnis Ihres Plugin-Projekts abgelegt werden. Achten Sie darauf, dass sie mit der Entwicklung Ihres Plugins auf dem neuesten Stand bleiben. Achten Sie darauf, dass sie mit der Entwicklung Ihres Plugins auf dem neuesten Stand bleiben.
Anforderungen.txt
Sie sollten immer die neuesten Abhängigkeiten verwenden, indem Sie ~= in Ihrer txt-Datei verwenden, und das dify_plugin~=0.0.1b72 ist ein Muss.