Skip to content

g1157/nl2sql-demo

Repository files navigation

自然语言数据库交互系统原型

提供一条较为完整的工程闭环:

自然语言问题 -> Schema 理解 -> SQL 生成 -> 执行反馈 -> 结果校验 -> 轨迹留存

当前仓库已经具备可运行的 Web 入口、API 通路、Agent 通路、评测通路,以及多数据源扩展与结果追踪能力。

项目概览

这个项目聚焦 DB-NLI(Database Natural Language Interaction),即让用户直接使用自然语言完成数据库查询、统计分析和结果呈现准备。

相对“单次生成 SQL”的轻量方案,本项目更强调以下工程特性:

  • 可执行:生成结果最终要落到数据库执行;
  • 可修复:执行失败或结构不匹配时可进入修复链路;
  • 可约束:通过输出合同约束列名、顺序和结构;
  • 可回归:支持批量评测与结果对比;
  • 可扩展:支持多数据集注册、多数据库适配与公开代理数据接入;
  • 可追踪:保留 grounding、生成、修复、执行、评测等关键轨迹。

核心能力

查询能力

  • 自然语言问题理解与意图分析
  • Schema grounding / 表列召回
  • SQL 自动生成与非 SQL 输出重试
  • 多候选 SQL 生成与重排
  • 执行失败自动修复
  • 输出列合同校验与结构修复
  • 结果规范化与最终产物落盘

工程能力

  • Flask Web 服务入口
  • Vue 前端壳层
  • 单轮查询与多步 Agent 两条运行通路
  • 本地 mini-eval 与专项评测
  • 审计日志与历史记录存储
  • RBAC / 语义视图 / 治理层基础设施
  • 多数据库适配层与外部数据集注册机制

系统通路

当前仓库存在 4 条主要通路:

通路 入口 适用场景 核心特点
遗留聊天通路 /chat 快速体验 基于 Vanna 原生页面,接入成本低
Fast 查询通路 POST /api/query + mode=fast 常规查询 单轮闭环,响应直接
Agent 查询通路 POST /api/query + mode=agent 复杂问题 多步观察、诊断、修复
Eval 通路 eval/run_mini_eval.py 回归验证 批量执行、统一报告输出

1. 遗留聊天通路

  • 入口:app.py 中的 main()VannaFlaskApp(vn)
  • 触发方式:用户直接在 /chat 的 Vanna 内置聊天框输入问题
  • 典型内建路由:/generate_sql/run_sql

数据流:

用户问题
  -> Vanna.generate_sql(question)
  -> Vanna.run_sql(sql)
  -> 返回 SQL + 表格 + 图表

关键代码:

位置 作用
app.py JunoVanna 组合 ChromaDB_VectorStoreOpenAI_Chat
app.py create_vanna() 创建 Vanna 实例并连接 SQLite
app.py generate_questions() 提供默认建议问题
app.py main() 组装 VannaFlaskApp 并启动服务

这条通路的特点是:

  • 使用门槛最低;
  • 适合快速验证基础问答;
  • 返回结果更接近“原生聊天 + SQL 展示”;
  • 不经过统一的 Intent / Contract / Governance / Audit 链路;
  • 没有统一审计、RBAC、语义视图和结构化追踪约束。

2. Fast 查询通路

  • 入口:POST /api/query
  • API 路由:nldb/api/query_routes.py
  • 核心方法:nldb/query_tool.py 中的 JunoQueryTool.run_question()
  • 请求模式:mode=fast

示例请求:

{
  "question": "按区域统计事件数",
  "mode": "fast",
  "dataset_name": "juno_demo",
  "user_role": "analyst",
  "num_candidates": 1
}

8 阶段完整链路:

阶段 核心动作 主要产物
1. Intent Analysis analyze_question() IntentAnalysis,包含意图类型、预期列、top-k 等信息
2. Schema Linking & Grounding ground_question() grounded_promptgrounding_trace
3. Output Contract build_output_contract() OutputContract,约束列名、顺序、额外列策略
4. SQL Generation generate_sql() / generate_sql_candidates() 单候选或多候选 SQL
5. Governed Execution governed_execute() SQLResult(columns, rows)
6. Execution Repair Loop build_execution_repair_prompt() + 再生成 执行失败后的修复 SQL
7. Contract Validation & Repair validate_output_contract() + build_contract_repair_sql() 列结构校验与结构修复
8. Value Normalization build_value_normalization_sql() 对数值、排序、维度列做规范化输出

关键类与数据结构:

