引言:最近在做nlp2sql的项目,就是用大模型把人话转成sql语句的项目,所以才会有这一篇文章,文章重点在vanna,NL2SQL-benchmark。这是我接触的第一个大模型的项目,所以这边文章会以这个项目为线索,混杂许多内容去讲,涉及到大模型、dify、spider、vanna、NL2SQL-benchmark等学习,反正就是很杂,每个都会讲,但是都不一定足够的深入,如果以后有机会把每个都学深入了,我再把每块都写一篇文章出来,但是这里要说两句话算是我的学习经验或者说感受吧(不一定对):1.不要老想着把每个块都学明白,学不完的,而且实际项目中很有可能是只会用到块的某个部分,只需要把这个块的某部分学透就行。2.最好的不如最合适的,这句话会在后面选择框架体现出来(当然了其实在很多事情上都会体现这个道理,嘿嘿)

一.dify(不细讲)

dify是个啥,在我看来就是一个比较浅显、快速地制作出agent(智能体,老实说我讨厌AI里的英文,毕竟上一篇文章我说了,AI相关的很多定义都是模糊的,所以这些知识里老是中英文混杂很烦)、工作流的框架,能够让人可以快速上手AI项目的这么一个搭建框架。dify里面有太多功能了,我也没学透彻,也没有使用完,就是用了一些比较浅显的功能,在画布上面拖拽出一个工作流,然后简单地实现了一个nlp2sql的功能,对,然后就被批说是这个工作是一个初高中生都可以完成的。(好吧,我承认这东西确实是新手入门的东西,实际项目不可能用低代码框架实现,但我不就是个新手吗,那我不得先从简单的开始啊)

关于dify使用时产生的一些问题:1.docker的使用,如何理解镜像与容器。2.会话管理(这俩问题是我在做的时候遇到的问题,暂时不在这篇文章中深入)

二.ollama(不细讲)

ollama是个啥,ollama前一篇文章就说了,它是一个推理框架,当然了它同时还有模型管理与会话管理的能力(应该是吧,因为可以从它的库里面下载模型,以及可以直接用它来与模型对话交互)。ollama的要深入了解后续再说吧,大不了再出一篇文章,但是实际上ollama也算是一个比较简单新手的框架,实际项目中会用到的还是像vllm这些。这里也可以看出,其实所谓的简单低代码就是封装的太好了,规定的太死了,能供人二次修改的东西少故而简单,而实际项目中多半都是用那种封装的很一般的,这样的话很多东西都可以让程序员去修改,这也就意味着更加困难了。(这里稍微提一点:ollama导入模型时,ollama的相对路径,是相对于“当前工作目录”,而不是相对于Modelfile本身,所以在.gguf导入olllama时,务必保证Modelfile中FROM路径的识别正确,这一步搞错了的话会导致后续出现报错,如果后面有报错可以检查一下是不是这里加入模型就问题)

三.spider

spider是一个测试数据集,用来测试大模型在执行nlp2sql这件事的正确率,这个在nlp2sql项目上还是比较权威的,现在还有spider2.0出来了,这个就是一个有数据有问题的东西,然后用一些自动化的测试框架,在这些框架上加入你要验证的模型,以及这个spider数据集,它就会自动地去跑这个测试,相当于大模型的考试,然后就会给出评分,也就是正确率,然后你就可以知道你测的这个大模型干nlp2sql的能力了。spider姑且叫1.0吧,其实表中内容还是比较干净整齐的,所以其实还不算很难,但即便在这种情况下我都没有发现有哪个模型敢说成功率100%的;spider2.0这个表就更贴近实际的应用场景,说白了就是表更复杂,更多,查询起来更难,我目前的看到的哈,不说开源模型了,就是闭源模型的成功率最高都才59%多。所以这件事还是比较难的哈,所以要看,能不能拿到实际项目的数据然后对模型进行训练微调了。

