返回顶部
热门问答 更多热门问答
技术文章 更多技术文章

Dify工具插件开发和智能体开发全流程实战

[复制链接]
链载Ai 显示全部楼层 发表于 1 小时前 |阅读模式 打印 上一主题 下一主题

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;display: table;padding: 0.3em 1.2em;color: rgb(255, 255, 255);background: rgb(15, 76, 129);border-radius: 8px 24px;box-shadow: rgba(0, 0, 0, 0.06) 0px 2px 6px;">前言

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">dify是一款开源的大语言模型应用开发平台,旨在降低AI应用的开发门槛,帮助开发者和企业快速构建、部署及管理生成式AI应用。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">Dify自1.0.0引入全新插件化架构,模型(Models)与工具(Tools)迁移为插件(Plugins),引入 Agent 策略(Agent Strategies)、扩展(Extensions)类型插件和插件集(Bundles)。通过全新的插件机制,能够增强 AI 应用的感知和执行能力,拓宽AI在软件操作领域的应用能力。

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">本文将介绍如下内容:

    ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;color: rgb(63, 63, 63);" class="list-paddingleft-1">
  • ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);">
    • 搭建基于Docker的MySQL数据库环境
  • ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);">
    • 开发Dify工具插件实现MySQL数据库操作
  • ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);">
    • 基于Dify搭建智能体通过插件操作MySQL实现理财助手智能体

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">文末可获取完整插件代码下载地址

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;display: table;padding: 0.3em 1.2em;color: rgb(255, 255, 255);background: rgb(15, 76, 129);border-radius: 8px 24px;box-shadow: rgba(0, 0, 0, 0.06) 0px 2px 6px;">搭建基于Docker的MySQL数据库环境

1) 启动Docker容器

  • • 建立docker_compose.yaml,内容如下
services:
mysql:
image:mysql:5.7
container_name:mysql5.7
ports:
-"3306:3306"
environment:
-MYSQL_ROOT_PASSWORD=root
-MYSQL_ALLOW_EMPTY_PASSWORD=yes
-TZ=Asia/Shanghai
volumes:
-./volumes:/var/lib/mysql
command:--character-set-server=utf8mb4
  • • 执行docker compose up -d启动数据库

2) 创建数据库和表

  • • 下载MySQL客户端软件,例如dbeaver (https://dbeaver.io/download)
  • • 连接数据库,创建数据库和表
createdatabase testdb;

use testdb;

CREATE TABLE`finance` (
`id`bigint(20)NOT NULLAUTO_INCREMENT,
`user_id`varchar(36)NOT NULLDEFAULT''COMMENT'用户ID',
`date` datetimeNOT NULLCOMMENT'金额发生日期',
`amount`decimal(10,2)NOT NULLDEFAULT'0.00'COMMENT'收入支出金额(收入记为正数,支出记为负数)',
`category`varchar(32)NOT NULLDEFAULT''COMMENT'收支类别',
`remark`varchar(100)NOT NULLDEFAULT''COMMENT'收支具体类目',
PRIMARY KEY(`id`),
KEY `idx_user_date` (`user_id`,`date`)
) ENGINE=InnoDBDEFAULTCHARSET=utf8mb4 COMMENT='日常收支';

开发Dify工具插件实现MySQL数据库操作

以windows开发环境为例:

1) 下载插件开发脚手架工具

https://github.com/langgenius/dify-plugin-daemon/releases下载适用于windows的dify-plugin-windows-amd64.exe。把程序所在目录加到系统PATH路径下,方便执行命令。运行命令查看版本信息,有输出版本信息则说明安装成功

2) 创建项目

执行命令dify-plugin-windows-amd64.exe plugin init创建项目,输入插件名(mysql),作者和描述
按Enter确认后,选择python做为开发语言
按Enter确认后,选择插件类型,这里我们选tool

按Enter确认后,选择插件权限。mysql插件不需要勾选任何权限,一直按down键移到最后一行,然后按回车即可完成项目创建,系统将自动生成插件项目代码,目录为mysql。

生成的目录结构如下:

3) 创建python虚拟环境

进入生成的目录mysql,修改生成的requirements.txt,添加用到的python包: mysql-connector-python。

创建python虚拟环境并安装依赖包

python -m venv .venv
# 激活环境
.\.venv\Scripts\activate
# 安装依赖包
pip install -r requirements.txt

4) 封装数据库功能

