Text2SQL研究-Chat2DB体验与剖析

news2025/1/16 6:04:26

文章目录

    • 概要
    • 业务数据库配置
    • Chat2DB安装设置
    • 原理剖析 
    • 小结

概要

近期笔者在做Text2SQL的研究,于是调研了下Chat2DB,基于车辆订单业务做了一些SQL生成验证,有了一点心得,和大家分享一下.:

业务数据库设置

基于车辆订单业务,模拟新建了以下四张表,并添加了一些测试数据
 1. organization:组织表,包含组织id,组织名称,组织分类等3个字段;
 3. vehicle:车辆信息表,包含组织id,车辆id,车牌号码,使用年限等字段;
 4. refueling_order:车辆加油订单表,包含组织id,车辆id,车牌号码,加油时间,加油费用等字段
 5. **driven_distance**:车辆行驶里程表,包含组织id,车辆id,车牌号码,年份,行驶里程等字段

Chat2DB安装设置

  1. docke安装Chat2DB服务,
    //通过docker,安装运行最新版本的chat2db容器
      docker run --name=chat2db -ti -p 10824:10824 -v ~/.chat2db-docker:/root/.chat2db  chat2db/chat2db:latest
  2. 安装完毕:打开链接登录系统,http://172.21.108.51:10824/login
  3. 配置数据库连接
  4. 配置Custom Ai,笔者设置体验了Chat2DB以及OpenAI
  5. 进入WorkSpace页面,连接配置好的业务数据库,并选择里面的的四张业务表(这一步非常重要,否则无法生成准确的SQL语句)
  6. 进入Dashboard页面,尝试生成SQL语句,并显示图表

原理剖析

从GIT上下载并剖析源码,最核心的Text-2-SQL生成代码部分:

  1. ChatController::completions:Controller入口,接受Web端请求,生成SQL,并通过WebSocket返回
    /**
         * SQL转换模型
         *
         * @param queryRequest
         * @param headers
         * @return
         * @throws IOException
         */
        @GetMapping("/chat")
        @CrossOrigin
        public 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);
        }
    
    ​
  2. 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);
        }
  3. 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;
        }
  4. 最后根据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的技术几大要点

  1. 业务简库:跟3D渲染一样,离线渲染用精模,实时渲染用简模。Text2SQL一定要基于业务库做一个“素描”精简库 
  2. 自组Prompt:根据业务上下文所需的库表结构,拼接prompt
  3. 选择合法靠谱的大模型:ChatGPT4肯定是最好的,但在国内目前商业不合法,大家要根据自己业务进行尝试和选型
  4. 用户数据权限:通过拦截器,在prompt中加入当前用户ID,组织id等用户信息,从而巧妙实现用户数据权限等问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1439488.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【stomp实战】websocket原理解析与简单使用

一、WebSocket 原理 WebSocket是HTML5提供的一种浏览器与服务器进行全双工通讯的网络技术&#xff0c;属于应用层协议。它基于TCP传输协议&#xff0c;并复用HTTP的握手通道。浏览器和服务器只需要完成一次握手&#xff0c;两者之间就直接可以创建持久性的连接&#xff0c; 并…

【DDD】学习笔记-领域模型驱动设计

领域模型驱动设计自然是以提炼和转换业务需求中的领域知识为设计的起点。在提炼领域知识时&#xff0c;没有数据库的概念&#xff0c;亦没有服务的概念&#xff0c;一切围绕着业务需求而来。尤其是领域建模的分析阶段&#xff0c;应该只关注问题域&#xff0c;模型表达的是业务…

自用metadata.pegasus.txt bat生成脚本

下面代码保存为一个bat文件,放在存放rom的文件夹下运行 echo off setlocal enabledelayedexpansion :menu cls echo Please select a game ROM type: echo 1. FC echo 2. PSP echo. set /p choice"Enter your choice (1 or 2): " if "%choice%…

林浩然与杨凌芸的Java奇遇记:内部类的四重奏

林浩然与杨凌芸的Java奇遇记&#xff1a;内部类的四重奏 Lin Haoran and Yang Lingyun’s Java Adventure: A Quartet of Inner Classes 在一个充满代码香气的午后&#xff0c;程序员界的才子林浩然与机智灵动的女程序员杨凌芸&#xff0c;在Java的世界里展开了一场别开生面的“…

FPGA_vga显示

一 VGA 1.1 VGA VGA是视频图像阵列&#xff0c;是一种使用模拟信号进行视频传输的标准协议。 1.2 VGA接引脚定义 VGA分公母两种&#xff0c;RGB显示标准。 1.3 VGA显示器 VGA显示器采用图像扫描的方式进行图像显示&#xff0c;将构成图像的像素点&#xff0c;在行同步信号…

