一文入门 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
初始化开发环境
- 打开终端,执行初始化命令:
./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 验证、持久存储等附加功能。
- 安装依赖
- 项目初始化时生成的
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(必填)参数类型,目前支持string、number、boolean、select、secret-input、file、files、model-selector、app-selector九种类型,分别对应字符串、数字、布尔值、下拉框、加密输入框、文件、文件集、模型选择、应用选择,对于敏感信息,请使用secret-input类型。label(必填)参数标签,用于前端展示。form(必填)表单类型,目前支持llm、form两种类型。- 在 Agent 应用中,
llm表示该参数 LLM 自行推理,form表示要使用该工具可提前设定的参数。 - 在 Workflow 应用中,
llm和form均需要前端填写,但llm的参数会做为工具节点的输入变量。
- 在 Agent 应用中,
required是否必填- 在
llm模式下,如果参数为必填,则会要求 Agent 必须要推理出这个参数。 - 在
form模式下,如果参数为必填,则会要求用户在对话开始前在前端填写这个参数。
- 在
options参数选项- 在
llm模式下,Dify 会将所有选项传递给 LLM,LLM 可以根据这些选项进行推理。 - 在
form模式下,type为select时,前端会展示这些选项。
- 在
default默认值。min最小值,当参数类型为number时可以设定。max最大值,当参数类型为number时可以设定。human_description用于前端展示的介绍,支持多语言。placeholder字段输入框的提示文字,在表单类型为form,参数类型为string、number、secret-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 上架(审核)的插件,可能存在安全隐患。建议在测试 / 沙箱环境内安装插件,确认安全后再安装至生产环境。