模块 2 · NL→SQL 管线

一句话怎么变成
可审计的表格?

NL→SQL 编排(app/service/analyst_agent.py)把用户问题拆成可测试步骤。 像翻译官 + 安检 + 记账员:先弄清指标含义,再生成 SQL,层层校验后才执行,最后解读并留痕。

七步流水线(动画)

点击「下一步」看 NL→SQL 在代码里怎么走:

📖消歧 dict
🤖LLM 生成
🛡SQL 安全校验
🗄execute
✓guardrail

校验失败 → 403 或 degrade(只给表格不给瞎编解读)

SQL 安全校验(sql_guard.py)在拦什么

只读白名单

拒绝 INSERT/UPDATE/DELETE 等写操作关键字

表白名单

core_* + risk_alert 等,超出即 403

行级归属

customer 域强制 customer_id = 本人;advisor 只能名下客户

粒度控制

ops 聚合域禁止下钻到单个客户明细

CODE · NL→SQL 编排(analyst_agent.py).run
amb = self._detect_ambiguity(question)
if amb: return self._clarify(amb, trace_id)
sql_text, usage = self._generate_sql(...)
vres = validate(sql_text, domain, scope)  # sql_guard
exec_result = self.repo.execute_readonly(sql_text)
answer, guard = self._generate_verified_answer(...)
self._persist(...)  # analytics_query_log
白话

指标说不清就先反问,不瞎猜 SQL。

生成后必须过 SQL 安全校验(sql_guard.py),执行只走只读连接。

AI 解读若数字对不上表,降级为「请看表格」;全程写入查询日志备查。

数字护栏(guardrail)校验失败时,用户还能看到查询结果表格吗?