微信扫码
添加专属顾问
我要投稿
Dify平台全流程实战,从数据库搭建到智能体开发,一文掌握AI应用开发核心技能。 核心内容: 1. Dify平台及其插件化架构介绍 2. 搭建基于Docker的MySQL数据库环境 3. 开发Dify工具插件和智能体,实现理财助手功能
dify是一款开源的大语言模型应用开发平台,旨在降低AI应用的开发门槛,帮助开发者和企业快速构建、部署及管理生成式AI应用。
Dify自1.0.0引入全新插件化架构,模型(Models)与工具(Tools)迁移为插件(Plugins),引入 Agent 策略(Agent Strategies)、扩展(Extensions)类型插件和插件集(Bundles)。通过全新的插件机制,能够增强 AI 应用的感知和执行能力,拓宽AI在软件操作领域的应用能力。
本文将介绍如下内容:
文末可获取完整插件代码下载地址
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
启动数据库create database testdb;
use testdb;
CREATE TABLE `finance` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` varchar(36) NOT NULL DEFAULT '' COMMENT '用户ID',
`date` datetime NOT NULL COMMENT '金额发生日期',
`amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '收入支出金额(收入记为正数,支出记为负数)',
`category` varchar(32) NOT NULL DEFAULT '' COMMENT '收支类别',
`remark` varchar(100) NOT NULL DEFAULT '' COMMENT '收支具体类目',
PRIMARY KEY (`id`),
KEY `idx_user_date` (`user_id`,`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='日常收支';
以windows开发环境为例:
https://github.com/langgenius/dify-plugin-daemon/releases
下载适用于windows的dify-plugin-windows-amd64.exe
。把程序所在目录加到系统PATH路径下,方便执行命令。运行命令查看版本信息,有输出版本信息则说明安装成功dify-plugin-windows-amd64.exe plugin init
创建项目,输入插件名(mysql),作者和描述按Enter确认后,选择插件权限。mysql插件不需要勾选任何权限,一直按down键移到最后一行,然后按回车即可完成项目创建,系统将自动生成插件项目代码,目录为mysql。
创建python虚拟环境并安装依赖包
python -m venv .venv
# 激活环境
.\.venv\Scripts\activate
# 安装依赖包
pip install -r requirements.txt
在tools目录下增加db.py,通过类DbManagerSingleton
封装数据库操作。DbManagerSingleton实现为单例模式,以便插件内不同的代码共用类的实例对象。
import json
import mysql.connector
from contextlib import contextmanager
from threading import Lock
# 单例模式
class DbManagerSingleton:
_instance = None
_lock = Lock() # 线程锁,确保线程安全
def __new__(cls, *args, **kwargs):
if not cls._instance:
with cls._lock:
if not cls._instance:
cls._instance = super().__new__(cls)
cls._instance.__init__(*args, **kwargs)
return cls._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
def get_cursor(self):
with self.connection_pool.get_connection() as connection:
cursor = None
try:
cursor = connection.cursor()
yield cursor
connection.commit()
except Exception as e:
connection.rollback()
raise e
finally:
if cursor:
cursor.close()
def execute_sql(self, sql: str) -> str:
with self.get_cursor() as cursor:
cursor.execute(sql)
if cursor.description is not None:
rows = cursor.fetchall()
result = {
"columns": [desc[0] for desc in cursor.description],
"rows": rows,
}
return json.dumps(result, default=str)
else:
return f"row affected:{cursor.rowcount}"
修改provider/mysql.yaml。其中,credentials_for_provider的信息用于配置插件授权(配置数据库连接相关信息)。内容如下:
identity:
author: testuser
name: mysql
label:
en_US: mysql
zh_Hans: mysql
description:
en_US: mysql tools
zh_Hans: mysql tools
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: MySQL Server Host
zh_Hans: MySQL Server主机
port: # 数据库端口
type: text-input # 输入类型为普通文本
required: true # 此凭证是必需的
label: # 在 Dify UI 中显示的标签 (支持多语言)
en_US: MySQL Server Port
zh_Hans: MySQL Server端口
user: # 数据库用户名
type: text-input # 输入类型为普通文本
required: true # 此凭证是必需的
label: # 在 Dify UI 中显示的标签 (支持多语言)
en_US: user name
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: database name
zh_Hans: 数据库名
修改provider/mysql.py,实现配置校验,通过建立连接执行show tables
验证参数是否正确。代码如下:
from typing import Any
from dify_plugin import ToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError
class MysqlProvider(ToolProvider):
def _validate_credentials(self, credentials: dict[str, Any]) -> None:
try:
"""
IMPLEMENT YOUR VALIDATION HERE
"""
from tools.db import DbManagerSingleton
dbManager = DbManagerSingleton(
host=credentials["host"],
port=credentials["port"],
user=credentials["user"],
password=credentials["password"],
database=credentials["database"],
)
dbManager.execute_sql("show tables")
except Exception as e:
raise ToolProviderCredentialValidationError(str(e))
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: get database table definition
zh_Hans: 获取数据库表定义
description:
human: # 给人类用户看的工具描述 (多语言)
en_US: get database table definition
zh_Hans: 获取数据库表定义
llm: get database table definition # 给 LLM 看的工具描述 (用于 Agent 模式)
parameters: # 定义工具的输入参数列表
- name: table
type: string
required: true
label: # 在 Dify UI 中显示的参数标签 (多语言)
en_US: database table name
zh_Hans: 数据库表名
human_description: # 给人类用户看的参数描述 (多语言)
en_US: database table name
zh_Hans: 数据库表名
llm_description: database table name # 给 LLM 看的参数描述 (指导 Agent 如何填充)
form: llm # 参数表单类型 ('llm' 或 'form')
extra:
python:
source: tools/get_table_definition.py
get_table_definition.py修改为如下内容:
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
from tools.db import DbManagerSingleton
class GetTableDefinitionTool(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}"
yield self.create_text_message(self.dbManager.execute_sql(sql))
在tools目录新建execute_sql.yaml和execute_sql.py
execute_sql.yaml修改为如下内容:
identity:
name: execute_sql
author: testuser
label: # 在 Dify UI 中显示的工具名称 (多语言)
en_US: execute sql
zh_Hans: 执行sql语句
description:
human: # 给人类用户看的工具描述 (多语言)
en_US: execute sql
zh_Hans: 执行sql语句
llm: execute sql # 给 LLM 看的工具描述 (用于 Agent 模式)
parameters: # 定义工具的输入参数列表
- name: sql
type: string
required: true
label: # 在 Dify UI 中显示的参数标签 (多语言)
en_US: sql
zh_Hans: sql语句
human_description: # 给人类用户看的参数描述 (多语言)
en_US: the sql to execute
zh_Hans: 要执行的sql语句
llm_description: sql # 给 LLM 看的参数描述 (指导 Agent 如何填充)
form: llm # 参数表单类型 ('llm' 或 'form')
extra:
python:
source: tools/execute_sql.py
execute_sql.py修改为如下内容:
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
from tools.db import DbManagerSingleton
class ExecuteSqlTool(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"]
yield self.create_text_message(self.dbManager.execute_sql(sql))
manifest.yaml定义了插件最基础的信息,包括插件名称、作者、包含的工具、模型等信息。
本插件虽然没用到storage持久化存储的权限,但需要将storage里的size字段从0改为大于等于1024,否则启动插件时会报错。
storage:
enabled: false
size: 1024
python main.py
启动插件,等待至显示"dify_plugin.plugin:Installed tool",工具安装成功。确认插件能够正常运行后,可以通过以下命令行工具打包插件,生成mysql.difypkg。
dify-plugin-windows-amd64.exe plugin package mysql
需要修改docker/.env,将FORCE_VERIFYING_SIGNATURE改为false,然后重建docker。修改该字段后,Dify平台将允许安装所有未在Dify Marketplace上架(审核)的插件,可能存在安全隐患。
docker compose down
docker compose up -d
docker重建后,重新安装本地插件。点击右上角“插件”按钮,进入插件页面,选择“探索Marketplace
选择插件Dify Agent 策略
进行安装。# 角色
你是记账助手,可以通过调用数据库工具完成记录日常收入和支出并作分析。
为了完成记账操作,需要先获取数据库表finance的定义。
记账的用户ID取值为{{#sys.user_id#}}
# 收支类别
收入:工资薪金,劳务报酬,投资收益,分红收入,租金收入,其它收入
支出:住房,交通,通讯,保险,餐饮,电子产品,日用品,服饰,旅行,娱乐,医疗,学习,其它支出
# 技能
## 技能1:记录日常开支
将开支信息记录到数据库表finance
## 技能2:统计日常开支
根据用户输入信息分析统计日常开支
# 限制
仅处理记账相关问题,不回复其它问题
确认无误后点击右上角的“发布”按钮发布应用
本文以实现MySQL数据库操作插件详细介绍开发Dify工具插件的全流程,并使用该插件搭建理财智能体,展示了Agent从语义理解到工具调用的完整决策链路。
跟MCP工具插件开发比较,Dify工具插件开发步骤相对复杂,且仅能使用Python开发,仅能用于Dify生态。但Dify插件的整体链路开销较MCP插件低,如果你对系统时延和成本更敏感,且无需使用MCP的动态发现工具能力,Dify工具插件也许是个更好的选择。
完整代码地址:https://github.com/copilot-coder/dify-plugin-mysql
#智能体开发 #Dify插件开发 #AI应用开发
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-05-28
Lemon AI:宜创AI发布全球首款全栈开源通用AI Agent,让人人可以单机部署超级智能体
2025-05-27
一个让工作效率翻倍的AI神器,Cherry Studio你值得拥有!
2025-05-27
Docext:无需 OCR,本地部署的文档提取神器,企业数据处理新选择
2025-05-26
太猛了,字节把GPT-4o级图像模型开源了!
2025-05-26
Qwen3硬核解析:从36万亿Token到“思考预算”
2025-05-26
蚂蚁集团开源antv的MCP服务:AI智能体与数据可视化的桥梁如何搭建?
2025-05-26
MinerU:高精度纸媒文档解析与数据提取一站式解决方案
2025-05-26
顶级开发者默默换掉了基础大模型
2024-07-25
2025-01-01
2025-01-21
2024-05-06
2024-09-20
2024-07-20
2024-07-11
2024-06-12
2024-12-26
2024-08-13
2025-05-26
2025-05-25
2025-05-23
2025-05-17
2025-05-17
2025-05-17
2025-05-16
2025-05-14