vanna:基于RAG的text2sql框架

文章目录

    • vanna简介及使用
    • vanna的原理
    • vanna的源码理解
    • 总结
    • 参考资料

vanna简介及使用

vanna是一个开源的利用了RAG的SQL生成python框架,在2024年3月已经有了5.8k的star数。

Vanna is an MIT-licensed open-source Python RAG (Retrieval-Augmented Generation) framework for SQL generation and related functionality.

Chat with your SQL database 📊. Accurate Text-to-SQL Generation via LLMs using RAG

使用pip即可安装vanna:pip install vanna

vanna的使用主要分为三步:1. 确认所用的大模型和向量数据库;2. 将已有数据库的建表语句、文档、常用SQL及其自然语言查询问题进行向量编码存储到向量数据库(只用进行一次,除非数据有更改);3. 使用自然语言查询数据库。

## 第一步,假设使用 OpenAI LLM + ChromaDB 向量数据库
from vanna.openai.openai_chat import OpenAI_Chat
from vanna.chromadb.chromadb_vector import ChromaDB_VectorStore

class MyVanna(ChromaDB_VectorStore, OpenAI_Chat):
    def __init__(self, config=None):
        ChromaDB_VectorStore.__init__(self, config=config)
        OpenAI_Chat.__init__(self, config=config)

vn = MyVanna(config={'api_key': 'sk-...', 'model': 'gpt-4-...'})

## 第二步,将已有数据库相关信息存储起来
# 建表语句ddl
vn.train(ddl="""
    CREATE TABLE IF NOT EXISTS my-table (
        id INT PRIMARY KEY,
        name VARCHAR(100),
        age INT
    )
""")
# 数据库相关文档 documentation
vn.train(documentation="Our business defines XYZ as ...")
# 常用SQL
vn.train(sql="SELECT name, age FROM my-table WHERE name = 'John Doe'")

## 第三步,就可以直接使用自然语言来查询数据了
vn.ask("What are the top 10 customers by sales?")

常用vanna函数(更多参见vanna 文档)

# 训练(实际是添加数据到向量数据库)
vn.train(ddl="")  #建表语句
vn.train(documentation="") #文档
vn.train(sql="", question="") #问题和sql对
vn.train(sql="") #只有sql没有提供问题,会使用LLM来生成相应的问题
vn.train(plan="") #一般是根据提供的数据库来生成训练计划,最终写入到向量数据库的还是ddl、documentation、sql/question三类

# 查看已经加入到向量数据库的数据
vn.get_training_data() #所有数据
vn.get_related_sql()   #sql
vn.get_related_ddl()   #ddl

# 查询
vn.ask()
# 查询实际上是由下面四个函数依次执行的
vn.generate_sql()  #生成sql语句
vn.run_sql() #执行sql语句
vn.generate_plotly_code() #根据执行结果生成plotly绘图代码
vn.get_plotly_figure() #使用plotly绘图

vanna的原理

下图是来自vanna文档,用来解释vanna的原理。

在这里插入图片描述

vanna是基于检索增强(RAG)的sql生成框架,会先用向量数据库将待查询数据库的建表语句、文档、常用SQL及其自然语言查询问题存储起来。在用户发起查询请求时,会先从向量数据库中检索出相关的建表语句、文档、SQL问答对放入到prompt里(DDL和文档作为上下文、SQL问答对作为few-shot样例),LLM根据prompt生成查询SQL并执行,框架会进一步将查询结果使用plotly可视化出来或用LLM生成后续问题。

如果用户反馈LLM生成的结果是正确的,可以将这一问答对存储到向量数据库,可以使得以后的生成结果更准确。

这篇博客记录了vanna尝试不同LLM和添加不同的上下文到prompt时生成SQL的准确率,表明在prompt中加入相关SQL问答对作为few-shot对于提升结果准确性很重要,GPT-4是效果最好的LLM。

在这里插入图片描述

vanna的源码理解

vanna所谓的训练(即vn.train())最终分为三类数据:ddldocumentationsql/question。使用向量数据库chromadb的实现时创建了三个collection,也就是三类数据将分别存储和检索。对于sql/question会将数据变成{"question": question,"sql": sql}json字符串存储。如果用户在训练时只提供了sql没有提供问题,会使用LLM来生成相应的问题(使用的prompt为"The user will give you SQL and you will try to guess what the business question this query is answering. Return just the question without any additional explanation. Do not reference the table name in the question.")。

