摘要
9-29/01 把知识库做成受治理的产品,本文把同一套底座接到数据分析场景:让"问一句话出一张表"也走上受治理的轨道。核心是用语义层(呼应 SuperSonic)屏蔽物理表复杂度、用多轮状态维护(接 9-28/02 上下文工程)承接追问、用SQL 可信校验(EXPLAIN 干跑 / 行数异常 / 禁 DML)把工具做成一个经 9-25 网关与 9-26 护栏的只读工具,最后用 9-26 法官评测量化"生成的 SQL 对不对"。ChatBI 的生死线是’生成的 SQL 能不能跑、跑出来信不信得过’——语义层降低幻觉、校验层拦住危险,二者缺一不可。
一句话结论:把对话式数据分析当成"受约束的 SQL 生成服务"——语义层把自然语言映射到业务口径、多轮上下文承接追问、校验层在真实执行前拦掉危险与错误、法官评测量化正确性,让业务人员"问得出口、信得过数"。
1. 为什么 NL2SQL “demo 很香、上线很痛”
直接让模型对着几百张物理表生成 SQL,三个必翻车点:
| 痛点 | 表现 | 解法 |
|---|---|---|
| schema 太复杂 | 表名/字段名晦涩,模型猜错 join | 语义层封装 |
| 歧义 | "上个月销售额"口径不一 | 语义指标统一定义 |
| 安全 | 生成DELETE、跨库扫全表 | 执行前校验 + 只读 |
9-27/01 的 RAG 解决"知识查得到",ChatBI 解决"数据问得动"——前者喂事实,后者喂数仓,底层都靠同一个受治理平台。
2. 语义层:把物理表翻译成业务语言(呼应 SuperSonic)
SuperSonic 这类 Headless BI 的核心价值,就是物理模型 → 语义模型的映射。NL2SQL 在语义层之上生成,模型只看到"订单.成交额""用户.活跃天"这种业务口径,而非t_ord.f_amt和t_usr.d_active。
# 语义层定义(SuperSonic 风格)datasets:-name:"订单"table:"dw.fact_order"dimensions:-name:"城市"# 业务口径expr:"city_code"# 物理字段-name:"下单日期"expr:"dt"measures:-name:"成交额"expr:"sum(f_amt)"agg:SUM-name:"订单数"expr:"count(1)"metrics:-name:"客单价"expr:"成交额 / 订单数"# 口径统一定义,避免每人算一遍| 层 | 责任 | 收益 |
|---|---|---|
| 物理层 | 真实表/字段 | — |
| 语义层 | 维度/指标/口径 | 屏蔽复杂度、统一口径 |
| 生成层 | NL → 语义 SQL | 模型只见业务语言 |
语义层复用 9-25 网关的租户隔离:不同租户的"销售额"可以指向不同物理表,却暴露同一业务口径。
3. 多轮对话状态(接 9-28/02 上下文工程)
“上个月销售额多少?”“那华北呢?”“同比呢?”——追问必须靠对话状态承接,这正是 9-28/02 上下文工程的用武之地:把上一轮的生成 SQL / 筛选条件 / 时间窗口塞进上下文,下一轮基于它改写而非凭空来。
classChatBIState:def__init__(self):self.history=[]# 9-28/02 的 History 来源self.last_sql=None# 上一轮语义 SQLself.slots={}# 已解析的时间/维度/指标defresolve(self,utterance):# 把新话术 + 历史 slots 一起喂给模型,做指代消解prompt=build_ctx(self.history,self.slots,utterance)sql,new_slots=nl2sql(prompt,semantic_layer)self.slots.update(new_slots)self.last_sql=sql self.history.append((utterance,sql))returnsql| 上下文要素 | 来自 | 作用 |
|---|---|---|
| 历史 SQL | 9-28/02 History | 承接"那华北呢" |
| 已填 slots | 状态机 | 时间/维度复用 |
| 语义层 | 第 2 节 | 约束生成空间 |
4. 可信校验:执行前的三道闸
生成 SQL 不能直接甩给数仓。执行前必须过三道闸,把它做成 9-28/01 里"隔离运行"的只读工具:
defsafe_execute(sql,db):parsed=parse(sql)# 闸 1:禁 DML / DDLifparsed.typenotin("SELECT","WITH"):raiseBlocked("只允许只读查询")# 闸 2:禁跨库 / 系统表iftouches_forbidden_table(parsed):raiseBlocked("触及受限表")# 闸 3:EXPLAIN 干跑,估行数防全表扫plan=db.explain(sql)est_rows=plan.estimated_rowsifest_rows>1_000_000:raiseBlocked(f"预估扫描{est_rows}行,疑似全表扫")returndb.run(sql,readonly=True)| 闸 | 拦什么 | 失败动作 |
|---|---|---|
| 禁 DML | DELETE/UPDATE/INSERT | 直接拒绝 |
| 禁越权表 | 跨租户/系统表 | 拒绝 |
| EXPLAIN 行数 | 全表扫/笛卡尔积 | 拒绝或要求加 limit |
这一工具经 9-25 网关路由(只读实例)、受 9-26 出站护栏约束(结果脱敏),与 9-28/01 的沙箱理念完全一致:模型能"查数据",但碰不到"写权限"。
5. 结果叙事:从表格到洞察
SQL 跑出结果只是开始,业务人员要的是洞察。把表格转成自然语言 + 自动图表:
- 异常检测:环比/同比突变自动高亮;
- 归因:指标下跌自动拆分维度贡献;
- 图表:按维度自动选柱状/折线/饼图(接前端渲染)。
defnarrate(result_df,question):insight=llm_summarize(question,result_df)# 自然语言洞察chart=auto_chart_select(result_df)# 自动选图return{"text":insight,"chart":chart,"rows":result_df}6. 评测:生成的 SQL 对不对(接 9-26 法官评测)
ChatBI 的正确性必须可量化。两层评测:
- 可执行性:SQL 能否在语义层 + 数仓跑通(第 4 节闸);
- 语义正确性:用 9-26 的法官评测,把"问题 + 标准 SQL"与"生成 SQL 的执行结果"比对,让法官判断语义等价。
| 评测项 | 方法 | 接 |
|---|---|---|
| 执行成功率 | 闸通过率 | 9-28/01 工具 |
| 结果一致性 | 标准 vs 生成结果比对 | 9-26 法官 |
| 口径命中 | 指标是否用语义层定义 | 第 2 节 |
低分样本回流 9-20 RLVR / 9-23 CI 门禁,形成"生成 → 评测 → 改提示词/语义层"的闭环。
7. 小结:数据也走上受治理轨道
至此,平台的"能力面"从知识(9-29/01)扩展到数据:
- 语义层屏蔽物理复杂度、统一口径(呼应 SuperSonic);
- 多轮状态承接追问(接 9-28/02 上下文);
- SQL 校验把它做成只读工具(接 9-25 网关 / 9-26 护栏 / 9-28/01 沙箱);
- 法官评测算正确性(接 9-26)。
下一站(9-29/03)不再加新能力,而是把前面所有"花钱的地方"——9-20 KV、9-25 缓存与路由、9-26 引擎、9-25 配额——收口成企业级 LLM FinOps,回答老板最关心的问题:“这平台到底值不值”。
常见问题(FAQ)
Q1:语义层和直接在 prompt 里塞 schema 有什么区别?
A:prompt 塞 schema 时模型面对几百张晦涩物理表,join 和口径极易错;语义层只暴露业务口径(成交额/客单价),并统一定义指标公式,既降幻觉又保证"全公司一个算法"。
Q2:多轮追问崩了怎么办?
A:状态机里保留 last_sql 和可解析 slots,崩时回退到上一轮有效 SQL 重新改写,而不是直接凭空生成;同时限制对话轮数上限,过长则提示"重新开始一个分析"。
Q3:EXPLAIN 干跑在所有数仓都支持吗?
A:主流都支持(PostgreSQL/MySQL/ClickHouse/Hive 均有 EXPLAIN),但估算行数的字段名不同,需按引擎适配;对不支持的引擎退化为"强制 LIMIT + 超时熔断"。
Q4:ChatBI 能写数据回写吗?
A:生产默认只读。若业务确实需要(如"把这批客户标记为高价值"),必须走独立写通道 + 人工二次确认 + 9-25 网关审计,绝不与查询通道混用。
Q5:结果叙事会引入新的幻觉吗?
A:会。所以叙事模型只被允许"描述已返回的数据"(不许编造未出现的数字),并附原始表格供核对;异常归因用确定性规则而非自由生成。
Q6:语义层怎么和 RAG 知识库(9-29/01)配合?
A:语义层定义"指标口径",知识库存"指标背后的业务说明/负责人",ChatBI 回答时可引用知识库文档作为口径出处,二者在 9-25 网关下共享同一租户权限。
Q7:评测集怎么来?
A:从真实对话日志抽典型问题 + 专家标注标准 SQL,沉淀为 9-25 黄金集,每次语义层或提示词变更都跑回归(接 9-23 CI 门禁)。
参考资料
- 本专栏 9-29《企业级 RAG 知识库产品化实战》:共享的权限与治理底座
- 本专栏 9-28《上下文工程实战》:多轮对话的状态维护
- 本专栏 9-28《函数调用与工具执行沙箱实战》:只读工具与隔离运行
- 本专栏 9-25《统一 LLM 推理网关实战》:租户隔离与工具路由
- 本专栏 9-26《LLM-as-Judge 自动化评测流水线》:SQL 语义正确性评测
- 腾讯 SuperSonic 开源项目文档:Headless BI 与语义层建模,2026