一文入门 Dify平台的插件开发

news/2025/11/23 22:27:03/文章来源:https://www.cnblogs.com/dddy/p/19261717

一文入门 Dify平台的插件开发

欢迎开始 Dify 插件开发 - https://docs.dify.ai/plugin-dev-zh/0111-getting-started-dify-plugin
Dify Plugin 开发速查表 - https://docs.dify.ai/plugin-dev-zh/0131-cheatsheet#环境要求
官方插件市场 - https://marketplace.dify.ai/

你可以将 Dify 插件想象成赋予 AI 应用增强感知和执行能力的模块化组件。它们使得将外部服务、自定义功能以及专用工具以”即插即用”的简洁方式集成到基于 Dify 构建的 AI 应用中成为可能。通过插件,你的 AI 应用可以更好地”看”、“听”、“说”、“画”、“计算”、“推理”,连接外部 API,甚至执行真实世界的操作。作为插件开发者,你可以为自己的 Dify 应用构建专属的功能扩展,或者将你的创新贡献给整个 Dify 生态系统,让更多用户受益。

插件的类型

  • 工具插件: 集成第三方 API 和服务
    https://docs.dify.ai/plugin-dev-zh/0211-getting-started-dify-tool

  • 模型插件: 集成 AI 模型
    https://docs.dify.ai/plugin-dev-zh/0131-model-plugin-introduction

  • Agent 策略插件: 自定义 Agent 思考和决策策略
    https://docs.dify.ai/plugin-dev-zh/9433-agent-strategy-plugin

  • Extension 类型插件 扩展插件: 扩展 Dify 平台功能,例如 Endpoint 和 WebAPP
    https://docs.dify.ai/plugin-dev-zh/9231-extension-plugin

插件的开发流程

0 安装命令行工具

安装插件开发工具 - https://docs.dify.ai/zh-hans/plugins/quick-start/develop-plugins/initialize-development-tools
下载页面 - https://github.com/langgenius/dify-plugin-daemon/releases

Tool 插件 https://docs.dify.ai/plugin-dev-zh/0222-tool-plugin#前置准备

为了在系统范围内全局使用 dify 命令,建议将二进制文件(dify-plugin-windows-amd64.exe)重命名为 dify 并复制到 /usr/local/bin 系统路径中。

1. 新建插件

./dify plugin init

2. 代码目录结构

your_plugin/
├── _assets/             # 图标和视觉资源
├── provider/            # 提供者定义和验证
│   ├── your_plugin.py   # 凭证验证逻辑
│   └── your_plugin.yaml # 提供者配置
├── tools/               # 工具实现
│   ├── feature_one.py   # 工具功能实现
│   ├── feature_one.yaml # 工具参数和描述
│   ├── feature_two.py   # 另一个工具实现
│   └── feature_two.yaml # 另一个工具配置
├── utils/               # 辅助函数
│   └── helpers.py       # 通用功能逻辑
├── working/             # 进度记录和工作文件
├── .env.example         # 环境变量模板
├── main.py              # 入口文件
├── manifest.yaml        # 插件主配置
├── README.md            # 文档
└── requirements.txt     # 依赖列表

Manifest文件 - https://docs.dify.ai/plugin-dev-zh/0411-plugin-info-by-manifest
Manifest 结构和工具规范 - https://docs.dify.ai/plugin-dev-zh/0411-general-specifications

3. 开发模式运行

配置 .env 文件,然后在插件目录下运行以下命令:

python -m main

远程调试插件 - https://docs.dify.ai/plugin-dev-zh/0411-remote-debug-a-plugin

4. 打包与部署

返回上级目录: 确保您的终端当前路径在 yourapp 文件夹的上一级
打包插件:

cd ..
dify plugin package ./yourappdify plugin package dify-plugin-database

https://docs.dify.ai/plugin-dev-zh/0321-release-overview

实例 - 一个读取文件的工具插件

搭建的工作流如果需要文件作为输入, 每次测试都需要上次文件到服务器, 太麻烦了且还占用服务器资源, 实现一个插件 给定文件名读取服务器的本地文件 作为工作流的文件对象, 输出到工作流的上下文中

