前言:

基于华为云Flexus服务器和ModelArts Studio构建的自然语言转SQL系统展现出极高的智能化和自动化水平。部署过程简洁,借助Flexus的一键部署模板,即使非专业开发者也能轻松搭建平台。平台运行高效稳定,特别是在模型推理和SQL执行方面,Flexus服务器强大的算力提供了坚实保障。

此外,结合DeepSeek大模型在自然语言理解与结构化查询生成方面的优势,该系统极大降低了使用门槛,让数据分析真正“触手可及”。不再需要编写复杂SQL,用户只需提出问题,即可获得详尽的分析和直观的图表结果,极大提升了企业的数据敏感性与响应效率。

在这里插入图片描述

  • ①. 聊天助手(Chat Assistant):
    基于LLM的对话助手,能够与用户进行自然语言交互,理解用户的问题、请求或指令,并给出相应的回答或执行相应的操作。

  • ②. 文本生成(Text Generation):
    专注于各种文本生成任务,如撰写故事、新闻报道、文案、诗歌等创意写作,以及文本分类、翻译等任务。

  • ③. Agent(智能代理):
    这种助手不仅具备对话能力,还具备任务分解、推理、工具调用等高级能力。它能够理解复杂的指令,将任务分解为多个子任务,并调用相应的工具或API来完成这些子任务。

  • ④. 工作流程(Workflow):
    根据用户定义的流程编排,灵活地组织和控制LLM的工作流程。用户可以自定义一系列的操作步骤和逻辑判断,让LLM按照预定的流程执行任务。


二、SQL的工作流的开发:

2.1 基于Text2SQL构建自然语言转SQL应用:

Text2SQL(或称NL2SQL)是一种自然语言处理技术,旨在将自然语言(Natural Language)问题转化为关系型数据库中可执行的结构化查询语言(Structured Query Language,SQL),从而实现对数据库的查询和交互。

Text2SQL可以无需用户具备SQL语法知识,只通过自然语言的描述,即可实现对数据库的查询和交互,完成复杂的数据库查询任务,Text2SQL的任务包括以下步骤:

  • ①. 输入分析:用户以自然语言形式输入问题。
  • ②. 语义解析:系统将输入的自然语言问题解析转化为数据库中可以执行的的结构化查询语句。
  • ③. SQL生成:根据解析结果生成对应的SQL DLL相关语句。
  • ④. 执行与反馈:系统执行SQL查询并返回结果。

这里我们通过右上角“插件”的搜索框中,直接搜索database的插件名称,第一个就是database的工具,此工具可以用来连接现有数据库,并执行SQL语句和自然语言转SQL。

  • ①. SQL Execute:此工具用于在已存在的数据库中执行 SQL 查询。
  • ②. Text to SQL:提供数据库上下文和用户的问题,来得到一个 SQL 语句。
  • ③. Get Table Schema:从数据库中获取表结构。
  • ④. CSV Query:运行在 CSV 文件上的 SQL 查询。

在这里插入图片描述

通过添加Database工具节点后,可以选择“SQL Execute”这个工具,这个工具主要用于已存在数据库中执行SQL查询,因为考虑到用实现text2SQL 所以免不了使用到这个SQL Execute 工具。

在这里插入图片描述

目前这个项目支持的数据库有mysql、postgresql、sqlite、sqlserver、oracle,在插件市场把它安装好后,就需要对它配置,用的是mysql参考上述链接字符串:

mysql+pymysql://root:1234@localhost:3306/testdb

这里还有一个小技巧,就是如果数据库密码是带有@符号的,需要转义一下,上述因为密码也带有特殊符号“@” 和后面的数据链接符号@产生了歧义,这样程序连接就会报错,若要借助转义的方式来处理包含特殊字符 @ 的连接字符串,在标准的数据库连接字符串里,一般没有通用转义符号能直接用在字符串里。

在这里插入图片描述

这里如果没有建表的话,可以先在数据库进行建表数据,需通过‌结构化SQL语句‌完成表结构定义与数据插入:

在这里插入图片描述

可以看到我们“迭代代码”片块,可以匹配出来数组中的每个query的字段,通过这些query语句后,可以执行查询的结果,以下就是相关query SQL的查询语句:

