支持私有化部署
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


Dify工作流实践:text2Sql与图表生成

发布日期:2025-05-11 17:19:52 浏览次数: 1582 作者:开源纪行
推荐语

利用Dify工作流自动化报告和图表生成,提升工作效率。

核心内容:
1. Dify工作流在text2Sql与图表生成中的应用实践
2. 测试表的创建与数据生成方法
3. 结果输出稳定性调优与实践总结

杨芳贤
53A创始人/腾讯云(TVP)最具价值专家

工作中经常会有对结果表数据进行分析并生成报告和图表的需求,就想着尝试使用dify自动完成这项任务。总体想法是通过配置Dify工作流,以自然语言文字输入将需求转化为SQL语句,进而调用外部工具或插件查询数据库以获取返回结果,并借助大模型能力生成报告和图表。经过实践,该方法具有一定的可行性,但输出结果的稳定性还需要进一步调优,这里对实践过程做个记录 (以下过程基于Dify1.2.0版本)。

测试表整理

    用deepseek帮我生成了几张测试表,分别是用户表、产品表、订单表和订单明细表,并让其帮我生成测试数据;其中表结构及字段信息我整理成md格式文件,后面导入到知识库使用。

表结构

### 用户表CREATE TABLE users (    id SERIAL PRIMARY KEY, --用户ID,主键    username VARCHAR(50NOT NULL UNIQUE--用户名    phone VARCHAR(11NOT NULL UNIQUE--手机号    email VARCHAR(100UNIQUE--电子邮箱(唯一)    address VARCHAR(200), --收货地址    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP --创建时间);
### 产品表CREATE TABLE products (    id SERIAL PRIMARY KEY, --商品ID,主键    product_name VARCHAR(100NOT NULL--商品名称    price NUMERIC(10,2NOT NULL CHECK (price > 0), --商品价格(必须>0)    stock INT NOT NULL CHECK (stock >= 0), --库存数量(必须≥0)    status VARCHAR(10CHECK (status IN ('上架''下架')),  --商品状态(上架/下架)    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP --创建时间);
### 订单表CREATE TABLE orders (    id SERIAL PRIMARY KEY, --订单ID,主键    user_id INT REFERENCES users(id), --用户ID,外键关联users.id    order_no VARCHAR(20NOT NULL UNIQUE--订单编号    total_amount NUMERIC(10,2NOT NULL--订单总金额    status VARCHAR(10CHECK (status IN ('已付款''已发货''已完成''已取消')), --订单状态(已付款/已发货/已完成/已取消)    order_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP --下单时间);
### 订单明细表CREATE TABLE order_items (    id SERIAL PRIMARY KEY, --明细ID,主键    order_id INT REFERENCES orders(id), --订单ID,外键关联orders.id    product_id INT REFERENCES products(id), --商品ID,外键关联products.id    quantity INT NOT NULL CHECK (quantity > 0), --购买数量(必须>0)    unit_price NUMERIC(10,2NOT NULL--下单时的商品单价    total_price NUMERIC(10,2) GENERATED ALWAYS AS (quantity * unit_price) stored --明细总价(自动计算:数量×单价));
表数据
INSERT INTO users (username,phone,email,address,created_at) VALUES ('张三','13812345678','zhangsan@example.com','北京市朝阳区','2025-05-07 20:31:34.510'),('李四','13987654321','lisi@example.com','上海市浦东新区','2025-05-07 20:31:34.510'),('王五','13698765432','wangwu@example.com','广州市天河区','2025-05-07 20:31:34.510'),('赵六','13312341234','zhaoliu@example.com','深证福田区','2025-05-09 13:46:45.036');INSERT INTO products (product_name,price,stock,status,created_at) VALUES ('智能手机',2999.00,100,'上架','2025-05-07 20:31:38.313'),('无线耳机',499.00,200,'上架','2025-05-07 20:31:38.313'),('智能手表',899.00,50,'上架','2025-05-07 20:31:38.313'),('笔记本电脑',7999.00,30,'下架','2025-05-07 20:31:38.313'),('蓝牙鼠标',59.00,1000,'上架','2025-05-09 13:48:00.413'),('智能音箱',199.00,150,'上架','2025-05-09 13:48:31.846');INSERT INTO orders (user_id,order_no,total_amount,status,order_time) VALUES (2,'ORDER20231001567',1398.00,'已发货','2025-05-07 20:32:03.184'),(1,'ORDER20231001123',3997.00,'已付款','2025-05-07 20:32:03.184'),(3,'ORDER20231001999',8998.00,'已取消','2025-05-07 20:32:03.184'),(4,'ORDER20250509213',558.00,'已付款','2025-05-09 13:51:30.838');INSERT INTO order_items (order_id,product_id,quantity,unit_price,total_price) VALUES (1,1,1,2999.00,2999.00),(1,2,2,499.00,998.00),(2,3,1,899.00,899.00),(2,2,1,499.00,499.00),(3,4,1,7999.00,7999.00),(3,3,1,899.00,899.00),(4,2,1,499.00,499.00),(4,5,1,59.00,59.00);

