基于网站开发小程序,建立百度网站,网站建设Skype打不开,做装修工程找什么网站接单今天我们来重点研究与实测一个开源的Text2SQL优化框架 – Vanna 1. Vanna 简介【Text-to-SQL 工具】
Vanna 是一个基于 MIT 许可的开源 Python RAG#xff08;检索增强生成#xff09;框架#xff0c;用于 SQL 生成和相关功能。它允许用户在数据上训练一个 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(modelmodel_name, api_keyapi_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_VectorStoreclass MyVanna(ChromaDB_VectorStore, OpenAI_Chat):def __init__(self, configNone):ChromaDB_VectorStore.__init__(self, configconfig)OpenAI_Chat.__init__(self, configconfig)vn MyVanna(config{api_key: sk-..., model: gpt-4-...})这里的OpenAI_Chat和ChromaDB_VectorStore是Vanna已经内置支持的LLM和VectorDB。 如果你需要支持 没有内置支持的LLM和vectorDB 则需要首先 扩展出自己的LLM类与VectorDB类 实现必要的方法具体可参考官方文档 然后再 扩展出自己的Vanna对象
4.2 自定义关系型数据库
Vanna默认支持PostgresSQL ServerDuck DBSQLite等关系型数据库可直接对这一类数据库进行自动访问实现数据对话机器人。 但如果需要连接自己企业的其他数据库比如企业内部的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(modelvanna_model_name, api_keyapi_key)由于我们需要使用自己的本地Mysql数据库需要定义一个run_sql方法 设置好MySQL数据库的user 、password、host 和 database
这个database名称是DBeaver工具customer上方的数据库名称CommunityRAG model的名称是网页上设置的 community首字母是小写的各位别抄错啦按自己的配置来哈
import pandas as pd
import mysql.connectordef run_sql(sql: str) - pd.DataFrame:cnx mysql.connector.connect(userroot,password111000,hostlocalhost,databaseCommunity)cursor cnx.cursor()cursor.execute(sql)result cursor.fetchall()columns cursor.column_namesdf pd.DataFrame(result, columnscolumns)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(planplan)我构建计划(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 居住城市,
) COMMENTcustomer CHARACTER SETutf8mb4 COLLATEutf8mb4_unicode_ci;
)vn.train(question年龄最大的是哪个,sqlSELECT 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.connectorapi_key 7acxxx68c
vanna_model_name community
vn VannaDefault(modelvanna_model_name, api_keyapi_key)def run_sql(sql: str) - pd.DataFrame:cnx mysql.connector.connect(userroot,password111000,hostlocalhost,databaseCommunity)cursor cnx.cursor()cursor.execute(sql)result cursor.fetchall()columns cursor.column_names# print(columns:,columns)df pd.DataFrame(result, columnscolumns)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 居住城市,
# ) COMMENTcustomer CHARACTER SETutf8mb4 COLLATEutf8mb4_unicode_ci;
# )vn.train(question年龄最大的是哪个,sqlSELECT name FROM customer ORDER BY age DESC LIMIT 1)
vn.train(question居住在重庆的人有哪些,sqlSELECT 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 Vanna10分钟快速构建基于大模型与RAG的SQL数据库对话机器人