2024年阿里云服务器活动价格表

2024年2月阿里云服务器租用价格表更新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核…

Python 深入理解 os 和 sys 模块

Python 深入理解 os 和 sys 模块 OS 介绍代码智能连接&#xff08;拼接&#xff09;路径创建目录展示&#xff08;列出目录&#xff09;删除文件重命名文件或目录 sys 介绍代码命令行参数处理 (sys.argv)标准输入输出重定向 (sys.stdin, sys.stdout, sys.stderr)&#xff1a;解…

备战蓝桥杯---搜索(进阶3)

看一道比较难又有趣的题&#xff1a; 下面是分析&#xff1a; 我们不妨把属性值看成点&#xff0c;一个装备可以看成一条边&#xff08;只能选一个端点&#xff09;不存在有装备属性值的当成一个点&#xff0c;于是我们便形成了树或图&#xff0c;如果是树的话&#xff0c;有一…

请立即收藏!春节必备AI工具盘点:一键拜年短信、海报!AI全家福!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

Maven之安装自定义jar到本地Maven仓库中

Maven之安装自定义jar到本地Maven仓库中 文章目录 Maven之安装自定义jar到本地Maven仓库中1. 命令行窗口安装方式1. 常用参数说明2. 安装实例 2. IDEA中安装方式3. 使用 1. 命令行窗口安装方式 安装指定文件到本地仓库命令&#xff1a;mvn install:install-file; 在windows的cm…

iOS 需求 多语言(国际化)App开发 源码

一直觉得自己写的不是技术&#xff0c;而是情怀&#xff0c;一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的&#xff0c;希望我的这条路能让你们少走弯路&#xff0c;希望我能帮你们抹去知识的蒙尘&#xff0c;希望我能帮你们理清知识的脉络&#xff0…

正点原子--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…

购物车商品数量为0判断是否删除

当编辑商品的数量为1&#xff0c;再减的话&#xff0c;我们搞个模态提示&#xff0c;让用户决定是否要删除这个商品&#xff1f; //商品数量的编辑功能handleItemNumEdit(e){const {operation,id}e.currentTarget.dataset;console.log(operation,id);let {cart}this.data;let …

13. UE5 RPG限制Attribute的值的范围以及生成结构体

前面几章&#xff0c;我们实现了通过GameplayEffect对Attribute值的修改&#xff0c;比如血量和蓝量&#xff0c;我们都是有一个最大血量和最大蓝量去限制它的最大值&#xff0c;而且血量和蓝量最小值不会小于零。之前我们是没有实现相关限制的&#xff0c;接下来&#xff0c;我…

3.1-媒资管理之需求分析+搭建Nacos

文章目录 媒资管理模块1 模块需求分析1.1 模块介绍1.2 业务流程1.2.1 上传图片1.2.2 上传视频1.2.3 处理视频1.2.4 审核媒资 2.2 搭建Nacos2.2.1 服务发现中心2.2.2 配置中心2.2.2.1 配置三要素2.2.2.3配置content-api 2.2.3 公用配置2.2.4 配置优先级2.2.5 导入配置文件2.2.6 …

三、设计模式相关理论总结

一、面向对象编程 1.1 概述 简称Object Oriented Program(OOP)&#xff0c;指以类或对象作为基础组织单元&#xff0c;遵循封装、继承、多态以及抽象等特性&#xff0c;进行编程。其中面向对象不一定遵循封装、继承、封装和多态等特性&#xff0c;只是前人总结的套路规范&…

前端JavaScript篇之对闭包的理解

目录 对闭包的理解用途循环中使用闭包解决 var 定义函数的问题 对闭包的理解 闭包是指一个函数能够访问并操作其词法作用域&#xff08;定义时所在的作用域&#xff09;之外的变量的能力。它可以通过在一个函数内部创建另一个函数来实现。内部函数可以访问外部函数的局部变量、…

Python算法题集_两数相加

Python算法题集_两数相加 题2&#xff1a;两数相加1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【直接相加】2) 改进版一【对齐链表】3) 改进版二【数组求和】 4. 最优算法 本文为Python算法题集之一的代码示例 题2&#xff1a;两数相加 1.…

相机图像质量研究(10)常见问题总结:光学结构对成像的影响--光圈

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

Quicker读取浏览器的书签(包括firefox火狐)

从edge换了火狐&#xff0c;但是quicker不能读取本地的bookmarks文件了&#xff0c;就研究了一下。 方法1&#xff1a;读取本地Bookmarks文件&#xff08;仅谷歌内核浏览器&#xff09; 谷歌内核的浏览器本地会有Bookmarks文件&#xff0c;放了所有的书签数据&#xff0c;直接…