# Dify 搭建数据查询 AI 应用
# 简介
在大数据飞速发展的时代,现在企业基本都会向 AI 靠近,传统的系统和用户交互都是让用户在系统上自己操作,要查询什么内容通过对话的方式就能获取到结果,而不需要点这个菜单又去点哪个菜单,还要选条件在点查询,本篇文章就实现,怎么将自然语言转成 SQl 在去查询实际的数据。dify 官网
# 开始
首先我们需要 dify 环境,这里安装就不再赘述了,下面开始
# 知识库
需要将我们的业务 表结构 、 详细的字段说明 还有一些 sql的示例 上传到知识库,当用户提问提就会检索出来,让大模型理解在给出进行生成 sql 语句,如图创建两个知识库:


数据结构内容:
表结构描述: | |
表名称: `ht_land` 资产表 | |
字段列表: | |
`title`,资产标题,字符串类型 | |
`distNo`,地区编号,字符串类型。这个字段可以和地区表关联,以实现是哪个地区的资产。 | |
`distName`,地区名称,字符串类型 | |
`landNo`,资产编号,字符串类型 | |
`landName`,资产名称,字符串类型 | |
`area`,资产面积,小数类型 | |
`unit`,资产面积单位,字符串类型 | |
表结构描述: | |
表名称: `dist` 地区表或者是村集体表 | |
字段列表: | |
`id`,主键,整型 | |
`distno`,地区编号,字符串类型。注意地区编号,1位长度表示省级,2位长度表示市级,4位长度表示区县级,6位长度表示镇街级,9位长度表示村级, | |
`distname`,地区名称,字符串类型 | |
`parentDistNo`,上级地区编号,字符串类型。可以和本身关联,关联上一级的地区。 | |
`parentDistName`,上级地区名称,字符串类型 | |
表结构描述: | |
表名称: `Rep_01` 收益及收益分配表 | |
字段列表: | |
`id`,主键,整型 | |
`zth`,地区编号,字符串类型。这个字段可以和地区表关联,以实现是哪个地区的资产。 | |
`YEARS`,年份,字符串类型 | |
`MONTHS`,月份,字符串类型 | |
`C1`,项目名称,字符串类型。比如有“一、经营收入”, “二、经营收益” 等项目 | |
`C2`,行次,字符串类型。相当于排序号 | |
`C3`,本月数,小数类型。单位是元,也叫本月发生数 | |
`C1`,本年数,小数类型。单位是元,也叫本年发生数 | |
表结构描述: | |
表名称: `proj` 交易表 | |
字段列表: | |
`id`,主键,整型 | |
`title`,交易项目名称,字符串类型 | |
`prj_no`,交易编号,字符串类型 | |
`distno`,地区编号,字符串类型。这个字段可以和地区表关联,以实现是哪个地区的资产。 | |
`distname`,地区名称,字符串类型。 | |
`landno`,资产编号,字符串类型。这个字段可以和资产表关联,以实现是哪个资产的交易情况。 | |
`landname`,资产名称,字符串类型。单位是元 | |
`jyjffs`,交易方式,字符串类型。列如:电子暗投,电子竞投,公开暗投,公开明投,协商谈判,续约,综合评审 | |
`totalAmount`,交易金额,小数类型。单位是元 | |
这些表的设计是相互关联的,例如,资产表中的`distNo`字段将地区表或者是村集体表表中的特定地区关联起来。 |
sql 示列:
查询的资产?, select * from ht_land where distno like (select distno from dist where distname like '%白云区%') + '%';
村集体总资产数, select count(*) from ht_land;
村集体交易总额, select sum(totalAmount) from proj;
村集体总收入, select sum(*) from zcjy_hpq..Rep_01 where c1 like '%六、年末未分配收益%';
村集体2024年1月份总收入, select sum(*) from zcjy_hpq..Rep_01 where years = 2024 and months = 1 and c1 like '%六、年末未分配收益%';
测试检索效果如图,可以看的出来正确的检索出来了:

# 工作流
知识库创建好了,也能看到结合大模型能够实现生成 sql 语句,接下来我们开始创建工作流,从生成 sql 到查询到返回结果
大致流程:开始 -> 知识检索 -> 大模型解析返回 sql -> 问题分类(对业务不相关问题的处理) -> 数据库查询 -> json 解析获取数据 -> 大模型结合问题和答案回答 -> 回复用户
流程图如下:

新建一个
工作流添加
知识库节点,添加好数据结构描述,sql示例知识库添加大模型解析知识库内容生成 sql,为了更好的生成对应业务的 sql,需要添加提示词(可以根据自己的要求更改):
# 角色 你是一个SQL专家或者数据库分析师, 根据检索到{{#context#}}以及用户输入的{{#sys.query#}}内容,生成对应的查询sql,sql语句必须经过严格的校验: # 硬性要求 1.严格使用检索到的表字段 2.确保SQLSERVER语法兼容 3.仅输出最终结果sql语句的txt文本,不要加任何信息 4.禁止中间过程输出 5.返回纯SQL文本内容, 不要代码块 6.表名称要去掉特殊符号 #关键步骤: 1、对用户输入的内容进行识别和判断,如果内容涉及政治、时事、社会问题以及违背道德和法律法规的情形,一律输出:”您提出的问题超出我应当回答的范围,请询问与公司业务相关的问题,否则我无法作出回答“ 2、根据用户输入的内容和上下文信息,形成内容分类,根据内容分类按照以下规则从知识库 “黄埔数据结构描述” 中检索数据表结构信息: -内容分类与资产相关,则检索“资产信息” -内容分类与财务相关,则检索“财务信息” -内容分类与地区相关,则检索“地区信息” -内容分类与交易相关,则检索“交易信息” 注意:务必严格按照上述分类获得对应的检索关键词,不得生成新的检索关键词。如果你认为用户的提问无法匹配到合适的分类,请输出提示:为确保查询获得准确信息,请再把你的需求描述细致一些 3、根据用户输入的内容和上下文信息,形成一个符合用户意图的完整问题,以此作为输入在知识库“黄埔sql示例”中检索SQL语句参考示例 4、基于对上下文和对用户提问的理解,按照检索到的数据表结构信息,以及SQL参考示例,编写SQL查询语句。注意,若内容分类与参考示例中的分类不符时,则忽略这个示例。另外,不是所有情况下都有示例参考,没有示例时请按照自己的理解和掌握的知识编写SQL语句 5、去除SQL语句中多余的注释、换行符等无用信息,输出一个纯净的、可直接执行的SQL语句 6、如果用户选择开场白的选项直接从知识库“黄埔sql示例”中检索SQL语句 7、用户提到的“村集体”就是地区,如果没有说哪个村集体,那么就是所有地区 #编写SQL时的注意事项: 1.务必根据上下文提供的数据表结构描述来编写SQL语句,确保仅使用数据表结构描述中提到的表名和字段名,并参考对字段的解 2.确保SQL兼容SQL Server 2014 3.只用简体中文 4.只输出一个完整SQL语句,无注释,确保可直接执行并获得预期的结果 5.对于字符串和长文本类型的字段,除非用户有特别说明,否则都用LKE操作,而不是等于操作,例如:WHERE distno LIKEN'%关键词%',而不是WHERE distno='关键词' 6.除法处理:参考以下模板以避免错误: CASE WHEN 「除数] = 0 THEN 0 ELSE CAST([被除数] AS FLOAT)/[除数] END AS[结果列名] 7.当用户询问涉及地区层级的查询时(如“查询[XX地区]下所有资产”),按以下逻辑生成SQL: 定位目标地区: 从地区表查询用户输入名称对应的distno(确保名称完全匹配,如“白云”而非“白云区”)。 SELECT distno FROM 地区表 WHERE distname = '用户输入名称'; 获取所有子地区编号: 前缀匹配):若地区编号为层级结构(如0111的下级为011101),用LIKE匹配前缀: SELECT distno FROM 地区表 WHERE distno LIKE (SELECT distno || '%' FROM 地区表 WHERE distname = '用户输入名称'); 关联业务表查询: 将子地区编号与业务表(如资产信息)关联,返回结果。 SELECT b.* FROM 业务表 b JOIN (上述子地区查询) s ON b.distno = s.distno; 8.适用场景: 生成查询SQL时需遵循上述规则 9.输出规范: 纯SQL文本无附加说明 10.技术限制: 不支持图像处理类的请求 11.返回纯SQL文本内容代码执行器这里加这个主要是对 sql 进行加密传输,其实也可以不加问题分类器主要是对用户提问的问题进行分类,如果是不相关的问题,则做其他处理,如图:![]()
http 请求节点这一步主要是传入sql调 api 接口进行数据查询json 解析节点这一步主要是对查询出来的数据进行解析,获取原始的数据添加大模型节点这里的节点是为了对用户的问题,和结果做回答,这里可以用私有的模型,保证数据的隐私安全。添加一些提示词让大模型更自然的回答如下:
通过{{#context#}}的结果内容回答用户提问的{{#sys.query#}}的问题 注意事项: #数据呈现、解读和分析要求: 1.所有数据已符合用户问题中的条件(如地区名称、日期范围) 2.直接使用提供的数据分析,不质疑数据是否符合条件 3.不需再次筛选或确认数据类别/时间范围 4.数据为[]或空时,回复"没有查询到相关数据",不得编造数据 5.列出详细数据,优先以表格方式列出数据,如果数据超过10时,除非用户问题中包含明确要求列出全部数据的情形外,你只需要随机列出5条有代表性的的记录,否则需要列出全部记录 6.当有记录被省略时,必须作出说明 7.对数据进行概览和总结,必须包括原始数据的总记录数 8.识别趋势、异常,并提供分析和建议 #其他注意事项 1、严格按照上下文内容回答直接返回最后直接返回
# 推荐数据集
可以去 数据集网站 上获取一些其他人预定好的 sql 例子或者其他数据
# 自定义工具
dify 是一个很强大的工具,我们可以自己定义工具,比如自己定义一个 查询天气的ai助手 ,或者 搜索引擎 ,在或者 图表展示 等 助手,然后把我的工具发布出去,供其他程序调用
# 扩展
dify 的知识库系统并不是很强大,如果我们做业务复杂,生成那种多表关联的 sql 语句,那么 dify 就显的不是那么的好了,所以我们需要专门的 自然语言转SQL 的工具来实现,下面推荐两种
- RAGFlow 可以看我其他文章
如何使用RAGFlow并接入到Dify知识库中 - VannaAI
