Vanna训练数据初始化指南:三步跑通文本转SQL
【免费下载链接】vanna🤖 Chat with your SQL database 📊. Accurate Text-to-SQL Generation via LLMs using Agentic Retrieval 🔄.项目地址: https://gitcode.com/GitHub_Trending/va/vanna
导入了 200 条问答,vn.ask()依然对着不存在的表名生成查询——这通常是训练数据初始化没做对,而不是 LLM 不行。Vanna 是一个基于 RAG 检索增强生成的文本转SQL框架,它靠训练数据"认识"你的数据库,再检索出相关素材生成 SQL。读完本文,你能完成第一次训练数据导入、校验与试跑,拿到一个稳定可查的模型。
📦 三类训练素材及其分工
喂数据之前,先搞清楚三类素材的分工:
| 素材 | 对应数据形态 | 典型来源 | 缺失后果 |
|---|---|---|---|
| DDL 模式 | CREATE TABLE语句 | DBA 迁移脚本、数据库元数据 | LLM 编造表名、列名 |
| 问答对 | 问题 + 可执行 SQL | 业务方历史查询、BI 报表语句 | 生成的 SQL 缺乏业务语义 |
| 业务文档 | 自然语言术语定义 | 指标口径文档、业务词典 | 口径混淆(如"总薪酬"算哪些项) |
底层机制不复杂:三类素材统一做 embedding 后存入向量库,入口是 base.py 里的train方法;提问时再用问题的 embedding 检索出相关片段拼进 prompt。所以这里的"训练"本质是建知识库,不是参数学习——素材给错,检索层就会把错的喂给 LLM。
从 0 到 1:三步喂数据
第一次训练数据导入可以一口气完成,关键是每一步都留下判断依据。
第一步:导入训练数据
目的:让模型同时拿到"库长什么样"和"业务怎么问"两方面的信息。
vn.train(ddl="CREATE TABLE salaries (id INT PRIMARY KEY, company VARCHAR(100), base_salary FLOAT, bonus FLOAT)") vn.train(question="哪家公司总薪酬最高?", sql="SELECT company, AVG(base_salary + bonus) AS total FROM salaries GROUP BY 1 ORDER BY total DESC LIMIT 3") vn.train(documentation="总薪酬 = 基本工资 + 奖金 + 股票授予")- 判断标准:
train返回存储片段的 ID 且不抛异常;只传question不传sql会直接报Please also provide a SQL query,这条报错本身就是校验逻辑。
第二步:用表格校验训练数据
目的:确认三类素材真的都落库了,数量与内容没有缺漏。
df = vn.get_training_data() print(df.groupby("type").count()) # 核对 ddl / question / documentation 三类条数- 判断标准:
type分组计数与导入条数一致,抽查文本字段是完整的 SQL 或完整句子,没有截断和乱码。
第三步:试跑验证 SQL 可执行
目的:用一条覆盖已喂口径的问题,验证检索链路端到端可用。
sql = vn.ask("哪家公司总薪酬最高?") print(sql) # 连接了数据库时,ask 也可以直接返回执行结果表- 判断标准:生成的 SQL 使用的是你导入的表和列名,且
base_salary + bonus这类口径与文档一致;如果结果不符合预期,先怀疑素材缺失,而不是换更大的 LLM。
🕳️ 高频踩坑与修复路径
按出现频率从高到低,每个坑都是"症状 → 根因 → 修复动作":
- 生成 SQL 编造表名/列名→ DDL 没导入,或 DDL 列名与实际库不一致 → 补导 DDL,逐列核对命名。
- 指标数值不对→ 术语(如"总薪酬")没有定义,LLM 自行猜口径 → 补一条
documentation写清计算公式。 - 重复导入片段→ 每次重跑都追加,检索结果被旧数据污染 → 清空对应集合重新导入,或按 ID 删除。
- SQL 报方言错误→ 训练 SQL 来自别的库(如把 MySQL 函数喂给 Postgres)→ 统一成当前库方言后重导。
想系统性排查数据格式,可以写一个validate_training_data(file_path)函数,只校验每条记录是否含question/answer两个字符串字段即可。
让训练集跟着业务一起演进
库在变,训练集也要有版本。建议按版本快照管理,每版三类素材分目录存放:
training_data/ ├── v1.0/ │ ├── ddl/ │ ├── questions/ │ └── documentation/ └── v2.0/ ├── ddl/ ├── questions/ └── documentation/变更检测的触发点放在结构迁移脚本之前:提取当前库的CREATE TABLE语句,与最新版快照做 diff,有差异就追加vn.train(ddl=...)并归档旧快照;问答对同理,口径变更后先补新版问题,再删旧片段。这样每次变更对 SQL 生成准确率的提升都是可回溯的。
下一步可以去看 evaluation 模块量化准确率变化,或用 Flask UI 收集人工反馈回流进训练集。
整条操作路径其实就一句:训练数据导入 → 表格校验 → ask 试跑 → 坏 case 回流训练集,循环。 三类素材不在多而在对,先保证 DDL、问答对、文档各就位,再谈规模。 你喂的数据就是模型能力的上限,喂得对比喂得多重要得多。
训练数据是模型唯一的资产,建议把各版本 training_data 目录与向量库导出文件一起定期备份;完整参数说明见 README.md。
【免费下载链接】vanna🤖 Chat with your SQL database 📊. Accurate Text-to-SQL Generation via LLMs using Agentic Retrieval 🔄.项目地址: https://gitcode.com/GitHub_Trending/va/vanna
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考