智能问数系统(三):生成数据报告
文章目录
摘要
在智能问数系统的前两个阶段中,我们已经完成了:
- 高质量 Text-to-SQL:将自然语言精准转换为可执行 SQL,确保"取数准确";
- 数据分析师Python:对原始查询结果进行聚合、计算与结构化处理,实现"数据分析"。
然而,普通业务人员面对 JSON 或表格数据仍需自行解读,这违背了"人人都是数据分析师"的初衷。
因此,本篇聚焦第三阶段------自动生成专业、可读、可行动的数据报告 ,通过 LLM + 报告模板 + 可视化嵌入 的方式,将分析结果转化为自然语言叙述、关键指标图表展示,真正实现 "说数清晰" ,我们可以通过Markdown 或HTML形式来展示报告。
Markdown格式数据报告
- 我们可以通过提示词(提供示例)来让LLM来生成Markdown数据报告
markdown
# Context
你是一位专业的数据分析专家。请根据用户提供的需求和数据执行结果,生成一份结构清晰、内容详实的分析报告。
# 核心指令 (Core Instructions)
1. **输出格式**:必须且只能输出 **Markdown** 格式。
2. **禁止事项**:
- **严禁**输出 `<html>`, `<head>`, `<body>`, `<script>` 等 HTML 标签。
- **严禁**输出 CSS 样式代码。
- **严禁**输出 Markdown 代码包裹标记(如不要在最外层写 ```markdown)。
3. **图表绘制 (关键)**:
- 当需要展示图表时,请输出一个代码块。
- **代码块的语言标记必须是 `echarts`**。
- 代码块的内容必须是 **纯 JSON** 格式的 ECharts Option 配置对象。
输入数据
用户需求与计划
## 用户原始需求
统计分析2025年6月(2025-06-01至2025-06-30)每个产品的销售额
## 执行计划概述
**思考过程**: 用户要求统计2025年6月每个产品的销售额。我已检查可用的数据库Schema,确认相关表为:orders(订单表)、order_items(订单明细表)和products(商品表)。关键字段包括:orders.order_date(用于时间过滤)、orders.id与order_items.order_id(关联订单)、order_items.product_id与products.id(关联产品)、order_items.unit_price和quantity(用于计算销售额)。由于需要按产品聚合销售额,且涉及多表关联和时间过滤,第一步将使用SQL提取所需数据。第二步使用Python对结果进行汇总分析并生成图表。最后一步生成报告。
## 详细执行步骤
### 步骤 1: 步骤编号 1
**工具**: SQL_GENERATE_NODE
**参数描述**: 从 orders 表和 order_items 表中查询 2025-06-01 至 2025-06-30 期间的所有订单明细,关联 products 表获取商品名称,返回字段包括 product_id、name(商品名称)、quantity 和 unit_price,仅包含订单状态为 completed 的有效订单。
### 步骤 2: 步骤编号 2
**工具**: PYTHON_GENERATE_NODE
**参数描述**: 读取上一步的查询结果,计算每个产品的销售额(销售额 = unit_price * quantity),按 product_id 和商品名称分组进行汇总,并生成销售额从高到低的排序列表,同时绘制前10名产品的销售额柱状图。
### 步骤 3: 步骤编号 3
**工具**: REPORT_GENERATOR_NODE
**参数描述**: null
分析步骤与数据结果
## 数据执行结果
### step_2
**步骤编号**: 2
**使用工具**: PYTHON_GENERATE_NODE
**参数描述**: 读取上一步的查询结果,计算每个产品的销售额(销售额 = unit_price * quantity),按 product_id 和商品名称分组进行汇总,并生成销售额从高到低的排序列表,同时绘制前10名产品的销售额柱状图。
**执行结果**:
```json
2025年6月,笔记本电脑销售额为4999.0元,位居第一;智能手机销售额为2999.0元,排名第二;咖啡机销售额为1198.0元,位列第三。其他产品销售额依次为羽绒服1197.0元、历史书276.0元、T恤衫178.0元、牛奶31.0元、巧克力25.0元、小说16.0元。
```
### step_1
**步骤编号**: 1
**使用工具**: SQL_GENERATE_NODE
**参数描述**: 从 orders 表和 order_items 表中查询 2025-06-01 至 2025-06-30 期间的所有订单明细,关联 products 表获取商品名称,返回字段包括 product_id、name(商品名称)、quantity 和 unit_price,仅包含订单状态为 completed 的有效订单。
**执行结果**:
```json
{"column":["product_id","name","quantity","unit_price"],"data":[{"quantity":"1","product_id":"1","name":"智能手机","unit_price":"2999.00"},{"quantity":"1","product_id":"2","name":"T恤衫","unit_price":"89.00"},{"quantity":"2","product_id":"4","name":"咖啡机","unit_price":"599.00"},{"quantity":"2","product_id":"5","name":"牛奶","unit_price":"3.00"},{"quantity":"1","product_id":"6","name":"笔记本电脑","unit_price":"4999.00"},{"quantity":"1","product_id":"2","name":"T恤衫","unit_price":"89.00"},{"quantity":"5","product_id":"5","name":"牛奶","unit_price":"5.00"},{"quantity":"1","product_id":"8","name":"巧克力","unit_price":"25.00"},{"quantity":"2","product_id":"9","name":"羽绒服","unit_price":"399.00"},{"quantity":"1","product_id":"3","name":"小说","unit_price":"16.00"},{"quantity":"4","product_id":"10","name":"历史书","unit_price":"69.00"},{"quantity":"1","product_id":"9","name":"羽绒服","unit_price":"399.00"}],"errorMsg":null}
```
总结建议要求
总结2025年6月各产品的销售额分布情况,列出销售额最高的产品及其贡献,指出长尾产品表现,并基于销售集中度提出库存优化或营销推广建议。
# ⚠️ 关键优化指令 - CRITICAL OPTIMIZATION DIRECTIVES ⚠️
## 用户自定义优化要求 (最高优先级)
**重要说明:以下是用户特别配置的优化指令,必须严格遵守并优先应用于报告生成过程。这些指令代表用户的核心诉求,具有最高执行优先级。**
# 图表输出示例
下面是图表输出的标准格式示例:
```echarts
{
"title": { "text": "月度销售额" },
"tooltip": { "trigger": "axis" },
"xAxis": { "type": "category", "data": ["1月", "2月"] },
"yAxis": { "type": "value" },
"series": [
{ "type": "bar", "data": [120, 200] }
]
}
```
## 销售趋势分析
从数据可以看出,销售额稳步增长。
报告结构建议
执行摘要:简明扼要地总结核心发现。
关键指标:使用图表展示最重要的数据。
详细分析:结合数据步骤进行深入剖析。
结论与建议:基于数据给出具体的业务建议。
请开始生成报告:
- Markdown结果
markdown
# 2025年6月产品销售额分析报告
## 执行摘要
本报告对2025年6月1日至6月30日期间各产品的销售额进行了全面统计与分析。通过对订单数据的提取与聚合,发现销售额高度集中于少数高价值产品,其中"笔记本电脑"以4999.0元位居榜首,"智能手机"和"咖啡机"紧随其后。整体销售呈现明显的头部效应,长尾产品贡献较小。基于此,建议优化库存结构并加强中长尾产品的营销推广。
## 关键指标
```echarts
{
"title": { "text": "2025年6月各产品销售额 Top 10" },
"tooltip": { "trigger": "axis", "axisPointer": { "type": "shadow" } },
"grid": { "left": "3%", "right": "4%", "bottom": "15%", "containLabel": true },
"xAxis": {
"type": "category",
"data": ["笔记本电脑", "智能手机", "咖啡机", "羽绒服", "历史书", "T恤衫", "牛奶", "巧克力", "小说"],
"axisLabel": { "rotate": 30 }
},
"yAxis": { "type": "value", "name": "销售额(元)" },
"series": [
{
"name": "销售额",
"type": "bar",
"data": [4999.0, 2999.0, 1198.0, 1197.0, 276.0, 178.0, 31.0, 25.0, 16.0],
"itemStyle": { "color": "#5470C6" }
}
]
}
```
## 详细分析
### 数据来源与处理过程
本次分析基于 `orders`、`order_items` 和 `products` 三张表联合查询结果,筛选条件为:
- 订单日期:2025-06-01 至 2025-06-30
- 订单状态:completed(已完成)
原始数据共包含12条订单明细记录,涵盖9种不同商品。通过计算每条记录的销售额(`unit_price * quantity`),并按商品名称进行分组汇总,得出各产品总销售额。
### 销售额分布情况
- **头部产品表现突出**:
- 第一名:笔记本电脑,销售额 **4999.0元**
- 第二名:智能手机,销售额 **2999.0元**
- 第三名:咖啡机,销售额 **1198.0元**
前三大产品合计贡献 **9196.0元**,占总销售额(约10,820元)的 **85%以上**,显示出极强的头部集中趋势。
- **中腰部产品**:
- 羽绒服(1197.0元)和历史书(276.0元)处于中游水平,虽不及头部电子产品,但仍有可观需求。
- **长尾产品**:
- T恤衫(178.0元)、牛奶(31.0元)、巧克力(25.0元)、小说(16.0元)等日用消费品销售额较低,属于典型的长尾品类,单个产品贡献有限。
## 结论与建议
### 主要结论
1. **销售高度集中**:少数高单价电子产品主导了本月销售额,表明客户更倾向于在特定品类上进行大额消费。
2. **长尾效应明显**:超过半数的产品销售额低于200元,整体分布呈"金字塔"结构。
3. **品类多样性存在**:尽管销售额不均,但订单覆盖电子、服饰、食品、图书等多个类别,显示平台具备一定的综合服务能力。
### 业务建议
#### 1. 库存优化建议
- **优先保障头部产品库存**:确保"笔记本电脑"、"智能手机"等畅销品不断货,避免因缺货导致收入损失。
- **动态调整长尾产品备货量**:对于牛奶、巧克力、小说等低频次、低客单价商品,采用小批量、高频补货策略,降低库存积压风险。
#### 2. 营销推广建议
- **捆绑销售策略**:将高单价产品(如笔记本电脑)与中低单价配件或周边(如T恤衫、咖啡机)打包促销,提升客单价并带动长尾产品销量。
- **定向推送中腰产品**:针对"羽绒服"、"历史书"等有一定市场需求但曝光不足的商品,开展精准广告投放或会员推荐活动。
- **设立"新品试用"或"每日特惠"专区**:激活用户对长尾商品的兴趣,提高整体SKU利用率。
#### 3. 数据监控建议
- 建立月度产品销售额排名看板,持续追踪头部集中度(如Top3占比)变化趋势,及时识别潜在风险或机会。
---
> 报告生成时间:2025年7月5日
> 分析单位:数据分析部
HTML格式数据报告
-
Markdown格式转换为HTML格式
-
HTML头 + Markdown数据 + HTML尾,依赖Markdown渲染库和ECharts 图标库
配置项 说明 默认值 marked-urlMarked.js 路径 (Markdown渲染库) https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/marked/12.0.0/marked.min.js echarts-urlECharts 路径 (图表库) https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/echarts/5.5.0/echarts.min.js -
HTML头
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>分析报告</title>
<!-- ⚠️ 使用国内 Staticfile CDN 源,速度快且稳定 -->
<!-- 1. Marked.js (Markdown 解析器) -->
<script src="https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/marked/12.0.0/marked.min.js"></script>
<!-- 2. ECharts (图表库) -->
<script src="https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
<style>
/* --- 替代 Tailwind 的手写样式开始 --- */
/* 1. 全局重置 */
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 20px;
background-color: #f3f4f6;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
color: #374151;
line-height: 1.6;
}
/* 2. 报告容器 (白纸效果) */
.container {
max-width: 900px;
margin: 0 auto;
background-color: #ffffff;
padding: 40px;
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}
/* 3. 标题样式 */
h1 {
font-size: 2.25rem;
font-weight: 800;
color: #1e3a8a;
margin-top: 0;
margin-bottom: 1.5rem;
border-bottom: 2px solid #e5e7eb;
padding-bottom: 0.5rem;
}
h2 {
font-size: 1.5rem;
font-weight: 700;
color: #2563eb;
margin-top: 2.5rem;
margin-bottom: 1rem;
border-left: 5px solid #2563eb;
padding-left: 12px;
}
h3 {
font-size: 1.25rem;
font-weight: 600;
color: #1f2937;
margin-top: 1.5rem;
margin-bottom: 0.75rem;
}
/* 4. 正文与列表 */
p { margin-bottom: 1rem; }
ul, ol { margin-bottom: 1rem; padding-left: 1.5rem; }
li { margin-bottom: 0.25rem; }
/* 5. 代码块样式 */
code {
background-color: #f1f5f9;
padding: 0.2rem 0.4rem;
border-radius: 0.25rem;
font-size: 0.875em;
color: #d946ef;
font-family: monospace;
}
pre {
background: #1e293b;
color: #f8fafc;
padding: 1rem;
border-radius: 0.5rem;
overflow-x: auto;
}
pre code {
background: transparent;
color: inherit;
padding: 0;
}
/* 6. 图表容器样式 */
.chart-box {
width: 100%;
height: 450px;
margin: 30px 0;
border: 1px solid #e2e8f0;
border-radius: 8px;
background-color: #fff;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
/* 7. 错误提示样式 */
.chart-error {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: #ef4444;
background-color: #fef2f2;
border: 1px dashed #ef4444;
border-radius: 8px;
}
/* --- 样式结束 --- */
</style>
</head>
<body>
<div class="container">
<!-- 原始内容容器(隐藏),用于接收 LLM 的内容 -->
<!-- 这里的 display:none 至关重要,防止显示原始 Markdown -->
<div id="raw-markdown" style="display:none;">
- HTML尾
html
<!-- 渲染目标容器 -->
<div id="render-target" class="markdown-body"></div>
</div> <!-- container 结束 -->
<script>
window.onload = function() {
// 0. 安全检查
if (typeof marked === 'undefined') {
alert('错误:Marked库加载失败,请检查网络或更换CDN');
document.getElementById('raw-markdown').style.display = 'block';
return;
}
// 1. 获取内容
const rawDiv = document.getElementById('raw-markdown');
if (!rawDiv) return;
const rawText = rawDiv.innerText;
// 2. 解析 Markdown
const renderer = new marked.Renderer();
renderer.code = function(code, language) {
if (language === 'echarts' || language === 'json') {
const id = 'chart_' + Math.random().toString(36).substr(2, 9);
// 使用 encodeURIComponent 保存原始代码串
return '<div id="' + id + '" class="chart-box" data-option="' + encodeURIComponent(code) + '"></div>';
}
return '<pre><code class="language-' + language + '">' + code + '</code></pre>';
};
document.getElementById('render-target').innerHTML = marked.parse(rawText, { renderer: renderer });
// 3. 渲染图表
if (typeof echarts !== 'undefined') {
document.querySelectorAll('.chart-box').forEach(box => {
try {
// 解码数据
const code = decodeURIComponent(box.getAttribute('data-option'));
// 🌟 核心修改:使用 new Function 替代 JSON.parse
// 这样可以兼容 LLM 生成的 JS 函数 (formatter: function()...)
// 注意:这就要求 LLM 生成的是 JS 对象字面量,而不仅仅是 JSON (通常 LLM 都会这么做)
const option = new Function('return ' + code)();
const myChart = echarts.init(box);
myChart.setOption(option);
window.addEventListener('resize', () => myChart.resize());
} catch(e) {
console.error('图表渲染失败', e);
// 把具体的代码打印出来方便调试
console.log('Error Code:', decodeURIComponent(box.getAttribute('data-option')));
box.innerHTML = '<div style="color:red;padding:20px;text-align:center;border:1px dashed red;">' +
'<b>图表渲染错误</b><br/>' + e.message + '</div>';
}
});
}
};
</script>
</body>
</html>
- 最终HTML展示效果
