首页 › tutorials › 造Mock数据Skill:一键填充测试数据

Claude Code Skills 开发实战:从零造一个 Mock 数据生成 Skill

概述

本教程面向已装通 Claude Code、想掌握 Skills 开发全流程的开发者。你将从零创建一个Mock 数据生成 Skill——输入一个数据结构描述,Claude 自动产出符合约束的假数据(姓名、身份证、手机号、订单、嵌套对象、数组),并学会 SKILL.md frontmatter 的触发词设计、渐进披露(progressive disclosure)、脚本捆绑、权限收敛、触发准确性测试与团队分享。学完你能把任意重复性工作封装成"一句话触发"的能力,而不是每次都重写提示词。

前置条件


一、先理解:Skill 到底是什么

很多人把 Skill、MCP、子代理(Subagent)混为一谈。一张表区分清楚:

能力载体 本质 何时加载 适合做什么
Skill 一个目录 + SKILL.md 指令包(可带脚本) 触发时才读正文(渐进披露) 教 Claude "怎么做某类事"的流程与约定
MCP 服务器 独立进程,暴露 tools/resources 始终连接 给 Claude 新的"手"(外部 API、数据库)
Subagent 独立上下文的代理实例 委派时启动 隔离上下文、并行处理大任务

Skill 最轻、最适合"把团队规范 / 重复套路固化下来"。它的杀手锏是渐进披露:

flowchart LR
    A["启动会话"] --> B["仅加载所有 Skill 的<br/>name + description"]
    B --> C{"用户输入<br/>是否匹配某 Skill?"}
    C -->|匹配| D["读取该 Skill 的 SKILL.md 正文"]
    C -->|不匹配| E["不加载,省 token"]
    D --> F{"正文是否引用<br/>脚本/参考文档?"}
    F -->|引用| G["按需读取 scripts/ references/"]
    F -->|不引用| H["直接执行"]
    G --> H

这意味着你的 Skill 可以塞进几千字的详细规则和几十个脚本,而日常会话零开销——因为正文只在被触发时才进上下文。理解这一点,你就不会再把所有规则堆进 CLAUDE.md 把全局上下文撑爆了。

Skill 存放位置有两种作用域:


二、步骤 1:用 skill-creator 生成脚手架

Claude Code 内置了 skill-creator 能力。最稳的起手式是直接让它帮你生成目录骨架,而不是手敲。

操作:在 Claude Code 交互模式里输入

/skill-creator 帮我创建一个名为 mock-data 的 Skill,作用是根据用户描述的数据结构生成贴近真实的 Mock 测试数据

预期结果:Claude 会在 .claude/skills/mock-data/ 下生成:

.claude/skills/mock-data/
├── SKILL.md          # 主指令文件(含 frontmatter)
├── references/        # 可选:详细参考文档
└── scripts/           # 可选:可执行脚本
    └── gen_mock.py

常见问题:生成的 description 太笼统(如 "生成 mock 数据"),导致触发不准。这正是下一步要重写的重点。


三、步骤 2:写好 frontmatter —— 整个 Skill 最关键的 5 行

frontmatter 不是装饰,它是 Claude 判断"要不要触发这个 Skill"的唯一依据(正文此时还没加载)。把 description 写废了,Skill 就永远沉睡。

打开 SKILL.md,把 frontmatter 改成:

---
name: mock-data
description: Generate realistic mock/test data (Chinese names, IDs, phone numbers, addresses, nested JSON, arrays) from a data structure description. Use when the user needs fake sample data, test fixtures, seed data, dummy JSON for API development, or asks to "造点测试数据/生成假数据/mock 一下". Outputs deterministic, constraint-respecting data.
---

设计 description 的四条铁律:

  1. 前两句话写"做什么 + 什么时候用":Claude 的触发匹配高度依赖开头。把动词和场景词放前面。
  2. 塞进真实的触发词:用户不会说"请生成符合约束的测试夹具",他们会说"造点假数据"、"mock 一下"、"来几条测试用户"。把这些口语词写进去。
  3. 声明输出特征:"deterministic, constraint-respecting" 告诉 Claude 期望的产出质量。
  4. 同时覆盖中英文:你的用户既可能英文也可能中文提问。

常见问题:"description 写得越详细越好吗?"——错。description 是给触发路由器看的,控制在 3-5 句。详细规则写进正文,正文不会参与初始匹配。


四、步骤 3:写 SKILL.md 正文 —— 用祈使句,像写给新同事的 SOP

正文是触发后才加载的"操作手册"。风格要像给一个聪明但不知情的新同事写的 SOP:直接、可执行、带例子。

# Mock Data Generation

You generate realistic mock data that respects the user's stated constraints.
Do NOT hallucinate fields the user didn't ask for. When a field type is
ambiguous, ask one clarifying question, then proceed.

## Workflow