{
  "output": [
    {
      "result": [
        {
          "total_orders": 17
        }
      ]
    },
    {
      "result": [
        {
          "total_revenue": "16951.80"
        }
      ]
    },
    {
      "result": [
        {
          "cate_name": "服装鞋帽",
          "order_count": 4
        },
        {
          "cate_name": "电子产品",
          "order_count": 4
        },
        {
          "cate_name": "日用百货",
          "order_count": 2
        },
        {
          "cate_name": "食品饮料",
          "order_count": 2
        },
        {
          "cate_name": "家居用品",
          "order_count": 2
        },
        {
          "cate_name": "玩具图书",
          "order_count": 1
        },
        {
          "cate_name": "运动器材",
          "order_count": 1
        },
        {
          "cate_name": "美妆护理",
          "order_count": 1
        }
      ]
    },
    {
      "result": [
        {
          "status": "已完成",
          "status_count": 14
        },
        {
          "status": "待付款",
          "status_count": 2
        },
        {
          "status": "已取消",
          "status_count": 1
        }
      ]
    },
    {
      "result": [
        {
          "goods_name": "冰淇淋",
          "total_quantity": "3"
        },
        {
          "goods_name": "T恤",
          "total_quantity": "3"
        },
        {
          "goods_name": "冰箱贴",
          "total_quantity": "3"
        },
        {
          "goods_name": "防晒霜",
          "total_quantity": "2"
        },
        {
          "goods_name": "充电小风扇",
          "total_quantity": "2"
        },
        {
          "goods_name": "沙滩玩具",
          "total_quantity": "2"
        },
        {
          "goods_name": "便携风扇",
          "total_quantity": "2"
        },
        {
          "goods_name": "牛奶",
          "total_quantity": "2"
        },
        {
          "goods_name": "华为平板",
          "total_quantity": "2"
        },
        {
          "goods_name": "户外折叠桌",
          "total_quantity": "1"
        }
      ]
    },
    {
      "result": [
        {
          "daily_orders": 10,
          "order_date": "2025-06-22"
        },
        {
          "daily_orders": 1,
          "order_date": "2025-06-01"
        },
        {
          "daily_orders": 6,
          "order_date": "2024-01-01"
        }
      ]
    },
    {
      "result": [
        {
          "hour_of_day": 9,
          "hourly_orders": 4
        },
        {
          "hour_of_day": 10,
          "hourly_orders": 7
        },
        {
          "hour_of_day": 11,
          "hourly_orders": 4
        },
        {
          "hour_of_day": 23,
          "hourly_orders": 2
        }
      ]
    },
    {
      "result": [
        {
          "cate_name": "电子产品",
          "category_revenue": "14434.80"
        },
        {
          "cate_name": "服装鞋帽",
          "category_revenue": "874.00"
        },
        {
          "cate_name": "家居用品",
          "category_revenue": "598.00"
        },
        {
          "cate_name": "美妆护理",
          "category_revenue": "318.00"
        },
        {
          "cate_name": "食品饮料",
          "category_revenue": "239.50"
        },
        {
          "cate_name": "日用百货",
          "category_revenue": "218.70"
        },
        {
          "cate_name": "玩具图书",
          "category_revenue": "139.80"
        },
        {
          "cate_name": "运动器材",
          "category_revenue": "129.00"
        }
      ]
    },
    {
      "result": [
        {
          "avg_price": "712.205882",
          "avg_quantity": "1.7059"
        }
      ]
    },
    {
      "result": [
        {
          "unique_orders": 17
        }
      ]
    }
  ]
}

2.2 代码执行进行数据汇总:

上面是把数据库的数据全部查出来了,但是这里想要把数据全部聚合起来,将对象转换为字符串格式的信息,这样方便后面LLM大语言模型的思考与归类。

在这里插入图片描述


2.3 LLM大语言模型数据归类生成:

这个地方也用到了LLM大语言模型,同样使用华为云提供的deepseek V3模型。将根据上个模型生成的 SQL 及其查询结果,优先回答用户问题,回答内容不要发散,并且将关联问题的结果进行分析并以 JSON 格式返回给用户。

在这里插入图片描述

这里是相关的提示词信息:

### 角色
你是一个数据分析师,需要根据上个模型生成的 SQL 及其查询结果,优先回答用户问题,回答内容不要发散,并且将关联问题的结果进行分析并以 JSON 格式返回给用户。

