用dify + agent构建自然语言查询数据库信息并展示

1. 数据准备

1.1. 数据库表结构描述
CREATE TABLE `host` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `ApplicationID` varchar(128) DEFAULT NULL COMMENT '应用ID',
  `AssetID` int(11) DEFAULT NULL COMMENT '资产ID',
  `BakOperator` varchar(128) DEFAULT '' COMMENT '备份操作人',
  `Cpu` int(3) NOT NULL DEFAULT '0' COMMENT 'CPU',
  `CreateTime` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '创建日期',
  `Description` varchar(256) DEFAULT '' COMMENT '备注',
  `Env` varchar(20) DEFAULT NULL,
  `DeviceClass` varchar(50) DEFAULT '一级',
  `HostName` varchar(32) NOT NULL DEFAULT '' COMMENT '主机名',
  `InnerIP` varchar(128) NOT NULL DEFAULT '' COMMENT '网内地址',
  `LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日期',
  `Mem` int(8) NOT NULL DEFAULT '0',
  `OS_kernel` varchar(128) DEFAULT NULL,
  `Operator` varchar(128) DEFAULT '' COMMENT '管理员',
  `OS_type` varchar(128) NOT NULL DEFAULT '' COMMENT '系统类型',
  `OuterIP` varchar(128) NOT NULL DEFAULT '' COMMENT '外网地址',
  `Status` varchar(10) DEFAULT '1',
  `Extend001` varchar(255) NOT NULL DEFAULT '',
  `Extend002` varchar(255) NOT NULL DEFAULT '',
  `Extend003` varchar(255) NOT NULL DEFAULT '',
  `Extend004` varchar(255) NOT NULL DEFAULT '',
  `Extend005` varchar(255) NOT NULL DEFAULT '',
  `Disk_mount` varchar(255) DEFAULT NULL COMMENT '硬盘挂载信息',
  `Disk` int(8) DEFAULT NULL COMMENT '硬盘信息',
  `IdcName` varchar(128) DEFAULT '' COMMENT '机房名称',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=614 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='主机记录表' ;

CREATE TABLE `server` (
  `ApplicationID` int(11) DEFAULT NULL COMMENT '应用ID',
  `ID` int(64) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `HardMemo` varchar(16) NOT NULL DEFAULT '' COMMENT '服务器品牌型号',
  `Cpu_model` varchar(128) DEFAULT '0' COMMENT 'CPU',
  `Cpu_number` int(4) DEFAULT NULL COMMENT '物理cpu个数',
  `HostName` varchar(32) NOT NULL DEFAULT '',
  `DeviceClass` varchar(50) DEFAULT '一级',
  `Region` varchar(8) DEFAULT '' COMMENT '区域-ucloud使用',
  `OS_type` varchar(32) DEFAULT '' COMMENT '系统类型',
  `OS_kernel` varchar(32) NOT NULL DEFAULT '' COMMENT '系统内核',
  `SN` varchar(32) NOT NULL DEFAULT '' COMMENT 'SN编号',
  `ServerRack` varchar(16) NOT NULL DEFAULT '' COMMENT '架机号',
  `CreateTime` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '创建日期',
  `IdcName` varchar(128) DEFAULT '' COMMENT '房机名称',
  `LastTime` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新日期',
  `Operator` varchar(128) NOT NULL DEFAULT '' COMMENT '理管员',
  `BakOperator` varchar(128) DEFAULT '' COMMENT '备份操作人',
  `Status` varchar(10) DEFAULT '1',
  `ManagerIP` varchar(128) NOT NULL DEFAULT '' COMMENT '管理地址',
  `Raid` varchar(255) DEFAULT NULL COMMENT 'raid级别',
  `Is_virtualization` varchar(10) DEFAULT '1',
  `InnerIP` varchar(128) NOT NULL DEFAULT '' COMMENT '网内地址',
  `OuterIP` varchar(128) DEFAULT '' COMMENT '外网地址',
  `Description` varchar(256) NOT NULL DEFAULT '' COMMENT '备注',
  `Extend001` varchar(255) DEFAULT NULL,
  `Extend003` varchar(255) DEFAULT '',
  `Extend004` varchar(255) DEFAULT '',
  `Extend005` varchar(255) DEFAULT '',
  `Extend002` varchar(255) DEFAULT '',
  `Cpu_cores` int(4) DEFAULT NULL COMMENT 'cpu核数',
  `Mem` int(18) DEFAULT '0',
  `Disk_mount` varchar(2000) DEFAULT NULL COMMENT '硬盘分区',
  `Disk_total` int(255) DEFAULT NULL COMMENT '硬盘',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='服务器记录表';

1.2. 生成数据库查询接口,请求sql语句 ,返回查询结果
(base) root@ubuntu:/data/scripts# more sql-query.py 
from flask import Flask, request, jsonify
from sqlalchemy import create_engine, text

app = Flask(__name__)

# 配置数据库连接
DATABASE_URI = 'mysql+pymysql://test:123456@192.168.0.13:3306/test'
engine = create_engine(DATABASE_URI)

@app.route('/query', methods=['POST'])
def query_database():
    # 获取请求中的SQL语句
    sql_query = request.json.get('sql')

    if not sql_query:
        return jsonify({"error": "SQL query is required"}), 400

    try:
        # 执行SQL查询
        with engine.connect() as connection:
            result = connection.execute(text(sql_query))
            rows = result.fetchall()

            # 将结果转换为字典列表
            columns = result.keys()
            result_dict = [dict(zip(columns, row)) for row in rows]

            return jsonify(result_dict)

    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True)

1.3. 测试数据库查询接口
(base) root@ubuntu:~# curl -X POST "http://127.0.0.1:5000/query" -H "Content-Type: application/json" -d '{"sql": "select * from host limit 1;"}'

[

{

"ApplicationID": "10",

"AssetID": 0,

"BakOperator": "",

"Cpu": 24,

"CreateTime": "Wed, 30 Aug 2017 21:49:10 GMT",

"Description": "111",

"DeviceClass": "\u4e8c\u7ea7",

"Disk": 815,

"Disk_mount": "/ ext4 51471126528;/boot ext4 499355648;/home ext4 20507914240;/services ext4 772097990656;/tmp ext4 10186764288;/var ext4 20507914240;",

"Env": "dev",

"Extend001": "192.168.122.1",

"HostName": "opt2",

"ID": 274,

"IdcName": "SHOFFICE",

"InnerIP": "172.16.26.2",

"LastTime": "Wed, 13 Sep 2017 15:35:12 GMT",

"Mem": 64375,

"OS_kernel": "2.6.32-642.1.1.el6.x86_64",

"OS_type": "CentOS 6.8",

"Operator": "1",

"OuterIP": "",

"Status": "1"

}

]

2. 配置数据库查询工作流

2.1. 工作流预览

2.2. 代码执行节点内容
from urllib  import request
import urllib.request
import json

def main(sql: str) -> dict:

    data = {"sql": sql}
    url = 'http://192.168.0.13:5000/query'

    json_data = json.dumps(data)
    byte_data = json_data.encode('utf-8')

    req = urllib.request.Request(url, data=byte_data, headers={'Content-Type': 'application/json'})

    response = urllib.request.urlopen(req)
    response_data = response.read().decode('utf-8')
      
    return {
        "result": response_data,
    }

2.3. 输入sql语句测试

2.4. 返回数据库查询结果

2.5. 工作流发布为工具

3. 配置agent

3.1. 表结构信息导入知识库
表结构描述:
表名称: `host`  主机表
字段列表:
`BakOperator`,备份操作人,字符串
`Cpu`, CPU, 整型
`CreateTime`, 创建日期,日期类型
`Description`,备注,字符串
`Env`,环境,字符串
`DeviceClass`,设备级别,字符串
`HostName`,主机名,字符串
`InnerIP`,内网地址,字符串
`LastTime`,更新日期,日前类型
`Mem`,内存,整型
`OS_kernel`,内核,字符串
`Disk_mount`,硬盘挂载信息,字符串
`Disk`,硬盘信息,字符串
`IdcName`,机房名称,字符串



表名称: `Server`  服务器表
字段列表:
`HardMemo`,服务器品牌型号,字符串
`BakOperator`,备份操作人,字符串
`Cpu_model`, CPU, 整型
`Cpu_number`,物理cpu个数,整型
`Region`,区域, 字符串
`OS_type`,系统类型,字符串
`OS_kernel`,内核,字符串
`CreateTime`, 创建日期,日期类型
`Description`,备注,字符串
`Env`,环境,字符串
`DeviceClass`,设备级别,字符串
`HostName`,主机名,字符串
`InnerIP`,内网地址,字符串
`LastTime`,更新日期,日前类型
`Mem`,内存,整型
`SN`,SN编号,字符串
`Disk_mount`,硬盘挂载信息,字符串
`Disk`,硬盘信息,字符串
`IdcName`,机房名称,字符串
`Operator`,管理员,字符串
`Status`,状态,字符串,0 表示关机, 1 表示开机
`Cpu_cores`,CPU核数,整型
`Raid`,RAID级别,整型
`Is_virtualization`,是否虚拟化,字符串

3.2. 准备sql查询提示词

提示词:

#角色:你是一位精通SQL语言的数据库专家,精通MySql,同时擅长解读和分析数据

#任务:你的任务是理解用户的输入和上下文内容,编写SQL查询,并调用工具查询获得结果,结合用户的提问,对查询结果进行呈现、解读和分析

#关键步骤:

1、对用户输入的内容进行识别和判断,如果内容涉及政治、时事、社会问题以及违背道德和法律法规的情形,一律输出:”您提出的问题超出我应当回答的范围,请询问与公司业务相关的问题,否则我无法作出回答

2、根据用户输入的内容和上下文信息,形成内容分类,根据内容分类按照以下规则从知识库“数据结构描述”中检索数据表结构信息:

-内容分类与服务器相关,则检索“server”

-内容分类与主机相关,则检索“host”



注意:务必严格按照上述分类获得对应的检索关键词,不得生成新的检索关键词。如果你认为用户的提问无法匹配到合适的分类,请输出提示:为确保查询获得准确信息,请再把你的需求描述细致一些

3、根据用户输入的内容和上下文信息,形成一个符合用户意图的完整问题,以此作为输入在知识库“sql示例”中检索SQL语句参考示例

4、基于对上下文和对用户提问的理解,按照检索到的数据表结构信息,以及SQL参考示例,编写SQL查询语句。注意,若内容分类与参考示例中的分类不符时,则忽略这个示例。另外,不是所有情况下都有示例参考,没有示例时请按照自己的理解和掌握的知识编写SQL语句

5、去除SQL语句中多余的注释、换行符等无用信息,输出一个纯净的、可直接执行的SQL语句

6、执行SQL查询,获取结果

7、阅读查询结果,结合历史对话内容,对查询结果进行呈现、解读和分析

#编写SQL时的注意事项:

1. 务必根据上下文提供的数据表结构描述来编写SQL语句,确保仅使用数据表结构描述中提到的表名和字段名,并参考对字段的解释

2. 确保SQL兼容Mysql

3. 只输出一个完整SQL语句,无注释,确保可直接执行并获得预期的结果


#其他注意事项

1、不要输出中间的思考过程,只输出最终的结果

3.3. 创建Agent,输入提示词,知识库,选中数据库查询工具,大模型选择闭源大模型

3.4. 测试效果

完整的视频演示请移步B站:老吴聊技术

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值