# RAGFlow 搭建数据查询 AI 应用
# 简介
在大数据飞速发展的时代,现在企业基本都会向 AI 靠近,传统的系统和用户交互都是让用户在系统上自己操作,要查询什么内容通过对话的方式就能获取到结果,而不需要点这个菜单又去点哪个菜单,还要选条件在点查询,本篇文章就实现,怎么将自然语言转成 SQl 在去查询实际的数据。之前有介绍使用 dify 来实现,但是 dify 的知识库检索并不理想,所以我们用 RAGFlow
# 开始
首先我们需要 RAGFlow 环境,这里安装就不再赘述了。
我们需要准备一个专门用于生成 Text2SQL 提示词的知识库,该知识库包含各类自然语言到 SQL 的样例数据。当用户向 RAGFlow 发起一个 Text2SQL 提问时,先到该知识库中进行搜索,找到相似结果后拼接成生成 SQL 的提示词,再把该提示词发给大模型,让大模型生成最终的 SQL。该 SQL 可以直接用来查询数据库,如果返回结果出现错误,证明产生的 SQL 不对,那么需要继续调用大模型让它产生一个正确的 SQL 直到错误次数超过上限。
RAGFlow 提供了对应的 agent 例子, 下面开始具体步骤
# 知识库
需要将我们的业务 表结构 、 详细的字段说明 还有一些 sql的示例 上传到知识库,当用户提问提就会检索出来,让大模型理解在给出进行生成 sql 语句,如图创建 三个 知识库:

三资 Description:
解析的时候,分段标识符为 "#"
### 地区表(dist) | |
地区表用于存储地区的信息。以下是该表中每个字段的含义: | |
- `id`: 这是一个整数类型的自增字段。 | |
- `distno`: 字符串类型,用于存储地区的编号。地区编号,1位长度表示省级,2位长度表示市级,4位长度表示区县级,6位长度表示镇街级,9位长度表示村级。 | |
- `distname`: 字符串类型,用于存储地区的名称。 | |
- `parentDistNo`: 字符串类型,用于存储上级地区编号。可以和本身关联,关联上一级的地区。 | |
- `parentDistName`: 字符串类型,用于存储上级地区名称。 | |
### 资产表(ht_land) | |
资产表用于存储土地资产的信息。以下是该表中每个字段的含义: | |
- `id`: 这是一个整数类型的自增字段。 | |
- `title`: 字符串类型,用于存储资产的标题。 | |
- `distNo`: 字符串类型,用于存储地区编号,这个字段可以和地区表关联,以实现是哪个地区的资产。 | |
- `distName`: 字符串类型,用于存储地区的名称。 | |
- `landNo`: 字符串类型,用于存储资产的编号。 | |
- `landName`: 字符串类型,用于存储资产的名称。 | |
- `area`: 小数类型,用于存储资产所占面积。 | |
- `unit`: 字符串类型,用于存储资产的面积单位,可能的值有:亩、平方米等。 | |
这些表的设计是相互关联的,例如,资产表中的`distNo`字段将与地区关联起来,说明是哪个地区的资产。 |
三资 DDL
解析的时候,分段标识符为 ";"
CREATE TABLE `dist` ( | |
`id` INT NOT NULL AUTO_INCREMENT, | |
`distno` VARCHAR(32) NOT NULL, | |
`distname` VARCHAR(255) NOT NULL, | |
`parentDistNo` VARCHAR(32), | |
`parentDistName` VARCHAR(255) | |
PRIMARY KEY (`id`), | |
UNIQUE KEY `uk_distno` (`distno`) | |
); | |
CREATE TABLE `ht_land` ( | |
`id` INT NOT NULL AUTO_INCREMENT, | |
`title` VARCHAR(32), | |
`distNo` VARCHAR(32) NOT NULL, | |
`distName` VARCHAR(32), | |
`landNo` VARCHAR(255) NOT NULL, | |
`landName` VARCHAR(255), | |
`area` decimal(18,4), | |
`unit` VARCHAR(255) | |
PRIMARY KEY (`id`), | |
UNIQUE KEY `uk_landNo` (`landNo`), | |
FOREIGN KEY (`distno`) REFERENCES `dist` (`distno`) | |
); |
sql 示列:
解析方式选
Q&A
我有一个大表格,包含两个键(id,date),我希望每天的账户id都从1开始重新计数。\tSELECT dense_rank() OVER (PARTITION BY date\n ORDER BY id) as new_id,\n date\nFROM your_table;
测试检索效果如图:

# 工作流
我们可以直接在添加的时候选择对应的模板 Text To SQL
大致流程:开始 -> 知识检索 -> 大模型解析返回 sql -> 回复用户
流程图如下:

这里生成 SQL 的提示词是:
##用户提供一个问题,您提供SQL。您将仅以SQL代码回应,不做任何解释。 ##硬性要求 1.严格使用检索到的表字段 2.确保SQLSERVER语法兼容 3.仅输出最终结果sql语句的txt文本,不要加任何信息 4.禁止中间过程输出 5.返回纯SQL文本内容, 不要代码块 6.表名称要去掉特殊符号 ##关键步骤: 1、对用户输入的内容进行识别和判断,如果内容涉及政治、时事、社会问题以及违背道德和法律法规的情形,一律输出:”您提出的问题超出我应当回答的范围,请询问与公司业务相关的问题,否则我无法作出回答“ 2、去除SQL语句中多余的注释、换行符等无用信息,输出一个纯净的、可直接执行的SQL语句 3、用户提到的“村集体”就是地区,如果没有说哪个村集体,那么就是所有地区 ##编写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[结果列名] ##您可以使用以下DDL语句作为可能可用表的参考。使用对过去问题的回答来指导您:{Retrieval:TrueCornersJam}。 ##您可以使用以下文档作为可能可用表的参考。使用对过去问题的回答来指导您:{Retrieval:LazyChefsWatch}。 ##您可以使用以下SQL语句作为可能可用表的参考。使用对过去问题的回答来指导您:{Retrieval:EasyDryersShop}。
# dify 引入 RAGFlow 外部知识库
由于 RAGFlow 的工作流不是很好用,所以我们可以使用 dify 来外部调用 RagFlow 的知识库,具体操作如下:
首先开启
RAGFlow的 api![]()
在
dify中知识库中添加外部知识库![]()
API Key 填写第一步申请到的
添加到 dify 中
![]()
![ragflow-1-7]()



