有了 Text-to-SQL,为什么还要固定口径的指标工具?
简化版
核心原因是口径。同一个问题「暑期档票房前五」,让模型现写 SQL,每次的写法都可能不一样:档期怎么界定、点映算不算、同比怎么算,模型每次的理解都可能变,同一个对象换种问法算出来的数就对不上,不同对象之间也没法比。固定指标工具把口径写死在各自的 SQL 里,模型只负责选用哪个工具,同一个问题永远得到同一个数。Text-to-SQL 不是不要,而是退到兜底位置:固定工具盖不到的问题才现写 SQL,并且单独监控兜底的使用率。
详细版
两层查询的结构:
用户问题
→ 模型从「启用的工具清单」里选一个
├─ 选中固定指标工具 → 代码组装参数 → 执行写死口径的 SQL
└─ 都答不了 → 兜底工具:Text-to-SQL 现写 SQL → 安全校验 → 执行
→ 统一记录:用了哪个工具、是否走了兜底、返回多少行、耗时
两种方式的对比:
| 维度 | 固定指标工具 | Text-to-SQL |
|---|---|---|
| 口径 | 写死在 SQL 里,每次一致 | 每次由模型理解,可能变化 |
| 跨对象可比 | 可比 | 不保证 |
| 覆盖面 | 只覆盖事先设计好的问题 | 理论上什么都能问 |
| 安全 | SQL 由开发者写好 | 需要完整的安全校验链 |
| 成本 | 一次路由调用 | 路由 + 生成 SQL,可能还要纠错 |
| 适合 | 高频、口径敏感的核心指标 | 长尾、临时性的问题 |
完整版教学
一、Text-to-SQL 的问题不在「写不对」,而在「写不一样」
讨论 Text-to-SQL 时,大家通常担心 SQL 写错。但在业务分析里,更隐蔽的问题是写得都对,却写得不一样:
问题:「某部影片的首周票房是多少」
写法 A:上映日起 7 天的票房合计
写法 B:上映当周周一到周日的票房合计
写法 C:包含点映场次的首 7 天票房
三种写法语法都没错,也都能说出道理,但数字不同。用户今天问得到 A 的数,明天换种问法得到 B 的数,拿两部影片比的时候一部按 A 算、一部按 C 算——结论就不可信了。口径不一致的数字,比没有数字更危险,因为它看起来是对的。
二、固定指标工具:把口径变成代码
固定指标工具是一组事先设计好的查询,每个工具回答一类问题,口径写死在它的 SQL 里:
工具注册信息
编码 工具的唯一标识,与代码里的实现一一对应
名称 给人看的名字
说明 这个工具回答什么问题(拼进提示词,模型靠它来选)
入参说明 需要哪些参数
返回说明 返回哪些字段
是否兜底 标出兜底工具
启用状态 后台开关,停用后调不到
工具注册信息放在表里而不是写死在代码里,有两个好处:一是启停是真开关,工具清单每次现读表构建,停用的工具模型根本看不到;二是新增工具不改编排代码,加一行注册信息、加一个取数实现即可。
三、为什么 Text-to-SQL 还要保留
固定工具的问题是覆盖面:业务问题是长尾的,不可能为每一种问法都设计一个工具。「暑期档里评分高于 8 分、上映超过 30 天的影片有哪些」这种组合条件,固定工具很难覆盖。这时就需要 Text-to-SQL 兜底:
优先级:固定指标工具 > Text-to-SQL 兜底
兜底条件:模型判断固定工具都答不了;或者选中的固定工具执行失败
兜底要求:走完整的安全校验链,执行失败才纠错,并记录是否走了兜底
两层结构的本质是:高频、口径敏感的问题用确定性保证一致;长尾问题用灵活性保证能答。
四、兜底使用率:两层查询最关键的观测指标
兜底用得多了,说明固定工具的覆盖出了问题。这个数要单独统计:
兜底使用率 = 走兜底的调用次数 / 总调用次数
例:一周问数 1200 次,其中 180 次走了兜底
兜底使用率 = 180 / 1200 = 15%
下一周补了一个「按档期对比」的固定工具后,1150 次里走兜底 69 次 → 6%
补工具前后的对比能直接说明这个工具接住了多少原本要现写 SQL 的问题。实际使用中,还要把走兜底的那些问题拉出来看:如果大量问题都在问同一类事情,这就是下一个该补的工具;如果问题五花八门,兜底使用率偏高也可能是合理的长尾。
它升高时有两种处理方向:
| 情况 | 说明 | 处理 |
|---|---|---|
| 用户问的确实是新角度 | 现有工具都不回答这类问题 | 补一个固定工具 |
| 问题在现有工具的口径内 | 模型没选对 | 改写工具说明,让模型选得准 |
这个指标比「调用成功率」更有信息量:成功率只说明工具没报错,说明不了工具覆盖得够不够。
记忆钩子:固定工具管「一致」,Text-to-SQL 管「能答」;兜底使用率告诉你两者的边界该往哪边挪。
五、工具说明怎么写
模型选工具靠的是工具说明,所以说明的写法直接决定路由的准确率:
好的说明:回答某部影片在指定日期范围内的每日票房、排片占比和上座率走势。
适合「某某片最近票房怎么样」「某某片的排片变化」这类问题。
差的说明:查询票房数据。
说明要写「这个工具回答什么问题」,并给出典型问法;不要写「参数怎么填」——参数由代码根据路由结果组装,模型不需要知道。
六、指标工具和语义层是什么关系
语义层(指标口径表)是另一种保证口径一致的方式:把指标的名称、公式、SQL 表达式登记下来,让 Text-to-SQL 在生成 SQL 时参考。两者的区别:
| 语义层(指标口径) | 固定指标工具 | |
|---|---|---|
| 保证方式 | 把口径告诉模型,模型照着写 | 模型不写 SQL,只选工具 |
| 一致性 | 依赖模型是否照做 | 由代码保证 |
| 灵活性 | 可以自由组合维度和条件 | 只能回答工具覆盖的问题 |
语义层是「提醒模型遵守口径」,指标工具是「不给模型违反口径的机会」。口径越敏感、越需要跨对象比较,越应该做成工具。
七、统一执行入口
固定工具和兜底工具都应该走同一个执行入口,按固定顺序做五件事:
1 查注册表 工具不存在或已停用,直接拦下
2 校验入参 缺必要参数时说明缺什么,而不是空手而归
3 转交执行 固定工具执行写死口径的 SQL,兜底工具走 Text-to-SQL 链路
4 截断明细 按注册表里的返回上限截断逐行数据,汇总值不受影响
5 写日志 成功失败都记:哪个工具、入参、返回行数、耗时、是否兜底
每一步各拦一种问题:不查启用状态,停用的工具照样能被调用;不校验入参,用户不知道为什么没结果;不截断,一个工具能把几百行塞进模型上下文;不写日志,兜底使用率就无从统计。统一入口的另一个好处是,不管从问数页面、分析计划还是后台试运行调用,行为都一致。
八、常见误区与追问
- 误区:Text-to-SQL 足够强之后,固定工具就没必要了。 问题不在能不能写对,而在每次写得是否一样,口径敏感的核心指标需要确定性。
- 误区:固定工具越多越好。 工具多了,模型选工具的难度也上升,说明之间容易重叠;应该按兜底使用率和具体问题有针对性地补。
- 误区:兜底工具可以直接执行模型写的 SQL。 兜底走的是完整的 Text-to-SQL 链路,安全校验一步都不能少。
- 误区:工具说明里要写清楚参数怎么填。 说明写「回答什么问题」,参数由代码组装,写参数反而诱导模型输出不可靠的参数。
- 误区:调用成功率高就说明工具设计得好。 成功率只说明没报错,兜底使用率才反映工具覆盖是否足够。
- 追问:新增一个指标要改哪些地方? 注册表加一行,业务侧加一个取数实现;编排代码不用动,因为工具清单每次现读表构建。
- 追问:固定工具执行失败了怎么办? 换兜底工具再试一次,只降级一次,不循环重试同一个工具。
九、加强记忆
有了 Text-to-SQL 还要固定指标工具,是因为口径:同一问题现写 SQL 每次写法可能不同,写得都对却数字不同,跨对象也没法比。固定工具把口径写死在 SQL 里,模型只负责选工具;注册信息放表里,启停是真开关,新增工具不改编排代码。Text-to-SQL 退到兜底,覆盖长尾问题,走完整安全校验。兜底使用率是关键观测指标:高了要么补工具,要么改说明。工具说明写「回答什么问题」而不是参数怎么填。语义层是提醒模型守口径,工具是不给模型违反口径的机会;两类工具走同一个执行入口。