1. Parse the user's data structure description into a field list.
2. For each field, pick the most realistic generator (see references/field-types.md).
3. Respect constraints: count, uniqueness, value ranges, locale, format.
4. Output as the requested format (JSON / CSV / SQL INSERT / Python dict).
5. If count > 50, stream the output to a file instead of printing inline.

## Realism rules

- Chinese names: real-style surnames + given names, not "张三"/"李四" repeats.
- Phone numbers: start with valid Chinese prefixes (13x/15x/17x/18x/19x).
- ID numbers: valid checksum (use scripts/gen_mock.py --id to compute).
- Dates: spread across a plausible range, not all "2026-01-01".
- Money: realistic magnitude per domain (salary 5k–50k, not 999999).

## When to stop and ask

- If the user requests a field you cannot map to any generator.
- If two constraints conflict (e.g., "age between 0-3 AND employed").
- If output would exceed 200 rows — confirm the file path first.

注意几点: - 祈使句开头:"Parse…", "Respect…", "Output…",不要写 "你应该尽量…" - 给边界:"count > 50 就写文件"、"冲突就停下来问",把判断权显式化 - 反例约束:"不要重复张三李四"、"不要把日期都设成同一天"——告诉它不要做什么,比告诉它做什么更省事


五、步骤 4:捆绑脚本 —— 让 Skill 有真正的"手"

光靠 Claude 生成 ID 号的校验位很容易算错。把确定性的活交给脚本,Claude 只负责编排。在 scripts/gen_mock.py 写一个零依赖生成器:

#!/usr/bin/env python3
"""Mock data generator. Zero external deps.
Usage: gen_mock.py --field id --count 5
       gen_mock.py --field phone --count 3
"""
import argparse, json, random, sys

SURNAME = list("王李张刘陈杨黄赵吴周徐孙马朱胡郭何高林罗")
GIVEN = ["伟","芳","娜","秀英","敏","静","丽","强","磊","洋",
         "艳","勇","军","杰","涛","明","超","秀兰","霞","平"]
PHONE_PREFIX = ["133","135","137","150","159","170","180","188","199"]

def gen_id():
    # Simplified 18-digit ID with valid-ish region + checksum
    region = random.choice(["110101","310115","440305","510107"])
    birth = f"{random.randint(1960,2008)}{random.randint(1,12):02d}{random.randint(1,28):02d}"
    seq = f"{random.randint(0,999):03d}"
    base = region + birth + seq
    # Weighted checksum (GB 11643-1999)
    w = [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2]
    code = "10X98765432"
    s = sum(int(d)*wi for d, wi in zip(base, w))
    return base + code[s % 11]

def gen_name():
    return random.choice(SURNAME) + "".join(random.sample(GIVEN, random.randint(1,2)))

def gen_phone():
    return random.choice(PHONE_PREFIX) + "".join(str(random.randint(0,9)) for _ in range(8))

GENERATORS = {"id": gen_id, "name": gen_name, "phone": gen_phone}

if __name__ == "__main__":
    p = argparse.ArgumentParser()
    p.add_argument("--field", required=True)
    p.add_argument("--count", type=int, default=1)
    args = p.parse_args()
    fn = GENERATORS.get(args.field)
    if not fn:
        sys.exit(f"unknown field: {args.field}")
    print(json.dumps([fn() for _ in range(args.count)], ensure_ascii=False))

然后在 SKILL.md 正文里告诉 Claude 怎么用:

## Using the bundled script

For ID numbers, phone numbers, and names, prefer calling the bundled script
to guarantee format validity:

    python3 scripts/gen_mock.py --field id --count 10
    python3 scripts/gen_mock.py --field phone --count 5

Compose the script's output into the larger structure the user asked for.
Do NOT hand-compute ID checksums — always delegate to the script.

这是 Skill 区别于普通提示词的核心价值:把确定性的、容易出错的计算固化成代码,把语义理解交给模型。

常见问题:脚本路径用相对还是绝对?SKILL.md 里写相对路径(scripts/gen_mock.py),Claude 运行时会解析到 Skill 目录下,团队 clone 仓库后无需改路径。


六、步骤 5:渐进披露 —— references/ 装详细规则

正文保持精炼,把"各字段怎么生成"的查表式细节挪进 references/field-types.md,只在需要时加载:

# references/field-types.md

| 字段语义 | 生成策略 | 示例 |
|---------|---------|------|
| email | 拼音名+域名,域名随机自 gmail/qq/163 | `[email protected]` |
| address | 省+市+区+随机街道门牌 | `广东省深圳市南山区科技园路1号` |
| company | 行业词+公司类型 | `星河科技有限公司` |
| price | 按商品类目量级 | 电子产品 99–9999,生鲜 1–200 |
| timestamp | 最近 N 天内随机 ISO8601 | `2026-06-14T03:21:00Z` |
| boolean | 0.3–0.7 比例 True | `true` |
| enum | 从用户给的候选集随机 | `["active","pending","closed"]` |

