Text-to-SQL 工具Vanna + MySQL本地部署 | 数据库对话机器人

今天我们来重点研究与实测一个开源的Text2SQL优化框架 – Vanna
在这里插入图片描述

1. Vanna 简介【Text-to-SQL 工具】

Vanna 是一个基于 MIT 许可的开源 Python RAG(检索增强生成)框架,用于 SQL 生成和相关功能。它允许用户在数据上训练一个 RAG “模型”,然后提问问题,这将生成在数据库上运行的 SQL 查询语句,并将查询结果通过表格和图表的方式展示给用户。

简单的说,Vanna是一个开源的、基于Python的、用于SQL自动生成与相关功能的RAG(检索增强生成)框架。

基本特点:

  • 官网:https://vanna.ai/
  • 开放源代码https://github.com/vanna-ai/vanna
  • 基于Python语言。可通过PyPi包vanna在自己项目中直接使用
  • RAG框架。RAG最典型的应用是 私有知识库问答,通过Prompt注入私有知识以提高LLM回答的准确性。但RAG本身是一种Prompt增强方案,完全可以用于其他LLM应用场景。

2. Vanna工作原理

借助LLM实现一个最简单的、基于Text2SQL的数据库对话机器人本身原理是比较简单的:
在这里插入图片描述
Vanna则是借助了相对简单也更易理解的RAG方法,通过检索增强来构建Prompt,以提高SQL生成的准确率:
在这里插入图片描述
从这张图可以了解到,Vanna的关键原理为:

借助数据库的DDL语句、元数据(数据库内关于自身数据的描述信息)、相关文档说明、参考样例SQL等训练一个RAG的“模型”(embedding+向量库);
并在收到用户自然语言描述的问题时,从RAG模型中通过语义检索出相关的内容,进而组装进入Prompt,然后交给LLM生成SQL。

3. 使用步骤

第一步:在你的数据上训练一个RAG“模型”

把DDL/Schemas描述、文档、参考SQL等交给Vanna训练一个用于RAG检索的“模型”(向量库)。
在这里插入图片描述
本文尝试了1、3、4的方法,记住这几种方法,下面会用到。

第二步:提出“问题”,获得回答

RAG模型训练完成后,可以用自然语言直接提问。Vanna会利用RAG与LLM生成SQL,并自动运行后返回结果。

4. vanna的扩展与定制化

从上述的vanna原理介绍可以知道,其相关的三个主要基础设施为:

  • Database,即需要进行查询的关系型数据库
  • VectorDB,即需要存放RAG“模型”的向量库
  • LLM,即需要使用的大语言模型,用来执行Text2SQL任务

在这里插入图片描述
Vanna的设计具备了很好的扩展性与个性化能力,能够支持任意数据库、向量数据库与大模型。

4.1 自定义LLM与向量库

默认情况下,Vanna支持使用其在线LLM服务(对接OpenAI)与向量库,可以无需对这两个进行任何设置,即可使用。因此使用Vanna最简单的原型只需要五行代码:

import vanna
from vanna.remote import VannaDefault
vn = VannaDefault(model='model_name', api_key='api_key')
vn.connect_to_sqlite('https://vanna.ai/Chinook.sqlite')
vn.ask("What are the top 10 albums by sales?")

注意:使用Vanna.AI的在线LLM与向量库服务,需要首先到 https://vanna.ai/ 去申请账号,具体请参考下一部分实测。

如果需要使用自己本地的LLM或者向量库,比如使用自己的OpenAI账号与ChromaDB向量库,则可以扩展出自己的Vanna对象,并传入个性化配置即可。

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-...'})

这里的OpenAI_Chat和ChromaDB_VectorStore是Vanna已经内置支持的LLM和VectorDB。
如果你需要支持 没有内置支持的LLM和vectorDB
则需要首先 扩展出自己的LLM类与VectorDB类
实现必要的方法(具体可参考官方文档),
然后再 扩展出自己的Vanna对象
在这里插入图片描述

4.2 自定义关系型数据库

Vanna默认支持Postgres,SQL Server,Duck DB,SQLite等关系型数据库,可直接对这一类数据库进行自动访问,实现数据对话机器人。
但如果需要连接自己企业的其他数据库,比如企业内部的Mysql或者Oracle,自需要定义一个个性化的run_sql方法,并返回一个Pandas Dataframe即可。具体可参考下方的实测代码。

5. 实测:数据库对话机器人

这里我们使用Vanna快速构建一个与数据库对话的AI智能体,直观的感受Vanna的工作过程与效果。

