目录
一、前言
数字经济时代,数据已成为企业的核心资产,它不仅驱动着业务决策,也是推动创新和增长的关键动力,而SQL则是释放这些资产价值的主要工具。然而,SQL的复杂性往往成为非技术用户难以跨越的障碍,为了解决这一问题,Text2SQL技术应运而生,它允许用户通过自然语言与数据库交互,大幅降低了数据分析的门槛。
Vanna.AI 是一款基于 RAG 技术的 Text2SQL 工具,用户只需提出问题,即可快速从数据库获取查询结果。这款工具进一步简化了用户与数据的交互,将自然语言查询自动化、智能化地转化为准确的 SQL 代码。
二、Vanna.AI
(1)介绍
Vanna是一个基于 MIT 许可的开源 Python 检索增强生成 (RAG) 框架,专用于 SQL 生成及相关功能。它的优势在于大幅减少编写 SQL 的时间,使用户能够专注于数据分析和洞察的获取。无论你是否精通 SQL,Vanna 都能让你轻松从数据库中获取有用信息。如果你是 SQL 专家,Vanna 通过简化提问方式生成查询,也能帮助你节省大量时间,你只需提出业务问题,Vanna 即可从数据资产中找到相关的表和字段,并返回所需答案。
(2)原理
Vanna 是一款旨在普及 SQL 使用的 AI 代理。它基于 OpenAI 和 Google 的预训练大型语言模型(LLM),并支持微调为数据库定制的专用模型。Vanna 的核心是一个 Python 软件包,利用检索增强生成(RAG)技术,帮助用户为数据库生成精准的 SQL 查询。
Vanna 的工作分为两个简单的步骤 - 在您的数据上训练 RAG"模型",然后提出问题,这些问题将返回 SQL 查询,这些查询可以设置为在您的数据库上自动运行。
1、训练模型
首先,需要在数据集上训练一个"自定义模型"。使用的数据质量越高,数量越大,"模型"的性能就越好。下面以本地Milvus向量库及问学本地Embedding模型为基础,以DDL SQL处理为例,部分代码如下所示:
定义Milvus的基础信息
class MilvusVectorStore(VannaBase):
def __init__(self, config=None):
VannaBase.__init__(self, config=config)
self.alias = "default"
connections.connect(
alias=self.alias, host='127.0.0.1', port=31201,
user='root', password='Milvus12345', db_name='default',
)
self.embedding_function = self.default_embedding_fn()
self._embedding_dim = 1024
# 创建默认的ddl doc sql的collection
self._create_collections()
self.n_results = config.get("n_results", 10)
将ddl内容embedding处理并入向量库
def add_ddl(self, ddl: str, **kwargs) -> str:
if len(ddl) == 0:
raise Exception("ddl can not be null")
_id = str(uuid.uuid4()) + "-ddl"
embedding = self.embedding_function(texts=[ddl])[0]
data = {
"id": _id,
"ddl": ddl,
"vector": embedding
}
# Get an existing collection.
collection = Collection("vanna_ddl")
collection.insert(data)
collection.flush()
return _id
根据相似度从向量库中检索
def get_related_ddl(self, question: str, **kwargs) -> list:
collection = Collection("vanna_ddl") # Get an existing collection.
collection.load()
search_params = {"metric_type": "L2", "params": {"nprobe": 128}}
embedding = self.get_question_vector(question)
milvus_res = collection.search(
anns_field="vector",
data=embedding,
expr=None,
limit=self.n_results,
output_fields=["ddl"],
param=search_params,
consistency_level="Strong"
)
milvus_res = milvus_res[0]
list_ddl = []
for doc in milvus_res:
list_ddl.append(doc.entity.ddl)
class VannaMilvus(MilvusVectorStore, VannaCustomModel):
def __init__(self, config=None):
MilvusVectorStore.__init__(self, config=config)
VannaCustomModel.__init__(self, config=config)
vn_milvus = VannaMilvus(config=config)
#定义ddl sql语句 ddl_text
vn_milvus.train(ddl=ddl_text)
#定义sql及对应的question
#例如question='查询学生数量' sql='select count(*) from student'
vn_milvus.train(question=question, sql=sql_text)
#定义业务或字段相关的描述
vn_milvus.train(documentation='大模型信息存储表type字段为模型类型,其值需要从字典表中翻译做转换')
Embedding数据入库如下所示:
2、 提问
模型训练完成后,可以开始进行提问。Vanna 将利用该模型生成 SQL 查询,从目标数据库中检索出所需的数据
。
//定义连接的数据库,可将mysql替换为hive、clickhouse、oracle、postgres等多种常用数据库
vn_milvus.connect_to_mysql(host='127.0.0.1', dbname='vanna_test', user='root', password='123456', port=3306)
#根据问题只生成sql
generate_sql = vn_milvus.generate_sql('查询字典名称包含大模型类型的字典类型所对应的字典数据')
#根据问题生成sql并执行该sql,并且查询数据以元组格式返回
res = vn_milvus.ask('查询字典名称包含大模型类型的字典类型所对应的字典数据', False, False, False)
查询效果如下所示:
图1
图2
在图2中,更改提问内容后,通过将 DDL、文档数据(doc)和 SQL 作为提示词输入到大模型,模型成功生成了正确的三表关联 SQL 查询,并对输出字段进行了准确的调整,最终生成了符合要求的结果。
三、总结
本文介绍了 Vanna 的基本使用流程,涵盖了从设置和模型训练到连接数据库并利用其功能的各个环节。在模型训练阶段,需准备充足的 SQL、DDL 以及文档数据,这些数据应能准确描述表结构、字段含义、表与表之间的关联字段,以及特殊字段和业务术语的解释。
这有助于模型更好地理解数据和用户需求,提升其生成准确 SQL 的能力。在此充分准备的基础上,提问的准确率会有所提高。然而,仍可能存在 SQL 生成不准确,导致查询结果异常的情况。这时,可以通过其他方式进行优化,例如,优先使用宽表以减少表间关联查询,或采用理解能力更强的模型。
参考资料:
[1]. Vanna AI GitHub: GitHub - vanna-ai/vanna
[2]. Vanna AI Docs: Vanna.AI Documentation
作者:叶会林| 高级AI开发工程师
版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。
公众号搜索神州数码云基地,了解更多技术干货。