在tools目录下增加db.py,通过类DbManagerSingleton封装数据库操作。DbManagerSingleton实现为单例模式,以便插件内不同的代码共用类的实例对象。

importjson
importmysql.connector
fromcontextlibimportcontextmanager
fromthreadingimportLock


# 单例模式
classDbManagerSingleton:
_instance =None
_lock = Lock() # 线程锁,确保线程安全

def__new__(cls, *args, **kwargs):
ifnotcls._instance:
withcls._lock:
ifnotcls._instance:
cls._instance =super().__new__(cls)
cls._instance.__init__(*args, **kwargs)
returncls._instance

def__init__(self, host, port, user, password, database):
self.connection_pool = mysql.connector.pooling.MySQLConnectionPool(
pool_name="db_pool",
pool_size=5,
pool_reset_session=True,
host=host, # 数据库服务器Host
port=port, # 数据库服务器端口
user=user, # 数据库用户名
password=password, # 数据库密码
database=database, # 数据库名
)

@contextmanager
defget_cursor(self):
withself.connection_pool.get_connection()asconnection:
cursor =None
try:
cursor = connection.cursor()
yieldcursor
connection.commit()
exceptExceptionase:
connection.rollback()
raisee
finally:
ifcursor:
cursor.close()

defexecute_sql(self, sql:str) ->str:
withself.get_cursor()ascursor:
cursor.execute(sql)
ifcursor.descriptionisnotNone:
rows = cursor.fetchall()
result = {
"columns": [desc[0]fordescincursor.description],
"rows": rows,
}
returnjson.dumps(result, default=str)
else:
returnf"row affected:{cursor.rowcount}"

5) 实现授权配置

修改provider/mysql.yaml。其中,credentials_for_provider的信息用于配置插件授权(配置数据库连接相关信息)。内容如下:

identity:
author:testuser
name:mysql
label:
en_US:mysql
zh_Hans:mysql
description:
en_US:mysqltools
zh_Hans:mysqltools
icon:icon.svg
tools:# 插件包含的工具列表
-tools/get_table_definition.yaml
-tools/execute_sql.yaml

extra:
python:
source:provider/mysql.py

credentials_for_provider:
host:# 数据库HOST
type:text-input# 输入类型为普通文本
required:true# 此凭证是必需的
label: # 在 Dify UI 中显示的标签 (支持多语言)
en_US:MySQLServerHost
zh_Hans:MySQLServer主机
port:# 数据库端口
type:text-input# 输入类型为普通文本
required:true# 此凭证是必需的
label:# 在 Dify UI 中显示的标签 (支持多语言)
en_US:MySQLServerPort
zh_Hans:MySQLServer端口
user:# 数据库用户名
type:text-input# 输入类型为普通文本
required:true# 此凭证是必需的
label:# 在 Dify UI 中显示的标签 (支持多语言)
en_US:username
zh_Hans:用户名
password:# 数据库密码
type:secret-input# 输入类型为密码框
required:true# 此凭证是必需的
label:# 在 Dify UI 中显示的标签 (支持多语言)
en_US:password
zh_Hans:密码
database:# 数据库名
type:text-input# 输入类型为普通文本
required:true# 此凭证是必需的
label:# 在 Dify UI 中显示的标签 (支持多语言)
en_US:databasename
zh_Hans:数据库名

修改provider/mysql.py,实现配置校验,通过建立连接执行show tables验证参数是否正确。代码如下:

fromtypingimportAny

fromdify_pluginimportToolProvider
fromdify_plugin.errors.toolimportToolProviderCredentialValidationError


classMysqlProvider(ToolProvider):
def_validate_credentials(self, credentials:dict[str,Any]) ->None:
try:
"""
IMPLEMENT YOUR VALIDATION HERE
"""
fromtools.dbimportDbManagerSingleton

dbManager = DbManagerSingleton(
host=credentials["host"],
port=credentials["port"],
user=credentials["user"],
password=credentials["password"],
database=credentials["database"],
)
dbManager.execute_sql("show tables")
exceptExceptionase:
raiseToolProviderCredentialValidationError(str(e))

6) 实现工具get_table_definition获取表结构定义

provider/mysql.yaml的tools字段定义了插件包含的工具列表。

tools:# 插件包含的工具列表
-tools/get_table_definition.yaml
-tools/execute_sql.yaml

每个工具需要一个yaml文件进行描述,包含工具的名称、描述、参数列表等。