类/函数 作用
JunoQueryTool Fast 通路核心类
RunContext 单次调用上下文缓存,避免重复取 schema / profile
QueryRunResult 统一结果对象,包含 SQL、trace、结果表、状态
OutputContract 输出结构合同
SQLResult 执行结果容器

关键参数:

  • top_k_tables:Schema grounding 时选取的表数量;
  • num_candidates:候选 SQL 数量,>1 时进入多候选重排;
  • max_generation_retries:生成失败后的重试次数;
  • max_execution_repairs:执行修复次数;
  • disable_grounding:关闭 schema grounding;
  • disable_value_probe:关闭值域探测;
  • forced_sql:跳过生成,直接验证指定 SQL;
  • allow_extra_columns:放宽输出列严格匹配;
  • user:RBAC / 治理上下文;
  • extra_context:附加上下文知识。

状态值:

状态 含义
success 执行成功且结构通过
contract_mismatch 执行成功但结果列结构仍不匹配
generation_error 生成 SQL 失败
execution_error SQL 执行失败且修复未成功
validation_error forced_sql 非合法 SELECT

API 层集成过程:

  1. query_routes.py 中解析请求;
  2. 根据数据集构造 JunoQueryTool.from_dataset()
  3. 调用 tool.run_question()
  4. 将结果写入 AuditStore
  5. 返回统一 artifact 响应。

3. Agent 查询通路

  • 入口:POST /api/query
  • API 路由:nldb/api/query_routes.py
  • 核心方法:nldb/agent_loop.py 中的 AgentLoop.run()
  • 请求模式:mode=agent

这条通路适合复杂问题,因为它不是“一次生成然后执行”,而是一个多步状态机。

示例请求:

{
  "question": "按区域统计事件数",
  "mode": "agent",
  "config": {
    "round_budget": 3,
    "disable_value_probe": true
  }
}

7 个主要阶段:

阶段 主要动作 典型产物
PLANNING 解析问题,建立意图与预算 IntentAnalysis
LINKING 做 schema grounding 与合同构建 grounded_promptcontract
GENERATING 生成 SQL current_sql
EXECUTING 执行 SQL current_resultcurrent_error
OBSERVING 诊断错误或结果异常 ErrorDiagnosis
REPAIRING 基于诊断重写 SQL 修复后的 current_sql
COMPLETED / FAILED 进入终态 final_sqlfinal_result 或失败原因

状态机形态:

PLANNING
  -> LINKING
  -> GENERATING
  -> EXECUTING
  -> OBSERVING
     -> REPAIRING -> EXECUTING
     -> LINKING   -> GENERATING
     -> COMPLETED
     -> FAILED

两级诊断机制:

Level 1:硬错误诊断

错误类别 典型问题 恢复动作
SYNTAX_ERROR SQL 语法错误 REPAIR_SQL
TABLE_NOT_FOUND 表不存在 RETRY_LINK
COLUMN_NOT_FOUND 列不存在 REPAIR_SQL
TYPE_MISMATCH 类型不匹配 REPAIR_SQL
TIMEOUT 执行超时 RETRY_GENERATE
UNKNOWN 未知错误 REPAIR_SQL

Level 2:软异常诊断

错误类别 检测条件 恢复动作
CONTRACT_MISMATCH 实际列与期望列不一致 CONTRACT_REPAIR
EMPTY_RESULT 返回 0 行 RETRY_GENERATE
SUSPICIOUS_RESULT 全 NULL、单列单行等可疑结果 RETRY_GENERATE

终止规则:

  • 相同错误连续出现两次时中止;
  • 超过 round_budget 时中止;
  • 生成到非 SELECT SQL 时直接阻断;
  • 预算耗尽时状态记为 max_rounds_reached

关键类:

作用
AgentConfig 控制轮数预算、候选数量、观察开关等
AgentLoop Agent 核心执行器
AgentPhase 7 阶段枚举
AgentStep 单步记录,保存动作、观察与产物
AgentState 跨步状态容器与最终 trace 出口
ErrorCategory 错误类型枚举
RecoveryAction 恢复动作枚举
ErrorDiagnosis 诊断结果对象

返回形态:

AgentState.to_trace() 会输出统一 trace,通常包含:

  • question
  • status
  • round_count
  • round_budget
  • final_sql
  • final_result
  • steps
  • intent
  • contract
  • grounding_trace

4. Eval 通路

  • 入口:eval/run_mini_eval.py
  • 核心作用:
    • 校验整条查询链路是否可回归
    • 批量输出明细、汇总和报告
    • 做 schema linking 专项评测

