跳到正文

AGENT PROJECT INTERVIEW · Q21 / 25

Text2SQL 面对上百张表,怎样选对 Schema 并处理业务歧义

从业务槽位、元数据字典、Schema 召回、Join 图到澄清策略,讲清大规模 Text2SQL 怎样选表选列并消除业务歧义。

作者与复核:吴师兄内容依据:公开 Agent 教程、项目题资料与工程推导查看关联教程 →查看吴师兄公开作品 →

25 道题目Q21
本页内容21 节

30 秒先说结论

Text2SQL 面对大 Schema 时,先把问题拆成指标、维度、时间、粒度、过滤和实体,通过术语词典、元数据、指标目录、示例值和权限召回表列,再用关系图补齐 Join 路径。多个业务解释都合法时,提出能最大化消除歧义的最小澄清问题。

面试官可能会问:“数据库里有上百张表,用户只说‘查上个月华东的活跃客户’,你怎么让模型知道该用哪些表和字段?”

很多 Text2SQL Demo 会把全部建表语句塞进 Prompt,让模型直接生成 SQL。表少时看起来能跑,表一多就会出现三类问题:上下文被无关字段占满;同名字段和相似表互相干扰;用户说的是业务词,数据库里却只有技术字段。

更难的是“活跃客户”本身没有唯一含义。它可能指登录过、下过单、产生过付费或满足某个客户分层规则。“上个月”按自然月还是最近三十天,“华东”按客户注册地、收货地还是组织归属,也都需要业务定义。

所以高质量 Text2SQL 要先把问题拆成指标、维度、时间、粒度、过滤条件和业务实体,再从元数据中选择最小但完整的 Schema,之后才轮到 SQL 生成。选不清时要提出最小澄清问题,不能用模型猜测掩盖歧义。

先给出 30 秒回答

面对大 Schema,我不会把所有 DDL 直接塞给模型。先把用户问题解析成业务指标、维度、时间范围、统计粒度、过滤条件和实体,再通过业务术语词典、表列描述、主外键关系、示例值和权限生成候选表列。候选召回后要补齐 Join 路径,形成最小可执行 Schema,再让模型做字段映射。若“活跃客户”“收入”“上个月”存在多个合法定义,系统应比较候选解释和置信证据,提出一个能最大化消除歧义的澄清问题。评估要分别看表召回、列映射、Join 路径、澄清决策和最终 SQL,不能只看执行成功。

核心原则是:先缩小问题空间并确认业务语义,再生成 SQL。

Text2SQL 从问题到最小 Schema 的流程

业务解析、Schema 召回、关系补全和歧义澄清发生在 SQL 生成之前。

为什么全量 Schema 会让模型变差

全量 DDL 不只是消耗 Token。真正的问题是它把大量相似候选放在模型面前,却没有说明业务含义和权威关系。

一个系统里可能同时有订单主表、订单明细、支付流水、退款记录、离线宽表和历史快照。它们都包含金额和时间字段。模型看到 amounttotal_amountpay_amountgmv 时,并不知道哪个是下单金额、实付金额、退款前金额或已经聚合的口径。

表越多,同名列越常见。created_at 可能是客户注册时间、订单创建时间或记录同步时间。只靠列名相似度,系统很容易选到“看起来像”的字段。

全量上下文还会稀释关系信息。模型可能找到了事实表和维表,却不知道应该经过哪张桥接表,或者错误地把两个非唯一键直接连接,导致结果重复。

因此 Schema 裁剪不是简单节省上下文,而是把模型的选择空间限制在业务上合理、权限上可用、关系上连通的子图里。

元数据字典要补足 DDL 没说的内容

DDL 通常只有表名、列名、类型和约束,业务问题需要更多信息。

表级元数据可以包含业务描述、数据域、负责人、更新频率、数据新鲜度、主键、分区键、常见查询场景和访问等级。列级元数据可以包含业务含义、单位、枚举说明、是否可空、示例值、敏感等级、聚合方式和有效时间语义。

指标还需要单独的语义定义。例如“支付金额”对应哪个事实字段,是否扣除退款,按支付成功时间还是订单完成时间,统计粒度是什么。把这些口径只写在 Prompt 里很难维护,应该放在可版本化的指标或业务术语层。

示例值能帮助实体映射。用户说“华东”,数据库可能保存地区编码;用户说某个产品简称,维表里可能是标准名称。示例值只能提供候选,不能把敏感列的真实数据大规模暴露给模型。