将自动生成的tools目录下的mysql.yaml和mysql.py分别重命名为get_table_definition.yaml和get_table_definition.py

get_table_definition.yaml修改为如下内容:

identity:
name:get_table_definition
author:testuser
label:# 在 Dify UI 中显示的工具名称 (多语言)
en_US:getdatabasetabledefinition
zh_Hans:获取数据库表定义
description:
human:# 给人类用户看的工具描述 (多语言)
en_US:getdatabasetabledefinition
zh_Hans:获取数据库表定义
llm:getdatabasetabledefinition# 给 LLM 看的工具描述 (用于 Agent 模式)
parameters:# 定义工具的输入参数列表
-name:table
type:string
required:true
label:# 在 Dify UI 中显示的参数标签 (多语言)
en_US:databasetablename
zh_Hans:数据库表名
human_description:# 给人类用户看的参数描述 (多语言)
en_US:databasetablename
zh_Hans:数据库表名
llm_description:databasetablename# 给 LLM 看的参数描述 (指导 Agent 如何填充)
form:llm# 参数表单类型 ('llm' 或 'form')
extra:
python:
source:tools/get_table_definition.py

get_table_definition.py修改为如下内容:

fromcollections.abcimportGenerator
fromtypingimportAny
fromdify_pluginimportTool
fromdify_plugin.entities.toolimportToolInvokeMessage
fromtools.dbimportDbManagerSingleton


classGetTableDefinitionTool(Tool):
def__init__(self, runtime, session):
super().__init__(runtime, session)
self.dbManager = DbManagerSingleton(
host=runtime.credentials["host"],
port=runtime.credentials["port"],
user=runtime.credentials["user"],
password=runtime.credentials["password"],
database=runtime.credentials["database"],
)

def_invoke(self, tool_parameters:dict[str,Any]) -> Generator[ToolInvokeMessage]:
table = tool_parameters["table"]
sql =f"show create table{table}"
yieldself.create_text_message(self.dbManager.execute_sql(sql))

7) 实现工具execute_sql执行SQL语句

在tools目录新建execute_sql.yaml和execute_sql.py

execute_sql.yaml修改为如下内容:

identity:
name:execute_sql
author:testuser
label:# 在 Dify UI 中显示的工具名称 (多语言)
en_US:executesql
zh_Hans:执行sql语句
description:
human:# 给人类用户看的工具描述 (多语言)
en_US:executesql
zh_Hans:执行sql语句
llm:executesql# 给 LLM 看的工具描述 (用于 Agent 模式)
parameters:# 定义工具的输入参数列表
-name:sql
type:string
required:true
label: # 在 Dify UI 中显示的参数标签 (多语言)
en_US:sql
zh_Hans:sql语句
human_description:# 给人类用户看的参数描述 (多语言)
en_US:thesqltoexecute
zh_Hans:要执行的sql语句
llm_description:sql# 给 LLM 看的参数描述 (指导 Agent 如何填充)
form:llm# 参数表单类型 ('llm' 或 'form')
extra:
python:
source:tools/execute_sql.py

execute_sql.py修改为如下内容:

fromcollections.abcimportGenerator
fromtypingimportAny
fromdify_pluginimportTool
fromdify_plugin.entities.toolimportToolInvokeMessage
fromtools.dbimportDbManagerSingleton


classExecuteSqlTool(Tool):
def__init__(self, runtime, session):
super().__init__(runtime, session)
self.dbManager = DbManagerSingleton(
host=runtime.credentials["host"],
port=runtime.credentials["port"],
user=runtime.credentials["user"],
password=runtime.credentials["password"],
database=runtime.credentials["database"],
)

def_invoke(self, tool_parameters:dict[str,Any]) -> Generator[ToolInvokeMessage]:
sql = tool_parameters["sql"]
yieldself.create_text_message(self.dbManager.execute_sql(sql))

8) 修改manifest.yaml

manifest.yaml定义了插件最基础的信息,包括插件名称、作者、包含的工具、模型等信息。

本插件虽然没用到storage持久化存储的权限,但需要将storage里的size字段从0改为大于等于1024,否则启动插件时会报错。

  storage:
enabled: false
size: 1024

9) 调试

