【ChatBI】text2sql 不碰数据表:Vanna 轻量 Python 库快速上手,用 TaoToken 统一 Key 对接 oneapi
发布时间:2026/9/28 4:08:16来源:尧图网络
1. 为什么 ChatBI 里的 text2sql 总要先连库做 ChatBI 最尴尬的一步往往不是模型不会写 SQL而是你还没开始问就得先把数据库连接、表结构、字段注释全喂进去。很多 text2sql 方案默认要连生产库、拉 schema、甚至采样数据权限审批一圈下来Demo 还没跑通。Vanna 这个轻量 Python 库的思路正好相反它不碰你的数据表只靠你手写的建表 DDL 和几条示例 SQL 做检索增强让大模型模仿着生成查询语句。适合谁适合想快速验证 ChatBI 链路、又不想动生产库的 Python 开发者也适合把 text2sql 当成一个可插拔模块塞进现有系统的团队。这篇聚焦一件事用 Vanna 跑通「安装 → 训练 → 提问生成 SQL」的最小闭环并且用 TaoToken 统一 Key 对接 oneapi 风格的 OpenAI 兼容接口。你不需要真实数据只要几段 DDL 就能看到 SQL 被生成出来。整个过程我按可复制配置来写settings 片段、依赖清单、三步验证动作都给全照着敲就能复现。2. TaoToken 前置统一 Key 与 oneapi 通道Vanna 本身不绑定任何模型厂商它通过 OpenAI 兼容客户端发请求。所以只要你的接口是/v1/chat/completions这种形态就能接。这里用 TaoToken 作为统一入口好处是 Key 和 base_url 只维护一份后面换模型不用改 Vanna 的代码。先准备两样东西一个可用的 API Key以及确认你的调用地址。TaoToken 的 API 地址是https://taotoken.net/api注意这个地址不带任何查询参数直接作为 base_url 使用。Key 在控制台里创建创建入口在这里创建和管理 Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite接入文档确认参数格式https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite如果你只是想先确认模型能不能正常对话可以打开模型对话页面试一句模型对话https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite注意base_url 填https://taotoken.net/api不要自己拼/v1/v1。OpenAI SDK 会自动补/chat/completions这一段多写一层就会 404。拿到 Key 之后先别急着写 Vanna用最朴素的方式验证通道。这一步能省掉后面大量「到底是 Vanna 的问题还是网络的问题」的排查时间。from openai import OpenAI client OpenAI( api_key你的_TaoToken_Key, base_urlhttps://taotoken.net/api, ) resp client.chat.completions.create( modelmoonshot-v1-8k, # 换成你账号下可用的模型名 messages[{role: user, content: 你好}], max_tokens64, ) print(resp.choices[0].message.content)能打印出内容说明 Key、地址、模型名三者对齐了。如果这里就报错先解决它别往下走。3. 可复制配置依赖清单与 Vanna 骨架3.1 依赖清单Vanna 的核心包加上向量存储和 OpenAI 适配装这几个就够跑最小闭环pip install vanna openai chromadbvanna提供ChromaDB_VectorStore和OpenAI_Chat两个混入类chromadb是默认的本地向量库openai负责发请求。版本上不用太纠结能 import 成功即可。如果公司内网装包慢配好镜像源再装。3.2 把配置抽成 settings我习惯把地址、Key、模型名抽出来避免散落在代码里。建一个settings.py# settings.py TAOTOKEN_BASE_URL https://taotoken.net/api TAOTOKEN_API_KEY 你的_TaoToken_Key MODEL_NAME moonshot-v1-8k # 按账号可用模型替换然后主程序里组合 Vanna。关键点是自定义一个类同时继承向量存储和对话能力再把 OpenAI client 注入进去# vanna_demo.py from openai import OpenAI from vanna.openai.openai_chat import OpenAI_Chat from vanna.chromadb.chromadb_vector import ChromaDB_VectorStore from settings import TAOTOKEN_BASE_URL, TAOTOKEN_API_KEY, MODEL_NAME client OpenAI( api_keyTAOTOKEN_API_KEY, base_urlTAOTOKEN_BASE_URL, ) class MyVanna(ChromaDB_VectorStore, OpenAI_Chat): def __init__(self, clientNone, configNone): ChromaDB_VectorStore.__init__(self, configconfig) OpenAI_Chat.__init__(self, clientclient, configconfig) vn MyVanna(clientclient, config{model: MODEL_NAME}) vn.temperature 0.7这里config{model: MODEL_NAME}是必须的Vanna 发请求时会读这个字段。temperature可以按需调生成 SQL 我一般压到 0.7 以下减少胡编字段名的概率。3.3 训练只喂 DDL 和示例 SQLVanna 的「训练」不是微调模型而是把 DDL、文档、示例 SQL 存进向量库提问时检索出最相关的几条拼进 prompt。所以它不需要访问你的真实数据表。下面喂两张表的建表语句vn.train(ddl CREATE TABLE IF NOT EXISTS users ( id INT PRIMARY KEY COMMENT 用户ID, username VARCHAR(50) COMMENT 用户名, email VARCHAR(100) COMMENT 电子邮件, age INT COMMENT 年龄, gender VARCHAR(10) COMMENT 性别男/女, city VARCHAR(50) COMMENT 城市 ) COMMENT用户信息表 CHARACTER SETutf8mb4; ) vn.train(ddl CREATE TABLE IF NOT EXISTS consumption_record ( id INT PRIMARY KEY COMMENT 消费记录ID, user_id INT COMMENT 用户id, item_id INT COMMENT 商品id, amount INT COMMENT 数量, consumption INT COMMENT 总消费 ) COMMENT购买记录 CHARACTER SETutf8mb4; )字段注释一定要写清楚Vanna 生成 SQL 时靠这些注释理解语义。你还可以补几条示例 SQL让它模仿你的查询风格vn.train(sqlSELECT city, COUNT(*) FROM users GROUP BY city) vn.train(sqlSELECT SUM(consumption) FROM consumption_record WHERE user_id 1)DDL 和示例 SQL 越多越准但最小闭环两张表就够验证链路了。4. 验证请求三步确认链路可用4.1 第一步确认连接在训练之前先单独测一次对话接口确认 Vanna 用的 client 能通resp client.chat.completions.create( modelMODEL_NAME, messages[{role: user, content: 回复 ok}], max_tokens16, ) print(resp.choices[0].message.content)打印出内容即连接正常。这一步和第二节的验证重复但放在 Vanna 脚本里跑一遍能确认settings.py里的变量确实被读到了。4.2 第二步确认训练入库训练后可以查一下向量库里存了多少条training_data vn.get_training_data() print(training_data)正常会看到你刚喂进去的 DDL 和 SQL 记录。如果这里是空的说明训练没写进去检查ChromaDB_VectorStore的初始化参数默认会在当前目录建一个 chroma 持久化目录。4.3 第三步生成 SQL这是最关键的验证动作。提两个问题看生成的 SQL 是否引用了正确的表和字段query 男性用户的总消费是多少 sql vn.generate_sql(query) print(问题, query) print(SQL, sql) query2 男性用户有多少个 sql2 vn.generate_sql(query2) print(问题, query2) print(SQL, sql2)预期输出类似SELECT SUM(c.consumption) FROM users u JOIN consumption_record c ON u.id c.user_id WHERE u.gender 男;第二个问题应该生成SELECT COUNT(*) FROM users WHERE gender 男这类语句。注意Vanna 只生成 SQL不执行。要不要跑、在哪跑由你的系统决定这也是它「不碰数据表」的体现。如果你还想直接看模型对生成结果的解释可以在模型对话页面里手动贴同样的 prompt 对比模型对话https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite5. 本篇常见错排查5.1 报 404 或 model not found最常见的是 base_url 写错。https://taotoken.net/api后面不要再加/v1OpenAI SDK 会自己拼路径。另外模型名要和账号下可用的名称完全一致大小写、连字符都不能差。先在模型对话页面确认模型名再填进settings.py。5.2 生成的 SQL 字段名对不上多半是 DDL 注释太简略或者训练数据太少。Vanna 靠检索相似内容拼 prompt如果字段注释是空的模型只能猜。把COMMENT补全再补几条覆盖常见查询的示例 SQL准确率会明显上升。另外temperature调低一点也有帮助。5.3 训练数据重复或串味反复运行同一个脚本DDL 会被重复写入向量库检索时可能召回一堆重复项。开发阶段可以每次清掉 chroma 目录再跑或者用vn.remove_training_data(id)按 id 删除。生产环境建议把训练数据做成幂等的初始化流程。5.4 接口偶发超时生成 SQL 的 prompt 比普通对话长响应时间会更久。给 client 设置合理的 timeout别用默认的短超时client OpenAI( api_keyTAOTOKEN_API_KEY, base_urlTAOTOKEN_BASE_URL, timeout60.0, )如果长期在编码或 Agent 场景里高频调用可以考虑用 Coding Plan 把额度固定下来避免临时限流打断调试Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite5.5 中文注释乱码建表语句里的中文注释如果编码不对向量化后会变成乱码检索自然不准。确保脚本文件是 UTF-8DDL 字符串里不要混入其他编码的字符。数据库侧用utf8mb4保持一致。6. 把链路固定下来再谈扩展跑通最小闭环后你会发现 Vanna 的价值在于「解耦」模型通道由 TaoToken 统一管训练数据由你手写 DDL 控制生成 SQL 和执行 SQL 分开。这样换模型、换向量库、换数据库都不影响其他部分。下一步可以做的扩展包括把训练数据从文件加载、给generate_sql加一层字段白名单校验、把生成的 SQL 交给只读账号执行。但这些都是后话先把第三节的配置和第四节的三个验证动作跑通链路确认可用再往上叠功能。需要长期维护 Key 和调用记录的话控制台里可以随时查看和轮换API Keyshttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite
网站建设高端定制企业官网