内置 preset:

Preset 数据集 数据库 条数
juno_demo eval/mini_eval_v1.jsonl demo.db 30
public_proxy eval/public_proxy_eval_v1.jsonl public_proxy.db 20
juno_demo_v2 eval/mini_eval_v2.jsonl demo.db 45
public_proxy_v2 eval/public_proxy_eval_v2.jsonl public_proxy.db 40
internal_v1 eval/internal_eval_v1.jsonl demo.db 10

常用命令:

python eval/run_mini_eval.py --mode gold
python eval/run_mini_eval.py --mode model --use-query-tool
python eval/run_schema_linking_eval.py --top-k-list 1,2,3

两种运行模式:

Gold 模式

gold_sql
  -> execute_sql()
  -> 直接作为 prediction
  -> compare_results()

特点:

  • 不需要 API key;
  • 用于验证执行层、修复层、规范化层是否稳定;
  • 适合做基线回归。

Model 模式

有两种子路径:

Path A:统一查询运行时

question
  -> JunoQueryTool.run_question()
  -> 提取 final_sql / result_rows / result_columns
  -> compare_results()

Path B:直接评测流水线

question
  -> ground_question()
  -> infer_expected_output_columns()
  -> generate_sql() / generate_sql_candidates()
  -> execute_sql()
  -> build_contract_repair_sql() (if needed)
  -> compare_results()

结果比对逻辑:

  1. 浮点值统一保留 6 位小数;
  2. 字符串统一做 trim;
  3. 比较列名;
  4. 比较行数;
  5. 根据 ordered 决定是否按顺序比较行值。

主要失败分类:

  • correct
  • generation_error
  • execution_error
  • schema_mismatch
  • row_count_mismatch
  • value_mismatch
  • gold_execution_error

输出产物:

文件 说明
details.jsonl 每条样例的完整 trace
summary.json 汇总指标与分类统计
report.md 人类可读报告

补充说明:

  • 评测路径本身也支持多候选;
  • 评测里的多候选选择逻辑可以独立于运行时候选打分存在;
  • 这使评测既能复用统一主链,也能单独做方法分析。

核心数据流

主链路可以概括为:

Question
  -> Intent Analysis
  -> Schema Grounding
  -> Output Contract
  -> SQL Generation
  -> Candidate Reranking
  -> Execution / Repair
  -> Result Normalization
  -> Artifact / Trace

对应核心模块:

  • nldb/intent.py
  • nldb/schema_linker.py
  • nldb/output_contract.py
  • nldb/generation_runtime.py
  • nldb/candidate_scorer.py
  • nldb/query_tool.py
  • nldb/agent_loop.py
  • nldb/governance.py
  • nldb/dataset_registry.py
  • nldb/audit_store.py

共享模块矩阵

不同通路并不是各自孤立实现,而是复用同一批核心模块:

模块 遗留聊天通路 Fast 查询通路 Agent 查询通路 Eval 通路
intent.py Y Y
schema_linker.py Y Y Y(model)
generation_runtime.py Y Y Y(model)
candidate_scorer.py Y
output_contract.py Y Y
sql_utils.py Y Y Y
governance.py Y Y
agent_state.py / error_router.py Y
audit_store.py Y(API) Y(API)
dataset_registry.py Y(API) Y(API)

几个关键约束:

  • sql_utils.py 是叶模块,尽量保持零运行时依赖;
  • agent_loop.pyquery_tool.py 平行存在,不相互整包依赖;
  • 跨层引用尽量通过 TYPE_CHECKING 守卫降低循环依赖风险。

生成器模式

当前仓库存在两类生成器实现:

维度 VannaGenerator DirectAPIGenerator
核心机制 复用 Vanna 检索与生成 直接调用 OpenAI-compatible API
向量检索
System Prompt Vanna 内部管理 可通过 GeneratorConfig.extra 配置
重试 依赖 Vanna 与外层运行时 由统一运行时控制
适用场景 原型主路径 / 带检索增强 轻量测试 / 纯 prompt 路径
与 VannaFlaskApp 兼容 兼容 不兼容

这两类生成器共用统一的运行时接口,因此上层查询链路不需要知道底层模型调用细节。

技术栈

后端

  • Python 3.12+
  • Flask
  • SQLite / DuckDB
  • OpenAI-compatible API
  • Vanna

前端

  • Vue 3
  • 原生 JS / CSS

