| 功能 | 描述 |
|---|---|
| 🤖 自然语言转 SQL | 使用 LLM 将中文问题自动转换为 SQL 查询 |
| 📊 Schema 感知 | 动态加载数据库结构,避免幻觉字段 |
| 🔒 安全执行 | 6 层沙箱防护,只允许 SELECT 查询 |
| 🔄 自动修复 | SQL 错误自动检测与 LLM 智能修复 |
| 📖 RAG 增强 | 行业术语理解,黑话翻译 |
| 💬 多轮对话 | 模糊问题智能澄清 |
| 🔗 多表联结 | 自动生成最优 JOIN 路径 |
| 📝 自然语言答案 | 查询结果转友好文本 |
M0 ████████████ 100% 基础框架 M1 ████████████ 100% SQL 生成 M2 ████████████ 100% 数据库执行 M3 ████████████ 100% Schema 感知 M4 ████████████ 100% SQL 校验与修复 M5 ████████████ 100% 安全沙箱 M6 ████████████ 100% RAG 增强 M7 ████████████ 100% 多轮对话 M8 ████████████ 100% 多表联结 M9 ████████████ 100% 答案生成 M10 ████████████ 100% 评测框架 M11 ████████████ 100% 可观测性 M12 ████████████ 100% Web API & 前端 M13 ████████████ 100% Docker 部署
用户问题 │ ▼ ┌─────────────────┐ │ 意图解析 │ 解析问题类型和关键信息 └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Schema 加载 │ 动态加载数据库结构 └────────┬────────┘ │ ▼ ┌─────────────────┐ │ 模糊检测 │ 判断是否需要澄清 └────────┬────────┘ │ ┌────┴────┐ │ 需要澄清? │ └────┬────┘ │ 是 ▼ ┌─────────────────┐ │ 生成澄清问题 │ 向用户询问更多信息 └────────┬────────┘ │ ▼ ┌─────────────────┐ │ RAG 检索 │ 检索行业术语和 SQL 模板 └────────┬────────┘ │ ▼ ┌─────────────────┐ │ SQL 生成 │ LLM 生成 SQL └────────┬────────┘ │ ▼ ┌─────────────────┐ │ SQL 校验 │ 语法/Schema/安全检查 └────────┬────────┘ │ ┌────┴────┐ │ 校验通过? │ └────┬────┘ │ 否 ▼ ┌─────────────────┐ │ LLM 自动修复 │ 智能修复错误 SQL └────────┬────────┘ │ ▼ ┌─────────────────┐ │ 沙箱执行 │ 安全执行 SQL └────────┬────────┘ │ ▼ ┌─────────────────┐ │ 答案生成 │ 转换为自然语言 └────────┬────────┘ │ ▼ 返回结果
rookie-nl2sql/ ├── 📁 graphs/ # 核心图结构 │ ├── state.py # 状态定义 │ ├── base_graph.py # 主图实现 │ └── nodes/ # 各功能节点 ├── 📁 tools/ # 工具函数 │ ├── db.py # 数据库操作 │ ├── sandbox.py # 安全沙箱 │ └── rag_retriever.py # RAG 检索 ├── 📁 prompts/ # 提示词模板 ├── 📁 api/ # FastAPI 后端 ├── 📁 frontend/ # Streamlit 前端 ├── 📁 configs/ # 配置文件 ├── 📁 data/ # 数据库和向量存储 ├── 📁 eval/ # 评测框架 ├── 📁 docker/ # Docker 配置 └── 📁 deploy/ # 部署脚本
# 克隆项目
git clone https://github.com/your-repo/rookie-nl2sql.git
cd rookie-nl2sql
# 创建虚拟环境
python -m venv venv
source venv/bin/activate # Linux/Mac
# venv\Scripts\activate # Windows
# 安装依赖
pip install -r requirements.txt
# 复制配置模板
cp .env.example .env
# 编辑 .env 文件
支持的 LLM 提供商:
| 提供商 | 推荐度 | 获取 API Key |
|---|---|---|
| 🟢 Qwen (通义千问) | ⭐⭐⭐ 推荐 | 阿里云 DashScope |
| 🟡 DeepSeek | ⭐⭐⭐ 推荐 | DeepSeek 平台 |
| 🔵 OpenAI | ⭐⭐ 需科学上网 | OpenAI |
配置示例:
# .env 文件
LLM_PROVIDER=qwen
QWEN_API_KEY=sk-xxxxxxxxxxxxxxxx
QWEN_MODEL=qwen-plus
# 初始化数据库
python scripts/init_db.py
# 初始化 RAG 向量存储
python tools/init_vector_store.py
方式一:Web 界面(推荐)
# 启动 API 服务
python -m uvicorn api.main:app --host 0.0.0.0 --port 8000 --reload
# 新终端启动前端
python -m streamlit run frontend/app.py --server.port 8501
访问地址:
方式二:命令行交互
python graphs/base_graph.py
curl -X POST http://localhost:8000/api/v1/query \
-H "Content-Type: application/json" \
-d '{"question": "查询所有客户的信息"}'
import requests
response = requests.post(
"http://localhost:8000/api/v1/query",
json={"question": "查询消费金额最高的客户"}
)
result = response.json()
print(f"SQL: {result['sql']}")
print(f"答案: {result['answer']['conclusion']}")
print(f"执行时间: {result['execution_time_ms']:.0f}ms")
# 第一次请求
response = requests.post(
"http://localhost:8000/api/v1/query",
json={"question": "查询最近的订单"}
)
result = response.json()
if result.get("needs_clarification"):
print(f"需要澄清: {result['clarification_question']}")
# 用户提供澄清
response = requests.post(
"http://localhost:8000/api/v1/query",
json={
"question": "查询最近的订单",
"session_id": result["session_id"],
"clarification_response": "最近7天的"
}
)
result = response.json()
print(f"答案: {result['answer']['conclusion']}")
from graphs.base_graph import run_query
# 执行查询
result = run_query("查询销售额最高的前5个产品")
# 获取结果
print(f"SQL: {result['candidate_sql']}")
print(f"数据: {result['execution']['rows']}")
print(f"答案: {result['answer']['conclusion']}")
print(f"评分: {result['evaluation']['overall_score']:.0%}")
| 端点 | 方法 | 说明 |
|---|---|---|
/health | GET | 健康检查 |
/api/v1/query | POST | 执行查询 |
/api/v1/sessions | GET | 列出会话 |
/api/v1/sessions/{id} | GET | 会话详情 |
/api/v1/sessions/{id}/history | GET | 查询历史 |
/api/v1/cache/stats | GET | 缓存统计 |
/api/v1/cache | DELETE | 清空缓存 |
POST /api/v1/query
{
"question": "查询所有客户的信息",
"session_id": "可选,用于多轮对话",
"clarification_response": "可选,澄清响应"
}
{
"status": "completed",
"sql": "SELECT * FROM customers;",
"validation": {"ok": true, "errors": []},
"execution": {
"ok": true,
"columns": ["customer_id", "name", "email"],
"rows": [[1, "张三", "zhangsan@example.com"]],
"row_count": 1
},
"answer": {
"conclusion": "共查询到 1 位客户...",
"summary": "详细说明...",
"confidence": 0.95
},
"evaluation": {
"overall_score": 1.0,
"stage_success": {
"schema_loaded": true,
"sql_validated": true,
"sql_executed": true
}
},
"execution_time_ms": 2500,
"tokens_used": 1500
}
# 启动开发环境
cd docker
docker compose -f docker-compose.dev.yaml --env-file ../.env up -d
# 查看日志
docker logs -f nl2sql-api-dev
服务端口:
| 服务 | 端口 | 说明 |
|---|---|---|
| API | 8000 | FastAPI 后端 |
| 前端 | 8501 | Streamlit 界面 |
| Redis | 6379 | 缓存服务 |
| Grafana | 3000 | 监控面板 |
| Prometheus | 9090 | 指标收集 |
# 启动生产环境
cd docker
docker compose -f docker-compose.prod.yaml --env-file ../.env up -d
# 通过 Nginx 访问
# http://localhost (前端)
# http://localhost/api/v1/query (API)
# 使用部署脚本
./deploy/deploy.sh prod
# 或使用 Python 脚本
python start_m13_demo.py
# 运行所有测试用例
python eval/runner.py
# 限制用例数量
python eval/runner.py --limit 10
# 生成 HTML 报告
python eval/report_generator.py --input eval/results_*.json
| 指标 | 目标 | 说明 |
|---|---|---|
| SQL 精确匹配 | ≥ 70% | 生成的 SQL 与预期完全一致 |
| 执行准确率 | ≥ 90% | SQL 能正确执行 |
| 结果准确率 | ≥ 85% | 返回的数据正确 |
| 表选择准确率 | ≥ 90% | 使用了正确的表 |
# 运行各模块测试
python tests/test_m1_acceptance.py # SQL 生成
python tests/test_m4_acceptance.py # SQL 校验
python tests/test_m6_acceptance.py # RAG 增强
python tests/test_m12_acceptance.py # Web API
Q: ModuleNotFoundError 错误?
确保已激活虚拟环境并安装依赖:
pip install -r requirements.txt
Q: API Key 认证失败?
检查
.env文件中的 API Key 是否正确,注意不要有多余空格
Q: 数据库连接失败?
运行
python scripts/init_db.py初始化数据库
Q: SQL 执行被拦截?
系统只允许 SELECT 查询,其他操作会被安全沙箱拦截
Q: RAG 检索失败?
运行
python tools/init_vector_store.py初始化向量存储
Q: 查询超时?
LLM 调用可能较慢,可以在
.env中增加LLM_TIMEOUT=120
Q: Docker 容器 API Key 为空?
启动时需要指定 env 文件:
docker compose --env-file ../.env up -d
Q: Docker 构建失败?
清理缓存:
docker system prune -a && docker builder prune
Q: 容器无法访问?
检查端口是否被占用:
docker ps和netstat -tlnp
Q: 504 Gateway Timeout?
增加 nginx 超时配置,或检查后端服务是否正常
| 类别 | 技术 |
|---|---|
| 框架 | LangGraph, LangChain, FastAPI, Streamlit |
| 数据库 | SQLite, Redis |
| AI/ML | OpenAI/Qwen/DeepSeek API, FAISS |
| 安全 | sqlglot, 沙箱执行 |
| 部署 | Docker, Docker Compose, Nginx |
| 监控 | Prometheus, Grafana |
如果这个项目对你有帮助,请给一个 ⭐ Star!
Made with ❤️ by Rookie Team