1031 字
5 分钟
模型写完 SQL 以后,系统还要做什么?

这篇是银行问答系统的两条查询路径的第二篇。上一篇先说明为什么制度文档和业务数据不能共用一条检索链路,这里只追踪数据查询这条路:模型生成 SQL 以后,系统怎样判断它能不能执行,执行失败后怎样处理,最后又怎样避免把结果解释错。

Text2SQL 指的是把自然语言问题转换成 SQL。它解决的是“用户想查什么”到“数据库需要执行什么”之间的转换,但 SQL 能生成出来,并不代表结果就可信。

Text2SQL 的演示通常很顺利:给模型一份表结构,再问“哪个行业的敞口最大”,它能生成一条像模像样的 SQL。

真正接入业务库之后,问题才刚开始。

一条 SQL 即使语法正确,也可能查询了不该访问的表、返回过多数据,或者在结果解读时被模型补上了数据库里根本不存在的趋势和数字。生成 SQL 只是中间步骤,不能直接等同于“可以执行”。

关键字黑名单为什么不够#

最直观的做法是列一份危险词清单:出现 DELETE、UPDATE 或 DROP 就拒绝执行。

这类规则很快会遇到两个问题。第一,注释和字符串里也可能出现这些词,正常查询会被误伤。第二,写操作可以被包装在更复杂的语句里,单纯检查文本很难看出真正的意图。

更可靠的方式是先把 SQL 解析成抽象语法树。系统使用 SQLGlot 读取语句结构,再检查几个条件:

  • 只能有一条语句;
  • 顶层只能是 SELECT;
  • 不能包含写入、删除或修改操作;
  • 涉及的表必须在允许列表中;
  • 子查询不能绕开表权限;
  • 没有 LIMIT 时补上上限,过大的结果集直接限制。

这一步检查的是结构,不是关键词。

代码校验之后,还要看执行环境#

即使 AST 校验没有问题,也不应该让应用使用高权限账号连接数据库。

执行侧使用只读权限,同时限制可访问表、最大返回行数和执行时间。这样即使上层校验出现遗漏,也不会让一条模型生成的语句改写数据或无限占用资源。

多层限制看似重复,实际承担的是不同责任:应用层负责尽早拒绝明显风险,数据库权限负责兜底,资源限制负责避免一次查询拖垮服务。

失败后为什么只重试两次#

字段名猜错、分组条件不完整、时间口径不一致,都是 Text2SQL 的常见失败方式。数据库返回错误后,系统把错误原因整理成模型可理解的反馈,再让它修正一次。

重试次数并不是越多越好。超过两次仍然失败,通常说明问题不在 SQL 写法,而在上游没有召回足够的表结构或业务口径。继续重试只会增加调用成本,也会掩盖真正需要修复的环节。

最难发现的错误在结果解释阶段#

SQL 报错至少会暴露问题。更危险的情况是查询正常返回,但模型在解读时写出了结果表里没有的数字,或者把“一个行业占比最高”扩展成“整体风险正在上升”。

因此,结果解释也要受到约束:关键数字来自查询结果,无法验证的推断不应写成事实;遇到模糊结果时,宁可展示表格和口径,也不要补一段听起来合理的结论。

一条可靠的 Text2SQL 链路,不是让模型一次写对 SQL,而是让系统知道什么时候该执行、什么时候该停下,以及怎样把失败变成下一轮改进的线索。

系列文章
RAG 与 Text2SQL
相关文章
模型写完 SQL 以后,系统还要做什么?
https://www.yyylegend.com/posts/text2sql生成之后如何安全执行/
作者
YYYLEGEND
发布于
2026-09-18
许可协议
CC BY-NC-SA 4.0