本教程面向已经掌握Skill基础创建、希望系统化验证Skill质量的开发者。你将学会:用evals.json定义测试用例,用skill-creator四大模式驱动创建-测试-改进-基准的完整闭环,掌握触发率调优、回归检测、A/B盲测三项核心评测能力,最终构建一个经过数据验证的生产级Skill。适用人群:有3个月以上Claude Code使用经验、已创建过至少一个自定义Skill的开发者。
skill-creator是Anthropic官方提供的Skill开发工具链插件,2026年3月更新后新增Eval、Benchmark、Improve三大模式。
# 方式一:从官方仓库安装
claude plugin add anthropics/claude-plugins-official --plugin skill-creator
# 方式二:从插件市场安装
claude plugin install skill-creator
# 验证安装
claude /skill-creator
安装完成后,/skill-creator命令可用。它提供四个核心模式:
graph TD
A[用户需求] --> B[Create模式<br/>创建Skill]
B --> C[Eval模式<br/>运行测试用例]
C --> D{通过率 >= 80%?}
D -->|否| E[Improve模式<br/>优化描述/指令]
E --> C
D -->|是| F[Benchmark模式<br/>基准对比]
F --> G{Skill优于基线?}
G -->|否| H[重新设计Skill]
H --> B
G -->|是| I[生产发布]
skill-creator的评测系统不是单次问答,而是四个独立Agent在隔离上下文中并行工作:
| Agent | 职责 | 输入 | 输出 |
|---|---|---|---|
| Executor | 执行Skill,运行测试prompt | evals.json中的prompt | 实际输出 + metrics.json |
| Grader | 评判输出是否符合预期 | expectations列表 + Executor输出 | grading.json(通过/失败) |
| Comparator | 盲测A/B对比 | 两组匿名输出 | 偏好判定 |
| Analyzer | 聚合分析,发现模式 | 所有grading + timing数据 | 改进建议 |
核心数据文件流转:
skill-name/
├── SKILL.md # 被测Skill本体
├── evals.json # 测试用例定义(你编写)
├── grading.json # Grader评判结果(自动生成)
├── metrics.json # 运行时统计(工具调用、步骤数)
├── timing.json # 墙钟时间与Token消耗
└── history.json # 版本迭代记录
sequenceDiagram
participant User as 开发者
participant SC as skill-creator
participant Exec as Executor Agent
participant Grade as Grader Agent
participant Anal as Analyzer Agent
User->>SC: /skill-creator eval
SC->>Exec: 加载evals.json中的prompt
loop 每个测试用例
Exec->>Exec: 在隔离context中运行Skill
Exec->>Grade: 输出结果
Grade->>Grade: 逐条检查expectations
end
Grade->>Anal: 汇总grading.json
Anal->>Anal: 分析失败模式、Token分布
Anal->>User: 评测报告 + 改进建议
evals.json是评测的核心。它定义了一组测试prompt和对应的期望输出。这是你的Skill的"单元测试"。
{
"skill_name": "deploy-checker",
"version": "1.0.0",
"evals": [
{
"id": "eval-001",
"category": "trigger",
"prompt": "检查一下我的代码是否可以部署到生产环境",
"expected_output": "应该执行部署就绪检查,分析git状态、测试覆盖率、构建状态",
"expectations": [
{
"type": "contains",
"value": "部署",
"description": "输出应包含部署相关术语"
},
{
"type": "tool_used",
"value": "Bash",
"description": "应使用Bash工具检查git/测试状态"
},
{
"type": "not_contains",
"value": "直接部署",
"description": "不应建议直接部署,而是先做检查"
}
]
},
{
"id": "eval-002",
"category": "functional",
"prompt": "我改了auth模块,帮我看看能不能安全上线",
"expected_output": "应重点检查认证相关的安全问题",
"expectations": [
{
"type": "contains",
"value": "安全",
"description": "应提及安全检查"
},
{
"type": "file_read",
"value_pattern": "auth",
"description": "应读取auth相关文件"
},
{
"type": "structured_output",
"description": "输出应有结构化的检查清单"
}
]
},
{
"id": "eval-003",
"category": "negative",
"prompt": "帮我写一个Python排序算法",
"expected_output": "不应触发此Skill",
"expectations": [
{
"type": "not_triggered",
"description": "此prompt不应触发deploy-checker"
}
]
}
]
}
| type | 含义 | value格式 |
|---|---|---|
contains |
输出必须包含指定文本 | 字符串 |
not_contains |
输出不能包含指定文本 | 字符串 |
tool_used |
必须使用了指定工具 | 工具名(Read/Bash/Grep等) |
file_read |
必须读取了匹配的文件 | 正则表达式 |
not_triggered |
Skill不应被触发 | 无需value |
structured_output |
输出应有结构化格式 | 可选描述 |
custom |
自定义判断逻辑 | 自然语言描述 |
触发测试(trigger):验证Skill是否在正确的时机激活。这是最基础也最关键的测试——如果Skill不触发,一切都是空谈。
{
"id": "trigger-positive-001",
"category": "trigger",
"prompt": "准备上线,帮我做最后检查",
"expectations": [
{"type": "triggered", "description": "应触发deploy-checker"}
]
}
功能测试(functional):验证Skill执行后的输出质量。检查是否按预期流程工作。
{
"id": "func-001",
"category": "functional",
"prompt": "检查部署就绪状态",
"expectations": [
{"type": "tool_used", "value": "Bash", "description": "运行git/test命令"},
{"type": "contains", "value": "检查清单", "description": "输出检查清单"},
{"type": "contains", "value": "风险", "description": "识别潜在风险"}
]
}
负面测试(negative):验证Skill在不应触发时保持沉默。防止误触发浪费上下文。
{
"id": "neg-001",
"category": "negative",
"prompt": "这段CSS怎么居中?",
"expectations": [
{"type": "not_triggered", "description": "CSS问题不应触发部署检查"}
]
}
让我们从零构建一个完整的、经过评测验证的Skill:deploy-checker(部署就绪检查器)。
mkdir -p ~/.claude/skills/deploy-checker
cd ~/.claude/skills/deploy-checker
---
name: deploy-checker
description: >
检查代码是否准备好部署到生产环境。分析git状态、测试覆盖率、
构建状态和安全风险。Use when the user asks about deploying,
going to production, release readiness, or pre-deploy checks.
argument-hint: [environment]
---
# Deploy Readiness Checker
## Overview
评估当前代码变更是否可以安全部署。通过多层检查生成结构化的就绪报告。
## Pre-check: Dynamic Context
!`git status --short 2>/dev/null || echo "Not a git repo"`
!`git log --oneline -5 2>/dev/null || echo "No git history"`
!`git diff --stat HEAD 2>/dev/null || echo "No uncommitted changes"`
## Steps
### Step 1: Change Analysis
1. Use `Read` to examine each modified file from the git status above
2. Classify changes by impact level:
- **CRITICAL**: auth, payment, database schema, config changes
- **HIGH**: API endpoints, business logic, data processing
- **MEDIUM**: UI components, documentation, tests
- **LOW**: formatting, comments, dependencies
### Step 2: Test Coverage Check
1. Run `Bash` to check test status: look for test commands in package.json/Makefile
2. Identify untested changed files
3. Flag any modified critical files without corresponding test changes
### Step 3: Security Scan
For each CRITICAL/HIGH change, check:
- No hardcoded secrets (API keys, passwords, tokens)
- No SQL injection patterns (string concatenation in queries)
- No exposed debug endpoints
- Auth changes follow security best practices
### Step 4: Dependency Check
1. Check for new dependencies in package.json/requirements.txt
2. Flag any unknown or low-maintenance packages
3. Verify lock files are updated
## Output Format
### Deploy Readiness Report
| Check | Status | Details |
|-------|--------|---------|
| Change Impact | ✅/⚠️/❌ | Summary of change classification |
| Test Coverage | ✅/⚠️/❌ | Coverage of changed files |
| Security | ✅/⚠️/❌ | Security issues found |
| Dependencies | ✅/⚠️/❌ | New dependency assessment |
### Risk Items (if any)
For each risk:
- **File**: `path/to/file:line`
- **Severity**: CRITICAL / HIGH / MEDIUM / LOW
- **Issue**: Description
- **Recommendation**: How to fix
### Verdict
- **READY**: All checks pass, safe to deploy
- **READY WITH CAUTION**: Minor issues, document risks
- **NOT READY**: Blocking issues found, do not deploy
## Error Handling
- If not in a git repo: report "No git repository detected, limited checks available"
- If no test framework found: report "No test framework detected, manual testing required"
- If build fails: report as CRITICAL blocking issue
注意这个Skill使用了动态上下文注入(!git status --short``语法)——在Skill被加载时,这些命令会先执行,输出结果替换占位符。Claude看到的不是命令,而是实际的git状态。
在同一目录创建evals.json:
{
"skill_name": "deploy-checker",
"version": "1.0.0",
"evals": [
{
"id": "trigger-001",
"category": "trigger",
"prompt": "我的代码能上线了吗",
"expected_output": "触发部署就绪检查",
"expectations": [
{"type": "triggered", "description": "应触发deploy-checker"}
]
},
{
"id": "trigger-002",
"category": "trigger",
"prompt": "准备发布到生产环境,帮我把关",
"expected_output": "触发部署就绪检查",
"expectations": [
{"type": "triggered", "description": "应触发deploy-checker"}
]
},
{
"id": "trigger-003",
"category": "trigger",
"prompt": "pre-deploy check for the latest changes",
"expected_output": "触发部署就绪检查",
"expectations": [
{"type": "triggered", "description": "英文prompt也应触发"}
]
},
{
"id": "neg-001",
"category": "negative",
"prompt": "帮我写一个二叉树的层序遍历",
"expected_output": "不应触发此Skill",
"expectations": [
{"type": "not_triggered", "description": "算法问题不相关"}
]
},
{
"id": "neg-002",
"category": "negative",
"prompt": "这段代码的时间复杂度是多少",
"expected_output": "不应触发此Skill",
"expectations": [
{"type": "not_triggered", "description": "复杂度分析不相关"}
]
},
{
"id": "func-001",
"category": "functional",
"prompt": "检查我的代码能不能部署",
"expected_output": "生成结构化的部署就绪报告",
"expectations": [
{"type": "tool_used", "value": "Bash", "description": "执行git/test命令"},
{"type": "contains", "value": "检查", "description": "包含检查相关内容"},
{"type": "structured_output", "description": "输出应为结构化报告"}
]
},
{
"id": "func-002",
"category": "functional",
"prompt": "我刚改了支付模块,能上线吗",
"expected_output": "重点检查支付模块安全性",
"expectations": [
{"type": "tool_used", "value": "Bash", "description": "检查git差异"},
{"type": "contains", "value": "安全", "description": "支付模块必须安全检查"},
{"type": "contains", "value": "CRITICAL", "description": "支付变更应标记为高影响"}
]
}
]
}
在Claude Code中执行:
/skill-creator eval deploy-checker
skill-creator会:
1. 读取deploy-checker/evals.json
2. 为每个测试用例启动一个独立的Executor Agent
3. Executor执行prompt,记录所有工具调用和输出
4. Grader Agent逐条检查expectations
5. 汇总结果到grading.json
评测完成后,你将看到类似输出:
━━━ Eval Report: deploy-checker v1.0.0 ━━━
📊 Summary: 5/7 passed (71.4%)
✅ trigger-001 [trigger] "我的代码能上线了吗" → TRIGGERED
✅ trigger-002 [trigger] "准备发布到生产环境..." → TRIGGERED
✅ trigger-003 [trigger] "pre-deploy check..." → TRIGGERED
✅ neg-001 [negative] "帮我写一个二叉树..." → NOT TRIGGERED ✓
✅ neg-002 [negative] "这段代码的时间..." → NOT TRIGGERED ✓
❌ func-001 [functional] "检查我的代码能不能..."
→ FAIL: expectation "structured_output" not met
❌ func-002 [functional] "我刚改了支付模块..."
→ FAIL: "CRITICAL" not found in output
📈 Metrics:
Total tokens: 12,847
Avg duration: 8.3s per eval
Tools used: Bash(12), Read(8), Grep(3)
两个功能测试失败: 1. func-001:输出缺少结构化格式——说明SKILL.md的指令不够明确 2. func-002:未将支付模块标记为CRITICAL——说明分类逻辑需要加强
触发测试全部通过,但如果你在更大规模的测试中发现触发问题,Improve模式可以分析description字段并给出优化建议。
运行:
/skill-creator improve deploy-checker --focus trigger
Analyzer Agent会检查description中的关键词与测试prompt的匹配度,生成优化建议:
━━━ Trigger Analysis ━━━
Current description:
"检查代码是否准备好部署到生产环境。分析git状态、测试覆盖率、
构建状态和安全风险。Use when the user asks about deploying..."
Suggestions:
1. ADD trigger phrase: "can I release", "上线", "发布"
2. ADD negative trigger: "Do NOT use for coding questions, algorithm help"
3. IMPROVE: Include "pre-deploy" as explicit trigger keyword
Optimized description:
"检查代码变更是否准备好部署到生产环境。分析git状态、测试覆盖率、
构建状态和安全风险。Use when the user asks about deploying, release
readiness, going to production, pre-deploy checks, 上线检查, or 发布.
Do NOT use for general coding questions or algorithm help."
针对func-001和func-002的失败,改进SKILL.md中的指令。
关键改进点: 1. 在Output Format部分明确要求使用Markdown表格 2. 在Step 1的CRITICAL分类中明确列出"payment"关键词
改进后重新运行评测:
/skill-creator eval deploy-checker
━━━ Eval Report: deploy-checker v1.1.0 ━━━
📊 Summary: 7/7 passed (100%) ✅
📈 Tokens: 14,203 (+10%) | Avg duration: 9.1s
所有测试通过,Token消耗轻微增加(因为指令更详细了),但质量达标。
这是最关键的验证:你的Skill是否真的比裸模型表现更好?
/skill-creator benchmark deploy-checker
Benchmark模式会并行运行两组测试: - with_skill:加载SKILL.md后运行evals - without_skill:不加载Skill,直接运行相同的prompt
Comparator Agent进行盲测对比——它不知道哪组输出来自哪个版本。
━━━ Benchmark Report: deploy-checker ━━━
┌─────────────────┬────────────┬──────────────┐
│ Metric │ With Skill │ Without Skill│
├─────────────────┼────────────┼──────────────┤
│ Pass Rate │ 100% (7/7) │ 42.9% (3/7) │
│ Avg Tokens │ 14,203 │ 9,812 │
│ Avg Duration │ 9.1s │ 5.3s │
│ Structure Score │ 4.2/5 │ 1.8/5 │
│ Completeness │ 92% │ 45% │
│ Consistency │ 100% │ 28% │
└─────────────────┴────────────┴──────────────┘
Verdict: SKILL IMPROVES OUTPUT QUALITY ✅
- +57% pass rate improvement
- +133% structure score
- +104% completeness
- +257% consistency across runs
- Token cost: +45% (acceptable trade-off)
裸模型能处理简单的"检查代码"请求,但: - 输出格式不一致(每次不同结构) - 经常遗漏安全检查步骤 - 不了解你的项目约定 - 对支付等敏感模块缺乏特殊处理
你的Skill通过编码这些知识,显著提升了输出的一致性和完整性。
当Claude模型更新时,重新运行Benchmark:
/skill-creator benchmark deploy-checker --compare previous
这会将新模型的结果与上次的历史记录对比。如果发现通过率下降,说明存在回归,需要调整Skill。
对于大型Skill,评测可能耗时很长。skill-creator支持多Agent并行:
# 通过设置环境变量控制并行度
export SKILL_CREATOR_PARALLEL=4
# 运行评测(自动并行化)
/skill-creator eval deploy-checker
每个测试用例在一个隔离的Agent中运行,互不干扰,避免上下文污染。
当你不确定改进是否真的有效时,使用A/B盲测:
/skill-creator benchmark deploy-checker --ab-test
Comparator Agent会在不知道版本标签的情况下评判两组输出。这消除了确认偏差——有时你以为的"改进"实际上降低了质量。
对于复杂Skill,建议按优先级分层管理测试用例:
{
"skill_name": "deploy-checker",
"evals": [
{
"id": "P0-critical-001",
"priority": "P0",
"comment": "必须#1通过的用例,失败即阻塞发布"
},
{
"id": "P1-important-001",
"priority": "P1",
"comment": "应在Top 3中,允许偶尔失败"
},
{
"id": "P2-nice-001",
"priority": "P2",
"comment": "能触发就好,排名不重要"
}
]
}
优先级定义: - P0:阻塞级,必须100%通过。任何失败意味着Skill不可用 - P1:重要级,应>=90%通过。偶尔失败可接受 - P2:辅助级,>=70%通过即可
将评测集成到CI/CD中,确保每次修改都经过验证:
#!/bin/bash
# ci-skill-eval.sh
SKILL_NAME=$1
PASS_THRESHOLD=80
# 运行评测
claude -p "/skill-creator eval $SKILL_NAME --json > eval-results.json"
# 解析通过率
PASS_RATE=$(python3 -c "
import json
with open('eval-results.json') as f:
data = json.load(f)
print(data['summary']['pass_rate'])
")
# 判断是否通过
if (( $(echo "$PASS_RATE < $PASS_THRESHOLD" | bc -l) )); then
echo "❌ Skill $SKILL_NAME eval failed: ${PASS_RATE}% < ${PASS_THRESHOLD}%"
exit 1
else
echo "✅ Skill $SKILL_NAME eval passed: ${PASS_RATE}%"
exit 0
fi
在GitHub Actions中使用:
name: Skill Eval
on: [pull_request]
jobs:
eval:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run Skill Evals
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
./ci-skill-eval.sh deploy-checker
Anthropic在官方博客中区分了两类Skill,它们的评测重点不同:
这类Skill帮助Claude做到裸模型做不好或做不稳定的事。例如:专业级的文档排版、复杂的安全审计。
评测重点: - 与基线对比:裸模型 vs Skill的输出质量差异 - 过期检测:模型升级后重新运行无Skill基线,如果裸模型已经能做好,说明Skill可能需要退役 - 一致性:多次运行的输出质量方差
graph LR
A[模型升级] --> B[运行无Skill基线]
B --> C{基线通过率?}
C -->|<80%| D[Skill仍然必要<br/>继续维护]
C -->|>=80%| E[Skill可能过期<br/>考虑简化或退役]
E --> F[运行A/B对比]
F --> G{Skill仍优于基线?}
G -->|是| D
G -->|否| H[退役Skill]
这类Skill不教Claude"怎么做",而是告诉它"去哪里找信息、按什么顺序处理"。例如:公司周报生成流程、代码审查checklist。
评测重点: - 流程忠实度:是否严格遵循定义的步骤顺序 - 数据源完整性:是否从所有指定来源获取了信息 - 输出格式一致性:每次运行的结构是否一致
这类Skill更耐用——模型越强,执行效果越好。评测时应关注忠实度而非绝对质量。
让我们把上述所有步骤串起来,演示一个完整的Skill生命周期:
flowchart TB
subgraph Phase1["阶段一:创建"]
A1[识别重复工作流] --> A2[编写SKILL.md]
A2 --> A3[编写evals.json<br/>5+测试用例]
end
subgraph Phase2["阶段二:验证"]
B1[运行Eval模式] --> B2{通过率?}
B2 -->|<80%| B3[分析失败用例]
B3 --> B4[改进SKILL.md]
B4 --> B1
B2 -->|>=80%| B5[进入Benchmark]
end
subgraph Phase3["阶段三:基准"]
B5 --> C1[运行with/without对比]
C1 --> C2{Skill优于基线?}
C2 -->|否| C3[重新评估Skill价值]
C3 --> A2
C2 -->|是| C4[记录benchmark基线]
end
subgraph Phase4["阶段四:维护"]
C4 --> D1[模型更新时重跑Benchmark]
D1 --> D2{回归?}
D2 -->|是| B3
D2 -->|否| D3[发布/继续使用]
end
Phase1 --> Phase2 --> Phase3 --> Phase4
| 阶段 | 核心指标 | 目标值 | 工具 |
|---|---|---|---|
| 创建 | 测试用例覆盖度 | >=5个,覆盖3种类别 | 手动编写 |
| 验证 | Eval通过率 | >=80% | skill-creator eval |
| 基准 | vs无Skill提升 | >=20%通过率提升 | skill-creator benchmark |
| 维护 | 回归检测间隔 | 每次模型更新后 | CI自动化 |
/skill-name调用原因:description字段不够精确,缺少关键触发词。
解决:使用Improve模式优化description。关键是加入"Use when..."句式和多种表述的同义短语。官方数据显示,优化description后触发准确率可从61%提升至88%。
# 改进前
description: Helps with deployment
# 改进后
description: >
Checks code readiness for production deployment. Analyzes git status,
test coverage, build state, and security risks. Use when the user
asks about deploying, release readiness, going to production,
pre-deploy checks, 上线检查, or 发布.
原因:evals.json中的skill_name与SKILL.md目录名不匹配。
解决:确保三处一致:
1. 目录名:deploy-checker/
2. SKILL.md中name字段:name: deploy-checker
3. evals.json中skill_name:"skill_name": "deploy-checker"
原因:LLM的随机性导致输出波动。
解决:使用Benchmark模式多次运行(默认3-5次),取平均值。关注通过率的置信区间而非单次结果。
# 运行5次取平均
/skill-creator benchmark deploy-checker --runs 5
原因:SKILL.md过长或动态注入的上下文过多。
解决:
1. 将详细参考文档移至references/子目录,SKILL.md中只保留核心指令
2. 限制动态注入命令的输出:!git log --oneline -5`而非完整log
3. 使用context: fork`让Skill在隔离上下文中运行,不污染主对话
决策框架: 1. 运行Benchmark,对比无Skill基线 2. 如果无Skill基线通过率>=90%,且Skill无额外增益——考虑退役 3. 如果Skill是Encoded Preference型——通常不应退役,因为模型越强执行越好 4. 如果Skill是Capacity Uplift型——裸模型已经能做到,可以退役
| 维度 | 评估 |
|---|---|
| 适合训练营类型 | AI工程训练营、Claude Code进阶训练营 |
| 学员基础要求 | 已有Skill创建经验,理解YAML和Markdown |
| 预计教学时长 | 3-4小时(含实操) |
| 实操占比 | 70%(大量时间用于编写evals、运行评测、分析结果) |
| 所需环境 | 每人一个Git仓库 + Claude Code + skill-creator插件 |
| 课前准备 | 学员需提前创建一个简单Skill带到课堂 |
| 最佳分组方式 | 2人一组,互相编写对方Skill的测试用例 |
[!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 等场景全覆盖。
