Explorer 的 system prompt 明确告知 sandbox 规则 — "每条 SQL 必须包含聚合函数或 LIMIT",减少 LLM 生成违规 SQL 浪费轮次 LLM 客户端单例 — 所有组件共享一个 openai.OpenAI 实例,不再各建各的 sanitize 顺序修复 — 小样本抑制放在 float round 之前,避免被 round 干扰 quick_detect 从 O(n²) 改为 O(n) — 按列聚合一次,加去重,不再对每行重复算整列统计 历史上下文实际生效 — get_context_for 的结果现在会注入到 Explorer 的初始 prompt 里,多轮分析时 LLM 能看到之前的发现
163 lines
6.3 KiB
Markdown
163 lines
6.3 KiB
Markdown
# 数据分析 Agent —— Schema-Only + 四层架构自适应分析
|
||
|
||
**AI 只看表结构,不碰原始数据。通过四层架构自适应探索,生成深度分析报告。**
|
||
|
||
## 架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ Agent (编排层) │
|
||
│ 接收问题 → 调度四层 → 输出报告 │
|
||
└──┬──────────┬──────────┬──────────┬──────────┬──────────┘
|
||
│ │ │ │ │
|
||
┌──▼───┐ ┌───▼────┐ ┌───▼───┐ ┌───▼────┐ ┌───▼─────┐
|
||
│Planner│ │Playbook│ │Explorer│ │Insight │ │ Context │
|
||
│意图规划│ │预设匹配 │ │探索循环 │ │异常检测 │ │上下文记忆│
|
||
└──────┘ └────────┘ └───────┘ └────────┘ └─────────┘
|
||
```
|
||
|
||
### 分层分工
|
||
|
||
| 层 | 组件 | 职责 |
|
||
|---|---|---|
|
||
| L1 | **Planner** | 理解用户意图,生成结构化分析计划(类型、维度、指标) |
|
||
| L1.5 | **Playbook** | 匹配预设分析剧本,提供确定性查询保底 |
|
||
| L2 | **Explorer** | 先执行预设查询(如有),再基于结果多轮迭代发散探索 |
|
||
| L3 | **InsightEngine** | 从探索结果中检测异常、趋势、关联,输出主动洞察 |
|
||
| L4 | **ContextManager** | 管理多轮对话历史,后续问题可引用之前的分析 |
|
||
|
||
### 安全隔离
|
||
|
||
```
|
||
用户提问 → Agent 看 Schema 生成 SQL → 沙箱执行 → 聚合结果 → Agent 生成报告
|
||
↑
|
||
原始数据永远留在这里
|
||
```
|
||
|
||
- **Schema 提取器**:只提取表结构、列类型、行数、枚举值,不碰数据
|
||
- **沙箱执行器**:禁止 SELECT * / DDL / DML,必须聚合函数,小样本抑制(n<5)
|
||
- **AI 的视角**:只有 Schema + 聚合统计结果,从未接触任何一行原始数据
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
# 1. 安装依赖
|
||
pip install openai
|
||
|
||
# 2. 配置 LLM(兼容 OpenAI API 格式)
|
||
|
||
# OpenAI
|
||
export LLM_API_KEY=sk-xxx
|
||
export LLM_BASE_URL=https://api.openai.com/v1
|
||
export LLM_MODEL=gpt-4o
|
||
|
||
# Ollama(本地部署,隐私优先)
|
||
export LLM_API_KEY=ollama
|
||
export LLM_BASE_URL=http://localhost:11434/v1
|
||
export LLM_MODEL=qwen2.5-coder:7b
|
||
|
||
# DeepSeek
|
||
export LLM_API_KEY=sk-xxx
|
||
export LLM_BASE_URL=https://api.deepseek.com
|
||
export LLM_MODEL=deepseek-chat
|
||
|
||
# 3. 运行演示(自动创建 5 万条示例数据 + 3 个分析任务)
|
||
python3 demo.py
|
||
|
||
# 4. 交互式分析
|
||
python3 cli.py
|
||
|
||
# 5. 分析你自己的数据库
|
||
python3 cli.py /path/to/your.db
|
||
```
|
||
|
||
## 文件结构
|
||
|
||
```
|
||
├── config.py # 配置(LLM、安全规则、探索轮数)
|
||
├── schema_extractor.py # Schema 提取器(只提取结构)
|
||
├── sandbox_executor.py # 沙箱执行器(SQL 验证 + 结果脱敏)
|
||
├── planner.py # [L1] 意图规划器
|
||
├── playbook.py # [L1.5] 预设分析剧本匹配
|
||
├── explorer.py # [L2] 自适应探索器(预设 + 发散)
|
||
├── insights.py # [L3] 洞察引擎(异常检测)
|
||
├── context.py # [L4] 上下文管理器
|
||
├── reporter.py # 报告生成器
|
||
├── agent.py # Agent 编排层
|
||
├── demo.py # 一键演示
|
||
├── cli.py # 交互式 CLI
|
||
├── playbooks/ # 预设分析剧本
|
||
│ ├── regional_sales.json # 地区销售分析
|
||
│ ├── category_analysis.json # 商品类别分析
|
||
│ └── order_health.json # 订单健康度分析
|
||
├── requirements.txt # 依赖
|
||
└── README.md
|
||
```
|
||
|
||
## 预设分析剧本(Playbook)
|
||
|
||
Playbook 是"确定性保底 + AI 自由发散"的结合:
|
||
|
||
- 为常见分析场景预定义一组确定性 SQL 查询
|
||
- Planner 生成计划后,LLM 自动判断是否匹配某个 Playbook
|
||
- 匹配到:先执行预设 SQL(结果可控),再让 Explorer 基于结果自由发散
|
||
- 没匹配到:走纯自适应路径(和之前一样)
|
||
|
||
### 创建 Playbook
|
||
|
||
在 `playbooks/` 目录下创建 `.json` 文件:
|
||
|
||
```json
|
||
{
|
||
"name": "地区销售分析",
|
||
"description": "按地区维度分析销售额、订单量、客单价",
|
||
"tags": ["地区", "区域", "销售"],
|
||
"preset_queries": [
|
||
{
|
||
"purpose": "各地区销售总额",
|
||
"sql": "SELECT {{region_column}} AS region, ROUND(SUM({{amount_column}}), 2) AS total FROM {{table}} GROUP BY {{region_column}} ORDER BY total DESC"
|
||
}
|
||
],
|
||
"exploration_hints": "请关注地区间的增长差异和客单价异常",
|
||
"placeholders": {
|
||
"table": "orders",
|
||
"region_column": "region",
|
||
"amount_column": "amount"
|
||
}
|
||
}
|
||
```
|
||
|
||
- `preset_queries`: 确定性 SQL,用 `{{占位符}}` 标记可变部分
|
||
- `placeholders`: 默认值,LLM 匹配时会根据实际 Schema 自动替换
|
||
- `exploration_hints`: 给 Explorer 的提示,引导发散方向
|
||
- `tags`: 帮助 LLM 判断是否匹配
|
||
|
||
## 对比
|
||
|
||
| | 预制脚本 / 模板 | 纯自适应 | 本方案(Playbook + 自适应) |
|
||
|---|---|---|---|
|
||
| SQL 生成 | 模板拼接 | LLM 动态生成 | 预设保底 + LLM 发散 |
|
||
| 结果可控性 | 高 | 低 | 核心数据确定,发散部分灵活 |
|
||
| 查询数量 | 固定 | 1-6 轮 | 预设 N 条 + 自适应 M 轮 |
|
||
| 后续追问 | 无 | AI 自主判断 | 基于预设结果深挖 |
|
||
| 异常发现 | 无 | 主动检测 | 预设结果 + 主动检测 |
|
||
| 适用场景 | 已知分析模式 | 开放性问题 | 两者兼顾 |
|
||
|
||
## CLI 命令
|
||
|
||
```
|
||
📊 > 帮我分析各地区的销售表现 # 分析问题(自动匹配 Playbook)
|
||
📊 > rounds=3 最近的趋势怎么样 # 限制探索轮数
|
||
📊 > schema # 查看数据库 Schema
|
||
📊 > playbooks # 查看已加载的预设剧本
|
||
📊 > history # 查看分析历史
|
||
📊 > audit # 查看 SQL 审计日志
|
||
📊 > clear # 清空历史
|
||
📊 > help # 帮助
|
||
📊 > quit # 退出
|
||
```
|
||
|
||
## License
|
||
|
||
MIT
|