【0 - 选择基础环境】

  • LLM(大模型)
    选择Vanna.AI在线提供的OpenAI服务,真实环境中建议使用自己的LLM。
  • VectorDB(向量数据库)
    选择Vanna.AI在线提供的VectorDB服务,真实环境中可根据条件灵活选择。
  • RDBMS(关系型数据库)
    我们选择本地测试环境中的一个MySQL数据库,其中存放了一些测试的社区用户信息数据customer
    在这里插入图片描述

我用DBeaver工具来管理MySQL数据库,创建数据可以用SQL语句CREATE导入csv
导入csv可以参考【数据库】DBeaver链接MariaDB建表,导入csv数据这篇博客

【1 - 申请Vanna账号】

由于我们使用了Vanna.AI的在线LLM与vectorDB服务。因此首先在Vanna.AI申请一个账号,并获得API-key(红框中部分 / 代码中隐藏部分):
在这里插入图片描述
设置一个Model name,用于在线的RAG model:
我的设置为:community
在这里插入图片描述
注意:与新数据库对话,需要重新设置一个Model name

【2 - 构建Vanna对象】

pip install vanna

使用pip安装vanna库后,首先使用如下代码创建默认的Vanna对象:

import vanna
from vanna.remote import VannaDefault
api_key = '上面获得的API-key'
vanna_model_name = '上面设置的model-name( 我的是community )'
vn = VannaDefault(model=vanna_model_name, api_key=api_key)

由于我们需要使用自己的本地Mysql数据库,需要定义一个run_sql方法
设置好MySQL数据库的user 、password、host 和 database

(这个database名称是DBeaver工具customer上方的数据库名称Community,RAG model的名称是网页上设置的 community,首字母是小写的,各位别抄错啦!按自己的配置来哈!)

import pandas as pd
import mysql.connector

def run_sql(sql: str) -> pd.DataFrame:
    cnx = mysql.connector.connect(user='root',password='111000',host='localhost',database='Community')
    cursor = cnx.cursor()
    cursor.execute(sql)
    result = cursor.fetchall()
    columns = cursor.column_names
    df = pd.DataFrame(result, columns=columns)
    return df

将自定义的方法设置到上面创建的Vanna对象

vn.run_sql = run_sql
vn.run_sql_is_set = True

【3 - 训练RAG Model】

这里我们先采用Vanna提供的一种更简单的方式:通过数据库的元数据信息构建训练计划(plan),然后交给Vanna生成RAG model:

df_information_schema = vn.run_sql("SELECT * FROM INFORMATION_SCHEMA.COLUMNS where table_schema = 'chatdata'")
plan = vn.get_training_plan_generic(df_information_schema)
vn.train(plan=plan)

我构建计划(plan)的方式失败!
故通过 DDL语句SQL问答对 的方式来构建。

表和列名的注释很重要!
表和列名的注释很重要!
表和列名的注释很重要!
有助于vn识别语义,有的列名英文不是那么明确,可能会导致vn生成SQL出错。

比如身份证号的英文可以是id_number,我这里是id_card
比如性别的英文可以是sex,我这里是gender

当时我的表还没添加注释,所以多加了CREATE TABLE的操作,如果各位同学在创建表时,已添加了注释,下面这句CREATE TABLE就可以省略了。

需要注意的是,下面的训练代码只需要执行一次即可

vn.train(ddl="""
CREATE TABLE IF NOT EXISTS customer (
    name INT PRIMARY KEY COMMENT '姓名', 
    gender INT COMMENT '性别(男性=1/女性=2)', 
    id_card VARCHAR(100) COMMENT '身份证',
    mobile VARCHAR(100) COMMENT '手机', 
    nation VARCHAR(10) COMMENT '民族', 
    residential_city VARCHAR(100) COMMENT '居住城市',
) COMMENT='customer' CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
""")

vn.train(question='年龄最大的是哪个?',sql='SELECT name FROM customer ORDER BY age DESC LIMIT 1')

可能直接给个问答对即可。引导vn去customer表中查询。
不行的话这两句vn.train都加上。

【4 - 测试:与数据库对话】

以上的准备工作完成后,就可以与你的关系型数据库对话了:

vn.ask('统计不同民族数量?')

控制台可以看到输出的结果,包含了SQL和执行结果:
在这里插入图片描述
并且会弹出一个网页,显示执行的结果
在这里插入图片描述
【5 - 前端Web APP测试】
Vanna提供了一个内置的基于Flask框架的Web APP,可以直接运行后,通过更直观的界面与你的数据库对话,并且具有图表可视化的效果,还内置了简单的RAG Model数据的管理功能。通过这种方式启动web App:

from vanna.flask import VannaFlaskApp
app = VannaFlaskApp(vn)
app.run()