元数据要记录来源和版本。表结构变化、口径更新后,旧说明不能继续参与生成。没有版本的 Schema 缓存会让系统在数据库已经变更后仍生成旧字段。

先把自然语言问题拆成六个槽位

一个可操作的解析结果通常包括:指标、维度、时间、粒度、过滤和实体。

“查上个月华东的活跃客户”里,指标可能是活跃客户数或活跃客户明细;维度是地区;时间是上个月;粒度可能按客户、城市或日期;过滤是华东;实体是客户。

若用户说“按周看各渠道收入趋势”,指标是收入,维度是渠道,时间范围还缺失,粒度是周。系统可以先识别缺口,再决定使用默认范围还是澄清。

解析结果不等于业务定义已经确定。“收入”仍可能对应下单、支付、确认或净收入。槽位让歧义显性化,使后续模块知道缺的是哪一种信息,而不是把整个句子交给模型一次猜完。

结构化解析还便于 Trace。错误 SQL 出现时,可以判断是指标识别错、时间解析错、实体映射错,还是 Schema 检索错。

业务术语词典解决什么

业务词典连接用户语言与数据语言。

每个术语可以保存标准名称、同义词、定义、可选口径、适用数据域、对应指标或字段、时间语义、版本和负责人。“新增客户”可能映射注册事件,“付费客户”映射支付成功事实,“活跃客户”则可能按产品线有不同定义。

词典不是简单同义词替换。它要表达条件和歧义。例如“销售额”在经营报表里可能指含税订单金额,在财务报表里可能指确认收入。系统需要根据当前数据域和用户角色缩小候选,仍有多个合法口径时请求确认。

词典还要与权限结合。某个敏感指标即使语义匹配,当前用户无权访问时不能进入候选 Schema,更不能在澄清问题里泄露其存在和细节。

用户确认某个口径后,可以把选择保存在当前查询 State,后续追问沿用,但不能自动升级成所有用户的全局定义。

Schema 召回不能只搜表名

候选生成可以组合多路信号:表和列描述的语义相似;业务术语映射;指标目录;实体与示例值匹配;数据域和用户角色;历史正确样例;精确关键词。

例如问题涉及“退款后的支付收入”,语义召回可能命中支付表和退款表,术语词典命中净收入指标,关系图补充订单主键。只搜表名可能只找到一张 payment 表,遗漏退款调整。

候选表要带入相关列,而不是把每张表全部字段送入模型。保留主键、外键、指标字段、过滤字段、时间字段和必要维度字段。敏感或无关列继续排除。

召回阶段追求“正确表列在候选里”,但候选不能无限扩大。可以先按数据域和权限硬过滤,再语义召回和重排。阈值与候选数量需要根据评测集校准,不应在没有数据时给固定数字。

找到表还不够,还要补齐 Join 路径

用户问题常跨越事实表和维表。单独召回到订单、客户和地区表,不代表模型知道怎样连接。

系统可以维护 Schema Graph:节点是表,边记录外键、候选连接键、基数关系、有效条件和方向。召回到目标表后,在图中寻找允许的最短或最可信连接路径,并补齐中间桥接表。

连接信息要包含一对一、一对多或多对多关系。若订单明细与标签表都是一对多,直接连接会造成行数膨胀。模型需要知道先聚合、去重或使用存在性子查询,而不是只拿字段名拼 JOIN

并非所有数据库都声明完整外键。此时可以由数据团队维护关系元数据,或从已审核查询中提取候选关系,但必须标明可信度和来源。不能把列名相同当作可连接证明。

最终送给生成器的是一个连通的最小 Schema 子图:目标指标、过滤与分组字段、时间字段、必要主外键和业务说明。

Schema 召回与 Join 关系补全

候选表需要通过可信关系形成连通子图,不能让模型自由猜连接键。

歧义可以分成哪些类型

第一类是指标歧义。收入、用户、订单、活跃等业务词有多个口径。

第二类是时间歧义。上个月、最近一年、同比、当日可能涉及自然周期、滚动窗口、时区和业务日。

第三类是实体歧义。同名客户、产品简称、地区层级或组织名称可能对应多个编码。

第四类是粒度歧义。“查客户”可能要明细列表,也可能要数量;“趋势”可能按天、周或月。

第五类是范围歧义。“华东”按注册地、订单收货地、门店区域还是销售组织归属。

第六类是权限与可用性歧义。用户想要的指标存在,但当前只能访问脱敏或聚合版本。

将歧义分类后,澄清问题才能针对真正缺口。泛泛地问“请提供更多信息”对用户没有帮助。