表结构上传知识库

将测试表结构.md文件上传知识库,使用默认分段设置

点击预览块查看,与预期分块结果一致,一个表对应一个chunk

指定Embedding模型,及rerank模型

TopK默认为3需要调大些,因为联表查询的结果数据不止来源于3个表,因为测试表只有4个,这个指定了4。

配置完点击保存并处理,待索引完成,就可以作为后续的知识库使用。

工作流配置

知识检索节点

知识检索的节点知识库指定上述的测试表结构.md

生成SQL节点

#prompt提示词【角色设定】您是一位资深数据库专家,擅长根据业务需求将自然语言精准转换为符合规范的SQL语句。您具有以下核心能力:1. 精通关系型数据库设计,尤其熟悉PostgreSQL语法2. 深入理解当前业务系统的表结构{{#context#}}3. 能准确识别业务需求中的隐藏条件4. 熟悉SQL性能优化和事务控制
【输入处理流程】1. 结构确认:先验证涉及的表是否存在,检查字段名是否准确2. 关联分析:确认多表关联时的连接条件是否正确3. 条件推导:将模糊的业务描述转化为精确的WHERE条件4. 异常处理:识别可能存在的逻辑矛盾或性能陷阱
【输出要求】输出sql中不要添加注释信息采用如下格式返回结果:[符合ANSI标准的SQL语句]
【示例】用户问题:"查询北京用户最近一个月购买过智能手机的订单"输出:-- 查询北京用户近一个月购买智能手机的订单SELECT o.order_no, u.username, oi.total_price, o.order_time FROM orders oJOIN users u ON o.user_id = u.idJOIN order_items oi ON o.id = oi.order_idJOIN products p ON oi.product_id = p.idWHERE u.address LIKE '北京市%'  AND p.product_name = '智能手机'  AND o.order_time >= CURRENT_DATE - INTERVAL '1 month'  AND o.status NOT IN ('已取消'ORDER BY o.order_time DESC;

代码执行节点

LLM输出的SQL语句会使用```sql\n和```包裹,代码执行节点主要作用是去除Markdown语法标记(sql及闭合符),确保生成纯净可执行的SQL语句并传递至下游节点。

SQL查询节点

可以写个数据库查询的自定义工具或者从插件市场下载数据库查询插件,这里用现成的数据库查询插件

配置好数据库环境变量


结果润色

这个节点基于大模型能力,结合数据查询结果与用户问题,智能分析并生成自然语言回复。

#prompt提示词你是一个问答机器人。你的任务是根据下述给定的已知信息回答用户问题,回答的内容尽量通俗易懂。确保你的回复完全依据下述已知信息。不要编造答案。如果下述已知信息不足以回答用户的问题,请直接回复"我无法回答您的问题"
已知信息:{{#1746692457950.text#}}
用户问:{{#sys.query#}}
请用中文字符串文本回答用户问题。

图表生成

这个节点基于大模型智能解析数据库返回的数据,自动匹配可视化图表类型,并生成符合ECharts规范的json字符串配置代码,用于展示节点中以交互式图表形式呈现数据。

#prompt提示词你是一个专业的ECharts图表生成器,严格遵循以下规则:
输入规则:1. 接收格式:{{#context#}} + {{#sys.query#}}2. 仅当输入包含可图表化的结构化数据时响应
处理规则:1. 自动识别数据类型(数值/分类/时间序列等)2. 智能匹配最佳图表类型(柱状/折线/饼图等)3. 默认启用响应式布局
输出规则:1. 必须为字符串```echarts拼接上json字符串格式的echarts内容2. 包含完整option配置3. 务必不要添加注释或说明的文本4. 无效输入返回空字符串

结果润色+图表生成最终生成的效果:

测试问题:

这个月,消费金额排名前3的客户是谁?他们买了哪些热销商品?消费金

各是多少?

这个问题需要联表查询4张测试表才能得出预期结果,尝试问了多次,大部分回答结果是对的,可能也是因为这里用了Gemini2.5Pro模型,生成的查询数据库的SQL质量比较好;测试过程中也遇到一些报错的情况,这块文末再说明遇到过哪些问题; 此外,由于图表生成节点prompt没有指定让大模型输出固定的图表类型,这里生成的图表有时候会有差异;

饼状图(用户消费总额)

柱状图(用户消费总额)

柱状图(用户消费总额)结合环形图(消费明细金额)

抽取了其中一个工作流中自动生成的SQL语句进行分析,发现其生成的SQL语句考虑的还挺全面的,相比之下,如果让我手动实现相同功能的sql可能还需要几次调测才能达到预期的结果,大模型生成的SQL语句如下:

with TopCustomers as (select	u.id as user_id, u.username, SUM(o.total_amount) as total_spent_this_monthfrom	users ujoin orders o on	u.id = o.user_idwhere	o.order_time >= date_trunc('month', CURRENT_DATE)and o.order_time < date_trunc('month', CURRENT_DATE) + interval '1 month'and o.status not in ('已取消', '待付款')group by	u.id, u.usernameorder by	total_spent_this_month desclimit 3 ),CustomerProductDetails as (select	tc.user_id, tc.username, tc.total_spent_this_month, p.product_name, 	SUM(oi.quantity) as total_quantity_bought, SUM(oi.total_price) as amount_spent_on_productfrom	TopCustomers tcjoin orders o on	tc.user_id = o.user_idjoin order_items oi on	o.id = oi.order_idjoin products p on	oi.product_id = p.idwhere	o.order_time >= date_trunc('month', CURRENT_DATE)and o.order_time < date_trunc('month', CURRENT_DATE) + interval '1 month'and o.status not in ('已取消', '待付款')group by	tc.user_id, tc.username, tc.total_spent_this_month, p.product_name )select	cpd.username,	cpd.total_spent_this_month,	cpd.product_name,	cpd.total_quantity_boughtfrom	CustomerProductDetails cpdorder by	cpd.total_spent_this_month desc,	cpd.username,	cpd.total_quantity_bought desc;

该SQL在数据库中的查询结果:

工作流执行异常情况说明

在测试过程中,主要遇到了以下几类错误情况:

  1. 调用数据库查询插件时出现报错,由于问题没有复现,没排查原因;
  2. 图表展示异常,主要原因包括生成的json字符串被添加了注释(尽管prompt中明确要求不要添加注释),以及其他语法错误,可能需要对prompt调优或使用更好的模型进行尝试;
  3. 在结果润色节点,尽管成功获取了上下文中数据库返回的正确数据,但因生成的别名列名未能与用户问题精准关联,导致回复中出现“无法获取前3用户的消费金额”的错误提示,这个问题,可能也需要对prompt进行调优;

总结

    经过此次实践,将自然语言需求转化为 SQL 查询并自动生成报告与图表的方案,展现出了一定的可行性,为简化数据处理流程开辟了新的路径。然而,在实际业务场景中,复杂多变的需求导致语义解析出现模糊性,生成 SQL 语句时也容易出现异常,同时不同场景下图表的适配存在较大差异,这些都对方案的准确性与稳定性提出了更高的挑战。但随着大模型能力的持续进化,其在理解复杂业务逻辑、生成精准 SQL 语句以及润色结果等方面的能力将不断提升,我相信这些问题都将得到有效解决。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询