利用ChatGLM3构建Prompt实现Text2SQL

之前使用ChatGLM3的自定义工具实现了查询MySQL数据库,但感觉功能还是比较受限。
https://blog.csdn.net/weixin_44455388/article/details/135270879?spm=1001.2014.3001.5501

使用ChatGLM3实现Text2SQL

  • 前言
  • Text2SQL的构建
      • 第一阶段:SQL脚本构建
        • (1)构建数据信息表的 schema,利用 LLM 生成 embedding
        • (2)prompt 提示词构建
      • 第二阶段:查询数据库,提供数据分析
  • 优化
  • 参考

前言

将自然语言文本(Text)转换成结构化查询语言 SQL,帮助用户快速生成想要查询的 SQL 语句;或者是用户输入一段话,然后系统完成一系列自动化查询和报表展示的操作,过自然语言描述完成复杂数据库的查询工作,得到想要的结果。

Text2SQL的构建

我们在 Text2SQL 上面的应用主要包括两个阶段,第一阶段是利用 LLM 理解你的请求,通过请求去生成结构化的 SQL;下一个阶段是在生成的 SQL 上自动化的查询数据库,返回结果,然后利用 LLM 对结果生成总结,提供分析。

第一阶段:SQL脚本构建

利用 LLM大模型理解文本信息,生成 SQL。因为考虑到数据的安全性,我们考虑使用ChatGLM生成SQL语句,从测试结果看,ChatGLM和GPT 对比,还是有比较大的差距,所以无法直接使用。

(1)构建数据信息表的 schema,利用 LLM 生成 embedding

这里我们根据用户描述的 text,让预训练的 chatglm2-6b 生成 embedding,通过 embedding 检索的方式,选出 top1 数据表,这个过程属于先验过滤阶段。
数据表的 schema 设计非常重要,需要描述清楚这个表它的主体信息以及表中重要字段和字段含义。

以下是我们设计的schema:
–tableName表示表名
–info表示该表的描述信息
–fields表示表字段信息,包括英文字段名、中文字段名和字段类型

[{"tableName":"prompt_history","info":"问答历史会话记录表,包括会话编号id、会用编号id、会话历史记录、会话时间。","fields":{"session_id":"会话编号,String","user_id":"用户编号,String","history":"会话历史,String","create_time":"会话时间,datetime"}},{"tableName":"common_prompt","info":"常用prompt提示词表,包括提示词id、提示词标题、提示词内容。","fields":{"id":"提示词id,int","title":"提示词标题,String","content":"提示词内容,String"}}
]

开发代码,将以上表信息进行向量化,存储到向量数据库:

