---
name: data-insight-runbook
description: 数据洞察报告：输入原始数据（CSV 文件 / 粘贴表格 / SQL 查询结果 / DuckDB 直连数据库）→ 输出带图表与业务结论的结构化 Markdown 分析报告。覆盖数据探查、指标计算、同环比、TopN、异常值、图表生成与严谨性检查。需要做数据分析、出报告、看数据、算指标、画图时加载本技能。
tags: [data-analysis, csv, sql, duckdb, markdown-report, charts]
---

# 数据洞察 Runbook

把原始数据变成「业务结论 + 指标数据 + 图表」的结构化 Markdown 报告。

## 执行原则（贯穿全程，违反即返工）

1. **每个数字必须有口径**：时间范围、过滤条件、聚合方式、计算公式都要写清楚。
2. **每条结论必须有数字支撑**：禁止无依据的推断；结论引用的数字必须在正文或附录可查到。
3. **区分事实与推断**：数据事实（GMV 环比 -12%）与模型推断（可能受大促错期影响）分开标注，推断要给出依据与置信度。
4. **报告可复现**：附录记录原始数据、处理步骤、算法参数，任何人能按附录重算得到同样数字。
5. **不编造数据**：探查不到的数字不猜；缺失值按下方规则处置并如实记录。

按阶段执行，每阶段有硬性门槛；未过门槛不得进入下一阶段。

---

## 阶段 0：输入受理与口径确认

识别数据源类型，确认分析口径。**门槛：数据已加载 + 口径已确认，才进入探查。**

### 0.1 识别数据源
- **CSV 文件**：用户给路径，或在工作区找 `.csv`/`.tsv`。
- **粘贴表格**：用户直接粘贴的表格文本（含 SQL 查询结果导出）。约定：列用 `|` 或制表符分隔，首行为表头；NULL 写 `NULL`/`null`/空值需说明。
- **DuckDB 直连**：见下方「数据源接入细则·DuckDB」。

### 0.2 确认口径（缺失就用 ask_user_question 一次问清）
- **分析目标**：要回答什么业务问题？（看趋势 / 找异常 / 做对比 / 找 TopN / 综合体检）
- **指标定义**：核心指标（GMV、转化率、留存…）的确切计算公式。
- **时间范围与粒度**：起止日期、聚合粒度（日/周/月）。
- **维度**：按什么分组（渠道/地区/品类…）。
- **过滤条件**：排除哪些脏数据 / 测试数据。

用户说「随便 / 你定」时采用默认：全量数据、日粒度、核心指标按列名语义推断并在报告中明确写出推断依据。

---

## 阶段 1：数据探查

**门槛：探查记录完成，异常数据有处置决定。**

### 1.1 加载与解析
- CSV：用 `scripts/csv-profile.mjs` 探查（优先），或 read 头几行确认结构。
- 编码：优先 UTF-8；出现乱码再按 GBK 重读。分隔符：`,` > `\t` > `;` > `|` 依次尝试，以「列数一致且无单列吞并」为准。
- 记录：文件路径、行数（不含表头）、列数、编码、分隔符。

### 1.2 探查内容（写入探查记录，供附录引用）
- **Schema**：列名、每列推断类型（数值/文本/日期/布尔/ID）。
- **缺失值**：每列缺失数、缺失率；>20% 的列标注。
- **值分布**：数值列（min/max/mean/median/分位数）、文本列（唯一值数、Top 高频值）、日期列（范围与粒度）。
- **脏数据**：重复行、异常格式（日期不统一、数字带单位/千分位）、明显错误值（负数年龄、未来日期）。

### 1.3 异常处置（必须明确决定，写进报告附录）
- 缺失值：删除 / 填 0 / 填均值 / 单独标记——按列语义决定并记录。
- 重复行：去重（保留规则）或保留（说明）。
- 单位不一致：统一单位并记录换算。

---

## 阶段 2：指标计算

**门槛：每个输出数字都有明确口径与计算公式。**

用确定性规则计算，禁止每轮自创算法。可用 `scripts/csv-profile.mjs` 或让 LLM 按规则手算（大数据量优先脚本，避免算错与上下文爆掉）。

### 2.1 汇总统计
总数、求和、均值、中位数、标准差、min/max、分位数（P25/P50/P75/P90）。

### 2.2 同环比（基准期规则写死）
- 环比：本期 vs 上一期（日环比=昨天；周环比=上周；月环比=上月）。
- 同比：本期 vs 去年同期；跨年数据缺失时降级为「不可算，记录原因」。
- 增长率公式：`(本期 − 基期) / 基期 × 100%`；基期为 0 时标注「不适用（基期为 0）」。

### 2.3 TopN
- N 默认 5（报告空间有限），用户可指定 5/10/20。
- 按指标降序；并列时都列出并标注并列名次。

### 2.4 异常值
- 数值列：Z-score 法 `|z| > 3` 判定异常，同时给出 IQR（1.5×IQR）对照；口径写进附录。
- 报告中异常值列出「值 + 所属维度 + 判定依据」，不做无依据的归因猜测。

---

## 阶段 3：图表呈现（三通道）

