
Dify开发实战-自制插件消除 DeepSeek 标签冗余
在使用 Dify 搭配 DeepSeek 大模型的过程中,许多用户常常觉得 DeepSeek 的 think 标签有些多余。借此契机,本文将详细演示 Dify 插件开发,以帮助大家解决这一困扰。本次项目的目标是实现对 DeepSeek 模型节点输出内容的清洗。
你是否在使用 Dify 搭配 DeepSeek 大模型时,被多余的
think
标签困扰?本文以 Windows 环境为例,为你带来保姆级 Dify 插件开发教程。从环境准备、项目构建,到代码编写、调试打包,详细展示如何开发一个去除think
标签的插件。无论你是新手还是有一定经验的开发者,都能从中获得实用的开发技巧和经验。快来一起开启 Dify 插件开发之旅吧!
一、背景简介
在使用 Dify 搭配 DeepSeek 大模型的过程中,许多用户常常觉得 DeepSeek 的 think 标签有些多余。借此契机,本文将详细演示 Dify 插件开发,以帮助大家解决这一困扰。本次 plugin_demo
项目的目标是实现对 DeepSeek 模型节点输出内容的清洗。需要注意的是,本次开发以 Windows 环境为例进行演示。
二、环境准备
开发 Dify 插件需要进行以下准备。
- Dify 插件脚手架工具
- Python 环境,版本号 ≥ 3.12
2.1 脚手架准备
访问 Dify Plugin CLI 项目地址,下载并安装最新版本号和对应操作系统的工具。
接下来以windows为例,展示如何开发dify插件。
windows 下载 dify-plugin-windows-amd64.exe 。
下面需要在windows自带的powershell中执行 。
脚手架检查
切换到 dify-plugin-windows-amd64.exe 所在目录,然后复制以下代码执行:
./dify-plugin-windows-amd64.exe version
此时版本是0.0.6版本,dify更新比较块,不过大致是相似的。
三、构建项目
3.1 插件初始化
./dify-plugin-windows-amd64.exe plugin init
3.2 基本信息填写
这里需要依次填写三个内容
- plugin name 插件名称
- author 作者信息
- description 详细
按照提示依次输入,enter进入下一步。
3.3 开发语言选择
选择开发语言,这里使用Python为例
3.4 选择模板
本次演示的是tool开发
3.5 权限选择
上下移动,tab键选择。开发tools 必选tools、apps、endpoints权限,存储、大模型根据需求来选择。
完成选择后,项目框架就被自动创建完成。
四、插件代码编写
以pychram 打开plugin_demo工程。
4.1重点文件介绍
4.1.1 环境
.env
文件是用于调试的,拷贝 .env.example
文件并重命名为 .env
,将获取的远程服务器地址和调试 Key 等信息填入其中。
INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=YOUR_HOST
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****
port 与 key 可以在dify插件页面找到,如下:
4.1.2 provider
provider目录中有两个文件,.py
与.yaml
。
yaml文件 主要是tools的描述与作者。
py文件 是供应商的代码,如果你的插件用到其他供应商的api key,会做验证,如果验证不通过会抛出异常。若未用到则无需填写。
4.1.3 tools
以下是本次项目的.yaml
文件
identity:
name: plugin_demo
author: fengjian
label:
en_US: plugin_demo
zh_Hans: plugin_demo
pt_BR: plugin_demo
description:
human:
en_US: plugin demo by fengjian
zh_Hans: plugin demo by fengjian
pt_BR: plugin demo by fengjian
llm: plugin demo by fengjian
parameters:
- name: deepseek_output
type: string
required: true
label:
en_US: deepseek output string
zh_Hans: deepseek输出内容
pt_BR: deepseek output string
human_description:
en_US: plugin demo by fengjian
zh_Hans: plugin demo by fengjian
pt_BR: plugin demo by fengjian
llm_description: plugin demo by fengjian
form: llm
extra:
python:
source: tools/plugin_demo.py
identity
包含了工具的基本信息,包括名称、作者、标签、描述等。parameters
参数列表name
(必填)参数名称,唯一,不允许和其他参数重名。type
(必填)参数类型,目前支持string
、number
、boolean
、select
、secret-input
五种类型,分别对应字符串、数字、布尔值、下拉框、加密输入框,对于敏感信息,请使用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 能够理解该参数。
.py
文件是插件的核心代码 ,下面在具体开发中细说。
4.1.4 其他
requirements.txt
文件是用来规定python代码用到的包,如果用到了其他依赖,在这里添加。
icon.pvg
是插件图标,可以自己修改
4.2 具体开发
本次的目标是把think标签去掉,因此代码很简单,只需要split即可。这里是插件代码的主体,具体开发全在这里完成。
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
class PluginDemoTool(Tool):
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
context = tool_parameters['deepseek_output']
if '</think>' in context :
result = context.split('</think>')[1]
else:result = context
yield self.create_text_message(result)
需要注意的是最后的返回值。下一节细说插件的输入输出。
4.3 插件input、output
很多人在使用tools或者其他结点时常见的问题就是搞不清楚结点的输入输出情况。
每个结点对入参都有要求,有的结点能输出多种内容,做好前一个节点的出参与下一节点的入参匹配,大部门使用上就不会出现问题。
4.3.1 插件开发input
插件开发时,需要规定插件的input,具体在 tools
目录中的.yaml
文件 。
parameters name
是参数名,本次案例是 deepseek_output
,因此在代码中使用 context = tool_parameters['deepseek_output']
来获取入参。在dify tools中 支持五种入参:string
、number
、boolean
、select
、secret-input
。
4.3.2 插件开发output
Dify 支持文本
链接
图片
文件BLOB
JSON
等多种消息类型,你可以通过以下不同的接口返回不同类型的消息。
在默认情况下,一个插件在 workflow
中的输出会包含 files
text
json
三个固定变量,且你可以通过下面的方法来返回这三个变量的数据。
例如使用 create_image_message
来返回图片,但是同时插件也支持自定义的输出变量,从而可以更方便地在 workflow
中引用这些变量。
以下是每种返回值的demo
- 文本
def create_text_message(self, text: str) -> ToolInvokeMessage:
pass
- 链接
def create_link_message(self, link: str) -> ToolInvokeMessage:
pass
- 图片
def create_image_message(self, image: str) -> ToolInvokeMessage:
pass
-
文件BLOB
-
blob
文件的原始数据,bytes 类型。 -
meta
文件的元数据。如果开发者需要明确的文件类型,请指定mime_type
,否则 Dify 将使用octet/stream
作为默认类型。
def create_blob_message(self, blob: bytes, meta: dict = None) -> ToolInvokeMessage:
pass
- JSON
如果你需要返回一个格式化的 JSON,可以使用以下接口。这通常用于 workflow 中的节点间的数据传递。在 agent 模式中,大部分大模型也都能够阅读和理解 JSON。
object
一个 Python 的字典对象,会被自动序列化为 JSON。
def create_json_message(self, json: dict) -> ToolInvokeMessage:
pass
- 变量
对于非流式输出的变量,你可以使用以下接口返回,如创建多份,后者将覆盖前者。
def create_variable_message(self, variable_name: str, variable_value: Any) -> ToolInvokeMessage:
pass
- 流式变量
如果你想以“打字机”效果输出一段文字,可以使用流式变量输出文本。如果你在 chatflow
应用中使用 answer
节点并引用了该变量,那么文本将以“打字机”的效果输出。但目前该方法仅支持字符串类型的数据。
def create_stream_variable_message(
self, variable_name: str, variable_value: str
) -> ToolInvokeMessage:
五、插件调试
至此插件开发已经完成,下面开始使用。先确保.env
文件的信息按照上述需求填好。调试时,只要执行main.py
文件即可。
如上图,插件就被提交到dify插件中。在插件列表中可以找到这个插件:
新建一个工作流进行测试
以下是整体工作流。
测试执行,观察plugin_demo的输入、输出确实把deepseek的标签解决了。
六、插件打包
打包时,依然使用powershell执行
./dify-plugin-windows-amd64.exe plugin package ./plugin_demo
出现一下说明打包成功
只需要把difypkg文件上传到dify的插件中即可。
如果你有兴趣,或者已经在用Dify了,欢迎添加作者微信,我们组织了一个Dify交流群,欢迎来提问或者分享你的经验。 关注公众号 dataspeed ,更能及时获取最近文章,更有作者联系方式
七、总结
插件开发有需要注意以下:
-
使用脚手架做项目初始化
-
做好入参与出参的设定
有插件开发的能力,可以让你的dify能力更上一层楼
更多推荐
所有评论(0)