AI 生成的 SQL 不符合预期时如何处理?
未标记
考查重点:SQL 语义、数据口径与结果核对。先区分语法错误、字段错误、统计口径和关联重复,再用元数据与样例结果定位;将具体错误反馈给模型,只重生成受影响的查询
本题目录
参考答案
核心回答
先定位“不符合预期”是哪一类:语法或方言错误、选错表字段、业务口径错误、关联导致重复、权限遗漏,还是查询太慢。SQL 能成功执行只能说明部分语法和访问条件成立,不能证明回答了用户的问题。
处理流程应是记录失败样本、复现并分类、补足缺失上下文、有限修正,再用独立数据与业务规则验证,而不是不断让模型重试同一个含糊问题。
怎样定位错误来源
保留用户问题、解析出的指标与时间范围、检索到的表结构和指标定义、模型版本、生成 SQL、校验错误与结果摘要。先核对当前 Schema、枚举、关联键和数据库方言,排除知识库或元数据过期。
若用户问“上月销售额”,需要明确按支付还是下单、是否扣退款、时区和月边界。口径不清时先澄清或使用已定义的业务指标。表结构检索应包含必要的关联关系和粒度,避免把订单明细多对多关联后直接求和。
分层验证与修正
- 结构与访问:解析
SQL,限制允许的语句、库表和权限范围;租户条件和只读权限由系统执行,不能仅依靠提示词。 - 语法与成本:使用对应方言的解析或
EXPLAIN等手段检查对象、语法和访问路径,并限制运行时间、结果规模和扫描成本。EXPLAIN通过仍不能证明统计口径正确。 - 语义与结果:用人工确认的案例、独立计算或参考查询比较结果,覆盖空数据、
NULL、重复行、退款、跨月和多表关联等反例;不能只比较SQL字符串完全相同。 - 有限反馈修正:把必要的错误信息与相关 Schema 反馈给生成步骤,限制次数和总预算;连续失败时返回可解释的失败或转人工处理,避免循环。
对应教程第 17 章展示 validate_sql 将数据库校验错误交给 correct_sql 的条件分支;项目中还需补上上述语义与访问约束。
怎样持续提高准确率
把线上错误按类型沉淀为回归集,分别观察表字段召回、首次执行成功、语义结果正确、修正后成功、耗时和费用。修 Schema 描述、指标词典、示例或模型时,用同一组保留样本比较,并增加新反例,防止只对已知问题过拟合。
模型自检可以作为候选判断,但不能让同一生成逻辑成为唯一裁判。语义验证也不能只靠一份偶然数据:两条逻辑不同的 SQL 可能在当前数据上恰好返回相同结果。
参考资料
- 国内:汀丶人工智能 / 火山引擎开发者社区:NL2SQL 技术方案与评估难点:语义错误与评估反例帮助区分执行成功、文本一致和业务正确三个标准。
- 国内:NineData:Text2SQL / Chat2SQL:Schema 注释、E-R 关系和结果复核清单帮助定位选表、过滤与聚合口径错误。
- 国内:JavaGuide / Snailclimb:常见 SQL 优化手段:执行计划、关联与扫描量部分帮助排查生成 SQL 的性能问题,并检查修正是否改变访问代价。
- 国外:LangChain:Build a SQL agent:官方 SQL Agent 的步骤帮助组织可观察的修正链路,并说明数据库权限需要在执行侧收窄。
- 国外:Oracle MySQL:EXPLAIN Statement, MySQL8.4:官方执行计划语义帮助界定校验和真实执行的区别,避免把检查通过当作业务答案正确。
电商问数Python
核心回答
先把数据库报错和业务结果错误分开处理。电商问数已有的分支能把 EXPLAIN 返回的错误连同原问题、原 SQL、表字段、指标和数据库环境交给模型,生成一次修正后的查询;当前图随后直接执行,没有纠错后复验。
如果查询能执行但取值、指标或关联不对,就要沿三路召回与上下文合并定位原因,不能只靠数据库报错。进一步完善时,可把修正结果重新送入校验,保留一次纠错上限:复验通过再执行,仍失败则结束并返回具体原因;业务结果另外用参考查询和样例数据核对。
数据库错误怎样反馈给模型
validate_sql 调用数仓仓储执行 EXPLAIN,成功返回 error=None,失败则把异常文字写入 error。条件边读取这个字段,选择 run_sql 或 correct_sql。
correct_sql 同时读取 query、table_infos、metric_infos、date_info、db_info、原 sql 和 error,将上下文序列化后组成修正提示词,再用字符串解析器取得纯 SQL,覆盖原来的 sql。保留原问题与指标定义,是为了让模型修字段或语法时仍有业务依据。校正节点源码展示了这些输入和输出。
例如查询华北地区销售总额时,模型若生成不存在的 fact_order.sales_amount,数据库可能反馈未知列。若上下文已经包含配置中的 fact_order.order_amount 及 GMV 依赖,修正节点就有依据改回正确字段;若上下文本身缺失金额字段,应先检查指标依赖补齐和过滤结果,而不是要求模型猜一个替代列。
能执行但结果不对,查哪一步
仍用“华北地区销售总额”这个问题,可以沿中间结果区分三类问题:
- 条件值不对。 生成了
region_name = '华北地区',而数据保存的是“华北”。这类查询可能通过EXPLAIN但返回空结果,应检查取值路是否命中,以及命中值是否进入所属字段的examples。 - 口径不对。 金额字段存在,却采用了错误的计算或过滤条件。应检查指标定义、依赖字段和生成上下文;业务定义不清时先澄清,数据库不会替业务选择口径。
- 关联不对。 缺少订单与地区的连接条件,或连接方式放大了行数。应核对候选表与键字段是否齐备,再检查实际连接和聚合粒度;“补了主外键”并不自动证明查询正确。
定位后修正相应元数据、召回或生成环节,用人工确认的查询和固定数据比较结果。等价查询不要求字符串完全相同;空结果也可能是真实业务事实,不能为了得到非空结果擅自放宽条件。
怎样增加复验和有限重试
当前固定图的边是 correct_sql → run_sql,因此一次修正不经过第二次数据库预检查。图编排源码可以直接看到这个顺序。
若补齐这段流程,可以增加纠错计数,把修正后的查询送回校验节点。以最多纠错一次为例:首次校验失败后记录错误并校正;第二次校验成功才执行,再失败就终止。每次校验覆盖当前 error,并记录本次候选查询与反馈,避免沿用旧错误。权限、允许的语句及资源约束若已接入,也要对修正后的新查询重新检查。
连接故障或服务超时也不能一律归入语义纠错:临时连接问题可按调用预算处理,权限拒绝应停止,字段或口径错误则需要修输入或上下文。没有新依据时重复生成同一问题,只会增加模型调用与数据库负载。
对应教程
- 电商问数:SQL 生成与执行闭环:回看数据库错误怎样进入校正提示词,以及校正一次后执行的实际流程。
参考资料
- 国内:NineData:Text2SQL / Chat2SQL:借鉴表列、时间状态、聚合与关联的核对方式,解释查询可执行但结果不符时怎样定位上下文问题。
- 国内:阿里云 Quick BI:数据准备:参考字段描述、维值匹配和结构变化后的更新要求,说明字段或取值错误应修相应知识,而非盲目再生成。
- 国内:飞致云:SQLBot 最佳实践:采用查询范围、表关系、标准查询和术语的准备方式,解释缺表、错误关联和口径混淆的处理分工。
- 国内:JavaGuide:常见 SQL 优化手段:参考连接、执行计划与同条件复测,说明修正后的查询既要保持业务含义,也要检查实际访问代价。
- 国外:LangChain:Build a SQL agent:借鉴错误反馈、查结构、改写后检查再执行的循环,组织本文进一步提出的复验和停止条件;其中模型检查与数据库验证仍需区分。
- 国外:MySQL 8.4:EXPLAIN Statement:依据执行计划和实际运行的区别,说明数据库预检查不能判定真实取值、指标口径与结果是否正确。