public void addTable2Milvus(MultipartFile file) {List<String> sqls = new ArrayList<>();StringBuilder sb=new StringBuilder();try (InputStream inputStream = file.getInputStream()) {byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {sb.append(new String(buffer));}JSONArray jsonArray = JSONArray.parseArray(sb.toString());for (int i = 0;i<jsonArray.size();i++){String string = jsonArray.getString(i);sqls.add(string);}List<Integer> contentWordCount = new ArrayList<>();List<List<Float>> contentVector = new ArrayList<>();for(String str : sqls){contentWordCount.add(str.length());}contentVector = embeddingModel.doEmbedding(sqls);List<InsertParam.Field> fields = new ArrayList<>();fields.add(new InsertParam.Field("content", sqls));fields.add(new InsertParam.Field("content_word_count", contentWordCount));fields.add(new InsertParam.Field("content_vector", contentVector));InsertParam insertParam = InsertParam.newBuilder().withCollectionName("sqls").withFields(fields).build();//插入数据milvusClient.insert(insertParam);log.info(file.getOriginalFilename()+" -> 向量化结束...");} catch (IOException e) {e.printStackTrace();}
}
(2)prompt 提示词构建

我们需要将解析数据表中的信息,加入到 prompt 中,以此来构建完成的 prompt,让 LLM 去理解你的真实意图,生成标准的 SQL。

①开头prompt定义:

你是一个文本转SQL的生成器,你的主要目标是尽可能的协助用户,将输入的文本转化为正确的SQL语句。
上下文开始
表名和表字段来自以下表:

②查询向量数据库

public String buildQuerySql(String prompt) {String finalPrompt = null;//调用自定义的python服务List<Float> vector = embeddingModel.doEmbedding(prompt);List<PDFData> searchResult = search(Arrays.asList(vector));StringBuilder builder = new StringBuilder();for(PDFData data:searchResult){builder.append(data.getContent()).append("\n");}//处理需要请求的信息String msg = prefix_prompt+"%s。%s";finalPrompt = String.format(msg,builder, prompt);return finalPrompt;
}/*** 查询向量数据库* @param search_vectors* @return*/
private List<PDFData> search(List<List<Float>> search_vectors){milvusClient.loadCollection(LoadCollectionParam.newBuilder().withCollectionName("sqls").build());final Integer SEARCH_K = 4;final String SEARCH_PARAM = "{\"nprobe\":10}";List<String> ids = Arrays.asList("id");List<String> contents = Arrays.asList("content");List<String> contentWordCounts = Arrays.asList("content_word_count");SearchParam searchParam = SearchParam.newBuilder().withCollectionName("sqls").withConsistencyLevel(ConsistencyLevelEnum.STRONG).withOutFields(ids).withOutFields(contents).withOutFields(contentWordCounts).withTopK(SEARCH_K).withVectors(search_vectors).withVectorFieldName("content_vector").withParams(SEARCH_PARAM).build();R<SearchResults> respSearch = milvusClient.search(searchParam);List<PDFData> pdfDataList = new ArrayList<>();if(respSearch.getStatus() == R.Status.Success.getCode()){//respSearch.getData().getStatus() == R.Status.SuccessSearchResults resp = respSearch.getData();//判断是否查到结果if(!resp.hasResults()){return new ArrayList<>();}for (int i = 0; i < search_vectors.size(); ++i) {SearchResultsWrapper wrapperSearch = new SearchResultsWrapper(resp.getResults());List<Long> id = (List<Long>) wrapperSearch.getFieldData("id", 0);List<String> content = (List<String>) wrapperSearch.getFieldData("content", 0);List<Integer> contentWordCount = (List<Integer>) wrapperSearch.getFieldData("content_word_count", 0);PDFData pdfData = new PDFData(id.get(0),content.get(0),contentWordCount.get(0));pdfDataList.add(pdfData);}}milvusClient.releaseCollection(ReleaseCollectionParam.newBuilder().withCollectionName("sqls").build());return pdfDataList;
}

③得到完成的prompt

你是一个文本转SQL的生成器,你的主要目标是尽可能的协助用户,将输入的文本转化为正确的SQL语句。
上下文开始
表名和表字段来自以下表:{"fields":{"create_time":"会话时间,datetime","user_id":"用户编号,String","session_id":"会话编号,String","history":"会话历史,String"},"tableName":"prompt_history","info":"问答历史会话记录表,包括会话编号id、会用编号id、会话历史记录、会话时间。"}
。查询一下23年12月20日以来的问答历史记录

(3)利用LLM大模型生成SQL语句

JSONObject params = new JSONObject();
params.put("model", "chatglm3-6b");
params.put("max_tokens", maxTokens);
params.put("stream", true);
params.put("temperature", temperature);
params.put("top_p", topP);
params.put("user", user);
JSONObject message = new JSONObject();
message.put("role", "user");
message.put("content", finalPrompt);
params.put("messages", Collections.singleton(message));
log.info("ChatGLM请求参数:"+message.toJSONString());
return webClient.post().uri(chatGlmUrl).header(HttpHeaders.AUTHORIZATION, "Bearer none").bodyValue(params.toJSONString()).retrieve().bodyToFlux(String.class).onErrorResume(WebClientResponseException.class, ex -> {HttpStatus status = ex.getStatusCode();String res = ex.getResponseBodyAsString();log.error("ChatGLM error: {} {}", status, res);return Mono.error(new RuntimeException(res));});

得到最终的SQL语句:

SELECT * FROM prompt_history WHERE create_time > '2023-12-20'

在这里插入图片描述

第二阶段:查询数据库,提供数据分析

可以在代码中连接数据库,运行SQL语句并返回结果。

优化

如果觉得ChatGLM的Text2SQL能力还是比较弱,可以采用微调的方式,强化ChatGLM的Text2SQL能力。

推荐项目:DB-GPT-Hub

参考

https://baijiahao.baidu.com/s?id=1780693355413218644&wfr=spider&for=pc

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

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

相关文章

软件工程_复习

软件工程 软件危机(1968 60年代) 产生软件危机的原因: 一方面与软件本身的特点有关,另一方面也和软件开发和维护的方法不正确有关。 与软件本身特点有关: 1.软件不同于硬件,软件是计算机系统中的逻辑部件,缺乏“可见性”,管理和控制软件开发过程相当困难 2.软件在运行过…

Python笔记06-文件操作

文章目录 文件的编码文件读取文件写入文件追加 文件的编码 编码技术即&#xff1a;翻译的规则&#xff0c;记录了如何将内容翻译成二进制&#xff0c;以及如何将二进制翻译回可识别内容。算机中有许多可用编码&#xff1a;UTF-8、GBK、Big5等 不同的编码&#xff0c;将内容翻译…

typescript递归处理

typescript是一种类型强约束的语言&#xff0c;一般来讲定义类型时都要明确指定类型的数据结构。而如果数据结构中涉及到不知道基层嵌套的递归时&#xff0c;就会有一些麻烦。 在 https://stackoverflow.com/questions/51657815/recursive-array-type-typescript 有一个回答…

Java Swing手搓坦克大战遇到的问题和思考

1.游戏中的坐标系颇为复杂 像素坐标系还有行列坐标&#xff0c;都要使用&#xff0c;这之间的互相转化使用也要注意 2.游戏中坦克拐弯的处理&#xff0c;非常重要 由于坦克中心点是要严格对齐到一条网格线&#xff0c;并沿着这条线前进的&#xff0c;如果拐弯不做处理&#…

柠檬Lemon测评机的配置和测试方法

柠檬Lemon测评机的配置和测试方法 只需3步,即可配置好柠檬 第一步:选择g++,点击下一步 第二步:找到g++的目录,添加编译器,点击下一步 第三步:检查结果,点击完成。(此时,配置完成) 只需3步,即可用柠檬做考试测试 第一步:新建比赛

SpringCloud系列篇:核心组件之注册中心组件

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于SpringCloud的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.注册中心组件是什么 二.注册中心…

大模型机器人原理解析:如何从RT/RT2、Berkeley Gello到发展到斯坦福Mobile ALOHA、Google家务机器人

前言 23年7月&#xff0c;我在朋友圈评估Google的RT2说道&#xff1a; “大模型正在革新一切领域啊&#xff0c;超帅&#xff0c;通过大模型不仅能理解“人话”&#xff0c;还能对“人话”进行推理&#xff0c;并转变为机器人能理解的指令&#xff0c;从而分阶段完成任务。回…

opencv006图像处理之仿射变换(旋转,缩放,平移)

空间变换中的仿射变换对应着五种变换&#xff0c;平移&#xff0c;缩放&#xff0c;旋转&#xff0c;翻转&#xff0c;错切。而这五种变化由原图像转变到变换图像的过程&#xff0c;可以用仿射变换矩阵进行描述。而这个变换过程可以用一个2*3的矩阵与原图进行相乘得到。关键就是…

5年经验之谈 —— 探索自动化测试用例设计粒度!

自动化测试用例的粒度指的是测试用例的细致程度&#xff0c;即每个测试用例检查的功能点的数量和范围。 通常&#xff0c;根据测试用例的粒度&#xff0c;可以被分为3种不同的层次&#xff0c;从更低层次的细粒度到更高层次的粗粒度。 第一种&#xff1a;单元测试 - 细粒度 单…

16、Kubernetes核心技术 - 节点选择器、亲和和反亲和

目录 一、概述 二、节点名称 - nodeName 二、节点选择器 - nodeSelector 三、节点亲和性和反亲和性 3.1、亲和性和反亲和性 3.2、节点硬亲和性 3.3、节点软亲和性 3.4、节点反亲和性 3.5、注意点 四、Pod亲和性和反亲和性 4.1、亲和性和反亲和性 4.2、Pod亲和性/反…

chatGPT带你学习设计模式 (二)抽象工厂模式(创建型模式) GURU

深入理解抽象工厂模式 引言 在面向对象编程中&#xff0c;对象的创建是一个常见且关键的挑战。尤其在需要管理一系列相关对象的创建时&#xff0c;传统的对象创建方法&#xff08;如直接使用 new 关键字&#xff09;可能导致代码的高耦合和低灵活性。这时&#xff0c;抽象工厂…

jmeter连接数据库

下载jdbc 在浏览器输入 mysql jdbc官网 &#xff1b; 网址&#xff1a;MySQL :: MySQL Connectors 点击 Download 查看自己mysql服务的版本&#xff0c;找到对应版本的jdbc 所以下载5版本的jdbc 安装jdbc&#xff08;绿色版安装&#xff09; 操作jmeter 打开jmeter&#xff0…

前端框架中的状态管理(State Management)

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

GEE:随机数

作者&#xff1a;CSDN _养乐多_ 本文将介绍在 Google Earth Engine&#xff08;GEE&#xff09;上生成随机数的 API&#xff0c;可以指定随机数的生成范围、类型&#xff08;整型、浮点型&#xff09;、分布方式&#xff08;均匀分布、正态分布&#xff09;。 文章目录 一、随…

基于springboot的基于协同过滤算法的东北特产销售系统的设计与实现

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于springboot的基于协同过滤算法的东北…

2024年度 ROTS - 实时操作系统 Top 15

RTOS&#xff08;实时操作系统&#xff09;。 这里说的 RTOS 并非新星球大战电影中的机器人&#xff0c;而是物联网设备、航空系统、空中交通管制等背后的无声协调者&#xff0c;就在地球上。 RTOS&#xff0c;或称实时操作系统&#xff0c;设计它们是为了更好的管理资源&…

MySQL5.7 InnoDB 内存结构

官网地址&#xff1a;MySQL :: MySQL 5.7 Reference Manual :: 14.5 InnoDB In-Memory Structures 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. MySQL 5.7 参考手册 / ... / 缓冲池 14.5.1 缓冲池 缓冲池是…

20240106-换一种思维,工作也不过就是一种挣钱的方式而已了

今天在车上一个百度的同事聊抱怨说&#xff1a;累了&#xff0c;真的累了&#xff0c;干不动了&#xff0c;想跑路了&#xff0c;不想打工了。我们之前也会经常聊到和吐槽这种事情&#xff0c;但是我最近由于思维的一些改变&#xff0c;所以就想到把这个事情记录下来。 在大厂…

第四讲_css常用属性

css常用属性 1. css颜色表示方式1.1 颜色名1.2 rgb 和 rgba1.3 hex 和 hexa1.4 hsl 和 hsla 2. css 常用属性2.1 常用的文本属性2.2 常用的列表属性2.3 常用的边框属性2.4 表格独有属性2.5 常用的背景属性2.6 常用的鼠标属性 1. css颜色表示方式 1.1 颜色名 在css中定义了一些…

华为OD机试 - 矩阵匹配(Java JS Python C)

题目描述 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式: N M K N*M矩阵 输出描述 N*M 的矩阵中可以选出 M! / N! 种组合数…