什么时候必须澄清,什么时候可以使用默认值

如果不同解释会改变核心指标、表、Join 路径或权限,就应该澄清。若只是展示排序或默认分页,产品已有明确约定,可以使用默认值并在结果中说明。

澄清问题应最小化。不要一次列出十个数据库字段让用户选择。可以问:“这里的活跃客户,是指上个月登录过,还是上个月完成过支付?”两个选项直接对应候选口径。

如果候选解释很多,可以先根据用户角色、当前报表域和历史上下文缩小,再问区分度最大的一个问题。用户回答后更新结构化槽位和 Schema 候选,而不是把回答只追加到对话末尾。

不能用置信度高就掩盖高风险歧义。模型很确信地选择错误财务口径,后果仍然严重。是否澄清还要考虑指标风险、执行影响和结果用途。

默认值必须可见。系统使用自然月、北京时间、支付成功金额或明细上限时,应在查询解释中明确,让用户能纠正。

一个完整例子:查上个月华东的活跃客户

第一步解析槽位:实体是客户,地区条件是华东,时间是上个月,活跃口径未定义,输出粒度未定义。

第二步查术语词典,发现当前业务域里“活跃客户”有登录活跃与支付活跃两种有效定义。“华东”也可按客户注册地址或订单收货地解释。

第三步提出高信息量澄清:“你要看登录过的客户,还是完成过支付的客户?地区按客户注册地还是订单收货地?”如果产品希望一次只问一个问题,先问会改变事实表的活跃口径,再问地区字段。

用户回答“完成支付,按收货地,给客户明细”。系统据此选择支付事实、订单与地址维表,补齐连接路径,选择客户 ID、客户名、支付时间和地区字段,并把“上个月”解析成当前时区下的上一自然月。

生成 SQL 前,最小 Schema 已经包含明确口径和关系。即使最后 SQL 仍可能出错,错误空间已经从上百张表缩小到一个可解释子图。

多轮追问怎样沿用上下文

用户得到结果后说“再按城市汇总”,这不是一个全新查询。系统应沿用已经确认的支付活跃、收货地区域和上月时间,只把粒度从客户明细改成城市聚合。

State 需要保存原问题、已确认槽位、默认值、Schema 版本、候选子图和用户修改。若用户说“时间改成今年”,只更新对应槽位并重新检查分区与可用表。

历史上下文不能无条件沿用。用户切换数据域或明确说“换成登录活跃”,旧口径应被替代。当前确认高于模型从历史推断的偏好。

多轮查询的测试要覆盖指代、条件追加、条件撤销、粒度变化和口径改写,避免系统每轮重新猜 Schema 或错误叠加旧过滤。

怎样评估 Schema 选择和澄清

不能只看 SQL 是否执行成功。错误表和错误口径也可能返回一张看似合理的结果。

评测样本应保存用户问题、业务定义、允许的表列集合、必要 Join 关系、歧义标签、期望澄清问题和最终意图。对同一表达设计不同业务域,测试系统是否使用正确作用域。

分层指标可以看:目标表是否进入候选;关键列是否召回;最小子图是否包含必要关系;无关 Schema 是否过多;业务术语映射是否正确;该澄清时有没有问;不该澄清时是否直接处理;用户回答后槽位是否正确更新。

最终 SQL 准确性属于后续层。Schema 选对但 SQL 写错,与 Schema 一开始就漏表,需要不同修复路径。

Badcase 也要分类回流。新术语补词典,表说明不清补元数据,关系漏失补 Schema Graph,澄清问题无效则改歧义策略。不要只把失败样本塞进 Few-shot,希望模型自己悟出数据库治理问题。

Text2SQL 歧义类型与处理方式

指标、时间、实体、粒度和范围歧义需要不同的澄清与默认策略。

常见的四种错误方案

第一种是只做向量 TopK 表召回。它可能找对语义相似表,却漏掉中间 Join 表和关键外键。

第二种是把历史 SQL 当唯一真相。历史查询可能使用旧口径、旧 Schema 或特定用户权限,只能作为带版本候选。

第三种是让模型自行发明业务定义。答案流畅不代表“活跃”口径正确。

第四种是每个模糊词都追问。过度澄清让系统不可用,应把产品默认、低风险展示选择和真正改变业务结果的歧义分开。

历史正确 SQL 能不能直接当 Few-shot

可以作为候选样例,但必须先验证它与当前问题处在同一数据域、Schema 版本、业务口径和权限范围。

