alchaincyf/huashu-excel
数据分析与 Excel 全流程 skill:体检脏表、清洗、对齐需求、分析、对账、交付。让 AI 算出来的数字经得起追问。跨 agent 通用,依赖仅 openpyxl。
项目说明
huashu-excel
「给我一份Excel,给你交一份专业报告。」 一个真正懂数据分析的skill。
数据分析与 Excel 全流程 · 体检 → 清洗 → 对齐 → 分析 → 对账 → 交付
「这个数你怎么算的?」 —— 每个交过数字的人都被这么问过。 答不上来通常不是记性差,是那个数从一开始就没法被追溯。
而 AI 算错的时候不会报错。 你写代码,错了会抛异常; 你做数据分析,错了什么都不会发生。一个 +161% 的错误, 交付出去的时候和正确答案长得完全一样。
丢一份乱七八糟的 Excel 给它——标题占了第一行、表头两级、地区列用合并单元格、 金额带千分位、中间夹着「华东小计」、尾巴三行是「合计/占比/同比」。 主流做法算这份表的月度总额,比真值高 161%,零报错、零 NaN、零警告。
这个 skill 存在的全部理由,就是让那句反问能被答上来。它先读原始单元格再动 pandas,把表里的「合计」行当成免费的校验和拿来对账,交付前跑一遍 master check——不通过就不给你数字。
npx skills add alchaincyf/huashu-excel
跨 agent 通用——Claude Code、Cursor、Codex、OpenClaw、Hermes 都能装。
看效果对比
同一份表,同一个问题:「1 月总销售额是多少?」
主流做法:pd.read_excel()
发现表头位置不对就加 header=,发现数字读不出来就清掉千分位。看起来已经挺周全了。
清理后求和:34,893,234 真值:13,367,767
总额误差:+161.0%
均值误差:+117.5%
零报错 零 NaN 零警告
错在三个地方,没有任何一处会报错:
合计行的 15,368,317 被当成了一家门店华东小计的 6,157,150 又被当成一家门店- 有一行是粘贴事故造成的完全重复,算了两次
huashu-excel
体检阶段就把问题全列出来,一个都不猜:
【必须先处理】
1. 表头不在第 1 行:第 1, 2 行是标题/说明,真表头在第 3, 4 行
2. 两级表头。用 header=[2, 3] 读,否则下级表头会掉进数据区
3. 发现 4 个汇总/小计行(第 12, 17, 18, 19 行)混在数据区
4. 1 行与前面完全重复(第 11 行)
5. 3 处合并单元格落在数据区,pandas 只保留左上角,其余行变空
【逐列】
E 一季度 / 1月
⚠ 10/10 个数字被存成了文本 → 直接 sum() 会变成字符串拼接或得 0
I 退货额(元)
⚠ 缺失值被写成了具体文字:「—」×2、「无」×1、「N/A」×1
D 首单日期
⚠ 日期格式不统一:YYYY-M-D×7、YYYY年M月D日×1、Excel日期序列号×1、
M月D日(缺年份)×1
然后拿清洗后的明细,去对表里自带的合计行:
✓ 对账 · E列「1月」 vs 第12行「华东小计」
表内写 6,497,500.00,按「A列地区 == 华东」取 4 行算得 6,497,500.00 ✓ 一致
✗ 对账 · F列「2月」 vs 第12行「华东小计」
表内写 6,490,430.00,明细算得 6,490,420.00 ✗ 差 10.00
MASTER CHECK:不通过。1 项对不上。
在解决之前,不要把这些数字写进任何交付物。
那个差 10 块钱的错,是造这份测试数据的人手填小计时填错的。 相对误差 0.00%,肉眼永远发现不了,脚本一次揪出来。
Panko (1998) 的研究说 86% 的电子表格含有错误。欧洲电子表格风险兴趣组 (EuSpRIG)从 1995 年起持续收录见诸媒体的事故——最著名的是 Reinhart-Rogoff 论文,Excel 选区少选了 5 行,把 +2.2% 的 GDP 增速算成 −0.1%, 而那篇论文当时是全球紧缩政策的主要学术依据。
装上就能用
npx skills add alchaincyf/huashu-excel
或者直接 clone 到你的 agent 读 skills 的那个目录:
| Runtime | 路径 |
|---|---|
| Claude Code | ~/.claude/skills/ |
| Codex / Kimi Code / 多 agent 共用 | ~/.agents/skills/ |
| 项目级(跟着仓库走) | <项目>/.claude/skills/ 或 <项目>/.agents/skills/ |
git clone https://github.com/alchaincyf/huashu-excel <上表里的目录>/huashu-excel
不确定装哪就用上面的 npx skills add,它会自己探测。
也可以完全不装——把 SKILL.md 当成一份数据分析的方法论文档直接读。
装完直接说人话:
"帮我分析下这份销售表" → 走完整八步
"这两个数怎么对不上" → 体检 + 对账,先找口径差异
"这个数靠谱吗" → 对账 + 独立复核
"这个表有多少行是脏的" → 只跑体检
"帮我把这份表洗干净" → 体检 + 清洗,附一份可审计的 pandas 脚本
"这个数你怎么算出来的" → 对账 + 口径回溯
"给我做份报告" → 图表 + 洞察 + html/xlsx/docx 任选
这些脚本也能脱离 agent 单独用:
python3 scripts/profile_table.py 你的表.xlsx # 算数字之前先看清楚
python3 scripts/verify_numbers.py 你的表.xlsx # 退出码 1 = 有对不上的
python3 scripts/verify_visual.py 报告.html # 退出码 1 = 图画错了
python3 scripts/verify_docx.py 报告.docx # 退出码 1 = Word 换台机器就走样
依赖只有 openpyxl(读写 .xlsx 时),CSV 路径和报告生成连它都不用,纯标准库。
不用 pandas、不用绘图库、不用 LibreOffice、不联网、不依赖任何 agent 平台特性
(不需要 subagent、不需要沙盒)。
这不是为了炫技。体检要在「还没决定用什么工具处理这张表」的时刻就能跑, 所以它自己必须几乎没有前置条件。已在屏蔽 pandas / numpy / openpyxl 的 解释器里验证过全流程跑通。
skill 会在开工时探测所处环境的能力,选那个环境下的最佳工作流—— 能起并行子任务就并行分析,只能串行就串行轮转视角,跑不了脚本就转成 「我告诉你在 Excel 里怎么点」。
八步标准作业流程
1 体检 这张表长什么样 —— 结构、类型、脏点。先看再算
2 清洗 变成规范分析表,每一步可追溯可回放
3 对齐 摸底 → 查外部基准 → 告诉用户 → 问清他要什么 → 定口径
4 分析 扫陷阱,走配方,每条发现都推到「所以呢」
5 对账 行数守恒、总和守恒、与表内合计交叉验证
6 交付 Excel / 图表 / 报告,口径随数字一起交付
7 验图 渲染出来看画错了没有——手写 SVG 必然会犯那几类错
8 质控 另派一个没参与创作的 agent 从原始数据重算,拆你的台
最后一步是最容易被省掉的一步,而它抓到的问题比前面所有闸门加起来还多。 退出码验的是「算得对」,不是「结论对」——一份内部对账分毫不差的报告, 可以整体错一个财年,只要那一列的列名不是它字面的意思。
| 脚本 | 干什么 | 什么时候 |
|---|---|---|
profile_table.py | 表结构体检 | 算任何数字之前 |
clean_table.py | 清洗 + 生成可审计的 pandas 脚本 | 体检之后 |
scan_traps.py | 分析陷阱扫描 | 下结论之前 |
verify_numbers.py | 数字对账 | 交付之前 |
verify_visual.py | HTML 渲染自检:越界 / 重叠 / 遮挡 / 双轴 / 图文数字打架 | 交付之前 |
verify_docx.py | Word 自检:字体平台绑定 / 中文缺 eastAsia / 空白页 / 图超版心 / 表头不重复 | 交付之前 |
make_chart.py | 图表推荐与生成 | 交付时 |
make_report.py | xlsx / docx 报告(HTML 直接写,不套模板) | 交付时 |
第 3 步「对齐」为什么值得单独成一步
用户开口的时候,往往还不知道自己要什么——因为他也没看过这份数据长什么样。 「帮我分析一下」是他此刻能给出的最诚实的表述。你这时候问他「你想看哪些维度」, 他只能瞎猜,猜出来的还得你去实现。
所以澄清不放在最开始,放在你已经看懂数据、他也能看懂你的描述之后: 清洗完先出一段人话摸底(几行几列、有哪些维度和指标、分布形态、 一到两个已经能看到的现象),带着它去问他要回答什么问题、 这份分析拿去做什么决定、有没有你从数据里看不出来的背景。
然后停下来等回答。这是整个流程里少数几个值得停的地方—— 带着错的问题做完整套分析,返工成本远高于等这一次。
脚本是眼睛,不是大脑
每跑完一个脚本,必答三问再往下走:我看到了什么 / 这意味着什么 / 下一步要查什么。
判据写死在 skill 里:如果跑完脚本之后,下一步动作和跑之前计划的一模一样, 说明没有真的在看那个输出。 分析是一次不断分叉的调查, 照着固定顺序跑完八个脚本,产出的只是八段输出。
五个和别的工具不一样的地方
一、它不是一个分析师,是一个团队。 这件事外包给顶级咨询公司,不会只派一个数据分析师。所以它要依次成为 领域专家 / 数据分析师 / 战略顾问 / 视觉设计师 / 前端工程师 / 质控—— 角色之间打架的地方保留下来,那是信息量最大的部分。
其中领域专家最容易被跳过、代价也最大:结论全是「这条比那条好」 「这个月比上月强」,用户读完还是不知道要不要改——因为他不知道 20% 的完播率 在这个平台算什么水平。内部对比只能说明哪里变了,外部基准才能说明哪里不行。 所以第 3 步会去查行业基准,查不到就明写「本次没有外部基准」。
二、先看原始单元格,再动 pandas。
pd.read_excel() 读进来的那一刻,合并单元格、单元格格式、原始类型就全丢了。
现有工具都是在信息已经损毁之后才开始判断。体检脚本先用 openpyxl 读原始格子。
三、把表里的「合计」行当成免费的校验和。
所有工具都把汇总行当噪音过滤掉。但那是原表作者用公式算出来的真值。
拿清洗后的明细自己求和去对它——对不上就说明有一方错了,两种情况都必须报出来。
这对应 ICAEW《Financial Modelling Code》(2024) 的 Include a master check。
四、默认给五数概括,不给均值。
业务数据几乎总是右偏的(少数大客户、少数爆款)。df.describe() 把 mean/std
放在最前面,而均值在偏态分布下描述的不是任何一个真实对象。
默认输出 min/Q1/中位数/Q3/max + IQR,这是 Tukey 的抗差统计。
五、机器判事实,人判品味。 「行数对不对、总和守不守恒、这个数能不能追回源单元格」——机器验死,自动跑。 「这个分析有没有意义、该不该这么切」——明确交还给人, 绝不用一个分数冒充客观。
还有一类问题,对账抓不到
数字全算对了,结论照样是错的。scan_traps.py 专扫这一类:
| 陷阱 | 会让你得出什么错误结论 |
|---|---|
| 辛普森悖论 | 分组内都是 A 好,合起来变成 B 好 |
| 幽灵分组 | 「张伟」和「张伟 」被算成两个人,每组的数都是残缺的 |
| 小基数 | 样本 3 个的组报「增长 200%」,其实是多了 4 个 |
| 时间断点 | 缺失的月份不会报错,但会让趋势线撒谎 |
| 双峰分布 | 混了两群对象,均值描述的是一个不存在的人 |
| 极端集中 | 前 20% 贡献了 80%,均值没有代表性 |
图表:比《用图表说话》多一个维度
继承 Gene Zelazny《用图表说话》的核心律条——先确定要传达的信息,再选图表形式, 并补上那本书 1985 年还没有的两件事。
一、用实证决定视觉编码
Cleveland & McGill (1984) 的图形感知实验,测出了人读取不同视觉编码的精度阶梯:
位置(共同基线) > 位置(非对齐) > 长度/方向/角度 > 面积 > 体积/曲率 > 明暗/色饱和
位置判断比长度准 1.4–2.5 倍,比角度准 1.96 倍
饼图靠角度和面积编码,正好落在下游。所以 make_chart.py
在类别超过 3 个时会拒绝生成饼图:
拒绝生成饼图:当前 10 个类别,超过 3 类。
原因:饼图靠角度和面积编码,在 Cleveland-McGill 的感知精度阶梯上排第 3 和第 4,
而条形图的长度编码排第 2。
改用 --type bar,并在标签上标注百分比——信息一样,读者读得更准。
这不是审美偏好,是有测量结果的。
二、检查这张图有没有在误导人
生成时自动执行,不靠自觉:
- 柱形图数值轴强制从 0(它编码长度,截断即失真)
- 折线图不强制从 0(它编码位置和斜率,强行归零会压平真实波动)
- 坐标轴用整刻度,不是
139.68 / 115.50 / 91.32这种从数据直接算出来的碎数字 - 类别按值排序、单系列去图例、类别过多自动聚合
- 不完整的最后一期画虚线——本期没走完却画成实线,是最常见的误导
- 套用色盲友好色板(约 8% 的男性有红绿色觉障碍,而红绿恰是最常用的选择)
完整的诚实性检查清单见 references/charts.md。
报告:直接写,不套模板
HTML 报告直接写 HTML/CSS,不从模板里挑。顶级设计师不用模板生成器—— 他看过内容之后为这份内容做设计。没有内置风格可挑:动手前先落一份设计计划 (色 / 字 / 数字 / 间距 / 版式五段),照着它写;写完对照十五条最常见的 默认倾向自查一遍。
手写时这几条不能丢,它们是内容要求不是技术限制:
- 自包含——无 CDN、无外部字体,图表用内联 SVG 自己画,离线和内网都能开
- 口径声明在前,分析边界在后——没有口径的数字没法被检验; 说出自身弱点的报告比天衣无缝的可信
- 图表诚实性——柱形轴从 0、折线不强制从 0、整刻度、同列同小数位、 不完整末期画虚线、色盲友好
- 该是图就别是字——N 行 × 1 数值列的排名表画条形图,含正负的分解画瀑布图
Office 格式仍走脚本,因为手写不划算:
| 格式 | 怎么做 |
|---|---|
| HTML 报告 | 直接写 |
| 幻灯片 / PPT | 不在本 skill 做 —— 转 huashu-design,见下 |
xlsx Excel 内报告 | make_report.py --format xlsx,图表引用数据 sheet,改数图跟着变 |
docx 六页纸文档 | make_report.py --format docx,Amazon six-pager 叙述体。字体用 Office 双平台自带款,交付前跑 verify_docx.py |
docx 那条走的是 six-pager 的精髓:叙述体,不用项目符号——
bullet 允许把没想清楚的东西并列摆着蒙混过关,完整段落会逼你写出因果和取舍。
写不清楚,就是没想清楚。手写 OOXML,连 python-docx 都不需要。
幻灯片和 PPT 交给 huashu-design
要 PPT / deck / 演示文稿时,本 skill 只出分析内容和图表, 演示文稿的生成与视觉交给 huashu-design (没装会先引导安装)。排版、母版、封面、视觉方向是另一个专业, 硬做出来的结果是「一眼看得出是自动生成的」。
交接会带三样过去:口径声明、论点结构、已经过渲染自检的内联 SVG—— 而不是把原始数据丢过去让它自己算。口径是上游定的,不该在下游被重新发明。
方法论出处
这份 skill 的判断力不是凭空来的,每条都有出处:
| 来源 | 用在哪 |
|---|---|
| Hadley Wickham, Tidy Data | 清洗的目标形态与五类脏数据分类 |
| John Tukey, Exploratory Data Analysis (1977) | 五数概括、抗差统计、箱线图 |
| ICAEW, Financial Modelling Code (2024) | master check、可追溯引用、Excel 工程约定 |
| Cleveland & McGill (1984) | 视觉编码的感知精度阶梯 |
| Gene Zelazny, Say It With Charts | 先定信息再选图、比较类型 → 图表形式 |
| Barbara Minto, The Pyramid Principle | 结论先行、MECE、SCQA |
| Ronny Kohavi et al., Trustworthy Online Controlled Experiments | Twyman's Law、常见陷阱 |
| Cassie Kozyrkov | 探索与推断的分工红线 |
| Panko (1998)、EuSpRIG | 电子表格错误的实证规模 |
引用的规范文本均为提炼转述并注明出处,不含受版权保护的原文复制。
三届微软 Excel 世界冠军 Andrew Ngai 对 AI 做数据分析的判断,是这份 skill 的立论:
如果你用错误的数据训练 AI,它会给你错误的结果——但它还会装出对这些错误结果非常自信的样子。
License
MIT