通过默认的端口访问http://localhost:8084,即可与你的数据库对话,界面如下:
在这里插入图片描述
在这里插入图片描述
以上,我们深入了解了Vanna这样一个基于Python与RAG的Text2SQL交互式数据分析框架。借助这样的框架,我们无需太多关心Prompt的构建、组装与优化,就可以快速实现一个基于Text2SQL方案的交互式数据库对话机器人,且具备更高的正确率。

此外,Vanna也提供了一些有用的关联功能:

  • RAG model数据的查询与管理API
  • 基于Plotly的结果可视化API
  • 前端Web APP的简单参考实现

在实际测试中,我们也发现Vanna仍然存在一些问题,

  • 大部分问题和我们交给Vanna训练RAG model的信息不足
  • 倾向于一次性生成,不便基于上一句SQL进行调优[增、删、改]

根据Vanna.ai官方的未来愿景规划,Vanna旨在成为未来创建AI数据分析师的首选工具。并在准确性(Text2SQL的最大挑战)、交互能力(能够实现交互协作,比如要人类做进一步澄清、解释答案、甚至提出后续问题),与自主性(主动访问必要的系统和数据甚至触发工作流程等)三个方面更加接近人类数据分析师,我们希望Vanna未来能够展示更强大的能力。

6. 训练技巧

利用好 SQL问答对

  • 没添加SQL问答对之前
    问:居住在重庆市的人有哪些?
    答:SQL语句不够准确

    SELECT name 
    FROM customer 
    WHERE residential_city = '重庆'; 
    

    在这里插入图片描述

  • 添加SQL问答对之后
    问:居住在重庆市的人有哪些?
    答:SQL语句可以模糊匹配,可以得到准确的查询结果

    SELECT name 
    FROM customer 
    WHERE residential_city LIKE '%重庆%'; 
    

    在这里插入图片描述

代码自取

import vanna
from vanna.remote import VannaDefault
from vanna.flask import VannaFlaskApp
import pandas as pd
import mysql.connector

api_key = '7acxxx68c'
vanna_model_name = 'community'
vn = VannaDefault(model=vanna_model_name, api_key=api_key)

def run_sql(sql: str) -> pd.DataFrame:
    cnx = mysql.connector.connect(user='root',password='111000',host='localhost',database='Community')
    cursor = cnx.cursor()
    cursor.execute(sql)
    result = cursor.fetchall()
    columns = cursor.column_names
    # print('columns:',columns)
    df = pd.DataFrame(result, columns=columns)
    return df

# 将函数设置到vn.run_sql中
vn.run_sql = run_sql
vn.run_sql_is_set = True

# vn.train(ddl="""
# CREATE TABLE IF NOT EXISTS customer (
#     name INT PRIMARY KEY COMMENT '姓名', 
#     gender INT COMMENT '性别(男性=1/女性=2)', 
#     id_card VARCHAR(100) COMMENT '身份证',
#     mobile VARCHAR(100) COMMENT '手机', 
#     nation VARCHAR(10) COMMENT '民族', 
#     residential_city VARCHAR(100) COMMENT '居住城市',
# ) COMMENT='customer' CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
# """)

vn.train(question='年龄最大的是哪个?',sql='SELECT name FROM customer ORDER BY age DESC LIMIT 1')
vn.train(question='居住在重庆的人有哪些?',sql="SELECT name FROM customer WHERE residential_city LIKE '%重庆%'")


first_conversation_sql = vn.ask('居住在重庆的人有哪些?')
print(type(first_conversation_sql))

app = VannaFlaskApp(vn)
app.run()

【参考链接】
手把手教你本地部署开源 Text-to-SQL 工具:Vanna
Vanna:10分钟快速构建基于大模型与RAG的SQL数据库对话机器人