Tool 插件 - https://docs.dify.ai/plugin-dev-zh/0222-tool-plugin#前置准备
参考 duckduckgo 插件的源码 - https://github.com/realvegechick/dify-duckduckgo

初始化开发环境

  1. 打开终端,执行初始化命令:
./dify plugin init

根据提示依次输入插件的基本信息:
Plugin name: 插件的唯一标识符。例如:telegraph 约束: 长度 1-128 字符,只能包含小写字母、数字、连字符(-)和下划线()。
Author: 插件作者的标识符。例如:your-name 约束: 长度 1-64 字符,只能包含小写字母、数字、连字符(-)和下划线(
)。
Description: 对插件功能的简短描述。例如:A Telegraph plugin that allows you to publish your content easily
选择开发语言: 当提示 Select language 时,请选择 python。
选择插件类型: 当提示 Select plugin type 时,对于本教程,请选择 tool。
选择附加功能: 接下来会提示是否需要包含 Provider 验证、持久存储等附加功能。

  1. 安装依赖
  • 项目初始化时生成的 requirements.txt 文件已包含插件开发所需的基础库 pip install -r requirements.txt
  • Python 环境: 需要 Python 3.12 或更高版本。

配置工具 (Tool) 入参

配置工具 (Tool) 参数 - https://docs.dify.ai/plugin-dev-zh/0211-getting-started-dify-tool#4-5-配置工具-tool-参数

其他已安装的插件源码也可以在 /docker/volumes/plugin_daemon 找到..

我们需要告诉 Dify 这个工具接收哪些输入参数。
编辑 Tool YAML 文件: 打开 local-file-mapper/tools/local-file-mapper.yaml

identity:name: telegraph_publisher # 工具的唯一内部名称author: your-namelabel: # 在 Dify UI 中显示的工具名称 (多语言)en_US: Publish to Telegraphzh_Hans: 发布到 Telegraph# ... (其他语言)
description:human: # 给人类用户看的工具描述 (多语言)en_US: Publish content to Telegraph as a new page.zh_Hans: 将内容作为新页面发布到 Telegraph。# ... (其他语言)llm: # 给 LLM 看的工具描述 (用于 Agent 模式)A tool that takes a title and markdown content, then publishes it as a new page on Telegraph, returning the URL of the published page. Use this when the user wants to publish formatted text content publicly via Telegraph.
parameters: # 定义工具的输入参数列表- name: p_title # 参数的内部名称,与 Python 代码中的 key 对应type: string # 参数类型required: true # 是否必需label: # 在 Dify UI 中显示的参数标签 (多语言)en_US: Post Titlezh_Hans: 文章标题human_description: # 给人类用户看的参数描述 (多语言)en_US: The title for the Telegraph page.zh_Hans: Telegraph 页面的标题。llm_description: # 给 LLM 看的参数描述 (指导 Agent 如何填充)The title of the post. Should be a concise and meaningful plain text string.form: llm # 参数表单类型 ('llm' 或 'form')- name: p_contenttype: stringrequired: truelabel:en_US: Content (Markdown)zh_Hans: 内容 (Markdown)human_description:en_US: The main content for the Telegraph page, written in Markdown format.zh_Hans: Telegraph 页面的主要内容,请使用 Markdown 格式编写。llm_description: # 强调格式要求对 LLM 很重要The full content to be published on the Telegraph page. Must be provided in Markdown format. Ensure proper Markdown syntax for formatting like headings, lists, links, etc.form: llm
extra: # 额外配置python:source: tools/local-file-mapper.py # 指向实现该工具逻辑的 Python 文件
  • identity 包含了工具的基本信息,包括名称、作者、标签、描述等。
  • parameters 参数列表
    • name (必填)参数名称,唯一,不允许和其他参数重名。
    • type (必填)参数类型,目前支持stringnumberbooleanselectsecret-inputfilefilesmodel-selectorapp-selector 九种类型,分别对应字符串、数字、布尔值、下拉框、加密输入框、文件、文件集、模型选择、应用选择,对于敏感信息,请使用 secret-input 类型。
    • label(必填)参数标签,用于前端展示。
    • form (必填)表单类型,目前支持llmform两种类型。
      • 在 Agent 应用中,llm 表示该参数 LLM 自行推理,form 表示要使用该工具可提前设定的参数。
      • 在 Workflow 应用中,llmform 均需要前端填写,但 llm 的参数会做为工具节点的输入变量。
    • required 是否必填
      • 在 llm 模式下,如果参数为必填,则会要求 Agent 必须要推理出这个参数。
      • 在 form 模式下,如果参数为必填,则会要求用户在对话开始前在前端填写这个参数。
    • options 参数选项
      • 在 llm 模式下,Dify 会将所有选项传递给 LLM,LLM 可以根据这些选项进行推理。
      • 在 form 模式下,type 为 select 时,前端会展示这些选项。
    • default 默认值。
    • min 最小值,当参数类型为number时可以设定。
    • max 最大值,当参数类型为number时可以设定。
    • human_description 用于前端展示的介绍,支持多语言。
    • placeholder 字段输入框的提示文字,在表单类型为form,参数类型为stringnumbersecret-input时,可以设定,支持多语言。
    • llm_description 传递给 LLM 的介绍。为了使得 LLM 更好理解这个参数,请在这里写上关于这个参数尽可能详细的信息,以便 LLM 能够理解该参数。