### 参数
- **SQL 模型生成**{{#1750579199539.text#}}
- **SQL 查询结果**{{#context#}}

### 图片使用场景
- 线性图 :适用于展示趋势变化的数据,例如时间序列数据(如每月、每年的变化)。
- 柱状图 :适用于比较不同类别之间的数量或占比,例如各市的占比情况。
- 饼状图 :适用于展示整体的组成部分及其比例,通常用于单维度的比例分布。

### 要求:
1. 优先回答用户问题,回答内容不要发散。
2. 根据用户问题正确使用线性图/柱状图/饼状图。
3. 将结果放入到 JSON 中,一定要生成如下格式:
{
  "results": "用md格式先回复用户问题,其它维度数据简单概括,但是数据一定要展示出来",
  "ECHarts": "1",  // 如果需要生成图表,则为 "1";否则为 "0"
  "chartType": "线性图/柱状图/饼状图",  // 图表类型(仅当 ECHarts 为 true 时提供)
  "chartTitle": "图表标题",            // 图表标题(仅当 ECHarts 为 true 时提供)
  "chartData": "图表的数据,多个用;隔开", // 图表数据(仅当 ECHarts 为 true 时提供)
  "chartXAxis": "图表的X轴,多个用;隔开"   // 图表的X轴数据(仅当 ECHarts 为 true 时提供)
}
4. chartData如果有的话,一定要是字符串的浮点数

#### 注意事项:
- 如果查询结果适合生成图表,则 ECHarts 设置为 "1",并补充 chartType、chartTitle、chartData 和 chartXAxis 字段。
- 如果查询结果不适合生成图表,则 ECHarts 设置为 "0",并省略 chartType、chartTitle、chartData 和 chartXAxis 字段。
- 咨询占比必须使用饼状图进行展示,饼状图chartData中应返回百分比。

2.3 转换为json固定格式:

将所有的数据库返回的数据进行分析后,全部转换为以下固定的格式,得到以下固定的格式后,我们需要将string类型的字符串,通过LLM3节点进行自动分析把以下的格式字段获取出来。

{
  "results": "用md格式先回复用户问题,其它维度数据简单概括,但是数据一定要展示出来",
  "ECHarts": "1",  // 如果需要生成图表,则为 "1";否则为 "0"
  "chartType": "线性图/柱状图/饼状图",  // 图表类型(仅当 ECHarts 为 true 时提供)
  "chartTitle": "图表标题",            // 图表标题(仅当 ECHarts 为 true 时提供)
  "chartData": "图表的数据,多个用;隔开", // 图表数据(仅当 ECHarts 为 true 时提供)
  "chartXAxis": "图表的X轴,多个用;隔开"   // 图表的X轴数据(仅当 ECHarts 为 true 时提供)
}

在这里插入图片描述

import re
import json

def main(arg1: str) -> dict:
    # 默认返回值
    default_output = {
        "results": "",
        "ECHarts": "0",
        "chartType": "",
        "chartTitle": "",
        "chartData": "",
        "chartXAxis": ""
    }
    
    try:
        # 使用正则表达式提取被 ```json 和 ```包裹的内容
        match = re.search(r'```json\s*([\s\S]*?)\s*```', arg1)
        if not match:
            raise ValueError("输入字符串中未找到有效的 JSON 数据")
        
        # 提取 JSON 字符串
        json_str = match.group(1).strip()
        
        # 将 JSON 字符串解析为 Python 字典
        result_dict = json.loads(json_str)
    except Exception as e:
        # 如果解析失败,打印错误信息并返回默认输出
        print(f"解析失败: {e}")
        return default_output
    
    # 检查是否包含 ECHarts 字段
    if "ECHarts" not in result_dict:
        result_dict["ECHarts"] = "0"  # 默认设置为 "0"
    
    # 根据 ECHarts 的值动态检查图表相关字段
    if result_dict["ECHarts"] == "1":
        required_chart_fields = ["chartType", "chartTitle", "chartData", "chartXAxis"]
        for field in required_chart_fields:
            if field not in result_dict:
                result_dict[field] = ""  # 自动补全缺失字段为空字符串
    
    # 构造返回值
    return {
        "results": str(result_dict.get("results", "")),
        "ECHarts": str(result_dict.get("ECHarts", "0")),
        "chartType": str(result_dict.get("chartType", "")),
        "chartTitle": str(result_dict.get("chartTitle", "")),
        "chartData": str(result_dict.get("chartData", "")),
        "chartXAxis": str(result_dict.get("chartXAxis", ""))
}

2.4 代码转换为ECHarts json对象:

上面可以通过大模型得到一个ECHarts json对象的字符串类型的返回值,那么可以通过代码执行器把string类型的返回值转换为json对象的,供后面的条件分支结果进行分析。

在这里插入图片描述

import re
import json

def main(arg1: str) -> dict:
    try:
        # 使用正则表达式提取被 ```json 和 ```包裹的内容
        match = re.search(r'```json\s*([\s\S]*?)\s*```', arg1)
        if not match:
            return {
                "results": "",
                "ECHarts": "0",
                "chartType": "",
                "chartTitle": "",
                "chartData": "",
                "chartXAxis": ""
            }
        
        # 提取 JSON 字符串
        json_str = match.group(1).strip()
        
        # 将 JSON 字符串解析为 Python 字典
        result_dict = json.loads(json_str)
        return result_dict
    except Exception as e:
        # 如果解析失败,打印错误信息并返回默认输出
        return {
            "results": "",
            "ECHarts": "0",
            "chartType": "",
            "chartTitle": "",
            "chartData": "",
            "chartXAxis": ""
        }

可以看到LLM2、LLM3、代码执行4之间的关系是以下这样,LLM2将数据库返回的数据分析成echats类型,LLM3将ehcarts类型的中的数据json这块全部匹配出来,代码块执行4将上面匹配的字符串转换为json对象。

在这里插入图片描述

主要是对查询结果进行汇总分析,另外把查询的结果ECHarts 图表组装需要的需要的JSON格式数据,上面llm大语言模型处理的结果我们这里用代码执行生成echart代码。


2.5 条件判断节点分支:

在 Dify 中,‌条件分支节点‌是工作流中根据预设逻辑动态分流的核心控件,其核心作用是通过‌布尔判断将数据流导向不同路径‌,而非依赖大模型进行意图识别,这个条件分支是考虑用户输入的信息 返回结果有线性图表、柱状图、饼图的输出,所以需要通过这个条件分支进行判断,比如:

当输入数据满足特定条件(如变量值匹配、表达式为真)时,自动激活对应分支。例如在退货流程中,若用户输入包含关键词「退款」,则触发退款处理分支;若匹配「换货」则进入换货分支,否则跳转至人工客服分支,这种硬编码规则替代了大模型的意图识别,显著降低调用成本并提升响应确定性。

在这里插入图片描述

在 Dify 中,‌条件分支节点‌的本质是工作流的逻辑分流中枢,它通过‌预设的规则引擎替代大模型的模糊判断‌,实现精准的流程控制。其核心逻辑在于将传统编程中的 if/else 结构转化为可视化模块,依据输入数据的属性(如文本内容、变量值或表达式结果)强制引导数据流向特定路径,而非依赖 AI 的意图推测。


2.6 处理Echarts图表数据结构:

这里出现一个问题,给Echats传data数据时,一直报错can’t string to float,经过查询后,发现需要传给Echats的数据格式是1;2;3;4,逗号隔开的字符串类型,所以,这个节点需要处理一下,将需要转换一个echarts工具data需要的数据格式,比如:

  • ①. 将[1,2,3,4]转换为[‘1’, ‘2’, ‘3’, ‘4’]是不行的。
  • ②. 将[1,2,3,4]转换为’[1,2,3,4]’也是不行的。
  • ③. 将[1,2,3,4]转换为1;2;3;4,用分号隔开,就正常。

在这里插入图片描述


2.7 ECharts图表:

Dify ECharts 是 Dify 平台中集成 ECharts 库的功能组件,它允许用户通过自然语言交互或工作流自动生成动态、交互式的数据可视化图表,无需手动编写代码。用户只需上传数据源(如 Excel 表格)。

在这里插入图片描述

Dify 会利用大模型(如 qwen-max)智能解析用户需求,生成对应的 ECharts 配置参数,再通过代码执行节点渲染出图表,最终在对话界面直接展示结果。这一功能简化了传统数据可视化流程,特别适用于销售分析、成绩统计等场景,用户可快速实现图表定制与更新。

在这里插入图片描述

具体实现中,Dify ECharts 的工作流通常包括文档上传、数据提取、模型解析、参数生成和图表渲染等环节,支持多种数据类型和编码格式,确保输出为标准 JSON 结构的 ECharts 配置。相比固定模板方案,它能动态适应不同数据源,提升了可扩展性和用户体验。

这个地方就是主要是使用ECharts图表对线性图表、柱状图、饼图的输出,这里输入的参数有3个分别是:标题、数据、x轴,其中线性图表、柱状图一样的,饼图有点区别 它不是x 轴而是换成分类,数据格式都是一样的。

在这里插入图片描述

Dify ECharts 的核心优势在于将数据分析与可视化流程智能化、平民化,通过大模型能力打通自然语言需求到专业图表的全链路,用户可直接用自然语言描述图表需求(如“展示近三年销售额季度对比的柱状图”),系统自动解析意图并生成对应的 ECharts 配置参数,彻底告别手动编写 SQL 或调试图表代码的繁琐过程,即使是复杂的数据分析指令,也能被精准拆解为可执行方案。


2.8 最后结果输出:

Dify ECharts支持对接多种数据源(如 MySQL 数据库、Excel 表格等),并能根据数据特征自动匹配合适的图表类型。上传新数据后,仅需调整指令即可快速刷新可视化结果,无需重构底层逻辑。

在这里插入图片描述

依托 ECharts 强大的渲染能力,直接输出可交互的动态图表(如支持缩放、悬停查看数据明细等),满足从基础柱状图到多维热力图的复杂展示需求,大幅提升数据表达的直观性和专业性。


三、其它准备工作:

前面给大家介绍了工作流制作,其实这个工作流还是需要依赖数据库,所以我们需要把数据库和创建表创建完成才能使用,以下为相关的建表语句:

CREATE TABLE `data_orders` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `order_id` varchar(32) NOT NULL COMMENT '订单号',
  `goods_name` varchar(100) NOT NULL COMMENT '商品名称',
  `cate_name` varchar(50) NOT NULL COMMENT '商品分类',
  `price` decimal(10,2) NOT NULL COMMENT '价格',
  `num` int(11) NOT NULL COMMENT '数量',
  `status` varchar(20) NOT NULL COMMENT '订单状态',
  `created_at` datetime NOT NULL COMMENT '订单创建时间',
  `updated_at` datetime NOT NULL COMMENT '订单更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_order_id` (`order_id`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单信息表';

在这里插入图片描述

以下是针对 data_orders 表的多条 SQL 插入语句示例,涵盖单条插入、批量插入及动态时间生成等场景:

-- 单条插入(显式指定列名)
INSERT INTO data_orders (
    order_id, goods_name, cate_name, price, num, status, created_at, updated_at
) VALUES (
    'ORD20250626001', '智能手表', '数码产品', 899.00, 1, 'paid', NOW(), NOW()
);

-- 批量插入(单语句多记录)
INSERT INTO data_orders (
    order_id, goods_name, cate_name, price, num, status, created_at, updated_at
) VALUES 
    ('ORD20250626002', '无线耳机', '数码产品', 299.00, 2, 'shipped', '2025-06-25 14:30:00', '2025-06-26 09:15:00'),
    ('ORD20250626003', '运动水壶', '户外用品', 59.90, 3, 'pending', '2025-06-24 10:00:00', '2025-06-24 10:00:00'),
    ('ORD20250626004', '编程书籍', '图书', 128.50, 1, 'delivered', '2025-06-20 16:45:00', '2025-06-22 11:20:00');

-- 动态时间插入(使用日期函数)
INSERT INTO data_orders (
    order_id, goods_name, cate_name, price, num, status, created_at, updated_at
) VALUES (
    'ORD20250626005', '办公椅', '家具', 450.00, 1, 'paid', DATE_SUB(NOW(), INTERVAL 2 DAY), NOW()
);

三、总结:

今天主要通过“华为云快速搭建Dify-LLM应用开发平台的技能”, 基于Dify平台开发AI Agent的完整流程实现了基于 Text2SQL 的 Dify 工作流,借助 Dify 平台实现自然语言到 SQL 查询的转换,并进行数据库查询与图表生成。

本文详细的介绍了整个工作流的实现步骤,包括工作流的制作,如添加对话开场白、获取当前系统时间、配置 LLM 大语言模型以及使用 SQL Execute 工具执行 SQL 查询等节点与工具的使用。

在这里插入图片描述

本次工作流涉及到 Dify 版本的使用、相关工具(时间工具、ECharts 图表生成、database)的安装与配置,以及 SQL 语句的生成与执行等知识,华为云Flexus服务器结合Dify平台与DeepSeek大模型,实现了从自然语言到SQL的智能转换与数据分析,极大推动了AI在企业数据场景的落地。

通过本文的介绍可以看到,随着模型能力与平台生态的不断完善,智能化数据分析将成为更多企业的“标配工具”,助力业务洞察与决策提效。如果正在寻找高效、智能、可扩展的数据分析方案,基于华为云构建的这一套系统无疑是值得尝试的理想选择。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