1. Vanna 是什么
Vanna 是一个开源 Python 框架,用 RAG 做 NL2SQL——不微调模型,而是把你数据库的元数据(DDL、业务文档、问→SQL 示例对)向量化存起来,提问时检索相关上下文拼进 Prompt 让 LLM 生成 SQL,再执行返回结果。核心一句话:Text-to-SQL = RAG 检索元数据 + LLM 生成 SQL + 执行校正。
💡 深入理解 · 为什么不微调模型而用 RAG?① 微调贵、要标注、Schema 一变就得重训;② RAG 只需把 DDL/文档/示例塞向量库,改表结构就更新语料,低成本、可增量、可解释;③ 生成质量靠"给对上下文"而非"改模型权重",和企业 RAG 知识库是同一套方法论,只是产物从"文本答案"变成"可执行 SQL"。
💡 深入理解 · 框架无关 / 库无关:LLM 可换(OpenAI/Claude/本地 Ollama)、向量库可换(ChromaDB/Qdrant/Milvus/PgVector)、数据库可换(MySQL/Postgres/Snowflake/BigQuery/ClickHouse),自带 Streamlit/Flask 前端集成。这种"可插拔"是它流行的原因。
2. 两阶段核心链路
Vanna 只有两个阶段:训练(train)+ 提问(ask)。
训练阶段:喂三类语料,向量化存进向量库(注意:这里的"训练"不是改模型参数,是往向量库塞检索语料)
1. DDL 表结构 → 让模型知道有哪些表、字段、类型、关系(vn.train(ddl="CREATE TABLE ..."))
2. 业务文档 → 字段的业务含义、术语口径、自定义指标定义(vn.train(documentation="..."))
3. 优质「问题→SQL」示例对 → few-shot,模型照着学写法(vn.train(question="...", sql="..."))
提问阶段:
1. 用户自然语言提问
2. 向量检索召回最相关的 DDL / 文档 / 示例对
3. 组装 Prompt 交 LLM 生成 SQL
4. (工程加固)安全校验:只读、白名单、拦 DML/DDL、强制 LIMIT
5. 执行 SQL,报错则把数据库报错回喂模型自校正重写(限次)
6. 返回结果表 + 可视化 / Excel 导出
💡 深入理解 · 关键细节:如果检索不到足够接近的语料,LLM 会退化到仅凭 Schema/文档裸推——Snowflake 实测这种情况准确率只有 ~50%,所以语料覆盖度直接决定准确率下限,这也是为什么"持续补充优质示例"是刚需。
💡 深入理解 · 自我改进闭环:用户验证/纠正过的 问题→SQL 回流训练集,检索质量越用越好——但前提是回流的必须是人工核验过的正确对,错误对被当"权威范例"检索命中会放大传播(见挑刺)。
3. Text-to-SQL 四大难点
记四个词:Schema 映射、业务口径、方言差异、SQL 安全。
| 难点 | 是什么 | 解法 |
|---|---|---|
| Schema linking | 表多字段多,全塞超窗口、召回少又漏表 | 每张表 DDL 单独向量化,按语义只召回相关表;表多再加粗粒度主题分类做两级检索 |
| 业务口径 | "活跃/续费"这种黑话,一词多义、部门理解不同 | 业务术语词典映射到字段+口径;歧义时多轮澄清 |
| 方言差异 | MySQL / ClickHouse / Postgres 语法函数不同 | 训练语料带方言示例;Prompt 指明目标方言 |
| SQL 安全 | 模型可能生成删改库、注入、全表扫描 | 只读账号 + 白名单 + 拦 DML/DDL + 强制 LIMIT(分层防御) |
💡 深入理解 · Schema linking 是核心矛盾(precision/recall 权衡):全量 Schema 塞进 Prompt 会超窗口且稀释注意力;只召回少量又可能漏掉关键表。Vanna 的解法就是用向量检索做 Schema 召回而非全量塞入——范围收窄(如只做一个数据域)时召回精度可控;表上到几十上百张,纯语义检索会漏召回,需要"先主题分类圈候选表,再细粒度语义检索"的两级检索。
4. 准确率评估:execution accuracy vs exact match
评 NL2SQL 准确率有两种口径,必须用执行结果准确率(execution accuracy):
- Exact Match(文本匹配):生成 SQL 和标准答案逐字比——❌ 不能用。同一意图能写出多种等价 SQL(JOIN vs 子查询、WHERE IN vs EXISTS),文本匹配把正确答案误判成错。
- Execution Accuracy(执行准确率):比执行结果是否等价——✅ 该用这个。
工程做法:攒一批业务真实高频问题,人工写「金标准 SQL + 期望结果」做回归测试集;词典/Prompt/模型版本变更前批量跑一遍对比执行结果,作为准确率量化依据。线上失败 case 人工 review 后补进基准集,让评估集自身也迭代。
❓ 常见追问 · 为什么不用 exact match? → 语法不同结果相同的 SQL 太多,文本匹配假阴性严重,衡量的是"像不像参考答案"而非"对不对",没有工程意义。
5. Vanna 2.0(会追"新版本变化"时用)
Vanna 2.0 是完全重写,从"函数式 VannaBase 类方法"转向Agent 化 + 生产就绪,关键变化:
- Agent-based API:不再是 vn.ask 单发单收,改成 Agent 架构,支持多轮迭代(max iterations 可配)。
- User-aware:每个组件都知道当前用户身份 → 天然支持行级权限、按用户存会话。
- 流式富 UI 组件:不再返回纯文本/DataFrame,而是流式返回可交互组件。
- 企业能力:Lifecycle Hooks(配额/日志/内容过滤)、LLM Middlewares(缓存/成本追踪)、Conversation Storage(按用户持久化历史)、内建 Observability(trace/metrics)、Context Enrichers(挂 RAG/记忆/文档)。
💡 深入理解 · 这条演进方向和 13-Harness 工程 完全同频:从"单发 RAG"走向"带 Hook/中间件/可观测/记忆的 Agent 系统"——单次 RAG 撑不住复杂业务问题,必然走向多步 Agentic 架构(社区实测:真实业务用户一介入,问题复杂度飙升,加示例/收紧规则都补不齐边界 case)。
6. 高频追问速答
❓ 常见追问 · 为什么用 Vanna 不自己写 Prompt? → Vanna 把 NL2SQL 的 RAG 训练、向量检索、SQL 生成执行、自校正都封装好了,开箱即用且能持续训练;业务术语层、安全校验这些定制逻辑在外面包一层即可,比从零手撸省时且规范。
❓ 常见追问 · Vanna 的"训练"是微调吗? → 不是。是往向量库加检索语料(DDL/文档/示例对),不动模型参数。所以语料没有自动过期机制,脏数据/过时数据不清理会污染检索——垃圾进垃圾出,需要人工维护语料生命周期。
❓ 常见追问 · 和 RAG 知识库项目啥区别? → 底层都用向量检索召回上下文,但 RAG 知识库产"文本答案",Vanna 产"可执行 SQL 并执行返回结构化数据"。详见 → 03-企业RAG知识库。
❓ 常见追问 · Prompt Injection 防得住吗? → 用户原话必须作为自然语言进 Prompt(这是 Vanna 生成 SQL 的必需输入),没法完全隔离,injection 风险确实存在。兜底靠白名单(限能查的表)+ 只读账号(限只读)+ 字段级脱敏(敏感字段不返明文)。注意区分:SQL 注入 ≠ Prompt 注入,是两类攻击面。
评论