**门槛：图中每个数据点都能在正文或附录表格找到，禁止图表与数字不一致。**

三通道规则见 `docs/chart-spec.md`，要点：
1. **主通道**：Markdown 表格 + 关键数字——永远可靠，任何查看器都渲染。
2. **次通道**：Mermaid（趋势用 `xychart-beta`、占比用 `pie`），标注「需 Mermaid 渲染器」；DSH Web GUI 不渲染 Mermaid，主通道表格必须能独立撑起报告。
3. **兜底**：ASCII 条形图（code block 内），纯文本处处可读。
- **禁止**手写 SVG（易错、难维护）。

---

## 阶段 4：报告产出

**门槛：严谨性检查清单全过。**

### 4.1 模板与检查清单
严格按 `docs/report-template.md` 的骨架与严谨性检查清单产出，固定结构：
核心结论 → 数据概况 → 关键指标 → 趋势与对比 → TopN 与异常 → 风险与建议 → 附录（口径与可复现说明）。

### 4.2 硬性要求
- 核心结论 3–5 条，每条带具体数字。
- 「风险与建议」中事实与推断分开标注。
- 附录含：数据源、时间范围、过滤条件、缺失/重复处置、算法与参数、图表数据表。
- 报告以 Markdown 文件落盘到工作区（文件名如 `data-insight-report.md`），并汇报路径。

---

## 数据源接入细则

### CSV 文件
- 优先 `node scripts/csv-profile.mjs <file.csv>` 出探查报告，再按口径计算。
- 大文件（>2000 行）：先探查，指标计算交给脚本/DuckDB，不要让 LLM 逐行读全文（会爆上下文）。

### 粘贴表格 / SQL 查询结果
- 直接按上述阶段 1 解析（表头 + 分隔符 + 类型推断）。
- 若来自 SQL：记录来源查询（脱敏后写入附录），确认是否已聚合。

### DuckDB 直连
- **启用检测**：`duckdb --version` 可用才走直连；不可用时 CSV/粘贴仍全功能，直连路径明确告知「需安装 DuckDB（Windows：scripts/setup-duckdb.ps1，macOS/Linux：scripts/setup-duckdb.sh；或按官方文档 https://duckdb.org/docs/stable/clients/cli/overview 自行安装——Windows 可执行 winget install DuckDB.cli，macOS 可执行 brew install duckdb）」，引导用户安装，不静默降级。
- **安全红线（必须遵守）**：
  - 连接库文件 / 远程库时一律 `-readonly`（v1.5.5 实测会拦截 INSERT/CREATE 等写语句），禁止任何写库 / 建表 / 破坏性语句。
  - 连接串走环境变量 `DATA_INSIGHT_DB_URL`，禁止把密码写进命令或报告。
  - 查询加 `LIMIT`（默认 5000），列宽截断；超限提示分批。
- **调用方式（直接调 CLI，勿写 Node spawn 包装——规避沙箱子进程管道 EPERM；已在 v1.5.5 实测）**：
  - CSV/Parquet 直接查（无库文件，**不加 `-readonly`**——不带库文件时 CLI 打开内存库，`-readonly` 会报 `Cannot launch in-memory database in read-only mode`；仅执行 SELECT，无持久化写入）：
    `duckdb -csv -c "SELECT * FROM read_csv_auto('data.csv') LIMIT 100"`
  - 库文件 / 远程库（`-readonly` 强制只读，连接串走环境变量）：
    `duckdb -readonly -csv -c "SELECT ... LIMIT 5000" "$env:DATA_INSIGHT_DB_URL"`（POSIX shell 为 `"$DATA_INSIGHT_DB_URL"`）

---

## 沙箱与环境约束（重要）

- 运行环境受 DSH 文件沙箱限制：读写尽量落在工作区内；`workdir` 必须指向已存在目录。
- **不要写 Node 脚本去 spawn 子进程**（如脚本内调用 duckdb/ffmpeg）：confined 模式下子进程管道捕获会报 `EPERM`。duckdb 由 runbook 指引通过 shell 工具直接调用；`csv-profile.mjs` 只做纯文件读写与计算，不 spawn 子进程。
- 需要联网查数据字典 / 口径时用 web_search，不臆造。
- **本技能包内脚本除 DuckDB 安装脚本外不发起任何网络请求、不下载二进制文件**：`csv-profile.mjs` 仅做本地文件读写；`setup-duckdb.ps1` / `setup-duckdb.sh` 仅在用户明确要求安装 DuckDB 时由用户运行，从官方渠道（winget / brew / duckdb.org / GitHub release）下载 DuckDB CLI。

## 例外与裁剪

- 极小数据（≤50 行、≤10 列）：可跳过脚本，LLM 直接探查与计算，但五阶段门槛不豁免。
- 用户明确只要「快速看一眼」：产出精简版（核心结论 + 关键指标表 + 一个图表），但严谨性清单中「结论有数字、区分事实/推断」不豁免。

## 参考文档

- `docs/chart-spec.md`：三通道图表规范与代码示例。
- `docs/report-template.md`：报告骨架与严谨性检查清单。
- `scripts/csv-profile.mjs`：零依赖 CSV 探查脚本。