四.NL2SQL-benchmark(略微重点)

这个东西就是我前面提到的自动化的测试框架,就是大模型在nlp2sql这件事的考场系统,你把大模型(考生)给他,spider(试卷和答案)给他,他就会完成这场考试并且给出执行正确率(打分)。许多这种测试框架都是原生支持spider的,前面说了嘛spider这个还是比较权威的,spider2.0就不清楚了。

4.1如何使用NL2SQL-benchmark

1.首先是部署NL2SQL-benchmark(一样的下载文件,搭建虚拟环境,pip install对应的包就行)

2.下载spider数据集和你想测试的大模型(这里我把spider数据集链接贴出来,2c671/spider.zip-代码预览-Spider数据集Text-to-SQL介绍:基于 Spider 数据集的 Text-to-SQL 研究资源项目 - AtomGit希望对你有帮助,也可能你使用的时候已经失效了,我当时找这个数据集也好费了段时间,很多包都把这个数据集剔出来了的要单独去下载,不好找)。这里下载模型要注意,因为 NL2SQL-benchmark原生的推理框架是PyTorch + Transformers,所以模型文件下载.safetensors或.bin格式的文件3.我是新手我比较犟,再不清楚其它推理框架前我还是沿用了ollama,那么这里就需要修改一些东西了,也算是误打误撞发现了其实NL2SQL-benchmark是可以使用其它推理框架的嘛(这种项目框架就是好,啥都可以改可以加),因为我要使用ollama来推理(为啥坚持使用ollama,因为新手期简单,而且当时下载成了.gguf的大模型文件,当时还不了解大模型文件有各种文件类型和处理方式),如果你也用非原生的推理框架,可以像我这样做,找到NL2SQL-Benchmark\language_model这个文件夹需要修改utils.py文件(这个相当于是导入文件),以及需要写入你自己对应的文件比如我写的就是OllamaLanguageModel.py(因为我用ollama),然后具体这个要怎么修改怎么写代码问AI吧(这里我就没有具体研究NL2SQL-benchmark的框架了,所以不知道具体代码干啥的,后面再说吧)

3.上面的东西都准备好了就可以开始测试了,激活前面的虚拟环境,然后到项目根目录下有个main.py然后输入以下指令:python main.py -m basic -d spider -l ollama:xiyansql-7b -s vanilla,指令肯定不一致,按照你自己的配置来,反正大致的意思就是:-l 指定模型名称,-d 指定数据集,-m 指定方法,-s 指定 schema_linker,这个具体可以用python main.py -h这个查询一下到底支持哪些参数。然后就会陆续跑测试(这里有个小趣事,我一开始没反应过来本地模型执行这些的时候使用的是本地的GPU,我还是说为啥主机转疯了,这也算是一个判断标准吧,要是成功跑起来了显卡的显存占用会飙起来),最后会弹出一个表格

这个就是最后的表了,上面又执行正确率这些东西。(这个框架从可以改推理框架就可以看出来,其实还是比较灵活的,所以这里算是遗留了一个想法,其实这东西不一定只能测试spider数据集,只要是干测试大模型执行nlp2sql的任务,都可以做,所以不论大模型、推理框架、数据集都是可以修改的,就看怎么去做修改了)

五.Vanna(本文重点)

这个就是一个nlp2sql的框架了,它负责连接你的数据库、你的大模型、你的问题,用户先提问,问题会交给大模型,然后大模型会给出sql语句并在数据库执行,执行后会返回执行结果结果。

5.1nlp2sql框架