正文里引用:

For the full field-type mapping table, consult references/field-types.md
when you encounter a field type not covered in the realism rules above.

这就是渐进披露的二层结构:frontmatter(总在)→ SKILL.md 正文(触发时在)→ references(按需在)。上下文成本随深度递减,能力却随深度递增。


七、步骤 6:测试触发准确性 —— 正反例对照

Skill 写完不算完,必须验证它在该触发时触发、不该触发时安静。开新会话,跑正反例:

应当触发的输入(期望命中): - "帮我 mock 10 条用户数据,要有姓名手机号身份证" - "造点测试数据,订单表,50 行" - "generate 5 fake user records with nested address" - "接口联调缺数据,给我点假的 JSON"

不应触发的输入(期望不命中): - "解释一下这段代码"(代码理解,无关) - "帮我写个单元测试"(已有专门的单测 Skill) - "mock 一下这个类"("mock" 在这里是测试替身,不是数据——若误触发,回到 description 加否定词:"Do NOT trigger for test doubles / mocking classes / mock objects in unit tests; this skill only generates fake DATA.")

常见问题:调试触发最有效的办法——直接问 Claude:"刚才那条输入,你为什么没/为什么用了 mock-data Skill?" 它会复述自己匹配到的关键词,据此微调 description。


八、步骤 7:用 allowed-tools 收敛权限

如果这个 Skill 只需要读描述、跑脚本、写文件,就别让它碰别的。在 frontmatter 加:

---
name: mock-data
description: ...
allowed-tools: Read, Write, Bash(python3 scripts/gen_mock.py:*)
---

Bash(python3 scripts/gen_mock.py:*) 是关键——只允许执行这一个脚本及其任意参数,杜绝 Skill 顺手跑别的命令。这把"教 Claude 怎么做"和"限定它能做什么"结合,遵循最小权限原则。


九、实战案例:一句话产出 1000 行订单测试数据

最终目录结构:

.claude/skills/mock-data/
├── SKILL.md
├── references/
│   └── field-types.md
└── scripts/
    └── gen_mock.py

在新会话里输入一句话:

给我 1000 条订单测试数据,字段:订单号、买家姓名、手机、收货地址、商品名、单价、数量、下单时间(近 30 天)、状态(paid/shipped/done)。输出 JSON 数组存到 orders.json。

Claude 的执行路径:

sequenceDiagram
    participant U as 用户
    participant C as Claude Code
    participant S as mock-data Skill
    participant P as gen_mock.py
    U->>C: 一句话需求
    C->>S: 命中 mock-data 触发词<br/>加载 SKILL.md
    S->>C: 返回 workflow + 调用规则
    C->>P: Bash: gen_mock.py --field phone --count 1000
    P-->>C: 返回合规手机号数组
    C->>P: Bash: gen_mock.py --field id --count 1000
    P-->>C: 返回合规身份证数组
    C->>C: 组装商品/地址/时间/状态<br/>(查 references/field-types.md)
    C->>U: 写入 orders.json (1000 行)
    C->>U: 汇总:字段、约束、行数

预期产出(截取):

[
  {"order_id":"ORD-20260710-0001","buyer":"陈艳霞","phone":"137xxxx2841",
   "address":"广东省深圳市南山区科苑南路8号","item":"无线蓝牙耳机",
   "unit_price":199,"qty":2,"ts":"2026-06-22T11:03:00Z","status":"paid"},
  {"order_id":"ORD-20260710-0002","buyer":"林涛","phone":"188xxxx7710",
   "address":"北京市海淀区中关村大街1号","item":"机械键盘",
   "unit_price":459,"qty":1,"ts":"2026-07-01T08:45:00Z","status":"shipped"}
]

对比"不写 Skill、每次手动提示":以前你要反复说明字段格式、手机号规则、价格量级,现在一句话搞定,且身份证/手机号格式由脚本保证永远合规。这就是 Skill 的复利——写一次,用无数次,每次质量稳定。


十、进阶:分享、版本与团队落地


延伸阅读


训练营适用性评估


参考来源

  1. Extend Claude with skills — Claude Code Docs — 官方权威:Skill 文件格式、frontmatter 字段、发现与调用规则
  2. Claude Code Skills Complete Guide: SKILL.md, MCP, Subagents & Teams (2026) — Skills 与 MCP/Subagents 的全景对比与渐进披露机制解析
  3. Claude Code Skill Frontmatter: Every YAML Option Explained — 十五个 frontmatter 字段的逐项语义与最佳实践
  4. Claude Skills Tutorial: Build Your First Skill — TECHSY — 从零构建首个 Skill 的实操教程与 skill-creator 用法
  5. Claude Code Skills Setup Guide (2026) — SKILL.md、frontmatter、渐进披露的逐步设置指南

[!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学通信知识星球海报-扫码加入