03-11
<think>好的,我现在需要处理用户关于Vanna的问题。首先,用户提到了Vanna,并引用了一个示例代码,说明用户可能想了解如何使用Vanna进行数据库查询。用户的问题可能集中在如何设置和使用Vanna,特别是如何快速开始。 首先,我需要回忆Vanna的基本信息。Vanna是一个Python库,用于通过自然语言生成SQL查询。它默认使用OpenAI的LLM和在线向量库,所以用户不需要自己配置这些,只需要提供API密钥和模型名称即可。用户提供的示例代码显示,只需五行代码就能连接数据库并提问,这可能让用户觉得入门简单。 接下来,我需要确保回答符合用户的要求。用户希望回答结构清晰,分步骤解决问题,并保证真实可靠。根据用户提供的引用,Vanna的默认设置确实支持使用其在线服务,无需额外配置。因此,我需要详细说明安装、初始化、连接数据库和提问的步骤,每个步骤给出代码示例,并解释参数的作用,比如model和api_key的来源。 另外,用户要求生成相关问题,我需要考虑用户可能进一步询问的内容。例如,Vanna支持的数据库类型,如何自定义模型,处理复杂查询的方法,以及本地部署的可能性。这些问题都是用户在使用Vanna过程中可能遇到的后续问题。 需要注意的是,回答中所有行内数学表达式必须用$...$,但这里可能用不上。不过如果有涉及公式的地方,比如性能分析中的时间复杂度,可能需要使用,但当前问题主要涉及代码和步骤,可能不需要数学表达式。但独立公式需要$$...$$,同样可能不适用。 另外,用户提到“使用中文回答”,所以整个回答必须用中文,并且引用标识要自然添加。在引用用户提供的示例时,需要在末尾加上[^1]。例如,在说明Vanna默认支持在线LLM服务时,引用该部分。 最后,生成的相关问题需要围绕Vanna的使用场景、配置、扩展功能等方面,帮助用户深入了解。例如,支持哪些数据库、自定义模型、处理复杂查询、本地部署等。这些问题应该能引导用户进一步探索Vanna的功能。 总结回答结构: 1. 简要介绍Vanna及其用途。 2. 分步骤说明如何使用Vanna,包括安装、初始化、连接数据库、提问。 3. 每个步骤给出代码示例和解释。 4. 生成相关问题,覆盖用户可能关心的扩展内容。 需要确保代码示例正确,特别是用户提供的示例中连接SQLite数据库的URL是否正确,是否需要本地文件还是支持远程连接。根据引用内容,示例中使用的是https URL,可能Vanna支持远程SQLite连接,或者是否有其他数据库的支持方式。需要确认这一点,避免给出错误信息。例如,可能用户需要先下载数据库文件到本地,或者Vanna确实支持远程SQLite连接。在回答中应指出连接方式,比如使用connect_to_sqlite函数并传入路径或URL。 另外,用户可能对API密钥和模型名称的来源有疑问,需要说明如何获取这些信息,例如在Vanna的注册流程中获取模型名称,而API密钥来自OpenAI。或者Vanna是否提供自己的API密钥?根据引用内容,示例中的api_key可能是Vanna的API key还是OpenAI的?需要明确。根据引用中的描述,“默认情况下,Vanna支持使用其在线LLM服务(对接OpenAI)”,可能意味着用户需要提供OpenAI的API key,而model_name可能是Vanna特定的模型名称。或者,Vanna可能提供自己的服务,用户需要在其平台注册获取model和api_key。这点可能需要进一步确认,但根据示例中的代码,model和api_key是创建VannaDefault实例的参数,可能用户需要在Vanna的平台注册账户,获取这些凭证,而Vanna的后端对接了OpenAI。因此,在回答中需要提示用户需要注册Vanna并获取相应的model名称和API key,或者如果直接使用OpenAI的API key,需要说明。 此外,可能存在的错误点是用户是否必须使用SQLite,或者是否支持其他数据库如PostgreSQLMySQL等。根据引用中的connect_to_sqlite函数,可能Vanna默认支持SQLite,但可能还有其他连接方法。需要指出Vanna可能支持其他数据库,但示例中使用的是SQLite,用户可以根据文档连接其他类型。 在生成的问题中,可以包括如何连接到其他数据库,如何处理更复杂的查询,是否支持本地部署LLM等,这些都是用户可能感兴趣的点。 最后,确保回答中没有使用Markdown格式,所有代码块用三个反引号包围,并正确标注语言为python。同时,检查LaTeX语法是否正确,但当前问题可能不涉及数学公式,所以可能不需要使用。</think>### 关于Vanna的使用说明 Vanna是一个基于自然语言生成SQL查询的Python库,默认集成了OpenAI的大语言模型(LLM)和在线向量库,无需额外配置即可快速使用。以下是基础使用方法: --- #### **1. 安装与初始化** 安装Vanna库并初始化模型: ```python pip install vanna ``` ```python import vanna from vanna.remote import VannaDefault # 初始化模型(需注册获取model_name和api_key) vn = VannaDefault(model="your_model_name", api_key="your_api_key") ``` --- #### **2. 连接数据库** 通过URL或本地路径连接数据库(示例为SQLite): ```python # 连接远程SQLite数据库(或本地路径如'./Chinook.sqlite') vn.connect_to_sqlite('https://vanna.ai/Chinook.sqlite') ``` --- #### **3. 通过自然语言提问** 直接输入问题生成SQL并返回结果: ```python # 提问并获取答案 response = vn.ask("What are the top 10 albums by sales?") print(response) ``` --- #### **4. 核心流程** 1. **自然语言解析**:Vanna将问题转换为SQL查询(依赖LLM)[^1]。 2. **数据库执行**:自动执行生成的SQL并返回结果。 3. **结果优化**:支持通过后续提问修正查询逻辑。 ---
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华尔街的幻觉

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值