工具(Tool) 的出参 Output Variables

Tool Return - https://docs.dify.ai/plugin-dev-zh/0411-tool
https://docs.dify.ai/zh-hans/plugins/schema-definition/tool#数据结构

在默认情况下,一个工具在 workflow 中的输出会包含 files text json 三个固定变量,且你可以通过下面的方法来返回这三个变量的数据。例如使用 create_image_message 来返回图片,但是同时工具也支持自定义的输出变量,从而可以更方便地在 workflow 中引用这些变量。

'''
Author: yangfh
Date: 2025-08-14 14
LastEditors: yangfh
LastEditTime: 2025-08-14 18
Description: '''
from collections.abc import Generator
from typing import Any
from pathlib import Path
import os
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage# 这个文件路径是沙盒 dify 的 docker 的路径 
# 实际路径得看 langgenius/dify-plugin-daemon 容器映射到的宿主机的路径
CONST_ROOT_PATH = r"/app/storage/local_file_mapper"class LocalFileMapperTool(Tool):def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:filename = tool_parameters["file_name"]targetFile = Path.joinpath(Path(CONST_ROOT_PATH), filename)if not targetFile.exists():# thow FileNotFoundError if file does not exist# for key, value in os.environ.items():#     print(f"{key}={value}")raise Exception(f"File {targetFile} does not exist.")file_bytes = targetFile.read_bytes()if filename.endswith(".doc") :# 指定文件类型mime_type = "application/msword" elif filename.endswith(".docx"):mime_type = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"print(f"File size: {len(file_bytes)} bytes")yield self.create_blob_message(file_bytes, meta ={"mime_type": mime_type})

文件类型 BLOB

文件 BLOB 如果你需要返回文件的原始数据,如图片、音频、视频、PPT、Word、Excel 等,可以使用以下接口。

  • blob 文件的原始数据,bytes 类型
  • meta 文件的元数据,如果你知道该文件的类型,最好传递一个mime_type,否则Dify将使用octet/stream作为默认类型

本地运行调试

准备 .env 文件

  • 确保您仍在 local_file_mapper 项目目录下。
  • 复制环境变量模板文件:
cp .env.example .env
  • 编辑 .env 文件: 打开刚刚创建的 .env 文件,填入您的 Dify 环境信息:
DIFY_API_HOST=https://your-dify-host.com # 替换为您的 Dify 实例地址 (例如 https://cloud.dify.ai)
DIFY_API_KEY=your-api-key             # 替换为您的 Dify API 密钥
#### @Author: yangfh# @Date: 2025-08-14 16# @LastEditors: yangfh# @LastEditTime: 2025-08-14 16# @Description: # 
### 
INSTALL_METHOD=remote
REMOTE_INSTALL_URL=172.16.21.155:5003
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=xxxxxxx-86e8-xxxx-xxxx-xxxxxxx

