2023 年前后,大语言模型(Large Language Model, LLM)把 Text-to-SQL 从”准确率 50% 上下、只能玩 demo”推到了”在 Spider dev 上 85%+、在 BIRD 上也接近 70%“的量级。这背后的工作既不是”把 GPT-4 塞进 chatbox 让它写 SQL”,也不是”再训一个微调 BERT”,而是一套从 schema linking、decomposition、self-consistency 到 agent 回路的系统工程。
本文上半把 DIN-SQL、C3、DAIL-SQL 三条代表性路线讲清楚,重点是它们在工程上能被复用的模块;下半给出一个不依赖付费 API、纯离线可跑的最小 Text-to-SQL 闭环 demo,演示 schema linking + SQL 校验 + 执行回退的工程骨架。
一、为什么 Text-to-SQL 是数据库问题,而不只是 NLP 问题
1.0 十年回顾
Text-to-SQL 不是一个新问题。早在 2017 年前后 Salesforce / Yale / IBM 就有一批 seq2seq 时代的工作(SQLNet、TypeSQL、SyntaxSQLNet),在 WikiSQL、Spider 上做分数。这些工作共享一个共识:跨 domain 的泛化是瓶颈,模型在训练 schema 上很好,换一个 schema 就退化。
2021 年前后随着 T5 / BART 这类预训练 seq2seq 模型出现,准确率被推高了一个台阶;2023 年 GPT-4 出现后又是一个台阶,在 Spider 上冲到 85%+。这条曲线看起来像”模型越大越好”,但它的代价在可控性而非准确率上:模型越大,错起来越像一本正经地瞎说,越难靠调参修正。
这就是为什么 2024 年以后的工程实践开始回归”流水线思维”:让确定性模块负责确定性的事(schema linking、validation、execution),让 LLM 只负责不确定的事(自然语言理解、草稿生成)。
1.1 这类系统的核心权衡
任何 Text-to-SQL 产品都要在三个维度做权衡:
- 覆盖率:多少问题能被回答?
- 准确率:回答的问题有多少真正正确?
- 可解释性:用户能不能理解这个回答的依据?
三者基本是相互制约的。做高覆盖率最容易(让 LLM 生 SQL 执行就行),做高准确率要严苛流水线,做高可解释性要产品化 UI。工程化 Text-to-SQL 的核心就是在这三者之间找甜点,而不是盲目追求 benchmark 分数。
很多人第一反应是把 Text-to-SQL 归到 NLP 任务。2024 年后的共识是:它本质上是一个数据库接入层问题。因为:
- 正确性判据是 执行结果等价,不是 SQL 字符串相似度——等价类爆炸,字符串比较对工程没意义。
- 瓶颈通常在 schema
linking:把自然语言里的”销售额”映射到
orders.amount还是invoice.total,依赖对 schema、数据分布、业务语义的理解。 - 生成之后必须可执行 + 可验证,否则等于没生成。这是一个典型的 “generate → validate → retry” 数据库交互回路。
所以 Text-to-SQL 在 2025 年的正确切入视角是:一个带 LLM 的查询中间层,而不是”让 AI 写 SQL”。
1.1 Spider 与 BIRD 两个基准
- Spider(Yu et al., EMNLP 2018):10k+ 问题 × 200 数据库 × 跨 domain。每个 DB 几个表、几十条记录。题目集中考 SQL 结构(join、嵌套、group by)。
- BIRD(Li et al., NeurIPS 2023):95 个真实生产库、33k 问题,数据量到几 GB,有脏数据、有业务术语。题目集中考”对 schema 的真实理解” + “对数据分布的利用”。
Spider 分数高不代表 BIRD 分数高。Spider 上 90%+ 的方案在 BIRD 上会跌到 50% 左右。原因是 BIRD 要求模型理解业务词汇映射和数据质量,这些在 Spider 里几乎没有。
判断一个 Text-to-SQL 方法是否真有工程价值,看它在 BIRD 上的表现,而不是 Spider。
二、DIN-SQL:把任务拆成子问题
DIN-SQL(Pourreza & Rafiei, NeurIPS 2023, “DIN-SQL: Decomposed In-Context Learning of Text-to-SQL with Self-Correction”)的核心观点朴素但有效:不要让 LLM 一步写完 SQL,把它拆。
2.1 四阶段 pipeline
question ──▶ Schema Linking ──▶ Classification ──▶ SQL Generation ──▶ Self-Correction
(找相关列) (简单/嵌套/连接) (按类模板) (执行失败回改)
- Schema Linking:让 LLM 读 schema + question,输出相关的表和列。提前剪枝缩小了后续 prompt 的噪声。
- Difficulty Classification:把问题分类为 easy / non-nested complex / nested complex,每类用不同模板和 few-shot 例子。
- SQL Generation:按类别给对应的 CoT prompt,生成 SQL。
- Self-Correction:执行 SQL,失败或结果可疑时把错误反馈给 LLM 让它改。
这四步在 2024 年之后几乎成为所有 production Text-to-SQL 系统的骨架,即使不用 LLM,用规则 + 小模型也是这一套流程。
2.2 DIN-SQL 的工程遗产
DIN-SQL 本身的论文里使用了 GPT-4,但它真正被广泛引用的不是分数,而是”先 schema link、再分类、再生成、再自检”这套流水线抽象。这套抽象对任何模型可迁移。
三、C3:强调 prompt 工程而不是 fine-tune
C3(Dong et al., arXiv 2023, “C3: Zero-shot Text-to-SQL with ChatGPT”)把注意力放到 prompt 设计:
- Clear Prompting:schema 表示用
CREATE TABLE原文,而不是简化版。 - Calibration bias:LLM
对某些模式(比如总用
DISTINCT)有系统偏好,显式注入”不要滥用 DISTINCT / not always JOIN”等约束。 - Consistency:多次采样 SQL,用执行结果做多数投票(majority voting on execution result)。
C3 的贡献在于证明了 即使完全不 fine-tune、不额外训练,光靠 prompt 工程 + self-consistency,闭源 LLM 就能把 Spider 推到当时 SOTA。这对工业界是一个解压信号:Text-to-SQL 不需要自建模型训练流水线。
3.1 Self-Consistency 的工程实现
question ──▶ prompt ──▶ LLM (sample k=5) ──▶ exec each ──▶ majority vote on rows
│
└─▶ 结果集做 set equality,而不是字符串比较
要点:投票必须在执行结果上,不能在 SQL 字符串上。一条正确 SQL 可以有几十种等价写法,字符串级投票几乎必定失败。
四、DAIL-SQL:把 example selection 做正确
DAIL-SQL(Gao et al., VLDB 2024, “Text-to-SQL Empowered by Large Language Models: A Benchmark Evaluation”)是一个系统性对比多种方法的综合工作,它自己提出的 DAIL-SQL 方法关注 few-shot example 的选择:
- 传统方法是从训练集随机 / 按相似度选 examples 放进 prompt。
- DAIL-SQL 的建议是 按 SQL skeleton 相似度 + question 相似度综合打分。SQL skeleton 指去掉具体 table/column 名之后的结构。
- 这样选出来的 examples 更贴近目标问题的结构,而不是只像表面文字。
4.1 DAIL-SQL 的另一半:系统评测
论文把前几年 Text-to-SQL 工作做了一个公平对比,结论里对工程师有价值的几条:
- GPT-4 + 好 prompt 通常 ≥ fine-tune 的小模型,除非任务分布与训练集非常贴近。
- schema linking 的准确率是上限的主要决定因素。schema linking 错了,再怎么 CoT 也救不回来。
- 小模型(Llama-3 8B 级别)在 BIRD 上仍明显落后,闭源 / 大开源(70B+)是 2024 下半年进入能用区间的分水岭。
2025 年之后,Qwen2.5-Coder、DeepSeek-Coder V2 等开源模型把小模型下沿也拉到了”能用”的水平,但这仍然需要配合完整的 DIN-SQL 式流水线。
4.2 别再追 benchmark 分数
一个对工程更实用的观察:Spider / BIRD 分数高低,与在你的真实 schema 上好不好用,几乎无关。原因很直接:
- 你的 schema 不会出现在训练集里。
- 你的业务词汇(“GMV”、“活跃用户”、“近 7 日留存”)也不会。
- 你的数据质量(NULL 比例、字符串脏数据)比 benchmark 差得多。
所以用 benchmark 选底座模型合理,用它决定”能不能上线”不合理。上线前一定要在自己 schema 的 100–500 条代表性问题上做真实回归。这部分工作没有捷径。
五、Agentic Query:plan-execute-verify
2024 年后的 Text-to-SQL 进一步 agent 化,核心模式是 plan-execute-verify:
┌────────┐ ┌────────────┐ ┌──────────────┐
│ Planner│──▶ │ Schema/IDX │──▶ │ SQL Draft │
└────────┘ └────────────┘ └──────┬───────┘
▲ │
│ ┌────────────────┐ ▼
└─── │ Verifier/Reflect│◀── exec on real DB
└────────────────┘
Planner 不只出 SQL,还要决定:先 EXPLAIN、先
SELECT LIMIT 5 探数据、再决定最终 SQL
要不要分步。Verifier 在执行后检查行数、NULL
比例、outlier,不合理就回到 Planner。
代表工作包括 MAC-SQL(Wang et al., COLING 2024)、CHASE-SQL(Pourreza et al., arXiv 2024)以及大量开源 agent 框架。它们共享的工程要点:
- 工具调用边界要窄:只暴露”执行只读 SQL”、“LIMIT 5 预览表”、“查索引列表”这几类只读工具,把副作用挡在外面。
- 循环必须有预算:默认 5 轮 retry 封顶,超过就降级返回 “我无法可靠回答”。
- 观测要完整:每一轮 plan / sql / exec / verify 都落结构化日志,用于回归和 A/B。
5.1 Agent 架构的几个失败模式
把 agent 架构用在 Text-to-SQL 上,常见失败模式:
- 无限纠错循环。LLM 每一轮都在同一个错误上换个说法,没收敛。对策是:同一个 error message 出现两次就降级。
- 执行抖动。verifier 的判断依赖数据分布,数据一换 verifier 就反复判 true/false。对策是:把 verifier 的判断锁死在确定性规则上,不让 LLM 判。
- 工具误用。LLM 给
DESCRIBE TABLE发了一个SELECT *当工具 input。对策是:工具的 schema 要有运行时校验,不信任 LLM 的输入结构。 - token 爆炸。每轮把全部历史都重拼进 prompt,几轮下来 context 就满了。对策是:把中间观察压缩成摘要(“表 orders 有 3 个数值列:amount, qty, discount”)。
这些模式都在 2024 年后的若干 production postmortem 里重复出现,说明 Text-to-SQL 的工程护栏很像传统数据库的只读事务:限制越多,越稳定。
六、工程落地:一个离线可跑的最小闭环
上半是研究线,下半换工程视角:如果我现在要给一个 PostgreSQL / SQLite 仓库接一个离线、可审计、可重放的 Text-to-SQL 层,最小骨架是什么?
这个最小骨架放在 demo/mini_text2sql.py:SQLite
+ Mock LLM + 模板化 schema linking + SQL 校验 +
执行回退。它不依赖任何付费
API,任何拉下来的人都能直接跑。
6.1 Demo 的五个步骤
question
│
▼
1. schema_linking(question, schema) ──▶ 候选表 / 列(规则 + LLM)
│
▼
2. render_prompt(question, linked_schema, few_shots)
│
▼
3. llm.generate(prompt) ──▶ SQL 草稿(Mock 模式:按模板返回)
│
▼
4. validate_sql(sql) ──▶ 语法检查 + 只读校验 + 表/列存在性
│
▼
5. execute_or_retry(sql) ──▶ 执行;失败把 stderr 回喂 LLM,最多 3 轮
6.2 Mock LLM:让 demo 离线可跑
Demo 默认用一个 MockLLM:它根据 question
关键词挑一个模板返回 SQL,参数化
schema。这足够演示整条流水线的形状,对读者理解工程骨架最有价值。接真实
LLM 只需要替换 MockLLM 为一个调用
openai / ollama /
llama-cpp-python 的实现。
MockLLM 的核心代码非常短:
class MockLLM:
"""Deterministic LLM stub: match keywords → template SQL."""
def generate(self, prompt: str, question: str, schema: dict) -> str:
q = question.lower()
if "how many" in q or "count" in q:
table = _best_table_match(q, schema)
return f"SELECT COUNT(*) FROM {table};"
if "average" in q or "avg" in q:
table, col = _best_numeric_column(q, schema)
return f"SELECT AVG({col}) FROM {table};"
if "top" in q:
table, col = _best_numeric_column(q, schema)
return f"SELECT * FROM {table} ORDER BY {col} DESC LIMIT 5;"
# fallback: full scan
table = next(iter(schema))
return f"SELECT * FROM {table} LIMIT 10;"6.3 SQL 校验:不是可选
校验层常被忽略但非常关键,它挡住 LLM 最常见的三类错误:
- 幻觉列:引用不存在的表或列。用
sqlite3.parse/sqlglot抽取 table-column,对照 schema 校验。 - 越权写:生成
DELETE/DROP。用 sqlglot 的 ast 白名单只放行SELECT/WITH。 - 笛卡尔积:join 没有条件。遍历
Join节点,缺ON直接拒绝。
Demo 里用 sqlglot 实现:
from sqlglot import parse_one, exp
def validate(sql: str, schema: dict) -> list[str]:
errors: list[str] = []
try:
tree = parse_one(sql, read="sqlite")
except Exception as e:
return [f"parse error: {e}"]
if not isinstance(tree, (exp.Select, exp.With)):
errors.append("only SELECT / WITH allowed")
for tbl in tree.find_all(exp.Table):
if tbl.name not in schema:
errors.append(f"unknown table: {tbl.name}")
for col in tree.find_all(exp.Column):
t = col.table or _single_table(tree)
if t and t in schema and col.name not in schema[t]:
errors.append(f"unknown column {t}.{col.name}")
for j in tree.find_all(exp.Join):
if not j.args.get("on"):
errors.append("join without ON clause")
return errors6.4 执行 + 回退
def answer(question: str, db: sqlite3.Connection, llm, schema: dict, max_rounds=3):
last_error = None
for _ in range(max_rounds):
prompt = render_prompt(question, schema, last_error)
sql = llm.generate(prompt, question, schema)
errs = validate(sql, schema)
if errs:
last_error = "; ".join(errs)
continue
try:
rows = db.execute(sql).fetchall()
return sql, rows
except sqlite3.Error as e:
last_error = str(e)
return None, None这个模式可以直接套到真实 LLM 上,只是把
MockLLM.generate 换掉。最大 3
轮的预算是经验值——多于 3 轮意味着 schema linking 或 prompt
有结构性缺陷,需要人工介入,而不是继续让 LLM 自我纠错。
6.5 运行方式
cd demo
pip install sqlglot==25.6.1
python mini_text2sql.py脚本会:
- 在内存里建
orders(id, amount, status)与customers(id, name, country)两张表。 - 跑一组预置问题(
"how many orders?"、"average amount"、"top customers by amount"、一个故意让模型幻觉的问题)。 - 打印每个问题的:linked schema、SQL、校验结果、执行结果。
故意失败的那个问题会触发 retry,用于让读者看到 validate + retry 是如何真的起作用的。
6.6 上线前要准备的四件事
- 回归集:100–500 条带答案的真实问题,每次模型 / prompt / schema 变更重跑。
- canary dashboard:每天随机抽样 50 条线上请求人工标注对错,周度监控准确率漂移。
- 降级开关:当 LLM 上游异常或日耗超限,立即切回”报表推荐”或纯按钮交互。
- 日志脱敏:每一条请求都会包含用户问句和真实数据行,落日志前必须脱敏,否则在数据治理评审里通不过。
这四件事每一件都比”换个更强的模型”更决定能否真正上线。反过来讲,很多团队踩的坑都是”光追模型,忘了工程基础设施”。
6.7 与其他文章的互链
- Schema linking 的底层问题和查询优化器的 cardinality 估计天然相邻,参考 学习型查询优化器。
- 把 Text-to-SQL 放进 Agent 记忆里会引入一致性问题,下篇会讨论,参考 数据库作为 LLM 记忆体。
七、一个更完整的参考架构
前面的 demo 偏骨架。把它扩展成一个可上线的参考架构大致长这样:
用户问句
│
▼
┌─────────────────────┐
│ 输入守卫 guard │ 禁用关键词、长度上限、PII 过滤
└─────────────────────┘
│
▼
┌─────────────────────┐
│ schema linking │ 向量召回 table/col + 规则强制加 tenant 列
└─────────────────────┘
│
▼
┌─────────────────────┐
│ SQL 生成 │ LLM + few-shot + CoT
└─────────────────────┘
│
▼
┌─────────────────────┐
│ sqlglot 校验 │ 语法 / 只读 / 权限 / join 条件
└─────────────────────┘
│
▼
┌─────────────────────┐
│ cost guard │ EXPLAIN,估计行数,> 10M 走 LIMIT 强制
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 只读执行 read only │ RLS-enabled 连接、非主库、超时 3s
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 结果核查 / 摘要 │ NULL 比例、行数、outlier 判定
└─────────────────────┘
│
▼
答案 + SQL + provenance
几个值得展开的点:
7.1 RLS 是最后一道墙
Row-Level Security 让你可以给不同 tenant / role
设置行级可见性。一个 Text-to-SQL 连接必须用有 RLS
policy 限制的账号,哪怕 LLM 幻觉出
SELECT * FROM orders
全表扫描,也只会看到当前租户的行。这条比任何 sqlglot
规则都更硬。
7.2 Cost Guard:EXPLAIN 做体检
LLM 生成的 SQL 常见问题是 “语法对、但跑起来全表扫 100 亿行”。上线前应该强制:
EXPLAIN (FORMAT JSON, VERBOSE) <generated sql>;拿到估计
plan_rows,超过阈值就拒绝,或者自动追加
LIMIT N。这和 Azure SQL 自动 tuning 里的
“what-if analysis” 思路一致。
7.3 Provenance 是产品化的关键
一个 Text-to-SQL 系统要上线,必须给用户看到”这个数字是怎么算出来的”。最小实现是把生成的 SQL、涉及到的表、执行时间都显示在 UI 上。用户才能判断”这是一个对我业务有意义的答案”还是”LLM 编出来的数字”。
7.4 一张对比表:NL2SQL 产品化的三层选型
| 层级 | 方案 | 优点 | 缺点 | 适用 |
|---|---|---|---|---|
| L1 纯按钮 | BI 预置 query | 零出错 | 灵活性差 | 面向 non-tech 用户 |
| L2 模板 + 槽填充 | 受限 NL + 参数 | 可控、低成本 | 需要预建模板 | 固定报表 |
| L3 Text-to-SQL | LLM pipeline | 最灵活 | 错误率 10%+ | 探索性分析 |
真实产品几乎都是 L1 + L2 + L3 混合。L3 只处理”模板覆盖不到的问题”,并且要让用户意识到这是 “AI 辅助”,不是”权威回答”。
八、一个具体对比:L2 模板 vs L3 Text-to-SQL
为了让前面的分层讨论更具体,用一个常见需求对比:“上周销售额排名前 10 的客户”。
8.1 L2 模板方案
DBA 预先写好模板 SQL:
-- template: top_customers_by_amount_in_period
SELECT c.name, SUM(o.amount) AS total
FROM orders o JOIN customers c ON o.customer_id = c.id
WHERE o.created_at BETWEEN :start AND :end
AND o.status = 'paid'
GROUP BY c.name
ORDER BY total DESC
LIMIT :top_n;用户通过 UI 填写”时间范围 = 上周” 和 “top_n =
10”。运行时把 :start、:end
换成具体时间戳。
优点:100% 正确,p99 可预期,审计容易;缺点:模板需要人写。 ### 8.2 L3 Text-to-SQL 方案
用户直接问”上周销售额排名前 10 的客户”。LLM pipeline:
- Schema linking 找到
orders、customers两张表。 - 识别时间词”上周” →
BETWEEN date_trunc('week', now() - interval '1 week') AND date_trunc('week', now())。 - 识别”销售额” →
SUM(orders.amount),需要判断是否过滤 refunded。 - 生成 SQL,校验,执行。
优点:灵活,用户不需要学习 UI;缺点:第 3 步最容易出错(销售额到底含不含退款?LLM 不知道业务口径),一旦出错数据是错的但看起来对。
8.3 推荐混合姿态
真实产品里,高频 20 个问题走 L2,长尾走 L3,L3 的回答必须标注 “AI 生成,请核对”。L2 + L3 的切换判断可以用一个”问题 → 模板”的语义路由器(本质也是个小 embedding 检索器)完成。这个姿态融合了两者的优点,是 2025 年之后”数据对话”类产品的主流做法。
九、再看数据契约
一个最容易被忽视、但对生产 Text-to-SQL 质量决定性的话题:数据契约(data contract)。
9.1 什么是数据契约
数据契约指”这张表这个列的业务语义是什么”的形式化描述。例如:
table: orders
columns:
amount:
description: "订单总金额,含税,以人民币分为单位"
unit: RMB_cents
nullable: false
status:
description: "订单状态"
enum: [pending, paid, refunded, canceled]
semantic:
paid: "真正计入 GMV 的成交"
refunded: "已退款,不计入 GMV"9.2 契约对 Text-to-SQL 的价值
没有契约时,LLM
必须通过列名猜业务语义,错是必然的。有了契约,schema linking
阶段可以把契约的 description /
semantic 字段塞进 prompt,LLM
准确率明显提高。
更重要的是:契约让错误可定位。当 LLM
生成的 SQL 把 status = 'paid'
漏掉时,你可以清楚指出”它违反了 GMV
定义契约”,而不是泛泛说”模型错了”。
9.3 契约维护的现实
2025 年之后,dbt / Spectacles / OpenMetadata 这类工具把数据契约做成工程一等公民。对想上 Text-to-SQL 的团队而言,先把契约建起来比先上 LLM 更重要。没有契约的 Text-to-SQL 就像没有 schema 的数据库——能用但早晚出事。
十、与仓库其他文章的互链补充
- 查询优化器的基础知识贯穿整条 Text-to-SQL 链路(EXPLAIN 解读、cost guard、hint 注入),参考 学习型查询优化器。
- Text-to-SQL 产出的 SQL 要走安全只读通道,本质上依赖 MVCC 的一致视图,参考 MVCC 原理与实践。
- 下一篇把 LLM 记忆和数据库一致性模型对齐,是 Text-to-SQL 系统多轮对话能力的理论基础,参考 数据库作为 LLM 记忆体。
十一、对产品团队的建议
最后给想把 Text-to-SQL 做成产品的团队几条提炼建议:
- 不要从 “做 Text-to-SQL” 开始,从 “做数据问答” 开始。Text-to-SQL 是技术手段,数据问答是业务目标。围绕业务目标做 L1 + L2 + L3 混合,而不是盲目追 L3。
- 先做数据契约 + 指标字典。没有契约,再强的 LLM 也会在”什么是 GMV”上栽跟头。这一步和 LLM 无关,属于数据治理基础。
- 把 SQL 可见给用户。用户看到 SQL 既能建立信任,也能更快发现错误。隐藏 SQL 的产品几乎都在 “AI 黑盒” 上吃过亏。
- 从只读开始,永远不要第一版就支持写入。第一版让用户问分析问题,写入留给 L1 按钮。一年后再考虑是否开写入,那时团队对错误模式已经有直觉。
- A/B 思维:不是 “上线或者不上线”,而是 “在 10% 用户上先放开,跟 baseline 对比留存率”。
- 接受 10% 左右的长期错误率。即使到 2026 年,Text-to-SQL 在真实业务上的准确率上限大概就是这个档。产品要设计成”错了也不崩”的形态。
这些建议都不惊艳,但它们决定一个项目能不能活过第一年。技术团队常犯的错误是低估”非技术问题”的比重,而产品化 Text-to-SQL 本质上是一个 2/3 数据治理 + 1/3 模型工程的问题。
十二、一个常被问的问题:训 / 不训模型
团队选型时最常问的一题是:要不要 fine-tune 一个自己的 Text-to-SQL 模型?
12.1 Fine-tune 的代价
fine-tune 一个能用的 Text-to-SQL 模型(假定基座是 7B–70B 开源)要:
- 几千到几万条高质量
(question, SQL)标注,最好包含 schema linking 中间产物。 - 多次迭代的训练 + 人工反馈。
- 自己搭推理服务(vLLM / TensorRT-LLM),持续维护。
总成本常常是几人月到几人年。
12.2 不 fine-tune 的替代
用闭源 API + 好的 prompt pipeline + 强 retrieval,很多场景能做到 fine-tune 90% 的效果,而运维成本低一个量级。
经验法则:
- query pattern 很宽、schema 多变 → 不 fine-tune,靠 prompt + retrieval。
- query pattern 窄、schema 稳定、对 latency / 成本敏感 → 考虑 fine-tune 小模型替代 API。
- 对数据出境合规敏感 → 只能自建模型,选 7B–14B 开源基座 fine-tune。
12.3 真正值得投入精力的三件事
无论 fine-tune 与否,以下三件事的 ROI 都很高:
- 数据契约 + 指标字典:如第九节所说。
- 可观测性:记录每次请求的 prompt / SQL / 结果 / 用户反馈,建立回归集合。
- 评估框架:自建 eval,不依赖 Spider / BIRD。eval 要贴近自己业务分布。
2024–2026 年的经验越发清晰:Text-to-SQL 的护城河在数据与评估,不在模型。把预算分配对,项目成功率会高很多。
十三、为什么这个问题值得长期跟踪
写这么多,最后想讲一下为什么 Text-to-SQL 在 2026 年仍然是个值得长期跟踪的方向。
- 它是数据对话最接近用户的一层。任何非技术用户都能用自然语言提问,这比任何 BI 工具都亲和。
- 它是 AI + 数据库交叉的最佳试验场。所有 AI-Native 数据库的想法——LLM 作 planner、RAG 作 schema linking、agent 作 verifier——都能在这里小规模验证。
- 它是数据治理的倒逼器。要做出好的 Text-to-SQL,你必须先把数据契约做好;这一步往往是团队十年来回避的难事。
这三点加在一起,使得 Text-to-SQL 即使长期停留在 “70% 准确率 + 人类兜底” 的状态,也依然有长期产品价值。它推动的副产品(数据治理、评估体系、可观测性)本身就对组织有价值,并不需要 “完美准确” 才值得投入。
所以,即使你不打算马上上线一个 Text-to-SQL 产品,把它作为一个思维训练场,定期看新论文、做小 demo、和数据治理团队对话,都是长期划算的投资。最后要提醒一句:这个方向的社区节奏非常快,每个月都有新 benchmark、新 prompt 技巧、新 agent 框架出现。保持跟踪但不盲目追新,是 2026 年的工程智慧。
十四、一个小结尾:为什么这一篇放了一个能跑的 demo
系列里大部分文章是讨论概念和工程建议,这一篇单独配了一个离线 demo。原因有三:
- Text-to-SQL 的坑在细节里。不跑一遍 schema linking → 生成 → validate → 执行的完整循环,光看论文很容易觉得”不过如此”。
- validate 层常被低估。demo 里 sqlglot 的寥寥数行代码,替代了读者很多天的试错。
- 闭环 > 完美模型。demo 证明即使 LLM 是 deterministic stub,加上完整闭环也能在玩具 schema 上工作;反过来,一个强大 LLM 没有闭环同样会翻车。
希望读者拉下 demo 跑一遍后,对 Text-to-SQL 工程化的实际形态有一个”动过手”的直觉。真正产品化时可以把 MockLLM 换成 OpenAI / Ollama 客户端,其它骨架基本不变。这种”骨架稳 + 模型可替换”的姿态,是 2026 年做 AI 应用最有生命力的工程哲学。
参考文献
T. Yu et al., “Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task”, EMNLP 2018, https://arxiv.org/abs/1809.08887.
J. Li et al., “Can LLM Already Serve as A Database Interface? A BIg Bench for Large-Scale Database Grounded Text-to-SQLs (BIRD)”, NeurIPS 2023, https://arxiv.org/abs/2305.03111.
M. Pourreza and D. Rafiei, “DIN-SQL: Decomposed In-Context Learning of Text-to-SQL with Self-Correction”, NeurIPS 2023, https://arxiv.org/abs/2304.11015.
X. Dong et al., “C3: Zero-shot Text-to-SQL with ChatGPT”, arXiv:2307.07306, 2023, https://arxiv.org/abs/2307.07306.
D. Gao et al., “Text-to-SQL Empowered by Large Language Models: A Benchmark Evaluation”, PVLDB 17(5), 2024, https://www.vldb.org/pvldb/vol17/p1132-gao.pdf.
B. Wang et al., “MAC-SQL: A Multi-Agent Collaborative Framework for Text-to-SQL”, COLING 2024, https://arxiv.org/abs/2312.11242.
M. Pourreza et al., “CHASE-SQL: Multi-Path Reasoning and Preference Optimized Candidate Selection in Text-to-SQL”, arXiv:2410.01943, 2024, https://arxiv.org/abs/2410.01943.
tobymao/sqlglot, GitHub, https://github.com/tobymao/sqlglot. 本文 demo 中使用的 SQL parser / AST 库。AlibabaResearch/DAMO-ConvAI, GitHub, https://github.com/AlibabaResearch/DAMO-ConvAI. DAIL-SQL 等工作的开源实现。
上一篇: 自治数据库十年回顾:Peloton、NoisePage、OtterTune 到云原生 auto-tuning 下一篇: 数据库作为 LLM 记忆体:语义缓存、RAG 与一致性
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【数据库研究前沿】系列导论:从 System R 到 AI-Native 的 2026 研究地图
以 System R、Postgres、Bigtable、Spanner、Snowflake 等关键节点串起 50 年数据库史,勾勒 2026 年 AI-Native、向量检索、HTAP 云原生、新硬件、隐私计算、新范式、方法论七条主线,并给出 25 篇系列文章的完整阅读地图。
【数据库研究前沿】如何读数据库顶会论文:SIGMOD/VLDB/CIDR 阅读路线
从顶会定位、检索渠道、三遍读法到工业与学术论文的辨别方法,给出 2023–2025 年数据库领域可信必读二十篇,并配套 CMU 15-721、Stanford CS 245 等公开课清单。
【数据库研究前沿】学习型查询优化器:Neo、Bao、Balsa 到 LLM-CBO
系统梳理 Neo、Bao、Balsa 以及新兴 LLM-assisted 查询优化的核心思想,结合 PostgreSQL pg_hint_plan 给出一条可落地的 learned QO 工程路径
【数据库研究前沿】学习型索引再审视:RMI、ALEX、PGM
从 Kraska 2018 RMI 到 ALEX、PGM-Index、RadixSpline,系统梳理学习型索引的数学骨架、更新代价与落地边界,并给出一个最小 RMI 的 Python 实现