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_VectorStoreclass 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 文档

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

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

相关文章

探讨大世界游戏的制作流程及技术——大场景制作技术概况篇

接上文,我们接下来了解一下大世界场景制作技术有哪些,本篇旨在给大家过一遍目前业界的做法,能让大家有一个宏观的知识蓝图。实际上,针对不同的游戏类型和美术风格,制作技术在细节上有着非常大的不同,业界目…

HarmonyOS NEXT应用开发—自定义视图实现Tab效果

介绍 本示例介绍使用Text、List等组件,添加点击事件onclick,动画,animationTo实现自定义Tab效果。 效果预览图 使用说明 点击页签进行切换,选中态页签字体放大加粗,颜色由灰变黑,起到强调作用,同时&…

手撕算法-队列实现栈And栈实现队列

手撕算法-队列实现栈And栈实现队列 两个栈实现队列两个队列实现栈包含min函数的栈 两个栈实现队列 分析:转换数据方向,第一个栈写,第二个栈读。 代码: import java.util.*; import java.util.Stack;public class Solution {Sta…

PyCharm中如何使用不同的虚拟环境

1. 简介 有些项目用老的运行环境,而有些项目用新的运行环境,那么我们在运行这些代码(比如跑对比实验的时候)如何进行切换呢,这时候就可以使用虚拟环境啦 2. 虚拟环境的创建 首先启动Anaconda Prompt 并在其中执行如…

调皮的String及多种玩法(下部)

👨‍💻作者简介:👨🏻‍🎓告别,今天 📔高质量专栏 :☕java趣味之旅 欢迎🙏点赞🗣️评论📥收藏💓关注 💖衷心的希…

LeetCode 面试经典150题 26.删除有序数组中的重复项

题目: 给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量…

C# SM2加解密 ——国密SM2算法

SM2 是国家密码管理局组织制定并提出的椭圆曲线密码算法标准。 本文使用第三方密码库 BouncyCastle 实现 SM2 加解密,使用 NuGet 安装即可,包名:Portable.BouncyCastle,目前最新版本为:1.9.0。 using Org.BouncyCastl…

相机sd卡照片删除后数据恢复,相机sd卡中的照片被删除后如何恢复数据

当我们使用相机拍摄照片时,有时会不小心删除了一些重要的照片。这可能是因为误操作、SD卡故障或者其他原因。无论是珍贵的照片、还是重要的工作文件,被删除后,我们往往会感到焦虑和失望。相机sd卡中的照片被删除后如何恢复数据?幸…

Java项目:54 springboot工资信息管理系统453

作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本系统的使用角色可以被分为用户和管理员, 用户具有注册、查看信息、留言信息等功能, 管理员具有修改用户信息&#…

洛谷P1097 [NOIP2007 提高组] 统计数字

#先看题目 题目描述 某次科研调查时得到了 n 个自然数,每个数均不超过 1.5109。已知不相同的数不超过 个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。 输入格式 共 n1 行。 第一行是整数 n&#x…

InfluxDB下载安装教程

InfluxDB下载安装教程 一、简介二、【linux】InfluxDB下载安装配置2.1 下载安装2.1.1 apt在线安装2.1.2 离线安装 2.2 配置及启动 3、windows 下的安装方式4、InfluxDB基本使用4.1 创建用户4.2 数据库 回到目录 一、简介 InfluxDB是一个由InfluxData开发的开源时序型数据库。它…

软件之禅(十)数据库

黄国强 2024/03/16 说点题外话,写程序是个非常有意思的智力游戏,想到业内很多人把这么一个智力游戏变成体力劳动,颇有些唏嘘。 回到正题,继续我对软件的思考。我是80年代的大学生,当时学的是dBASE数据库。毕业…

前端之CSS 创建css--行内引入、内联样式、外联样式

创建css有三种创建样式&#xff0c;行内引入、内联引入、外联引入。 行内引入 在行内标签引入 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>行内样式</title> </head> <body>…

php中 0 == ‘’(0等于任意字符串) 判断是否成立 返回true

php中不同类型变量之间比较大小 一、背景二、探究0是为什么&#xff1f;三、探究 0all是为什么&#xff1f;四、程序中如何判断0是否等于指定字符串 一、背景 最近在项目实际开发中&#xff0c;我需要判断前端传来的参数值是否等于一个字符串&#xff1b;然后发现当参数值是0时…

element-plus怎么修改表单中的label字体颜色及大小

问题描述&#xff1a; 当我们在vue3中使用element-plus组件库提供的表单组件时&#xff0c;有时我们需要修改表单中label的字体颜色等属性&#xff0c;这是如果直接选中label的class进行修改是不起作用的&#xff0c;我们只需深度选择即可选中并进行修改。 比如&#xff1a; …

IO Watch:用 Arduino UNO 制造的可编程手表

MAKER:mblaz/译:趣无尽 Cherry(转载请注明出处) 关于手表的项目,之前我们已经介绍过一款《Arduino + 3D 打印 DIY 电子手表》。本期的项目同样的一款基于 Arduino UNO 的可编程的手表,相比之下制造门槛更高一些。同时它更成熟、实用,外形也很有设计感,非常的漂亮! 这…

【打工日常】使用Docker部署团队协作文档工具

一、ShowDoc介绍 ​ShowDoc是一个适合IT团队共同协作API文档、技术文档的工具。通过showdoc&#xff0c;可以方便地使用markdown语法来书写出API文档、数据字典文档、技术文档、在线excel文档等等。 响应式网页设计&#xff1a;可将项目文档分享到电脑或移动设备查看。同时也可…

WXML 模板语法

数据绑定 1. 数据绑定的基本原则 ① 在 data 中定义数据 在页面对应的 .js 文件中&#xff0c;把数据定义到 data 对象中即可 ② 在 WXML 中使用数据 2. Mustache 语法的格式 把 data 中的数据绑定到页面中渲染&#xff0c;使用 Mustache 语法&#xff08;双大括号&#x…

三次握手seq和ack的流程 TCP协议栈seq和ack深层理解

☆ 大家可以把想了解的问题在评论发给我?我会根据问题补充到后面 ☆ 三次握手seq和ack的流程 是的,在TCP/IP协议中,三次握手过程确实涉及到序列号(Sequence Number, 简称Seq)和确认号(Acknowledgment Number, 简称Ack)的交换。这个过程是为了建立可靠的连接,确保数据能…

对OceanBase进行 sysbench 压测前,如何用 obdiag巡检

有一些用户想对 OceanBase 进行 sysbench 压测&#xff0c;并向我询问是否需要对数据库的各种参数进行调整。我想起有一个工具 obdiag &#xff0c;具备对集群进行巡检的功能。因此&#xff0c;我正好借此机会试用一下这个工具。 obdiag 功能的比较丰富&#xff0c;详细情况可参…