Text2SQL研究-Chat2DB体验与剖析
文章目录
-
- 概要
- 业务数据库配置
- Chat2DB安装设置
- 原理剖析
- 小结
概要
近期笔者在做Text2SQL的研究,于是调研了下Chat2DB,基于车辆订单业务做了一些SQL生成验证,有了一点心得,和大家分享一下.:
业务数据库设置
基于车辆订单业务,模拟新建了以下四张表,并添加了一些测试数据
1. organization:组织表,包含组织id,组织名称,组织分类等3个字段;
3. vehicle:车辆信息表,包含组织id,车辆id,车牌号码,使用年限等字段;
4. refueling_order:车辆加油订单表,包含组织id,车辆id,车牌号码,加油时间,加油费用等字段
5. **driven_distance**:车辆行驶里程表,包含组织id,车辆id,车牌号码,年份,行驶里程等字段
Chat2DB安装设置
- docke安装Chat2DB服务,
//通过docker,安装运行最新版本的chat2db容器docker run --name=chat2db -ti -p 10824:10824 -v ~/.chat2db-docker:/root/.chat2db chat2db/chat2db:latest
- 安装完毕:打开链接登录系统,http://172.21.108.51:10824/login
- 配置数据库连接
- 配置Custom Ai,笔者设置体验了Chat2DB以及OpenAI
- 进入WorkSpace页面,连接配置好的业务数据库,并选择里面的的四张业务表(这一步非常重要,否则无法生成准确的SQL语句)
- 进入Dashboard页面,尝试生成SQL语句,并显示图表
原理剖析
从GIT上下载并剖析源码,最核心的Text-2-SQL生成代码部分:
- ChatController::completions:Controller入口,接受Web端请求,生成SQL,并通过WebSocket返回
/*** SQL转换模型** @param queryRequest* @param headers* @return* @throws IOException*/@GetMapping("/chat")@CrossOriginpublic SseEmitter completions(ChatQueryRequest queryRequest, @RequestHeader Map<String, String> headers)throws IOException {//默认30秒超时,设置为0L则永不超时SseEmitter sseEmitter = new SseEmitter(CHAT_TIMEOUT);String uid = headers.get("uid");if (StrUtil.isBlank(uid)) {throw new ParamBusinessException("uid");}//提示消息不得为空if (StringUtils.isBlank(queryRequest.getMessage())) {throw new ParamBusinessException("message");}return distributeAISql(queryRequest, sseEmitter, uid);}
- distributeAISql:根据请求语句,以及系统的Custom AI设置进行SQL生成
/*** distribute with different AI** @return*/public SseEmitter distributeAISql(ChatQueryRequest queryRequest, SseEmitter sseEmitter, String uid) throws IOException {ConfigService configService = ApplicationContextUtil.getBean(ConfigService.class);Config config = configService.find(RestAIClient.AI_SQL_SOURCE).getData();String aiSqlSource = AiSqlSourceEnum.CHAT2DBAI.getCode();if (Objects.nonNull(config)) {aiSqlSource = config.getContent();}AiSqlSourceEnum aiSqlSourceEnum = AiSqlSourceEnum.getByName(aiSqlSource);if (Objects.isNull(aiSqlSourceEnum)) {aiSqlSourceEnum = AiSqlSourceEnum.OPENAI;}uid = aiSqlSourceEnum.getCode() + uid;switch (Objects.requireNonNull(aiSqlSourceEnum)) {case OPENAI :return chatWithOpenAi(queryRequest, sseEmitter, uid);case CHAT2DBAI:return chatWithChat2dbAi(queryRequest, sseEmitter, uid);case RESTAI :case FASTCHATAI:return chatWithFastChatAi(queryRequest, sseEmitter, uid);case AZUREAI :return chatWithAzureAi(queryRequest, sseEmitter, uid);case CLAUDEAI:return chatWithClaudeAi(queryRequest, sseEmitter, uid);case WENXINAI:return chatWithWenxinAi(queryRequest, sseEmitter, uid);case BAICHUANAI:return chatWithBaichuanAi(queryRequest, sseEmitter, uid);case TONGYIQIANWENAI:return chatWithTongyiChatAi(queryRequest, sseEmitter, uid);case ZHIPUAI:return chatWithZhipuChatAi(queryRequest, sseEmitter, uid);}return chatWithOpenAi(queryRequest, sseEmitter, uid);}
- chatWithOpenAi:通过选择的业务表结构以及客户的问题生成prompt,来从大模型获取所需的SQL语句
/*** 使用OPENAI SQL接口** @param queryRequest* @param sseEmitter* @param uid* @return* @throws IOException*/private SseEmitter chatWithOpenAi(ChatQueryRequest queryRequest, SseEmitter sseEmitter, String uid)throws IOException {String prompt = buildPrompt(queryRequest);if (prompt.length() / TOKEN_CONVERT_CHAR_LENGTH > MAX_PROMPT_LENGTH) {log.error("提示语超出最大长度:{},输入长度:{}, 请重新输入", MAX_PROMPT_LENGTH,prompt.length() / TOKEN_CONVERT_CHAR_LENGTH);throw new ParamBusinessException();}List<Message> messages = new ArrayList<>();prompt = prompt.replaceAll("#", "");log.info(prompt);Message currentMessage = Message.builder().content(prompt).role(Message.Role.USER).build();messages.add(currentMessage);buildSseEmitter(sseEmitter, uid);OpenAIEventSourceListener openAIEventSourceListener = new OpenAIEventSourceListener(sseEmitter);OpenAIClient.getInstance().streamChatCompletion(messages, openAIEventSourceListener);LocalCache.CACHE.put(uid, JSONUtil.toJsonStr(messages), LocalCache.TIMEOUT);return sseEmitter;}
- 最后根据docker日志,可以发现chat2db 的mysql prompt组成,从这里可以发现真相其实并不复杂,整个Chat2DB可以说了除了通用的数据库方面的增删改查,最核心的部分其实就是根据表结构和用户问题生成prompt了
请根据以下table properties和SQL input将自然语言转换成SQL查询. MYSQL SQL tables, with their properties:["CREATE TABLE `driven_distance` (\n `id` bigint(20) NOT NULL AUTO_INCREMENT,\n `organization_id` bigint(20) DEFAULT NULL,\n `vehicle_id` bigint(20) DEFAULT NULL,\n `license_plate` varchar(255) DEFAULT NULL,\n 。。。"]SQL input: 2023年,每个季度的加油金额各是多少元?
小结
经过测试,通常的业务查询基本上都能准确生成,另外通过上述一路使用和分析,笔者发现Text2SQL的技术几大要点
- 业务简库:跟3D渲染一样,离线渲染用精模,实时渲染用简模。Text2SQL一定要基于业务库做一个“素描”精简库
- 自组Prompt:根据业务上下文所需的库表结构,拼接prompt
- 选择合法靠谱的大模型:ChatGPT4肯定是最好的,但在国内目前商业不合法,大家要根据自己业务进行尝试和选型
- 用户数据权限:通过拦截器,在prompt中加入当前用户ID,组织id等用户信息,从而巧妙实现用户数据权限等问题
相关文章:

Text2SQL研究-Chat2DB体验与剖析
文章目录 概要业务数据库配置Chat2DB安装设置原理剖析 小结 概要 近期笔者在做Text2SQL的研究,于是调研了下Chat2DB,基于车辆订单业务做了一些SQL生成验证,有了一点心得,和大家分享一下.: 业务数据库设置 基于车辆订…...
JavaScript相关(二)——闭包
了解闭包的前提必须得了解什么是作用域链。也就是(一)的内容。 参考: 浏览器工作原理与实践 破解前端面试:从闭包说起 闭包 闭包是一个可以访问外部作用域中变量的内部函数,因为内部函数引用了外部函数的变量&#…...
MySQL的DDL语言
DDL:Data Definition Language(数据定义语言) DDL语言用来定义数据库对象(数据库,表,字段) ps:MySQL中关键字不区分大小写,但是库名、表名等是区分大小写的 一、对数据库操作的DDL 1、查询相关语句&…...
<网络安全>《21 工业安全审计系统》
1 工业安全审计系统 工业审计系统,支持多种工控协议的深度解析,对工控网络中的异常流量进行实时监测和告警,详实记录一切网络通信行为,为工业控制网络安全事件调查提供依据;产品聚焦工业生产安全事件分析,…...

实例分割论文阅读之:《Mask Transfiner for High-Quality Instance Segmentation》
1.摘要 两阶段和基于查询的实例分割方法取得了显著的效果。然而,它们的分段掩模仍然非常粗糙。在本文中,我们提出了一种高质量和高效的实例分割Mask Transfiner。我们的Mask Transfiner不是在规则的密集张量上操作,而是将图像区域分解并表示…...
阿里 EasyExcel 表头国际化
实体类字段使用EasyExcel提供的注解ExcelProperty,value 值写成占位符形式 ,匹配 i18n 文件里面的编码。 如: /*** 仓库名称*/ ExcelProperty("{warehouse.record.warehouseName}") private String warehouseName;占位符解析器 A…...

跨境电商新风潮:充分发挥海外云手机的威力
在互联网行业迅速发展的大环境下,跨境电商、海外社交媒体营销以及游戏产业等重要领域都越来越需要借助海外云手机的协助。 特别是在蓬勃发展的跨境电商领域,像亚马逊、速卖通、eBay等平台,结合社交电商营销和短视频内容成为最有效的流量来源。…...

Kubernetes实战(二十七)-HPA实战
1 HPA简介 HPA 全称是 Horizontal Pod Autoscaler,用于POD 水平自动伸缩, HPA 可以 基于 POD CPU 利用率对 deployment 中的 pod 数量进行自动扩缩容(除了 CPU 也可以基于自定义的指标进行自动扩缩容)。pod 自动缩放不适用于无法…...

IDEA 配置以及一些技巧
1. IDEA设置 1.1 设置主题 1.2 设置字体和字体大小 1.3 编辑区的字体用ctrl鼠标滚轮可以控制大小 1.4 自动导包和优化多余的包 1.5 设置编码方式 1.6 配置 maven 1.7 设置方法形参参数提示 1.8 设置控制台的字体和大小 注意:设置控制台字体和大小后需要重启IDEA才会…...

Android 11 访问 Android/data/或者getExternalCacheDir() 非root方式
前言: 需求要求安装三方应用ExternalCacheDir()下载下来的apk文件。 getExternalCacheDir() : /storage/emulated/0/Android/data/com../cache/ 获取访问权限 如果手机安卓版本为Android10的时候,可以在AndroidManifest.xml中添加下列代码 android:requestLegacyExt…...

Eclipse安装配置、卸载教程(Windows版)
Eclipse是一个开放源代码的集成开发环境(IDE),最初由IBM公司开发,现在由Eclipse基金会负责维护。它是一个跨平台的工具,可以用于开发多种编程语言,如Java、C/C、Python、PHP、Rust等。 Eclipse提供了一个可…...

正点原子--STM32基本定时器学习笔记(2)
目录 1. 相关寄存器介绍 1.1 控制寄存器 1(TIMx_CR1)编辑 1.2 DMA/中断使能寄存器(TIMx_DIER) 1.3 状态寄存器(TIMx_SR) 1.4 计数器(TIMx_CNT) 1.5 预分频器(TIMx_PSC) 1.6 自动重装载寄存器(TIMx_ARR) 2. 工程建立 3. 导入tim.c文件 4. 相关HAL库函数介绍 4.1 H…...
学习笔记:正则表达式
正则表达式是文本处理方面功能最强大的工具之一。正则表达式语言用来构造正则表达式,最终构造出来的字符串就称为正则表达式,正则表达式用来完成搜索和替换操作。 本文参考《正则表达式必知必会(修订版)》《Learning Regular Exp…...

03-抓包_封包_协议_APP_小程序_PC应用_WEB应用
抓包_封包_协议_APP_小程序_PC应用_WEB应用 一、参考工具二、演示案例:2.1、WEB应用站点操作数据抓包-浏览器审查查看元素网络监听2.2、APP&小程序&PC抓包HTTP/S数据-Charles&Fiddler&Burpsuite2.3、程序进程&网络接口&其他协议抓包-WireSh…...

C语言笔试题之实现C库函数 strstr()(设置标志位)
实例要求: 1、请你实现C库函数strstr()(stdio.h & string.h),请在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始);2、函数声明:int strStr(char* h…...
什么是IDE,新手用哪个IDE比较好
什么是IDE IDE(Integrated Development Environment,集成开发环境)是一种为程序员提供软件开发所需的代码编辑、构建、调试等功能于一体的应用程序。IDE通常包含了代码编辑器、编译器、调试器和图形用户界面等工具,这些工…...

Flask 入门6:模板继承
1. 一个网站中,大部分网页的模块是重复的,比如顶部的导航栏,底部的备案信息。如果在每个页面中都重复的去写这些代码,会让项目变得臃肿,提高后期的维护成本。比较好的做法是,通过模板继承,把一…...

欢迎来到操作系统的世界
🌞欢迎来到操作系统的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🙏作者水平很有限,如果发现错误ÿ…...

寒假作业-day5
1>现有无序序列数组为23,24,12,5,33,5347,请使用以下排序实现编程 函数1:请使用冒泡排序实现升序排序 函数2:请使用简单选择排序实现升序排序 函数3:请使用直接插入排序实现升序排序 函数4:请使用插入排序实现升序排序 代码: #include<stdio.h&g…...

互联网加竞赛 基于深度学的图像修复 图像补全
1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学的图像修复 图像补全 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-se…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...