你已经学会了写 SKILL.md、配置 frontmatter、管理支持文件。但一个残酷的事实是——大部分 Skill 开发者从未验证过自己的 Skill 是否真的在"工作"。本教程聚焦 Skill 开发中最被忽视的环节:质量验证。你将学会使用 skill-creator 的 Evals 系统、构建 A/B 基准测试、诊断三大常见故障,并通过数据驱动的迭代流程持续提升 Skill 效果。
适用人群:已掌握 SKILL.md 基础写法的开发者,希望从"能用"升级到"好用且有数据证明"。
前置条件:
- Claude Code v2.1.145+
- 已安装 skill-creator 插件(/plugin add skill-creator)
- 了解 SKILL.md frontmatter 基本字段
- 有一个待优化的 Skill 项目
Skill 本质是文本提示词(text prompts),而文本提示词没有测试套件。传统 Skill 开发遵循一个危险的模式:
写 SKILL.md → 手动测试一次 → 发布 → 祈祷它工作 → 几周后焦虑它是否真的有效
这种方式存在两个致命盲区:
| 盲区 | 具体表现 |
|---|---|
| 触发盲区 | 不知道 Skill 是否在正确场景被激活 |
| 效果盲区 | 不知道 Skill 是否真正改善了输出质量 |
一个合格的 Skill 需要在三个轴上通过验证:
graph TD
A[Skill 质量三角] --> B[触发准确性<br/>Trigger Accuracy]
A --> C[功能正确性<br/>Functional Correctness]
A --> D[性能增益<br/>Performance Gain]
B --> B1[该触发时触发]
B --> B2[不该触发时不触发]
C --> C1[指令被完整遵循]
C --> C2[输出格式符合预期]
C --> C3[边界场景处理正确]
D --> D1[Token 消耗可控]
D --> D2[任务完成步数减少]
D --> D3[输出质量可量化提升]
skill-creator 插件在生成 Skill 后会自动提议创建测试用例。你也可以手动创建 evals.json 文件:
{
"skill_name": "wp-security-review",
"version": "1.0.0",
"test_cases": [
{
"id": "test-sqli-detection",
"prompt": "Review the security of includes/class-payment-handler.php",
"target_files": ["includes/class-payment-handler.php"],
"assertions": [
{
"type": "contains",
"field": "output",
"value": "SQL injection",
"description": "必须检测到 SQL 注入风险"
},
{
"type": "contains",
"field": "output",
"value": "[HIGH]",
"description": "必须包含严重级别标记"
},
{
"type": "not_contains",
"field": "output",
"value": "WC_Settings_API",
"description": "不应将 WC Settings API 误报为缺少 nonce"
}
]
},
{
"id": "test-output-format",
"prompt": "Run a security review on my plugin",
"target_files": ["woocommerce-pay-when-you-want.php"],
"assertions": [
{
"type": "contains",
"field": "output",
"value": "severity",
"description": "输出必须包含严重级别分类"
},
{
"type": "contains",
"field": "output",
"value": "PASSED",
"description": "必须列出通过的检查项"
}
]
}
]
}
Evals 系统支持多种断言类型:
| 断言类型 | 含义 | 使用场景 |
|---|---|---|
contains |
输出包含指定文本 | 验证关键信息是否出现 |
not_contains |
输出不包含指定文本 | 验证无假阳性 |
matches_regex |
输出匹配正则 | 验证格式化输出 |
json_path |
JSON 输出的路径值 | 验证结构化数据 |
custom |
自定义校验函数 | 复杂逻辑判断 |
为你的 Skill 设计 3-5 个测试场景,覆盖不同维度:
<!-- 测试场景规划文档 -->
## 场景 1:核心触发测试
- 输入:与 description 高度匹配的自然语言
- 预期:Skill 被自动激活,输出结构化结果
## 场景 2:边界触发测试
- 输入:与 Skill 相关但非精确匹配的模糊表述
- 预期:不触发或触发后正确判断不适用
## 场景 3:复杂输入测试
- 输入:包含多文件、多参数的复杂请求
- 预期:正确解析参数,按步骤执行
## 场景 4:错误恢复测试
- 输入:引用不存在的文件或无效参数
- 预期:优雅降级,给出有意义的错误提示
skill-creator 的基准测试并行启动两组 Agent:
graph LR
A[测试用例集合] --> B[Agent 组 A<br/>启用 Skill]
A --> C[Agent 组 B<br/>基线对照]
B --> D[结果收集器]
C --> D
D --> E[对比分析]
E --> F[通过率对比]
E --> G[Token 消耗对比]
E --> H[执行时间对比]
使用 skill-creator 运行基准测试的完整流程:
步骤 1:确保你的 Skill 已安装
# 在项目目录中
claude
# 在 Claude Code 中执行
/plugin add skill-creator
步骤 2:描述你的测试意图
请为我的 wp-security-review Skill 创建评估测试。
测试需要验证以下方面:
1. 能检测到 $_POST 未过滤输入
2. 能识别 SQL 拼接注入风险
3. 不会对 WooCommerce 原生钩子产生假阳性
4. 输出格式包含严重级别和通过项列表
步骤 3:skill-creator 自动执行
skill-creator 将执行以下操作:
evals.json 文件,包含断言典型的基准测试输出:
| 指标 | 有 Skill | 无 Skill(基线) | 变化 |
|---|---|---|---|
| 通过率 | 100%(21/21) | 90.5%(19/21) | +9.5% |
| 平均 Token | 74,427 | 69,734 | +6.7% |
| 平均耗时 | 276s | 307s | 快 9.9% |
解读要点:
判断阈值参考:
| 指标 | 可接受范围 | 需要优化 |
|---|---|---|
| 通过率 | >95% | <85% |
| Token 开销 | <20% 增量 | >40% 增量 |
| 耗时变化 | ±15% | 慢 30%+ |
症状:你明确希望 Skill 生效,但 Claude 完全忽略它。
根因分析:
flowchart TD
A[Skill 不触发] --> B{检查 description}
B -->|太模糊| C[添加具体动词和名词]
B -->|太具体| D[扩大关键词覆盖面]
B -->|长度超限| E[精简到 1536 字符内]
A --> F{检查 disable-model-invocation}
F -->|设为 true| G[移除该字段或改为 false]
A --> H{检查 paths}
H -->|已设置| I[确认 glob 模式匹配当前文件]
A --> J{检查 skillOverrides}
J -->|设为 off| K[在 settings 中改为 on]
修复策略:
策略 A:优化 description 字段
# ❌ 不好的 description
description: "Help with code quality"
# ✅ 好的 description
description: "Review PHP code for security vulnerabilities including SQL injection, XSS, CSRF, missing nonce verification. Use when user mentions security review, vulnerability scan, or code audit."
关键原则:description 的前 50 个字符权重最高。把最核心的触发场景放在最前面。
策略 B:使用 when_to_use 补充触发上下文
description: "Review PHP code for security vulnerabilities"
when_to_use: "Trigger when user asks about security, vulnerabilities, code audit, penetration testing, or mentions specific attacks like SQL injection or XSS"
策略 C:添加触发短语示例
when_to_use: |
Examples of user requests that should trigger this skill:
- "Check this code for security issues"
- "Is this file safe?"
- "Run a security audit"
- "Any vulnerabilities in this plugin?"
症状:Claude 在不相关的对话中也频繁加载你的 Skill。
根因与修复:
# 问题:description 太宽泛
description: "Review code and provide suggestions"
# 修复:限定领域和场景
description: "Review PHP plugin code specifically for WooCommerce security vulnerabilities. Only use for WordPress/WooCommerce plugin files."
高级修复:使用 paths 限制作用域
name: wp-security-review
description: "Review WooCommerce plugin PHP files for security vulnerabilities"
paths:
- "**/*.php"
- "wp-content/plugins/**"
- "woocommerce/**"
设置 paths 后,Claude 只在操作匹配路径的文件时才考虑加载此 Skill。
高级修复:使用 disable-model-invocation 完全手动控制
name: deploy-production
description: "Deploy application to production environment"
disable-model-invocation: true
设置为 true 后,只有用户手动输入 /deploy-production 才会触发,Claude 永远不会自动调用。适合部署、发布等有副作用的操作。
症状:Skill 被正确加载,但 Claude 的输出偏离了 Skill 中定义的格式或流程。
诊断清单:
flowchart TD
A[触发但不遵循] --> B{Skill 内容是否过长?}
B -->|超过 500 行| C[拆分到支持文件]
B -->|< 500 行| D{指令是否明确?}
D -->|模糊表述| E[用祈使句重写]
D -->|已明确| F{是否被压缩?}
F -->|多次 Skill 调用后| G[Auto-compaction 丢失内容<br/>前 5000 token 保留]
F -->|首次调用| H{指令优先级冲突?}
H -->|与 CLAUDE.md 矛盾| I[CLAUDE.md 优先级更高<br/>调整两者一致性]
H -->|无冲突| J[加强指令措辞<br/>使用 MUST/ALWAYS]
修复策略 A:结构化指令
# ❌ 模糊指令
When reviewing code, check for security issues and report them.
# ✅ 结构化指令
## Security Review Steps (execute in order)
1. READ the target file completely
2. SCAN for each vulnerability category:
- SQL injection: look for string concatenation in queries
- XSS: look for unescaped output functions
- CSRF: look for form submissions without nonce
3. CLASSIFY each finding by severity: [CRITICAL] [HIGH] [MEDIUM] [LOW]
4. FORMAT output as:
## Findings
- [SEVERITY] File:Line — Description
## Passed Checks
- Category name: No issues found
修复策略 B:控制 Skill 体积
Skill 内容在会话中持续存在,每一行都是持续的 Token 开销。Auto-compaction 时只保留前 5000 token。超过的部分会被截断。
<!-- SKILL.md 最佳实践 -->
## 核心指令(必须在 5000 token 内)
<!-- 最关键的步骤和格式要求 -->
## 详细参考
<!-- 可选:放到支持文件中 -->
- 完整漏洞清单见 [vulnerability-database.md](vulnerability-database.md)
- 输出模板见 [output-template.md](output-template.md)
修复策略 C:强化行为约束
## Mandatory Rules
You MUST follow these rules without exception:
1. ALWAYS classify findings by severity level
2. NEVER skip a vulnerability category
3. ALWAYS include "Passed Checks" section
4. NEVER suggest fixes that break WooCommerce compatibility
我们构建一个 code-review Skill,用于自动化代码审查,要求:
.claude/skills/code-review/
├── SKILL.md # 主指令文件
├── checklists/
│ ├── security.md # 安全检查清单
│ └── performance.md # 性能检查清单
├── templates/
│ └── review-output.md # 输出模板
└── scripts/
└── validate-output.sh # 输出格式验证脚本
---
name: code-review
description: "Review code for security vulnerabilities, performance issues, and style violations. Use when user asks for code review, PR review, or mentions code quality."
when_to_use: |
Trigger phrases: "review this code", "PR review", "code quality check",
"security review", "performance review", "any security issues?"
argument-hint: "[file-or-pr-number]"
allowed-tools: Read Grep Glob Bash(git diff *) Bash(git log *)
context: fork
agent: Explore
---
## Code Review Task
Review the following code changes: $ARGUMENTS
### Step 1: Gather Context
```!
git diff HEAD --unified=5
For each changed file, check:
Security (see checklists/security.md for full list): - SQL injection via string concatenation - XSS via unescaped output - Authentication/authorization bypass - Sensitive data exposure
Performance (see checklists/performance.md for full list): - N+1 query patterns - Unnecessary memory allocation - Missing pagination - Blocking I/O in async context
Use the template in templates/review-output.md:
| Severity | File:Line | Category | Issue | Suggestion |
|---|---|---|---|---|
| [LEVEL] | path:123 | Security | desc | fix |
### 5.4 创建支持文件
**checklists/security.md**:
```markdown
# Security Checklist
## Injection
- [ ] No string concatenation in SQL queries
- [ ] No eval() or exec() with user input
- [ ] No command injection vectors
## Authentication
- [ ] Password hashing uses modern algorithm (bcrypt/argon2)
- [ ] Session management follows best practices
- [ ] API endpoints validate authentication
## Data Exposure
- [ ] No sensitive data in logs
- [ ] No hardcoded credentials
- [ ] Error messages don't leak internals
scripts/validate-output.sh:
#!/bin/bash
# 验证 code-review Skill 输出格式
OUTPUT="$1"
# 检查必要段落
for section in "Review Summary" "Findings" "Approved Patterns"; do
if ! echo "$OUTPUT" | grep -q "$section"; then
echo "FAIL: Missing section '$section'"
exit 1
fi
done
# 检查严重级别标记
if ! echo "$OUTPUT" | grep -qE '\[(CRITICAL|HIGH|MEDIUM|LOW)\]'; then
echo "FAIL: No severity level markers found"
exit 1
fi
echo "PASS: Output format validated"
{
"skill_name": "code-review",
"version": "1.0.0",
"test_cases": [
{
"id": "detect-sqli",
"prompt": "Review the security of src/db/queries.ts",
"target_files": ["src/db/queries.ts"],
"setup": "Create a test file with string concatenation in SQL query",
"assertions": [
{
"type": "contains",
"field": "output",
"value": "SQL injection",
"description": "必须检测到 SQL 注入"
},
{
"type": "contains",
"field": "output",
"value": "[CRITICAL]",
"description": "SQL 注入必须标记为 CRITICAL"
},
{
"type": "contains",
"field": "output",
"value": "parameterized query",
"description": "必须建议参数化查询修复方案"
}
]
},
{
"id": "output-format",
"prompt": "Review PR #42",
"assertions": [
{
"type": "matches_regex",
"field": "output",
"value": "\\|\\s*\\[CRITICAL\\|HIGH\\|MEDIUM\\|LOW\\]\\s*\\|",
"description": "Findings 表格必须包含严重级别列"
},
{
"type": "contains",
"field": "output",
"value": "Review Summary",
"description": "必须包含审查摘要"
},
{
"type": "contains",
"field": "output",
"value": "Approved Patterns",
"description": "必须列出做得好的部分"
}
]
},
{
"id": "no-false-positive",
"prompt": "Review the error handling in src/utils/helpers.ts",
"assertions": [
{
"type": "not_contains",
"field": "output",
"value": "[CRITICAL]",
"description": "良好代码不应有 CRITICAL 发现"
},
{
"type": "contains",
"field": "output",
"value": "No issues found",
"description": "无问题时应有明确说明"
}
]
}
]
}
在 Claude Code 中执行:
> /skill-creator
我已创建了 code-review Skill,需要对其进行评估测试。
请基于 evals.json 运行 A/B 基准测试,对比有 Skill 和无 Skill 的表现。
skill-creator 将启动并行 Agent 组,完成后输出类似:
Benchmark Results for code-review v1.0.0
========================================
With Skill Baseline Delta
Pass Rate: 100% (9/9) 66.7% (6/9) +33.3%
Avg Tokens: 52,340 48,200 +8.6%
Avg Time: 184s 213s -13.6%
Assertion Details:
✅ detect-sqli: 3/3 passed
✅ output-format: 3/3 passed
✅ no-false-positive: 3/3 passed
flowchart TD
A[创建 Skill v0.1] --> B[运行 Evals]
B --> C{通过率 ≥ 95%?}
C -->|否| D[分析失败断言]
D --> E[诊断故障类型]
E --> F[修复 SKILL.md]
F --> B
C -->|是| G[运行 A/B Benchmark]
G --> H{性能增益可接受?}
H -->|Token 开销 >20%| I[优化指令精简度]
I --> G
H -->|是| J[发布 Skill]
J --> K[收集使用反馈]
K --> L[添加新测试用例]
L --> B
当你发现问题时,按以下优先级修复:
| 优先级 | 问题类型 | 影响 | 修复难度 |
|---|---|---|---|
| P0 | 不触发 | Skill 完全无效 | 低(改 description) |
| P1 | 触发但输出错误 | 误导用户 | 中(改指令逻辑) |
| P2 | 假阳性过多 | 降低信任度 | 中(加排除规则) |
| P3 | Token 开销过大 | 成本问题 | 低(精简内容) |
| P4 | 触发过于频繁 | 干扰其他工作 | 低(加 paths 或 disable) |
为你的 Skill 维护一个变更日志:
# CHANGELOG.md
## v1.1.0 (2026-05-20)
### Changed
- 优化 description 触发精确度(通过率从 85% 提升到 100%)
- 精简指令内容,Token 开销从 +15% 降至 +8.6%
- 添加 paths 限制,避免在非 PHP 文件上触发
### Added
- 新增 evals.json 基准测试(3 个测试场景,9 个断言)
- 新增 scripts/validate-output.sh 输出验证脚本
## v1.0.0 (2026-05-15)
### Added
- 初始版本,包含安全和性能检查清单
- 结构化输出模板
当 Skill 使用 !command`` 注入动态内容时,测试需要覆盖命令执行的各种结果:
<!-- 测试动态注入的注意事项 -->
## 场景:git diff 为空
当工作区干净时,!`git diff HEAD` 返回空输出。
Skill 应优雅处理此情况,输出"没有未提交的变更"。
## 场景:命令执行失败
当 gh CLI 未安装时,!`gh pr diff` 会失败。
使用 fallback 指令:如果 PR 数据获取失败,提示用户安装 GitHub CLI。
当 Skill 使用 context: fork 在子代理中运行时,需要额外验证:
# 子代理模式下 Claude 无法访问对话历史
# 确保 SKILL.md 包含完整的自包含指令
context: fork
agent: Explore
测试要点: - 子代理是否能独立完成任务(无对话上下文) - 返回主会话的结果是否完整 - 错误是否正确传播回主会话
当项目有多个 Skill 时,测试它们之间的交互:
## 交互测试场景
1. 同时触发 code-review 和 commit Skill
- 预期:code-review 先执行,commit 后执行
- 验证:commit 消息是否反映了 review 结果
2. code-review 和 deploy-production 冲突
- 预期:deploy 不会在 review 发现 CRITICAL 时自动触发
- 验证:deploy 有 disable-model-invocation: true
构建你自己的评估矩阵,记录每次迭代的指标:
| 版本 | 通过率 | Token 开销 | 耗时变化 | 假阳性率 | 测试用例数 |
|-------|--------|-----------|---------|---------|-----------|
| v0.1 | 66% | +22% | +5s | 15% | 6 |
| v0.2 | 85% | +18% | -3s | 8% | 9 |
| v0.3 | 95% | +12% | -8s | 3% | 12 |
| v1.0 | 100% | +8.6% | -13s | 0% | 15 |
当你的 Skill 经过验证后,可以通过 skillOverrides 精细控制其行为:
// .claude/settings.local.json
{
"skillOverrides": {
"code-review": "on",
"legacy-security": "name-only",
"experimental-feature": "user-invocable-only",
"deprecated-review": "off"
}
}
| 状态值 | Claude 能看到 | 出现在 / 菜单 |
使用场景 |
|---|---|---|---|
on |
名称和描述 | 是 | 默认状态,完全启用 |
name-only |
仅名称 | 是 | 降低 Token 开销但保留手动调用 |
user-invocable-only |
隐藏 | 是 | 后台知识转为手动命令 |
off |
完全隐藏 | 隐藏 | 禁用不用的 Skill |
在 Claude Code 中输入 /skills,然后:
- 按 Space 切换 Skill 状态
- 按 Enter 保存到 .claude/settings.local.json
flowchart LR
subgraph 创建阶段
A1[定义需求] --> A2[编写 SKILL.md]
A2 --> A3[添加支持文件]
end
subgraph 验证阶段
B1[创建 evals.json] --> B2[运行 A/B 测试]
B2 --> B3[分析基准结果]
end
subgraph 迭代阶段
C1[诊断故障] --> C2[优化指令]
C2 --> C3[重新测试]
C3 --> C4{通过验证?}
C4 -->|否| C1
C4 -->|是| C5[发布]
end
A3 --> B1
B3 --> C1
Q:evals.json 应该放在哪里? A:放在 Skill 目录下,与 SKILL.md 同级。skill-creator 会自动发现它。
Q:基准测试需要多少个测试用例? A:最少 3 个(覆盖正常、边界、错误场景),推荐 5-8 个。少于 3 个无法统计显著性。
Q:Skill 压缩后内容丢失怎么办?
A:确保 SKILL.md 核心指令在前 5000 token 内。详细参考移到支持文件中。必要时重新调用 /skill-name 恢复完整内容。
Q:如何测试 context: fork 模式的 Skill?
A:fork 模式下 Skill 运行在独立子代理中。测试时注意:子代理看不到对话历史,SKILL.md 必须完全自包含。单独调用 /skill-name args 验证。
Q:多个 Skill 同时存在时如何避免冲突?
A:使用 paths 限定作用域、disable-model-invocation: true 控制手动触发、skillOverrides 调整优先级。同层级的 Skill 按名称字母序加载。
| 维度 | 评估 |
|---|---|
| 适合训练营类型 | 进阶开发者训练营(要求有 Skill 开发基础) |
| 预计教学时长 | 3-4 小时(含实操) |
| 前置知识 | SKILL.md 基础、YAML frontmatter、Shell 脚本 |
| 实操依赖 | skill-creator 插件、Claude Code v2.1.145+、Git 仓库 |
| 难度等级 | 中高级 |
[!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 等场景全覆盖。
