详解基于 RAG 的 txt2sql 全过程

前文

本文使用通义千问大模型和 ChromaDB 向量数据库来实现一个完整的 text2sql 的项目,并基于实际的业务进行效果的展示。

准备

在进行项目之前需要准备下面主要的内容:

  • python 环境
  • 通义千问 qwen-max 模型的 api-key
  • ChromaDB 向量数据库
  • acge_text_embedding 嵌入模型

RAG

首先在进行主要内容之前要先回顾一下基础知识,市面上 的 text2sql 项目的基本框架就是下图中展示的 RAG 框架图,也就是常说的检索增强生成技术。结合我们的 text2sql 业务数据,我们按照图中的 1 + 3 个步骤分别介绍。“1” 指的是要进行 RAG 的预先准备工作,“3” 是 RAG 的三个步骤。

  1. 使用我们准备好的 acge_text_embedding 嵌入模型 将相关的数据库表结构信息字段使用方法、供大模型参考的question-sql 对等信息都进行向量化,然后将向量存入ChromaDB 向量数据库
  2. 用户提出针对数据库的问题 query ,然后通过同样的 acge_text_embedding 嵌入模型query 转化成向量,通过相关性计算算法,从ChromaDB 向量数据库中召回和 query 最相关的文本作为上下文 context ,这里的 context 理想状态下肯定是和问题相关的表结构、字段信息,或者相似的 question-sql 对 ,这些信息会在后面输入进 LLM 中,供 LLM 理解。
  3. 将用户的 querycontext 拼接成一个完整的 prompt ,此时的 prompt 中既有供 LLM 参考的问题相关的可用信息,又有用户的问题 。
  4. promptLLM ,让其输出合理的结果,我们这里的结果其实就是预先想要得到的 sql

所以到现在我们应该能体会出来,RAG 的框架最核心的只有两个部分:

  1. 第一就是能从向量数据库中召回最相关的上下文供 LLM 理解问题相关的上下文:
  2. 第二就是大模型的理解能力,是否能在给出充足上下的情况下将问题解决。

在这里插入图片描述

RAG 疑问

有的人可能会说为什么不跳过第一步,把数据库所有的信息都输入给大模型,理论上也是可以的。但是具体实施会有困难,原因如下:

  1. 目前大模型输入 token 都有明确的限制,比如 qwen-max 模型只有 8K (尽管这些限制在逐渐消失,现在很多大模型的输入 token 都已经过百万 token 了)。
  2. 另外就是考虑到成本,发送大量 token 是非常昂贵的操作,如果模型理解能力有限,更是毫无意义。
  3. 最后就是从实际的研究,仅发送少量的但是质量较高的相关信息给大模型更有助于生成好的答案。

详细过程

数据准备

ddl.txt:这里面存放的都是业务范围内容的表结构。如下:

sql
复制代码
CREATE TABLE ai_prj_plan ( duty_party character varying(255) , pipeline_type character varying(255) , ... );
CREATE TABLE dtqjln (  xmbh character varying(100), jgsj integer, ...}

documentations.txt : 这里存放的是每个字段的详细说明或者注意事项。如下:

bash
复制代码
ai_prj_plan 表中的字段 id 表示工程计划的主键 id 。
ai_prj_plan 表中的字段 create_time 表示工程计划的创建时间。
...
dtqjln 表中的字段 jsdw 表示地铁线路或者地铁区间的建设单位名称。
dtqjln 表中的字段 sjdw 表示地铁线路或者地铁区间的设计单位名称。

question-sql.txt : 这里存放的是一些代表性的业务可能涉及到的问题-sql 对样本,如下:

sql
复制代码
已经投运的管线工程计划总长###select SUM(length::numeric) from ai_prj_plan where current_progress=5 and plan_type in (1,2,3)
查10条计划单独施工的工程名字###select project_name as "ai_prj_plan.project_name"  from ai_prj_plan where plan_type=1 limit 10
...

导入向量数据库

这里的三个文件,每一行都作为一个 doc ,然后将每一行使用预先准备的 acge_text_embedding 嵌入模型 转化成 1024 向量,也就是三个文件一共有多少行,就会有多少个 1024 的向量,然后都存入ChromaDB 向量数据库

用户提问

用户提问“2023年入廊管线中前期项目的计划有多少”,会使用预先准备的 acge_text_embedding 嵌入模型,将问题转化为一个 1024 向量,将其与ChromaDB 向量数据库 中的所有 1024 向量进行相似性召回,分别从三个文件中找出最相关的内容,至于召回策略可以自己定义。根据我的自定义召回策略,然后将召回的内容和问题进行拼接组成下面的完整的 prompt ,从完整的 prompt 我们可以看到召回了将要使用的表结构 ai_prj_plan 以及相关字段 plan_type 、annual_aim_json 、plan_category 的使用说明,最后找出了两个可能对模型有用的 question-sql 对供模型参考。所以下面的内容是提供了足够完成用户提问的相关信息,最终模型也给我们生成了符合要求的 SQL ,说明我们的整体项目实现了既定的目标。

python
复制代码
[
	{'role': 'system', 'content': '您是一名精通 SQL 的专家,用户会提出业务相关的问题,请根据相关信息回答合适的 SQL ,您将仅使用 SQL 代码进行回答,不进行任何解释。
        您可以使用以下展示出的表结构作为参考:\n\nCREATE TABLE ai_prj_plan\n(\n    id character varying(64)  NOT NULL,\n    create_time timestamp(6) without time zone,\n    update_time timestamp(6) without time zone,\n    remark character varying(255) ,\n    plan_type integer,\n    duty_party character varying(255) ,\n    pipeline_type character varying(255) ,\n    project_name character varying(255) ,\n    dlmc character varying(255) ,\n    start_end_point character varying(255) ,\n    ssqx character varying(100) ,\n    total_invest real,\n    length real,\n    plan_code character varying(255) ,\n    plan_category integer,\n    version integer,\n    accept integer,\n    verify_status integer,\n    refuse_reason character varying(255) ,\n    geom geometry(Geometry,4326), -- 几何使用 4326 坐标系\n    years character varying(255) ,\n    current_progress integer,\n    annual_aim_json text ,\n)\n\n
        您可以使用以下展示出的 documentation 作为参考,每个 documentation 解释了每个表的字段的名字和用法,使用他们以指导您有效准确地回答用户的问题,请务必遵循每个字段的使用方法和注意事项:\n\nai_prj_plan 表中的字段 plan_type 表示工程计划中涵盖的工程类型,我们规定只能枚举整数 1 、 2 、 3 、 4 、 5 ,整数 1 表示单独施工管线计划,整数 2 表示随道路施工管线工程计划,整数 3 表示入廊管线工程计划,整数 4 表示管廊工程计划,整数 5 表示互联互通工程计划,其中将整数 1 、 2 、 3 代表的三种工程计划合并起来统称为“管线工程计划”或者"管线计划"。\n\nai_prj_plan 表中的字段 plan_category 表示工程计划的计划分类,我们规定只能枚举整数 1 和 2 ,整数 1 表示工程计划在计划内,整数 2 表示工程计划在计划外。\n\nai_prj_plan 表中的字段 annual_aim_json 表示工程计划的每年详细计划列表,虽然该字段是字符串内容,但是存储格式是 json 列表。每个 json 中有三个字段 year、planProgress、 planInvest,表示打算计划在某年(year)给该项目一定的投资(planInvest),要将该项目推进到计划的进度(planProgress)。}, 
	{'role': 'user', 'content': '2024年入廊管线中前期项目的计划有多少'}, 
	{'role': 'assistant', 'content': "SELECT COUNT(*) FROM ai_prj_plan, jsonb_array_elements(annual_aim_json::jsonb) AS aim  WHERE (aim->>'planProgress')::integer = 1 AND plan_category = 1 AND plan_type = 3 AND (aim->>'year')::integer = 2024;"}, 
	{'role': 'user', 'content': '2024年入廊管线中已完成的前期项目有多少'}, 
	{'role': 'assistant', 'content': "SELECT COUNT(1) AS cnt FROM ai_prj_plan, jsonb_array_elements(annual_aim_json::jsonb) AS aim WHERE (aim->>'year')::int = 2024  and (aim->>'planProgress')::int <= current_progress and (aim->>'planProgress') is not null  and plan_type  = 3 and current_progress = 1    and plan_category = 1"}, 
 	{'role': 'user', 'content': '2023年入廊管线中前期项目的计划有多少'}
 ]

大模型结果输出:

sql
复制代码
Sql:SELECT COUNT(*) FROM ai_prj_plan, jsonb_array_elements(annual_aim_json::jsonb) AS aim  WHERE (aim->>'planProgress')::integer = 1 AND plan_category = 1 AND plan_type = 3 AND (aim->>'year')::integer = 2023;

完结撒花,希望上面的内容能给大家解释清楚相关的技术原理和细节。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一款 NodeJS 版本管理工具 NVM (Windows)

一、简介 Node Version Manager&#xff08;NVM&#xff09;是一种用于管理多个 NodeJS 版本的工具。在日常工作中&#xff0c;我们可能同时在进行多个不同的项目开发&#xff0c;每个项目的需求不同&#xff0c;依赖与不同版本的NodeJS 运行环境。这种情况下&#xff0c;维护…

数据处理学习笔记9

一些其他的函数 “Resize”和“Reshape”的区别主要在于它们对数组元素数量和形状的处理方式不同&#xff0c;以下是详细介绍&#xff1a; “Resize”通常会改变数组的元素数量&#xff0c;在放大数组形状时会用0补全新增的元素&#xff0c;而在缩小数组形状时会丢弃多余的元素…

一款AI工作流项目:phidatahq/phidata

一款AI工作流项目&#xff1a;phidatahq/phidata 构建和测试功能强大的 AI 工作流程。该项目提供了一个工作流平台,可以结合大型语言模型(LLM)和各种工具,扩展模型的实用性和应用范围。[1][4][5] 开发各种 AI 助手应用,如客服聊天机器人、数据分析工具、研究助手等。phidata 提…

Golang | Leetcode Golang题解之第72题编辑距离

题目&#xff1a; 题解&#xff1a; func minDistance(word1 string, word2 string) int {m, n : len(word1), len(word2)dp : make([][]int, m1)for i : range dp {dp[i] make([]int, n1)}for i : 0; i < m1; i {dp[i][0] i // word1[i] 变成 word2[0], 删掉 word1[i], …

LabVIEW波浪发电平台浮筒取能效率数据采集系统

LabVIEW波浪发电平台浮筒取能效率数据采集系统 随着化石能源的逐渐减少以及能源价格的上升&#xff0c;寻找可替代的、可再生的、清洁的能源成为了世界各国的共识。波浪能作为一种重要的海洋能源&#xff0c;因其巨大的潜力和清洁性&#xff0c;近年来受到了广泛关注。开发了一…

32 OpenCV Harris角点检测

文章目录 cornerHarris 算子示例 角点检测 cornerHarris 算子 void cv::cornerHarris ( InputArray src,OutputArray dst,int blockSize,int ksize,double K,int borderType BORDER_DEFAULT) src:待检测Harris角点的输入图像&#xff0c;图像必须是CV 8U或者CV 32F的单通道…

玩comfyui踩过的坑之使用ComfyUI_Custom_NODES_ALEKPET翻译组件问题

环境&#xff1a; 秋叶安装包&#xff0c;安装ComfyUI_Custom_NODES_ALEKPET组件或者直接下载网盘中的包&#xff0c;直接解压包到comfyui根目录/custom_nodes/&#xff0c;重启后&#xff0c;按指导文件操作。 注意&#xff1a;网盘指导包中有配置好的流程json文件&#xff0…

【源码】 频裂变加群推广强制分享引流源码

视频裂变加群推广强制分享引流源码&#xff0c;用户达到观看次数后需要分享给好友或者群,好友必须点击推广链接后才会增加观看次数。 引导用户转发QV分享,达到快速裂变引流的效果&#xff01; 视频裂变推广程序&#xff0c;强制分享链接&#xff0c;引导用户转发&#xff0c;…

prometheus搭建

1.prometheus下载 下载地址:Download | Prometheus 请下载LTS稳定版本 本次prometheus搭建使用prometheus-2.37.1.linux-amd64.tar.gz版本 2.上传prometheus-2.37.1.linux-amd64.tar.gz至服务器/opt目录 CentOS7.9 使用命令rz -byE上传 3.解压缩prometheus-2.37.1.linux…

VscodeC/C++环境配置

引言 vscode是一款非常好用的编辑器&#xff0c;集成了大量的插件&#xff0c;具有很高的自由度&#xff0c;因此广受大家的喜爱。但是他本身是不带编译器的&#xff0c;因此如果要使用vscode来编译C/C程序的话&#xff0c;我们需要额外安装编译器并且为vscode配上环境。 编译…

Docker 入门与实践:从零开始构建容器化应用环境

Docker 一、docker常用命令docker ps 格式化输出Linux设置命令别名 二、数据卷相关命令挂载到默认目录&#xff08;/var/lib/docker&#xff09;挂载到本地目录 三、自定义镜像Dockerfile构建镜像的命令 四、网络自定义网络 五、DockerCompose相关命令 一、docker常用命令 dock…

Python | Leetcode Python题解之第71题简化路径

题目&#xff1a; 题解&#xff1a; class Solution:def simplifyPath(self, path: str) -> str:names path.split("/")stack list()for name in names:if name "..":if stack:stack.pop()elif name and name ! ".":stack.append(name)re…

ThreeJS:光线投射与3D场景交互

光线投射Raycaster 光线投射详细介绍可参考&#xff1a;https://en.wikipedia.org/wiki/Ray_casting&#xff0c; ThreeJS中&#xff0c;提供了Raycaster类&#xff0c;用于进行鼠标拾取&#xff0c;即&#xff1a;当三维场景中鼠标移动时&#xff0c;利用光线投射&#xff0c;…

点亮一个LED

新建项目 #include <REGX52.H>void main() {P2 0xFE;while(1){} }调整字体大小 在编译之前要勾选一个东西,不然scp读取不了 去stc-isp中烧录进51单片机 两个地方要勾选,一个是单片机型号,一个是串口号,我的单片机型号不是江科大视频里面那个型号,所以不能按视频里面来选…

【数据结构(邓俊辉)学习笔记】列表04——排序器

文章目录 0. 统一入口1. 选择排序1.1 构思1.2 实例1.3 实现1.4 复杂度 2. 插入排序2.1 构思2.2 实例2.3 实现2.4 复杂度分析2.5 性能分析 3. 归并排序3.1 二路归并算法3.1.1 二路归并算法原理3.1.2 二路归并算法实现3.1.3 归并时间 3.2 分治策略3.2.1 实现3.2.2 排序时间 4. 总…

学习笔记:【QC】Android Q - IMS 模块

一、IMS init 流程图 二、IMS turnon 流程图 三、分析说明 1、nv702870 不创建ims apn pdp 2、nv702811 nv702811的时候才创建ims pdp&#xff1a; ims pdp 由ims库发起&#xff0c;高通没有开放这部分代码&#xff1a; 10-10 11:45:53.027 943 943 E Diag_Lib: [IMS_D…

只用语音能训练出AI大模型吗?就像训练会说话但不识字的人一样

AI语音对话技术通常是基于语音识别和自然语言处理&#xff08;NLP&#xff09;的。在这个过程中&#xff0c;语音首先被识别成文字&#xff0c;然后NLP技术对这些文字进行处理&#xff0c;生成回应。然而&#xff0c;我们是否可以直接训练一个“文盲”大模型&#xff0c;即只用…

45. UE5 RPG 增加角色受击反馈

在前面的文章中&#xff0c;我们实现了对敌人的属性的初始化&#xff0c;现在敌人也拥有的自己的属性值&#xff0c;技能击中敌人后&#xff0c;也能够实现血量的减少。 现在还需要的就是在技能击中敌人后&#xff0c;需要敌人进行一些击中反馈&#xff0c;比如敌人被技能击中后…

深度学习中的注意力机制二(Pytorch 16)

一 Bahdanau 注意力 通过设计一个 基于两个循环神经网络的编码器‐解码器架构&#xff0c;用于序列到序列学习。具体来说&#xff0c;循环神经网络编码器将长度可变的序列转换为固定形状的上下文变量&#xff0c;然后循环神经网络 解码器根据生成的词元和上下文变量按词元生成…

meshlab: pymeshlab计算两个模型的布尔交集(mesh boolean intersection)

一、关于环境 请参考&#xff1a;pymeshlab遍历文件夹中模型、缩放并导出指定格式-CSDN博客 二、关于代码 本文所给出代码仅为参考&#xff0c;禁止转载和引用&#xff0c;仅供个人学习。 本案例以两个圆环为例。 左侧为两个圆环&#xff0c;右上是重叠&#xff0c;右下是圆…