首页 › tutorials › 造CSV数据画像Skill:脚本Skill秒出体检报告

概述

本教程带你从零造一个带脚本的"计算型"Skill——CSV 数据画像工具。学完你能掌握 Skill 的两种核心形态差异、frontmatter 全字段、scripts/ 目录与 ${CLAUDE_SKILL_DIR} 变量、渐进式披露、allowed-tools 预授权、热加载与 skill-creator 评测闭环。适合已跑通过首个 Claude Code 项目、想进阶把重复数据处理流程封装成可复用能力的开发者。

前置条件


一、先想清楚:你要的是哪种 Skill

很多人第一次写 Skill,只会写一个 SKILL.md 里全是"分析代码、列风险"的提示词——这叫纯指令型 Skill。它依赖模型当场推理,遇到要算的活儿(统计分布、聚合、排序)既慢又容易算错。

真正强大的 Skill 是计算型 Skill(bundled-script skill):SKILL.md 只当"导航员",告诉模型何时该跑、跑哪个脚本、怎么读结果;重活儿全交给 scripts/ 下的可执行脚本。模型负责编排和解读,脚本负责精确计算。

┌─────────────────────────────────────────────┐
│  Skill 两种形态对比                          │
├──────────────────┬──────────────────────────┤
│ 纯指令型         │ 计算型(本教程)          │
├──────────────────┼──────────────────────────┤
│ 只有 SKILL.md    │ SKILL.md + scripts/*.py   │
│ 模型全程推理      │ 脚本精确计算,模型解读    │
│ 适合规则/规范     │ 适合统计/转换/生成        │
│ 计算易出错        │ 结果可复现                │
└──────────────────┴──────────────────────────┘

数据画像这种活儿——算每列空值率、基数、最大最小、高频值——天然属于计算型。交给模型逐格数会又慢又错,写个脚本秒出报告才是正解。

二、规划目录结构

Skill 是一个目录,SKILL.md 是入口,其余按需挂载。先想清楚再动手:

csv-profiler/
├── SKILL.md              # 入口:导航 + 触发说明(必填)
├── scripts/
│   └── profile.py        # 核心计算脚本(执行的,不是读进上下文的)
├── reference/
│   └── metrics.md        # 各指标详细定义(按需加载)
└── examples/
    └── sample-report.md  # 期望输出的样例

关键原则:SKILL.md 保持精简(官方建议 500 行以内),重材料拆到独立文件,并在导航里写清"什么时候去读哪个文件"。这就是渐进式披露(progressive disclosure)——默认只把 description 塞进上下文,正文和附件只在被触发时才加载,闲时几乎零成本。

三、写 frontmatter:决定"何时触发、谁能调用、给什么权限"

frontmatter 是 YAML,夹在两个 --- 之间。字段几乎都可选,但 description 强烈建议写好——它是模型决定是否加载本 Skill 的唯一依据。新建 ~/.claude/skills/csv-profiler/SKILL.md:

---
name: csv-profiler
description: Profile a CSV file and produce a per-column data quality report.
  Use when the user asks to inspect, profile, audit, or understand a CSV
  dataset, or wants column stats, null rates, cardinality, or distributions.
  Triggers on phrases like "看看这个表", "数据画像", "字段体检", "missing rate".
argument-hint: [path-to-csv]
arguments: [file]
allowed-tools: Bash(python3 *)
disable-model-invocation: false
user-invocable: true
---

逐字段拆解(这是后续所有 Skill 都通用的"配置盘"):

字段 作用 本例取值与理由
name 展示名,默认取目录名,不改变 / 后输入 csv-profiler
description 模型匹配触发的主依据;关键用例放开头,因为列表里会被截断到 1536 字符 写明"画像/体检/null 率"等触发词
argument-hint 自动补全时显示的参数提示 [path-to-csv]
arguments 命名位置参数,映射到 $name file,于是正文可用 $file
allowed-tools 技能激活期间免审批放行的工具 Bash(python3 *)——免得每次跑脚本都弹确认
disable-model-invocation true 则只允许人手动 /csv-profiler 触发 false,希望模型在聊到 CSV 时自动启用
user-invocable false 则从 / 菜单隐藏 true,允许人手动触发

预期结果:保存后,在任何项目里聊到"帮我看看这个 CSV"时,模型应自动加载本 Skill;也可直接 /csv-profiler data.csv 调用。

常见问题:写了 Skill 却不触发?多半是 frontmatter YAML 写坏(缩进错、: 后没空格)。Claude Code 会静默用空元数据加载,/csv-profiler 仍能用,但模型没了 description 就匹配不上。用 claude --debug 启动可看到解析报错。

四、写核心脚本 scripts/profile.py

脚本只做一件事:吃一个 CSV 路径,吐结构化的 Markdown 体检报告。全程用标准库,零依赖:

#!/usr/bin/env python3
"""CSV 列级数据画像:类型推断、空值率、基数、数值统计、高频值。"""
import csv
import sys
from collections import Counter
from pathlib import Path

def infer_type(values):
    nums, non_empty = 0, 0
    for v in values:
        if v == "" or v is None:
            continue
        non_empty += 1
        try:
            float(v); nums += 1
        except ValueError:
            pass
    if non_empty == 0:
        return "empty"
    return "numeric" if nums / non_empty > 0.8 else "text"

def profile(path):
    rows = list(csv.DictReader(open(path, encoding="utf-8-sig")))
    if not rows:
        return "## 报告\n\n(文件为空或无数据行)"
    cols = rows[0].keys()
    lines = [f"## 数据画像:`{Path(path).name}`\n",
             f"- 总行数:**{len(rows)}**,列数:**{len(list(cols))}**\n",
             "| 列 | 类型 | 空值率 | 基数 | 高频值 / 范围 |",
             "|---|---|---|---|---|"]
    for c in rows[0].keys():
        vals = [r[c] for r in rows]
        n = len(vals)
        missing = sum(1 for v in vals if v == "" or v is None)
        non_empty = [v for v in vals if v != "" and v is not None]
        ctype = infer_type(vals)
        card = len(set(non_empty))
        top = Counter(non_empty).most_common(3)
        if ctype == "numeric":
            nums = sorted(float(v) for v in non_empty)
            scope = f"min {nums[0]:g} / max {nums[-1]:g}"
        else:
            scope = "; ".join(f"{k}({ct})" for k, ct in top)
        lines.append(f"| `{c}` | {ctype} | {missing/n:.1%} | {card} | {scope} |")
    return "\n".join(lines)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("用法: profile.py <csv路径>"); sys.exit(1)
    print(profile(sys.argv[1]))

预期结果:终端 python3 profile.py sample.csv 直接打印一张 Markdown 表,空值率、基数、数值范围一目了然。

常见问题:中文 CSV 用 Excel 另存的常带 BOM,故 open(..., encoding="utf-8-sig");GBK 编码可在脚本里加个 try/except 兜底回退 gb18030。

五、写导航层正文:把脚本"挂"上去

frontmatter 下方写正文。核心是用 ${CLAUDE_SKILL_DIR} 引用脚本——这个变量在运行时会被替换为 SKILL.md 所在目录,无论 Skill 装在个人级、项目级还是插件级都能正确解析,所以脚本路径绝不写死:

## 任务

对用户给出的 CSV(路径在 $file,若未提供则先问用户要路径)生成列级数据画像。

## 步骤

1. 跑画像脚本,拿到结构化报告:
   ```bash
   python3 ${CLAUDE_SKILL_DIR}/scripts/profile.py "$file"
   ```
2. 把脚本输出的表格原样呈现给用户。
3. 针对**异常列**追加自然语言点评:空值率 >50% 的列提示"考虑删除或补全";
   基数=1 的常量列提示"无信息量";文本列基数接近行数提示"可能是 ID"。

## 何时不该用

- 文件不是 CSV(xlsx/json)→ 先转 CSV 或换工具
- 列数 >500 → 提醒用户可能需采样

## 附加资源
- 各指标精确定义见 [reference/metrics.md](reference/metrics.md)
- 期望输出样例见 [examples/sample-report.md](examples/sample-report.md)

注意 reference/ 和 examples/ 默认不进上下文,只在模型判断需要时才被读取——这正是渐进式披露省 token 的地方。

六、安装、热加载与触发测试

  1. 把 csv-profiler 目录放到 ~/.claude/skills/(个人级,所有项目可用)或项目 .claude/skills/(仅本项目)。
  2. 无需重启:Claude Code 实时监听 Skill 目录变化,改 SKILL.md 立即生效。
  3. 两种测试方式: - 自动触发:在新会话里说"帮我体检一下 orders.csv"; - 手动触发:/csv-profiler orders.csv。

预期结果:模型先跑脚本拿到表,再补一段异常点评,全程 python3 不弹权限确认(因 allowed-tools 已预授权)。

常见问题:脚本路径报"找不到文件"?检查正文里是不是漏了 ${CLAUDE_SKILL_DIR}、写成了相对路径 scripts/profile.py——相对路径会以当前工作目录解析,跨目录就崩。

七、用 skill-creator 跑评测,量化"触发准不准"

Skill 能触发 ≠ 它做对了事。官方推荐用 skill-creator 插件做对照基线测试:

/plugin install skill-creator@claude-plugins-official
/reload-plugins
evaluate my csv-profiler skill with skill-creator

它会引导你写一批"应该触发/不该触发"的提示词(如"这表有多少空"应触发、"帮我画个柱状图"不应触发),每个用例开独立子代理分别跑"有 Skill"和"无 Skill"两遍,对比通过率、耗时、token,输出 benchmark.json。还能对两个版本做盲测 A/B,确认改动是真改进再提交。

实战案例:体检一份脏数据订单表

准备 orders.csv:

order_id,customer,amount,status,note
1,张三,99.5,paid,
2,李四,,pending,
3,张三,250.0,paid,VIP
4,,12.0,paid,
5,王五,12.0,paid,

在会话里 /csv-profiler orders.csv,输出报告:

列 类型 空值率 基数 高频值 / 范围
order_id numeric 0.0% 5 min 1 / max 5
customer text 20.0% 3 张三(2); 李四(1); 王五(1)
amount numeric 20.0% 4 min 12 / max 250
status text 0.0% 2 paid(4); pending(1)
note text 80.0% 2 VIP(1)

模型据此点评:customer、amount 各缺 1 行(20%)需补全或确认;note 空值率 80% 几乎无信息量,建议删除;status 基数 2 适合做分组维度。一份本要人工翻半小时的脏表,秒级出结论。

整体工作流程

flowchart TD
    A[用户: 帮我体检这个CSV] --> B{description 匹配?}
    B -- 是 --> C[加载 SKILL.md 正文进上下文]
    B -- 否 --> Z[不触发本Skill]
    C --> D[模型读导航层<br/>决定跑哪个脚本]
    D --> E["执行 python3<br/>${CLAUDE_SKILL_DIR}/scripts/profile.py<br/>(allowed-tools 免审批)"]
    E --> F[脚本输出结构化表格]
    F --> G[模型: 表格原样呈现<br/>+ 异常列自然语言点评]
    G --> H[用户拿到数据画像报告]
    I[skill-creator 评测] -.基准对比.-> B
    I -.A/B盲测.-> D

延伸阅读

训练营适用性评估

参考来源

  1. Extend Claude with skills — Claude Code 官方文档 — frontmatter 全字段、${CLAUDE_SKILL_DIR}、动态上下文注入、bundled-script 模式(codebase-visualizer 示例)与 skill-creator 评测的权威来源
  2. Advanced: Progressive Disclosure, Bundled Scripts, and Subagent Orchestration — 把 SKILL.md 当"导航员"、scripts/ 挂载、渐进式披露保持上下文低成本的进阶架构讲解
  3. Evaluating skill output quality — agentskills.io — Agent Skills 开放标准的评测文件格式与"有/无 Skill 基线对比"迭代工作流
  4. Claude Agent Skills: A Complete 2025 Developer Guide — 对 Skills 作为"指令+脚本+资源"模块化能力包的开发者视角综述

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入