在Dify的插件管理页面,点击图中红框部分,弹出调试的URL和Key。
复制.env.example到.env,修改REMOTE_INSTALL_HOST和REMOTE_INSTALL_KEY。
执行命令python main.py启动插件,等待至显示"dify_plugin.plugin:Installed tool",工具安装成功。
此时,在Dify的插件管理页面可以看到mysql插件。选择mysql插件,在右侧点击“去授权”
填上相关参数并保存
新建测试Agent,添加mysql插件的两个工具,模型选择doubao-1.5-pro-32k,模型会根据用户提问自动调用数据库工具,并根据工具的响应生成回复。效果如下图:

10) 打包

确认插件能够正常运行后,可以通过以下命令行工具打包插件,生成mysql.difypkg。

dify-plugin-windows-amd64.exepluginpackagemysql

11) 发布

  • • 发布到Dify Marketplace
    参考: https://docs.dify.ai/zh-hans/plugins/publish-plugins/publish-to-dify-marketplace
  • • 发布到个人GitHub仓库
    参考: https://docs.dify.ai/zh-hans/plugins/publish-plugins/publish-plugin-on-personal-github-repo
  • • 本地发布与分享
在Dify的插件管理页面,点击“安装插件”=>“本地插件”
选择打包生成的mysql.difypkg,会提示签名错误。

需要修改docker/.env,将FORCE_VERIFYING_SIGNATURE改为false,然后重建docker。修改该字段后,Dify平台将允许安装所有未在Dify Marketplace上架(审核)的插件,可能存在安全隐患。

docker compose down
docker compose up -d
docker重建后,重新安装本地插件。

基于Dify搭建智能体通过插件操作MySQL实现理财助手智能体

1) 安装Agent策略插件

点击右上角“插件”按钮,进入插件页面,选择“探索Marketplace

选择插件Dify Agent 策略进行安装。

2) 创建应用

  • • 创建一个空白应用,类型为Chatflow
  • • 调整工作流,把默认的LLM节点替换为Agent节点
  • • 设置Agent节点的Agent策略,并添加MySQL工具
    策略选择Function Calling
  • • Agent节点的模型选择doubao-1.5-pro-32k
  • • 设置Agent节点的指令(系统提示词)
# 角色
你是记账助手,可以通过调用数据库工具完成记录日常收入和支出并作分析。
为了完成记账操作,需要先获取数据库表finance的定义。
记账的用户ID取值为{{#sys.user_id#}}

# 收支类别
收入:工资薪金,劳务报酬,投资收益,分红收入,租金收入,其它收入
支出:住房,交通,通讯,保险,餐饮,电子产品,日用品,服饰,旅行,娱乐,医疗,学习,其它支出

# 技能
## 技能1:记录日常开支
将开支信息记录到数据库表finance

## 技能2:统计日常开支
根据用户输入信息分析统计日常开支

# 限制
仅处理记账相关问题,不回复其它问题
  • • 设置Agent节点的查询和最大迭代次数
    Agent完成一项任务可能需要迭代多次调用工具,最大迭代次数设置过小可能导致无法正常完成任务。
  • • 预览调试
    输入“昨天吃饭用了50元,还花了35元买了拖鞋。今天买手机花了2999元,吃饭花了60元”,验证输出为成功记录支出。
另外,通过数据库表验证数据正常插入
输入“汇总各个类别的金额”,验证数据查询

确认无误后点击右上角的“发布”按钮发布应用

总结

本文以实现MySQL数据库操作插件详细介绍开发Dify工具插件的全流程,并使用该插件搭建理财智能体,展示了Agent从语义理解到工具调用的完整决策链路。

跟MCP工具插件开发比较,Dify工具插件开发步骤相对复杂,且仅能使用Python开发,仅能用于Dify生态。但Dify插件的整体链路开销较MCP插件低,如果你对系统时延和成本更敏感,且无需使用MCP的动态发现工具能力,Dify工具插件也许是个更好的选择。

完整代码地址:https://github.com/copilot-coder/dify-plugin-mysql

#智能体开发#Dify插件开发#AI应用开发

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

链载AI是专业的生成式人工智能教程平台。提供Stable Diffusion、Midjourney AI绘画教程,Suno AI音乐生成指南,以及Runway、Pika等AI视频制作与动画生成实战案例。从提示词编写到参数调整,手把手助您从入门到精通。
  • 官方手机版

  • 微信公众号

  • 商务合作

  • Powered by Discuz! X3.5 | Copyright © 2025-2025. | 链载Ai
  • 桂ICP备2024021734号 | 营业执照 | |广西笔趣文化传媒有限公司|| QQ