一条历史 SQL 执行成功,只能证明它在当时环境中可运行。表可能已经迁移,指标定义可能更新,历史用户也可能拥有当前用户没有的字段权限。若系统只按问题相似度拿来做 Few-shot,模型会复制旧表、旧过滤或旧 Join。

更稳的样例库应保存原问题、结构化意图、使用的表列、口径版本、Schema 版本、审核状态和适用范围。召回后先做元数据兼容检查,只把仍然有效的结构模式提供给生成器。

Few-shot 还能帮助模型学习特定查询模式,但不能替代元数据字典与关系图。历史上从未出现的新口径、新表或新权限,仍要回到当前 Schema 决策。

Text2SQL Schema 选择与澄清验收清单

历史样例、元数据、关系与澄清都要在当前版本和权限内验收。

面试官会怎样连续追问

追问一:为什么不把全部 DDL 放进长上下文

长上下文不能解决业务含义、权限和 Join 关系,还会引入大量相似字段干扰。动态裁剪的目标是得到最小但完整的连通 Schema。

追问二:Schema 召回只用 Embedding 可以吗

不够。需要结合业务词典、精确实体、指标目录、数据域、权限和关系图。向量相似只是一种候选信号。

追问三:怎样判断该不该问用户

看不同解释是否改变核心指标、数据源、Join、权限或高风险结果。能用明确产品默认解决的低风险项可以说明默认,不必全部追问。

追问四:找到了目标表,为什么还会生成错 SQL

可能漏了连接表、基数信息、时间口径或聚合粒度。Schema 选择要输出连通子图和业务说明,不只是表名列表。

追问五:业务词典谁来维护

由数据与业务负责人提供权威定义,系统记录版本和来源;Badcase 可以提出候选,但不能由模型静默改全局口径。

追问六:怎样证明澄清机制有效

建立带歧义标签和期望问题的评测集,分别测该问时能问、不该问时不打断,以及用户回答后 Schema 是否收敛。

从用户问题到最小 Schema:完整回答

大规模 Text2SQL 我会先做语义解析和 Schema Linking,而不是把全量 DDL 塞给模型。用户问题拆成指标、维度、时间、粒度、过滤和实体,通过业务术语词典、表列描述、指标目录、示例值与权限召回候选。然后在 Schema Graph 中补齐主外键和中间表,保留基数、时间语义和聚合说明,形成最小连通子图。如果指标、时间、实体或范围有多个合法解释,就根据风险和区分度提出最小澄清问题,用户确认后写回结构化 State。评估分层看表列召回、Join 路径、术语映射、澄清决策和最终 SQL,Badcase 分别回流元数据、词典、关系图与澄清策略。

Schema 选择与澄清,项目里要留下什么

  1. 是否能把问题拆成指标、维度、时间、粒度、过滤和实体。
  2. 元数据是否包含业务含义、单位、枚举、时间语义、权限和版本。
  3. Schema 召回是否组合语义、术语、指标、实体和数据域。
  4. 候选表是否补齐可信 Join 路径与基数关系。
  5. 最终上下文是否最小但完整,而非简单 TopK 表。
  6. 是否区分指标、时间、实体、粒度、范围和权限歧义。
  7. 澄清问题是否直接区分候选口径,避免泛泛追问。
  8. 多轮修改是否更新结构化槽位,而非不断拼接自然语言。
  9. 评估是否把 Schema 选择、澄清和 SQL 生成分层归因。
  10. 没有真实数据时,是否避免虚构准确率、表规模和收益数字。

Text2SQL 的上限不只由模型决定。把业务口径、Schema 关系和歧义处理做成可维护的语义层,才可能让“自然语言查数据”从演示变成可解释的工程链路。

INTERVIEW FOLLOW-UPS

面试官会怎样继续追问?

这些追问会继续检查方案取舍、验证方法和项目事实。
  1. Q01

    为什么不能把全部数据库 DDL 直接放进 Prompt?

  2. Q02

    Schema 召回怎样补齐中间 Join 表和基数关系?

  3. Q03

    哪些业务歧义必须向用户澄清?

  4. Q04

    怎样分层评估表列选择、澄清和最终 SQL?

PROJECT CHECK

换成你的项目,这几件事能否说清楚?

  • 解析指标、维度、时间、粒度、过滤和实体
  • 结合术语、元数据、权限与关系图选择 Schema
  • 形成最小但完整的连通表列子图
  • 用歧义评测集验证澄清与多轮更新
用自己的项目经历练一次