评测与工程化

  • pytest
  • JSONL/CSV 报告产物
  • 本地回归脚本
  • 配置文件驱动的数据集注册

仓库结构

.
├─ app.py
├─ init_db.py
├─ run_query.py
├─ run_public_proxy_event_demo.py
├─ train_vanna.py
├─ README.md
├─ requirements.txt
├─ pytest.ini
├─ config/
├─ eval/
├─ nldb/
├─ static/
├─ templates/
└─ tests/

关键目录说明:

  • nldb/:核心查询管线、Agent、治理、数据集注册、适配层
  • eval/:本地评测与专项评测
  • config/:开发与生产配置
  • tests/:自动化测试

快速开始

1. 安装依赖

python -m venv venv
.\venv\Scripts\Activate.ps1
pip install -r requirements.txt

2. 配置模型访问

$env:OPENAI_API_KEY="your-key-here"
$env:OPENAI_BASE_URL="https://api.117911.xyz/v1"
$env:OPENAI_MODEL="gpt-5.3-codex"

如果已经在 .env 中配置,可直接跳过。

3. 初始化本地数据库

python init_db.py

4. 启动 Web 服务

python app.py

默认入口:

常用运行命令

Web 与单题闭环

python app.py
python run_query.py --question "统计每个 run 的触发率"
python run_query.py --question "统计 A 区所有 PMT 的触发事件总数" --sql "SELECT COUNT(*) AS total_triggered_events FROM pmt_events WHERE zone = 'A' AND is_triggered = 1"

评测

python eval/run_mini_eval.py --mode gold
python eval/run_mini_eval.py --mode model --use-query-tool
python eval/run_schema_linking_eval.py --top-k-list 1,2,3

事件可视化原型

python run_public_proxy_event_demo.py --init-demo-db --db-path runs/public_proxy_demo.db
python run_public_proxy_event_demo.py --db-path runs/public_proxy_demo.db

默认页面:

  • http://127.0.0.1:8091

输出产物

单题运行

run_query.py 默认会在 runs/ 下生成:

  • result.json
  • result.csv

这些文件包含:

  • grounding 轨迹
  • 生成轨迹
  • 修复轨迹
  • 执行结果
  • 最终结果表

批量评测

eval/run_mini_eval.py 默认会在 eval/results/ 下生成:

  • details.jsonl
  • summary.json
  • report.md

数据与评测

当前主要依赖三类数据源验证系统能力:

  1. 内置示例数据库
  2. 公开代理数据
  3. 外部多库错例与评测集

当前支持两类核心评测:

  1. mini-eval
  2. Schema Linking Eval

评测价值主要体现在:

  • 支持批量回归
  • 支持错误分类统计
  • 支持对 grounding 与生成质量做拆分分析

更详细的评测说明见 eval/README.md

当前状态

当前仓库已经实现:

  • 可运行的自然语言查询主链路
  • VannaFast / Agent / Eval 核心工程通路
  • 多候选重排与执行修复
  • 多数据集注册与多数据库扩展基础
  • 事件可视化原型页
  • 本地自动化评测与测试基础设施

当前限制

当前仍有几个明确边界:

  1. 尚未接入真实内部业务数据
  2. 部分脚本与模块保留历史命名
  3. 遗留聊天通路与统一查询通路并存
  4. 当前重点仍是系统能力验证,不是特定业务库上的最终准确率

使用文档

当前仓库保留两类核心入口文档:

  1. README.md:项目总览、系统通路、运行方式
  2. eval/README.md:评测模式、参数与输出说明

后续优化方向

在不引入真实内部数据之前,后续最值得推进的方向包括:

1. 任务定义

  • 建立更完整的问题模板集
  • 为每类问题定义标准输出结构
  • 覆盖统计、过滤、时间趋势、多表关联、异常定位等任务类型

2. Schema 与上下文压缩

  • 强化表级召回
  • 做值域感知的列选择
  • 建立更细的业务词典与别名映射
  • 降低无关 schema 对模型上下文的干扰

3. SQL 生成增强

  • 更稳健的多候选共识
  • 更细粒度的执行反馈修复
  • 面向复杂问题的分步 SQL / CTE 修复

4. 结果呈现

  • 从结果表升级到结果表 + 图表规格
  • 在 UI 中呈现 grounding、候选、修复与最终结果之间的关系

5. 真实数据接入前准备

  • 定义影子 schema 与字段口径
  • 设计权限、脱敏、审计和结果上限
  • 让系统从原型验证平滑过渡到场景验证

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors