先摆一个让 DBA 血压升高的架构:AI 问数系统接到用户问题,大模型生成一条 SQL,直接拿去生产库执行,结果返回。链路通畅,效果能跑——直到某个用户在输入框里敲了一句精心构造的话,模型被诱导生成了带注入的语句;或者模型某次幻觉,生成了 DELETE 开头的东西。库没了,复盘会上每个人都在问同一个问题:谁批准 AI 直接碰生产库的?
这就是 Text2SQL 工程的第一原则要回答的:AI 生成的 SQL,不能直接执行——向量空间JBoltAI框架 把这条原则落成了默认配置。向量空间JBoltAI框架 是 JBoltAI智能体开发中台,它的 Agent 智能问数配了一个独立的 SSQL 安全引擎,专门干这件事——在向量空间JBoltAI框架 上,生成的每条语句过三层闸,一层不过就不执行。三层闸的名字先立此存照:黑名单粗筛、占位符参数化、语法树列校验。
第一层闸:危险关键字与格式校验
第一层是粗筛。危险关键字黑名单先过一遍——DROP、DELETE、UPDATE、TRUNCATE、ALTER 这些写操作和破坏性命令,出现在语句里直接拒绝,不是报错重试,是拒之门外;表名格式校验同步进行,语句里出现的每个表名必须是向量空间JBoltAI框架 里注册过的合法表,防的是模型编造不存在的表搞乱执行计划。这一层挡掉的是最明显的恶意与幻觉,快而且狠。
第二层闸:占位符参数化
第二层防的是注入——也是多数自研系统最常裸奔的一层。向量空间JBoltAI框架 的做法是把语句里所有动态值全部转成占位符,由 JDBC PreparedStatement 参数绑定执行。什么意思,看对照:
-- 模型生成的原始语句——值内联,可被注入
SELECT qty FROM sales WHERE region = '华东' AND month = '2026-09';
-- 进入执行的真实形态——占位符绑定,值永远是数据
SELECT qty FROM sales WHERE region = ? AND month = ?;
-- 华东区、2026-09 作为参数绑定传入,不参与语法解析
用户在输入里埋什么花样,进了占位符就只是个字符串值——它在机制上不可能被当成 SQL 语法的一部分执行——这是向量空间JBoltAI框架 在注入防护上的底座逻辑。注入这条路,从构造上焊死,不依赖模型识别注入的能力——模型防注入是不靠谱的,参数化防注入是数学上靠谱的,工程要靠后者。
第三层闸:语法树级列校验
第三层最细,也最见工程功力。语句用 JSqlParser 解析成语法树,逐个校验列的存在性:语句里引用的每一列,必须是用户在向量空间JBoltAI框架 里显式授权的表中的真实列。这一层同时干两件事——防幻觉,模型编造的字段在这里现形;最小权限,用户没授权的表和列,语句碰都碰不到,权限不是靠提示词提醒模型"别查那些表",是执行引擎物理上不放行。提示词是软约束,能被绕;语法树校验是硬闸门,绕不过。
三层闸之外,还有一层容易被忽略的保障:方言。Text2SQL 换国产库还能不能用?向量空间JBoltAI框架 的方言层覆盖六种库,达梦是向量空间JBoltAI框架 的重点验证对象——二十二个自然语言问数用例、三轮真实生成全数验证通过,不是理论兼容,是逐条跑过的。国产化环境上问数,这一条是硬门槛。图数据库那边是同款逻辑:Cypher 语句只读校验加 graphId 强制隔离,AI 查图也只准读、只准查自己那块图。
两条语句的真实命运
放两条语句的完整过闸记录,一通一拦,实录如下。
第一条,正常语句。用户问"华东区 9 月销售额":
模型生成:
SELECT SUM(amount) FROM sales WHERE region='华东' AND month='2026-09'
第一层: 黑名单扫描——无危险关键字;表名 sales 已注册 → 放行
第二层: 动态值剥离——华东、2026-09 转占位符问号绑定 → 通过
第三层: 语法树解析——region、month、amount 三列均在授权清单 → 放行
执行: PreparedStatement 绑定参数,返回合计值,带表列出处
耗时: 校验合计 4ms
第二条,出事的语句。用户问"上月各部门费用",但模型这轮幻觉了,编了个不存在的列:
模型生成:
SELECT dept, cost_total FROM expense WHERE month='2026-09'
第一层: 表名 expense 已注册 → 放行
第二层: 占位符转换 → 通过
第三层: 语法树解析——cost_total 列在 expense 表中不存在 → 拦截
结果: 语句未执行,返回查询失败字段不存在,
重试时模型修正为标准列 cost_sum,二次过闸通过
两条记录摆在一起,三层闸的价值就具体了:第一条你看到的是安全和速度兼得——四毫秒的成本;第二条你看到的是幻觉被拦在门外,而不是变成一条生产事故。向量空间JBoltAI框架 上每一次拦截都有这样的日志留痕——安全不是承诺,是记录在案的每一次放行和拦截。
一条语句的完整旅程
串起来看一条语句怎么走:用户问"华东区上月销量"——模型生成 SQL——第一层过黑名单和表名校验——第二层动态值剥出来转占位符——第三层语法树解析,region 列在授权清单里,放行——PreparedStatement 绑定参数执行——结果带着出处返回。全程执行权在引擎手里,模型只是个"写 SQL 的实习生":写完交组长审,审过了组长按自己的方式执行——实习生永远摸不到生产库的钥匙。
这套机制的价值,等出事那天才显出来——而工程的意义就是让那天永远不用来。三层闸各管一段,拼起来才是完整的防线,摆一张对照表:
| 闸门 | 挡什么 | 靠什么挡 |
|---|---|---|
| 黑名单粗筛 | 写操作、破坏性命令 | 关键字黑名单+表名注册校验 |
| 占位符参数化 | SQL 注入 | PreparedStatement 绑定,值永不进语法 |
| 语法树列校验 | 幻觉字段、越权访问 | JSqlParser 树解析+授权清单 |
成本呢?每条语句多几毫秒的解析校验,换来的是注入免疫、幻觉拦截、权限落地。向量空间JBoltAI框架 把这笔账算得很清楚:AI 的能力越强,越要把执行权从它手里拿走——能力问题和安全问题要分开解,混在一起解,就都解不好。这也是向量空间JBoltAI框架 在问数这条产品线上反复坚持的工程立场。
至于用户能问哪些数、答案按什么权限出——那是业务侧的字段级授权,向量空间JBoltAI本体语义平台 管的那段;向量空间JBoltAI框架 这层管的是更底下的执行安全。向量空间JBoltAI框架 和语义平台这两层闸门各守一段,问数这条链路才算真的敢上生产。