我看了有许多的nlp2sql框架:DB-GPT、SuperSonic、Chat2DB、WrenAI、LangGraph / LangChain SQL Agent、DSP(DSPy我都不熟,好像不是严格意义上的nlp2sql框架,而是一种训练框架,可以改善提示词调优。)、vanna(LangGraph / LangChain SQL Agent并不算是严格意义上的nlp2sql框架,只是说可以用来搭建这么一个框架,就是一个手搓/KJHGFDSSDFGHJK;L'
工具),为什么选择vanna,为什么不是DB-GPT这种知名度高的厉害的,因为,我这个项目属于子功能,DB-GPT相对而言比较完整不好搞二次开发,而且这玩意儿DB-GPT的SDK好像对windows不友好,我说的不是前端拖拽画布的方式,而是代码的形式,反正就是部署的时候出问题了,这玩意儿要在服务器上搞才好,至于为什么选vanna肯定就是好二次开发,而且一些自带的功能也不错,所以这里可以印证我文章开头说的话,最好的不如最合适的,就是在这里体现的。你要问为啥不用LangChain自己搭,问就是新手暂时不会,先用现成的,后面肯定会去学习怎么用LangChain搭一个出来。

5.2Vanna1.0(临时翻阅了一下资料2.0好像确实更厉害了一点,好像加了一些身份验证、会话管理之类东西进去,1.0也有但貌似不是强制的,2.0强制的身份验证,这里暂时只讲1.0,2.0我还没用过)

那么正式开讲这个vanna1.0了。

先讲vanna1.0的框架

5.2.1Vanna1.0 是一个基于检索增强生成(RAG)的开源 Python 框架,专门用于将自然语言问题自动转化为 SQL 查询,并能直接连接数据库执行查询、返回结果和可视化图表。

它的核心设计理念是:无需微调大模型,只需用你的数据库“知识”对其进行训练,就能让模型精准理解你的库表结构、字段含义和业务查询习惯。

5.2.2核心理念:训练而非微调(这个算是比较重要的部分,也是解决幻觉的关键)

Vanna 的独特之处在于“训练”这个步骤。这里的训练不是模型参数更新,而是将你的数据库元数据(DDL、文档、示例SQL)转化为向量并存入向量数据库,形成一套“业务记忆”。

当你提问时,它会从向量数据库中检索与问题最相关的 DDL、文档片段和历史 SQL 示例,将这些信息组装成一个信息丰富的 Prompt,再交给大语言模型生成 SQL。这种方式让生成结果对特定数据库有极强的针对性。

5.2.3系统架构与关键组件

Vanna 采用高度解耦的架构,主要抽象层是VannaBase类。你可以把 LLM、向量存储、数据库连接这些部件随意替换。

VannaBase:核心抽象类,定义了框架必须的最小接口。

LLM 客户端:负责调用各种大模型(OpenAI、Anthropic、本地模型等)。

向量存储:存储训练数据的嵌入向量,默认集成 ChromaDB,也支持 Pinecone、Weaviate、Qdrant、Milvus 等。

数据库连接器:用于直接执行生成的 SQL,支持 SQLite、PostgreSQL、MySQL、Snowflake、BigQuery、Redshift 等。

前端接口:内置支持 Jupyter Notebook、Flask Web App、Slack Bot 等。

其工作原理可概括为以下流程:

1.训练过程:

你提供 DDL、业务文档、SQL 示例 → 文本分块 → 嵌入模型转换为向量 → 存入向量数据库。

2.提问阶段:

用户自然语言问题 → 向量化 → 从向量库检索最相关的 DDL / 文档 / SQL 示例 → 与问题组合,构建 Prompt → 发送给 LLM 生成 SQL → 可选自动执行 SQL → 返回表格、数据或图表。

5.2.4训练数据的三种类型

vn.train()是注入知识的入口,支持三种参数:

DDL语句

直接传入建表语句,让模型了解表结构、字段类型和索引。

文档说明

用自然语言描述表/字段的业务含义,这能极大提升生成质量。

SQL示例

以 (question,sql)对的形式提供,让模型学习本数据库的查询风格和写法。

