冻冻智能数据分析助手
🧊 冻冻智能数据分析助手
基于 LangChain + LM Studio 的 语义层 NL2SQL 数据分析系统,支持用自然语言查询业务数据,自动生成 SQL、可视化图表和分析结论。
git地址
https://github.com/zxliucn/Datas_Agent
目录
1. 项目概述
冻冻智能数据分析助手是一个基于语义层 NL2SQL 架构的数据分析系统,采用 预定义模板 + LLM 意图解析 的安全方案,避免 LLM 直接生成 SQL 带来的安全风险。
核心特性
| 功能 | 说明 |
|---|---|
| 🔍 自然语言查询 | 输入自然语言问题,自动解析意图并生成 SQL |
| 📊 可视化图表 | 根据查询类型自动选择折线图、柱状图、饼图等 |
| 💡 智能洞察 | 从查询结果中提取关键结论和业务建议 |
| 🔒 安全可控 | 预定义 SQL 模板,LLM 仅负责意图解析,不直接生成 SQL |
| 🌐 Web 界面 | 基于 Gradio 的可视化交互界面 |
支持的查询类型
| 查询类型 | 示例问题 |
|---|---|
| 商品销量 | 虾滑卖了多少?上个月牛筋的销售额 |
| 商品排行 | 这个月哪个商品卖得最好?销量前10 |
| 订单趋势 | 最近7天的订单趋势 |
| 订单列表 | 待发货的订单有哪些? |
| 客户排行 | 哪个客户花钱最多? |
| 库存预警 | 库存不足的商品 |
| 售后排行 | 退款最多的商品 |
| 经营概况 | 本月经营情况 |
2. 技术架构
┌─────────────────────────────────────────────────────────┐
│ Gradio Web UI │
│ 输入自然语言问题 → 展示图表和洞察结论 │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ NL2SQL 主控制器 │
│ 意图解析 → SQL 构建 → 执行 → 可视化 │
└──────────────────────┬──────────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────────┐ ┌────────────┐ ┌──────────────┐
│ IntentParser │ │ SQLBuilder │ │ SQLExecutor │
│ LLM 意图解析 │ │ 模板拼装 │ │ MySQL 查询 │
└──────────────┘ └────────────┘ └──────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────────┐ ┌────────────┐ ┌──────────────┐
│ChartGenerator│ │ InsightGen │ │ QueryTemplates│
│ 图表可视化 │ │ 洞察分析 │ │ SQL 模板库 │
└──────────────┘ └────────────┘ └──────────────┘设计思路
采用 语义层 NL2SQL 方案,而非让 LLM 直接生成 SQL:
- LLM 只做意图解析:理解用户自然语言,输出结构化的
{intent, params}JSON - SQL 由模板拼装:每种查询类型对应预定义的 SQL 模板,安全可控
- 参数映射处理:通过
param_mapping将自然语言参数(如"上个月")转换为 SQL 条件
优势:
- ✅ 安全:杜绝 SQL 注入风险
- ✅ 可控:SQL 逻辑可审查、可维护
- ✅ 稳定:不依赖 LLM 生成正确 SQL 的能力
- ✅ 可扩展:新增查询类型只需添加模板
3. 项目结构
Datas_agent/
├── app.py # 主入口,启动服务
├── config.py # 配置文件(数据库、LLM)
├── .env # 环境变量
├── requirements.txt # 依赖清单
│
├── core/ # 核心业务模块
│ ├── __init__.py
│ ├── intent_parser.py # LLM 意图解析
│ ├── sql_builder.py # SQL 模板拼装
│ ├── sql_executor.py # SQL 执行器
│ ├── chart_generator.py # 图表生成(Plotly)
│ └── insight_generator.py # 洞察分析生成
│
├── templates/ # SQL 查询模板
│ ├── __init__.py
│ └── query_templates.py # 8 种查询模板定义
│
├── web/ # Web 界面
│ ├── __init__.py
│ └── gradio_app.py # Gradio 界面
│
├── utils/ # 工具模块
│ ├── __init__.py
│ └── logger.py # 日志与计时
│
└── preview/ # 预览截图
├── p1.png
└── p2.png4. 核心模块
4.1 主入口 (app.py)
NL2SQL 主控制器,串联整个处理流程:
class NL2SQL:
def __init__(self, llm):
self.intent_parser = IntentParser(llm) # LLM 意图解析
self.sql_builder = SQLBuilder() # SQL 模板拼装
def convert(self, question):
# 1. 解析意图 → {intent, params}
result = self.intent_parser.parse_with_defaults(question)
# 2. 构建 SQL
sql = self.sql_builder.build(intent, params)
return intent, sql, params启动流程:初始化 LLM → 创建各模块 → 测试数据库连接 → 启动 Gradio Web 界面(端口 7861)
4.2 意图解析 (core/intent_parser.py)
使用 LLM 将自然语言问题解析为结构化的意图和参数。
处理流程:
- 将用户问题 + 预定义的意图列表作为 Prompt 发送给 LLM
- LLM 返回 JSON 格式的
{intent, params} - 提取 JSON 并解析,失败则返回
unknown - 调用
parse_with_defaults()自动填充默认参数
Prompt 策略:
- 提供 8 种查询类型的触发词、参数说明和示例
- 强制 JSON 输出格式
- 使用
%s占位符避免format冲突
输出示例:
// 输入:"上个月虾滑卖了多少"
{"intent": "product_sales", "params": {"product": "虾滑", "time_range": "last_month"}}
// 输入:"销量前10的商品"
{"intent": "product_ranking", "params": {"top_n": 10}}4.3 SQL 构建 (core/sql_builder.py)
根据意图和参数,从预定义模板拼装 SQL。
构建流程:
- 从模板库获取 SQL 模板
- 应用默认值(如
limit=10,time_range=this_month) - 通过
param_mapping映射参数(如将time_range转换为AND DATE(o.order_time) = ...) - 填充模板占位符
- 清理 SQL(修复空 WHERE、多余 AND 等边界情况)
4.4 SQL 执行 (core/sql_executor.py)
基于 SQLAlchemy + PyMySQL 执行 SQL 查询。
- 仅允许
SELECT查询,拒绝写操作 - 返回
pandas DataFrame - 启动时自动测试数据库连接
4.5 图表生成 (core/chart_generator.py)
基于 Plotly 根据查询意图自动选择图表类型:
| 意图类型 | 图表类型 | 说明 |
|---|---|---|
order_trend | 折线图 | 时间趋势,支持多指标 |
product_ranking | 柱状图 | 排行榜,限显前 15 条 |
customer_ranking | 柱状图(绿色) | 客户消费排行 |
stock_warning | 柱状图(红色) | 库存预警 |
after_sale_ranking | 柱状图(橙色) | 售后排行 |
product_sales | Markdown 指标卡 | 单商品销量详情 |
business_overview | Markdown 表格 | 经营概况 |
| 其他 | 自动判断 | 饼图/柱状图/折线图 |
4.6 洞察生成 (core/insight_generator.py)
从查询结果中提取关键结论和业务建议,输出 Markdown 格式。
分析维度:
- 商品排行:Top3、总销量、集中度分析(Top3 占比)
- 订单趋势:日均数据、升降趋势判断、峰值日期
- 客户排行:VIP 客户识别、人均消费
- 库存预警:最紧急商品、按分类统计、补货建议
- 售后排行:退款率分析、改进建议
- 经营概况:核心指标表格、退款率评级
5. 查询模板系统 (templates)
query_templates.py 定义了 8 种查询模板,每种模板包含:
| 字段 | 说明 |
|---|---|
template | SQL 模板字符串,{placeholder} 占位 |
required_params | 必填参数列表 |
optional_params | 可选参数列表 |
param_mapping | 参数到 SQL 条件的映射函数 |
defaults | 默认值字典 |
时间范围转换:
支持 today、yesterday、this_week、this_month、last_month、last_7_days、last_30_days,自动转换为 MySQL 日期函数。
参数映射函数示例:
# 时间范围 → WHERE 条件
"time_range": lambda x: f"AND {get_time_condition(x)}"
# 商品分类 → 分类过滤
"category": lambda x: f"AND p.category = '{x}'"
# 经营概况 → 同时返回时间条件和中文时间名(tuple)
"time_range": lambda x: (get_time_condition(x), get_time_range_name(x))6. Web 界面 (web)
基于 Gradio 的交互式 Web 界面。
界面布局:
- 输入区:文本框 + 开始分析 / 清空按钮
- SQL 展示:代码块展示生成的 SQL
- 图表区:Plotly 交互式图表
- 洞察区:Markdown 格式的分析结论
内置示例问题:提供各查询类型的示例问题,引导用户使用。
7. 工具模块 (utils)
日志模块 (logger.py)
info/debug/error/warn四级日志@timing装饰器:记录函数执行耗时- 通过
APP_CONFIG['debug']控制是否输出 DEBUG 级别日志
8. 配置说明
环境变量 (.env)
# MySQL 数据库
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=your_username
MYSQL_PASSWORD=your_password
MYSQL_DATABASE=your_database
# LM Studio 本地模型
# base_url: LM Studio API 地址
# model: 使用的模型(如 qwen/qwen3.5-9b)
# temperature: 0(意图解析需要确定性输出)应用配置 (config.py)
LM_STUDIO_CONFIG = {
'base_url': 'http://127.0.0.1:1234/v1',
'model': 'qwen/qwen3.5-9b',
'temperature': 0,
'max_tokens': 512,
}
APP_CONFIG = {
'default_limit': 100,
'max_limit': 1000,
'debug': True,
}9. 数据库表结构
系统依赖以下 MySQL 表:
| 表名 | 说明 | 关键字段 |
|---|---|---|
products | 商品表 | product_id, name, category, price, stock |
orders | 订单表 | order_id, user_id, order_time, total_amount, order_status |
order_items | 订单明细表 | order_id, product_id, product_name, quantity, total_price |
users | 用户表 | id, username, nickname |
after_sale_item | 售后表 | order_id, product_name, refund_num, refund_amount |
10. 快速开始
安装依赖
pip install -r requirements.txt主要依赖:
langchain-openai— LLM 调用(兼容 OpenAI API 格式)gradio— Web 界面plotly— 图表可视化pandas— 数据处理sqlalchemy+pymysql— 数据库连接python-dotenv— 环境变量管理
配置
- 启动 LM Studio 并加载模型(如 Qwen3.5-9B),确保 API 服务运行在
http://127.0.0.1:1234/v1 - 修改
.env文件中的 MySQL 连接信息
启动服务
python app.py启动成功后访问:http://localhost:7861
试试这些问题
虾滑卖了多少?
这个月哪个商品卖得最好?
最近7天的订单趋势
待发货的订单有哪些?
哪个客户花钱最多?
库存不足的商品
退款最多的商品
本月经营情况11. API 接口
系统通过 Gradio 提供交互式 Web 接口(端口 7861),无需额外 API 调用。直接在浏览器中访问即可使用。
如需集成到其他系统,可参考 NL2SQL.convert() 方法封装为 REST API:
from app import NL2SQL
from core import SQLExecutor
nl2sql = NL2SQL(llm)
executor = SQLExecutor()
intent, sql, params = nl2sql.convert("虾滑卖了多少")
df = executor.execute(sql)12. 项目预览
系统提供基于 Gradio 的 Web 数据分析界面,输入自然语言即可获得 SQL、图表和洞察结论。
界面预览
![数据分析界面-主视图]
图 1:智能数据分析助手主界面 — 自然语言输入与结果展示
![数据分析界面-功能展示]
图 2:查询结果展示 — SQL 语句、可视化图表与分析结论
总结
| 特性 | 实现方式 |
|---|---|
| 🔒 安全可控 | 语义层模板方案,LLM 仅解析意图,不直接生成 SQL |
| 🧠 智能解析 | LangChain + LM Studio 本地大模型 |
| 📊 自动可视化 | Plotly 按意图自动匹配图表类型 |
| 💡 业务洞察 | 基于查询结果生成结构化分析结论 |
| 🚀 快速扩展 | 新增查询类型只需添加模板,无需修改 LLM 逻辑 |