在查询阶段的vn.ask()vn.generate_sql()vn.run_sql() vn.generate_plotly_code()vn.get_plotly_figure() 四个函数组成。其中最关键的是vn.generate_sql(),它分为以下关键几步:

  • get_similar_question_sql(question, **kwargs)去向量数据库中检索与问题相似的sql/question对

  • get_related_ddl(question, **kwargs) 去向量数据库中检索与问题相似的建表语句ddl

  • get_related_documentation(question, **kwargs) 去向量数据库中检索与问题相似的文档

  • get_sql_prompt(question,question_sql_list,ddl_list,doc_list, **kwargs) 生成prompt,

    ## prompt 分为下面几个部分
    initial_prompt = """
    The user provides a question and you provide SQL. You will only respond with SQL code and not with any explanations.\n\nRespond with only SQL code. Do not answer with any explanations -- just the code.\n"
    """
    ## 如果有相关ddl,且没超过上下文窗口大小
    if len(ddd_list)>0:
      initial_prompt += "You may use the following DDL statements as a reference for what tables might be available. Use responses to past questions also to guide you:\n\n"
      for ddl in ddl_list:
        initial_prompt += f"{ddl}\n\n"
    ## 如果有相关documentation,且没超过上下文窗口大小
    if len(doc_list)>0:
    		initial_prompt += f"\nYou may use the following documentation as a reference for what tables might be available. Use responses to past questions also to guide you:\n\n"
    		for documentation in doc_list:
        	initial_prompt += f"{documentation}\n\n"
    ## 如果有相关documentation,且没超过上下文窗口大小
    if len(question_sql_list)>0:
      	initial_prompt += f"\nYou may use the following SQL statements as a reference for what tables might be available. Use responses to past questions also to guide you:\n\n"
    		for question in question_sql_list:
          initial_prompt += f"{question['question']}\n{question['sql']}\n\n"
    
  • submit_prompt(prompt, **kwargs) 提交prompt到大模型生成sql

  • extract_sql(llm_response) 使用正则从LLM的回复中获取sql

总结

vanna使用RAG的方式来提高text2sql的准确性,个人觉得将prompt中的上下文分为DDL(建表语句schema)、数据库文档、相关问题和sql三大类是vanna框架里很重要的一个思路。从代码来看,对这三类数据编码和检索的向量模型是同一个,这对向量模型的通用表征能力要求很高。在实际使用时,与其他RAG应用一样,document的分块对于检索准确率同样有很大影响。

参考资料

  1. vanna github
  2. vanna 文档

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

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

相关文章

SAP CAP篇十五:写个ERP的会计系统吧,Part II

本文目录 本系列文章目标开发步骤数据库表设计初始数据初始数据:AccountCategories初始数据:AccountUsages初始数据:ChartOfAccounts初始数据:AccountSubjects Service 定义生成Fiori AppApp运行 本系列文章 SAP CAP篇一: 快速创…

【GitHub】使用git链接下载很慢?试试服务器配置SSH,起飞

参考文献 保姆级教学,教你用配置SSH拉取github代码 CentOS ssh -T gitgithub.comgit config --global user.name "learnore" git config --global user.email "15200831505163.com"cd /root/.ssh vim id_rsa.pubGitHub Settings 结果 下载速…

路由器端口转发远程桌面控制:一电脑连接不同局域网的另一电脑

一、引言 路由器端口转发:指在路由器上设置一定的规则,将外部的数据包转发到内部指定的设备或应用程序。这通常需要对路由器进行一些配置,以允许外部网络访问内部网络中的特定服务和设备。端口转发功能可以实现多种应用场景,例如远…

通用的springboot web jar包执行脚本,释放端口并执行jar包

1、通用的springboot web jar包执行脚本,释放端口并执行jar包: #!/bin/bash set -eDATE$(date %Y%m%d%H%M) # 基础路径 BASE_PATH/data/yitu-projects/yitu-xzhq/sftp # 服务名称。同时约定部署服务的 jar 包名字也为它。 SERVER_NAMEyitu-server # 环境…

java小型人事管理系统

开发工具: MyEclipseJdkTomcatSQLServer数据库 运行效果视频: https://pan.baidu.com/s/1hshFjiG 定制论文,联系下面的客服人员

高可用系统有哪些设计原则

1.降级 主动降级:开关推送 被动降级:超时降级 异常降级 失败率 熔断保护 多级降级2.限流 nginx的limit模块 gateway redisLua 业务层限流 本地限流 gua 分布式限流 sentinel 3.弹性计算 弹性伸缩—K8Sdocker 主链路压力过大的时候可以将非主链路的机器给…

【STM32定时器 TIM小总结】

STM32 TIM详解 TIM介绍定时器类型基本定时器通用定时器高级定时器常用名词时序图预分频时序计数器时序图 定时器中断配置图定时器定时 代码调试 TIM介绍 定时器(Timer)是微控制器中的一个重要模块,用于生成定时和延时信号,以及处…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:Row)

沿水平方向布局容器。 说明: 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 接口 Row(value?:{space?: number | string }) 从API version 9开始,该接口支持在…

HarmonyOS NEXT应用开发—Grid和List内拖拽交换子组件位置

介绍 本示例分别通过onItemDrop()和onDrop()回调,实现子组件在Grid和List中的子组件位置交换。 效果图预览 使用说明: 拖拽Grid中子组件,到目标Grid子组件位置,进行两者位置互换。拖拽List中子组件,到目标List子组件…

阿里云-零基础入门推荐系统 【特征工程】

文章目录 赛题介绍评价方式理解赛题理解制作特征和标签, 转成监督学习问题导包df节省内存函数训练和验证集的划分获取历史点击和最后一次点击读取训练、验证及测试集读取召回列表读取各种Embedding读取文章信息读取数据对训练数据做负采样将召回数据转换成字典制作与…

Java后端八股-------并发编程

图中的 synchronized方法如果没有锁,那么可能会有超卖,数据错误等情况。 加锁之后会按顺序售卖。 synchronized的底层是monitor。 线程没有竞争关系的时候,引入了轻量级锁,当需要处理竞争关系的时候一定要用到重量级锁(线程的…

图像处理ASIC设计方法 笔记10 插值算法的流水线架构

(一) 三次插值算法实现的图像旋转设计的流水线架构 传统上,三次插值算法实现的图像旋转设计需要三块一样的处理资源,为了节约资源,采用流水线设计,简单来讲就是三次插值算法共用一块资源,优化这…

Android Studio 打包 Maker MV apk 详细步骤

一.使用RPG Make MV 部署项目,获取项目文件夹 这步基本都不会有问题: 二.安装Android Studio 安装过程参考教材就行了: https://blog.csdn.net/m0_62491877/article/details/126832118 但是有的版本面板没有Android的选项(勾…

OpenCV 环境变量参考

返回:OpenCV系列文章目录(持续更新中......) 上一篇: OpenCV4.9.0配置选项参考 下一篇:OpenCV4.9.0配置选项参考 引言: OpenCV是一个广泛使用的图像和视频处理开源库,拥有丰富的图像算法和函…

ChatGPT编程—实现小工具软件(批量替换文本、批量处理图像文件)

ChatGPT编程—实现小工具软件(批量替换文本、批量处理图像文件) 今天借助[小蜜蜂AI][https://zglg.work]网站的ChatGPT编程实现一个功能:批量处理文件及其内容,例如批量替换文本、批量处理图像文件等。 环境:Pycharm 2021 系统&#xff1a…

DDR协议基础进阶(三)——(基本功能、初始化、MR寄存器)

DDR协议基础进阶(三)——(基本功能、初始化、MR寄存器) 一、DDR基本功能 DDR基本功能主要包括: 8-bit prefetch预取——8-bit,是指8位数据,即8倍芯片位宽的数据。由于DDR内部数据传输是32bit…

NVENC 视频编码器 API 编程指南 ( 中文转译 )

基于 NVIDIA Kepler™ 和更高版本 GPU 架构的 NVIDIA GPU 包含基于硬件的 H.264/HEVC/AV1 视频编码器(以下简称 NVENC)。NVENC 硬件采用 YUV/RGB 作为输入,并生成符合H.264/HEVC/AV1 标准的视频比特流。可以使用 NVIDIA 视频编解码器 SDK 中提…

柚见十三期(优化)

前端优化 加载匹配功能与加载骨架特效 骨架屏 : vant-skeleton index.vue中 /** * 加载数据 */ const loadData async () > { let userListData; loading.value true; //心动模式 if (isMatchMode.value){ const num 10;//推荐人数 userListData await myA…

GiT: Towards Generalist Vision Transformer through Universal Language Interface

GiT: Towards Generalist Vision Transformer through Universal Language Interface 相关链接:arxiv github 关键字:Generalist Vision Transformer (GiT)、Universal Language Interface、Multi-task Learning、Zero-shot Transfer、Transformer 摘要 …

Java 学习和实践笔记(38):接口中的默认方法

JAVA8以后,我们也可以在接口中直接定义静态方法的实现——以前是不行的。这个静态方法直接从属于接口(接口也是类,一种特殊的类),可以通过接口名调用。 如果子类中定义了相同名字的静态方法,那就是完全不同的方法了,直…