启动本地插件服务

在插件主目录下,运行主程序:

python -m main

注意一点, 调试是当前运行环境变量是在本地的, dify 应该只是把参数远程传递过来执行.

在 Dify 中查看并测试

  • 刷新 Dify 页面: 回到您的 Dify 环境(浏览器中),刷新插件管理页面 (通常是 https://your-dify-host.com/plugins)。
  • 查找插件: 您应该能在列表中看到名为 “Telegraph” (或您在 Provider YAML 中定义的 label) 的插件,并且可能带有一个“调试中”的标记。
  • 添加凭证: 点击该插件,系统会提示您输入之前在 provider/telegraph.yaml 中定义的 “Telegraph Access Token”。输入有效的 token 并保存。如果您的验证逻辑 (_validate_credentials) 实现正确,这里会进行验证。 (请参考您本地对应的截图 ,它展示了插件出现在列表并请求授权的界面)
  • 在应用中使用: 现在,您可以在 Dify 的应用(如 Chatbot 或 Workflow)中添加这个工具节点,并尝试调用它了!当您在应用中运行并触发该工具时,请求会被转发到您本地运行的 python -m main 进程进行处理。您可以在本地终端看到相关的日志输出,并进行调试。

打包 插件包

https://docs.dify.ai/plugin-dev-zh/0322-release-by-file

返回上级目录: 确保您的终端当前路径在 your_plugin_project 文件夹的上一级

dify plugin package ./your_plugin_projectdify plugin package ./local-file-mapper
dify plugin package ./dify-customplugin_pdf-to-images
dify plugin package ./dify-pdf-process-plugin

问题 the plugin you want to install has a bad signature?

安装插件时遇到异常信息:plugin verification has been enabled, and the plugin you want to install has a bad signature,应该如何处理?

在 /docker/.env 配置文件的末尾添加 FORCE_VERIFYING_SIGNATURE=false 字段,运行以下命令重启 Dify 服务:

cd docker
docker compose down
docker compose up -d

添加该字段后,Dify 平台将允许安装所有未在 Dify Marketplace 上架(审核)的插件,可能存在安全隐患。建议在测试 / 沙箱环境内安装插件,确认安全后再安装至生产环境。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/974298.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20232326 2025-2026-1 《网络与系统攻防技术》实验六实验报告

1. 实验内容 本实践目标是掌握metasploit的用法。 指导书参考Rapid7官网的指导教程。 https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/ 下载官方靶机Metasploitable2,完成下面实验内容。…

2025年11月小程序开发公司TOP5评测:功能落地与适配筛选标准,西南地区企业选择指南

随着数字化转型加速,小程序已成为企业连接用户、提升运营效率的核心载体。本榜单基于技术实现能力、行业适配深度、服务交付效能三大维度,结合企业服务平台公开数据及客户案例反馈,权威解析2025年西南地区五大小程序…

2025年11月云南数字人供应商最新TOP5推荐:精细建模优质选择

在数字经济加速渗透的当下,数字人技术正从概念走向规模化应用,成为企业降本增效、创新服务模式的核心工具。据艾瑞咨询《2025年中国数字人行业研究报告》显示,2024年中国数字人市场规模突破600亿元,企业级服务需求…

第二讲下梯度下降算法

梯度下降算法 梯度下降有时会使loss不降反而上升原因是: 核心结论是:loss 上升主要源于学习率过高、数据 / 特征问题或模型设置不当,导致优化偏离最优方向。 关键原因学习率过大:步长超过最优解范围,每次更新都跳…

Java云计算技术怎样应对故障

Java云计算技术通过一系列的策略和工具来应对故障,确保系统的稳定性和可用性。以下是一些关键的策略和工具: 故障排查策略CPU问题排查:使用jstack工具分析堆栈情况,定位CPU异常的原因,如死循环或频繁的垃圾回收(…

2025-08-02-Sat-T-RabbitMQ

基础篇1. 初识MQ 1.1 同步调用 同步调用是一种线性执行模式。当你调用一个函数后,程序会暂停在当前位置,直到这个函数执行完毕并返回结果后,才会继续执行下一行代码。这就像你在餐厅点餐后,站在柜台前一直等到厨师…

Nand2Tetris 笔记

布尔函数ALU内存机器语言计算机体系结构

审美积累暗色UI设计超越美学的用户体验

审美积累暗色UI设计超越美学的用户体验研究了上百个暗色设计,才发现顶尖的“黑”从不单调。它可以是深邃的科技感,也可以是温暖的陪伴感。分享5个超赞的暗黑系UI设计范本,一起来积累高级审美! 1. 克制用色,信息层…

具有超高峰值抑制比和低功耗的全光可调谐微波滤波器

该研究提出了一种基于4个级联的光机械微环谐振器(MRR)实现高抑制比、大中心频率和带宽调谐范围的微波光子滤波器(MPF)。当每两个MRR的谐振波长调谐到对齐时,硅器件的透射谱为具有高消光比的陷波双峰分布。光载波被固定…

11.23

1. page:最核心指令,定义页面编码、语言、导入包等示例:解决中文乱码+指定Java语言+导入工具类 jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="…

实用指南:F-INR: Functional Tensor Decomposition for Implicit Neural Representations

实用指南:F-INR: Functional Tensor Decomposition for Implicit Neural Representationspre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !importa…

实验3 类和对象_基础编程 - yuyue

TASK1 button.hpp #pragma once#include <iostream> #include <string>class Button { public:Button(const std::string &label_);const std::string& get_label() const;void click();private:s…

11/23/2025 一周总结

11/18/2025 模拟赛 T1 做太久了,方向是对的,但是一直没想清楚。做题的时候一定要想清楚,不然可能浪费很多时间。 T2 方向是对的,但是没想到怎么优化。优化需要观察性质,说明这种观察性质的能力还不够,以后还要继…

Java云计算技术如何确保稳定

Java云计算技术确保稳定的关键在于通过一系列安全措施、容错机制、高可用性设计以及性能优化来实现。以下是具体的介绍: 安全措施安全通信协议:使用HTTPS和TLS/SSL等安全协议保护数据传输。 身份验证和授权:利用JWT…

java中sql注入的防范措施是什么

在Java中,防范SQL注入的措施主要包括以下几点:使用预编译语句(PreparedStatement):预编译语句能够将SQL查询与数据分开,从而有效防止SQL注入攻击。在预编译语句中,参数值会被自动转义,避免了恶意代码的注入。 …

【第五章:计算机视觉-项目实战之推荐/广告体系】2.粗排算法-(4)粗排算法模型多目标算法(Multi Task Learning)及目标融合

【第五章:计算机视觉-项目实战之推荐/广告体系】2.粗排算法-(4)粗排算法模型多目标算法(Multi Task Learning)及目标融合2025-11-23 22:00 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important;…

二分查找刷题总结

推荐使用闭区间的方式去做二分查找的题目 如果数量比较少,那么建议使用顺序遍历的方式 因此二分结束时一定有: i指向首个大于 target 的元素,j指向首个小于 target 的元素。易得当数组不包含 target 时,插入索引为…

Solution Set #1

\(1\) 个 set 有 \(10\) 道题。 A. CF1874D Jellyfish and Miku 设 \(f_i\) 为 \(i\to n\) 的期望步数。那么有 \(f_0=f_1+1\),\(f_n=0\),和 \(f_i=f_{i+1}\times \frac{a_{i+1}}{a_i+a_{i+1}}+f_{i-1}\times \frac{…

zjoi2019 语言

好题好题。 我们先对一个结点 \(u\) 进行分析。 发现能对 \(u\) 产生贡献的所有结点可以构成一个联通分量。 只有经过 \(u\) 才会对 \(u\) 产生贡献。 而我们不可能将一条链上的所有点都扔到 \(u\) 上,这显然不现实,…

Java基础(代码块,内部类,函数式编程,常用API,GUI编程)

Java基础(代码块,内部类,函数式编程,常用API,GUI编程) 代码块静态代码块:static 类加载时自动执行,由于类只会执行一次,所有静态代码块也只会执行一次 完成类的静态资源初始化 比main方法先加载。实例代码块:…