这个vn.train其实就是不同于其它全量ddl注入prompt的关键了,全量ddl作为提示词塞给大模型只在极小的数据库中适用,但是,实际项目中的数据库的表几百上千张都是有可能的,每张表的字段就跟不用说了,要是此时还是全量ddl,这上下文直接疯了好吧,而且什么都给出去也会引起大模型的幻觉问题,所以就会先采用将全部知识(对于数据库而言就是ddl以及问答对文档描述,也就是vanna提供三种类型)先训练了向量化存储(这就是前面为啥要下载一个向量库模块),然后每次提问的时候都会根据语义只召回部分相关知识并作为提示词(vn.generate_sql内部干的就是rag的流程:检索、组装提示词的工作、调模型)发给大模型,这样的话1.不会上下文爆炸2.其实也更准确了。

5.2.5落到我实际项目中,我的过程

首先先部署vanna(具体部署我就不讲了,反正就是先创建虚拟环境,然后pip install下载vanna需要的模块就好了,因为它是Python库所以基本上没什么毛病),值得注意的是,网上基本上都是vanna1.0版本的资料,而最新的2.0版本的资料比较少,而vanna2.0的架构进行了大改,所以很多问题、代码的写法,你用AI问AI都是有问题的(我写代码就AI写,AI写完了再问他代码什么意思,为什么这样写,作用是啥,AI解决不了就自己上官网查资料研究,因为我绝对不会让AI包揽整个项目,只让他看部分代码的问题,所以我也不用花钱的AI,就deepseek/豆包,不想付费上班),所以下载的时候可以先下载vanna1.x版本先用着(用旧用稳不用新哈,这个算是常识了,如果你有探究精神开发者精神也可以尝试,我在后续再看这个vanna2.0有什么过人之处吧,这里我是新手就先用旧版的)。
然后就是写一个main.py,这个main.py里面就是要去写你要前面框架介绍中说的vn.trian中的内容了。这里其实就需要思考一个问题:大模型确实训练了许多相关知识进去,而且这里用的还是做过nlp2sql专项训练的大模型(我用的是XiYan-qween coder),但是即便是这样,实际项目算是特殊场景了,大模型又凭什么知道你数据库中有哪些字段,以及了解字段的含义,以及每个字段下的内容是用什么去表示的、含义又是什么,所以这就是vn.train的重要性了,刚才架构里面说了这里会写入建表语句,以及用户会写入一些类似于提示词的东西,供大模型了解你的数据库到底长什么样子,这样就不会出现幻觉查询一些不存在的字段或者内容了。这里有点搞笑哈,就是这个vn.train中的东西其实是需要自己写的,最好写一个函数可以直接训练整个数据库中的建表语句,一开始我还以为这个东西是vanna自动就会获得的,但是实际上还是需要用户自己写,并不是连上数据库就会自动获取到的。至于代码,必须写的就是:1.数据库配置(这个就是让vanna可以连接上你的数据库)2.vanna要初始化(这里需要根据你使用的是哪个推理框架去写)3.vn.connect_to_xxx()(根据前面的配置连接你的数据库)4.vn.train()(拿数据库中的内容去训练,以及一些用户提示词,以及qs问题sql语句示例对)5.写接口,可以要求返回携带图表以及总结,因为一半直接返回的东西是json,人看得懂但麻烦,也可以把这些返回内容再交给下一个大模型处理然后再返回结果给用户看(我后面就会看一下vanna+LangChain+其它的图表类大模型看能不能实现吧,后面再说)vanna其实原生也有图表能力的(具体代码我就不贴了,只写思路,这个代码不麻烦,deepseek/豆包都写了)。

文章大概就暂时写到这里吧,后续还有深入的研究(比如vanna2.0 比如NL2SQL-benchmark),还会新的文章。我的项目到这里暂时跑通了,但是后续肯定要调优的,架构肯定还要怎么去优化,这边文章只是一个沿着项目为线索的项目记录,其中存在一些问题和误解,不过也算是浅浅地搞通了一个nlp2sql项目了,加油!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