Skills 描述优化技巧
description 字段是 Skill 触发的唯一判断依据。
一个写得好的 description,能让 Skill 在正确的时机被触发,并避免在不相关的场景下干扰 Claude。
Description 的作用与限制
Claude 在决定是否使用某个 Skill 时,只会阅读 description 字段,不会提前读取 SKILL.md 正文。
这意味着 description 需要同时承担两件事:说明 Skill 能做什么,以及指明何时应该用它。
description 的理想长度是 50-150 字。太短会导致触发不准确,太长则可能超出上下文限制,且 Claude 难以快速扫描比对。
Description 的四要素结构
| 要素 | 作用 | 示例 |
|---|---|---|
| 核心功能一句话 | 最直接地说明 Skill 是什么 | "处理 Excel 和 CSV 格式的表格数据" |
| 具体能力列举 | 列出 3-5 个典型操作 | "包括数据清洗、统计分析、图表生成" |
| 触发场景描述 | 告诉 Claude 什么时候应该用 | "当用户提到数据分析、报表、统计时触发" |
| 推动性语句(可选) | 解决"低触发率"问题 | "即使用户没有明确提到格式,只要涉及表格数据就应使用" |
--- name: data-analyzer description: > 处理 Excel(.xlsx)和 CSV 格式的表格数据,包括数据读取、 清洗去重、统计分析(均值/中位数/分布)、生成可视化报告。 当用户需要分析数据文件、生成统计报告、处理表格、 查找数据规律时应优先使用此 Skill,即使用户只是上传了 一个数据文件并询问"帮我看看这个"。 ---
常见的 Description 写法问题
| 问题 | 示例(错误) | 修正方向 |
|---|---|---|
| 只写功能,不写触发场景 | "分析数据的工具" | 补充"当用户……时触发" |
| 描述过于宽泛 | "处理文件的通用工具" | 列举具体文件类型和操作 |
| 使用 Skill 内部实现术语 | "调用 pandas 进行分析" | 改为用户视角的业务描述 |
| 与其他 Skill 边界不清 | 两个 Skill 都写"处理文档" | 明确区分各自的文件类型或操作类型 |
用自动化工具优化 Description
skill-creator 提供了 description 自动优化脚本,通过迭代测试找出触发率最高的写法。
第一步:准备测试用例
实例
[
{
"id": "should_trigger_01",
"prompt": "帮我分析 runoob_sales.csv,找出月度销售趋势",
"expected": true,
"note": "典型的数据分析请求"
},
{
"id": "should_trigger_02",
"prompt": "这个 Excel 文件里哪些列有空值?帮我统计一下",
"expected": true,
"note": "涉及数据质量检查"
},
{
"id": "should_not_trigger_01",
"prompt": "Excel 和 CSV 有什么区别?",
"expected": false,
"note": "知识问答,不需要 Skill"
},
{
"id": "should_not_trigger_02",
"prompt": "帮我写一封邮件",
"expected": false,
"note": "完全无关的任务"
}
]
{
"id": "should_trigger_01",
"prompt": "帮我分析 runoob_sales.csv,找出月度销售趋势",
"expected": true,
"note": "典型的数据分析请求"
},
{
"id": "should_trigger_02",
"prompt": "这个 Excel 文件里哪些列有空值?帮我统计一下",
"expected": true,
"note": "涉及数据质量检查"
},
{
"id": "should_not_trigger_01",
"prompt": "Excel 和 CSV 有什么区别?",
"expected": false,
"note": "知识问答,不需要 Skill"
},
{
"id": "should_not_trigger_02",
"prompt": "帮我写一封邮件",
"expected": false,
"note": "完全无关的任务"
}
]
第二步:运行优化循环
实例
# 运行 description 自动优化
# 脚本会自动:评估 → 修改 → 再评估,循环 5 次
python -m scripts.run_loop \
--eval-set evals/trigger-eval.json \
--skill-path data-analyzer/ \
--model claude-sonnet-4-20250514 \
--max-iterations 5 \
--verbose
# 脚本会自动:评估 → 修改 → 再评估,循环 5 次
python -m scripts.run_loop \
--eval-set evals/trigger-eval.json \
--skill-path data-analyzer/ \
--model claude-sonnet-4-20250514 \
--max-iterations 5 \
--verbose
迭代 1:训练集得分 0.62,测试集得分 0.60 迭代 2:训练集得分 0.75,测试集得分 0.72 迭代 3:训练集得分 0.87,测试集得分 0.85 迭代 4:训练集得分 0.90,测试集得分 0.88 迭代 5:训练集得分 0.91,测试集得分 0.89 最优 description(测试集得分 0.89)已保存。
第三步:应用最优结果
实例
# 脚本输出 best_description 字段,将其替换到 SKILL.md 的 description 中
# 优化前
grep "description:" data-analyzer/SKILL.md
# 手动或用脚本替换为 best_description 的内容
# 替换后重新打包 Skill
python -m scripts.package_skill data-analyzer/
# 优化前
grep "description:" data-analyzer/SKILL.md
# 手动或用脚本替换为 best_description 的内容
# 替换后重新打包 Skill
python -m scripts.package_skill data-analyzer/
A/B 对比测试
在不确定哪种写法更好时,可以对两个版本的 description 进行盲测对比。
实例
# 版本 A:当前的 description
# 版本 B:候选的新 description
# 分别运行评估
python -m scripts.run_eval \
--eval-set evals/trigger-eval.json \
--skill-path data-analyzer-v1/ \
--output evals/results_v1.json
python -m scripts.run_eval \
--eval-set evals/trigger-eval.json \
--skill-path data-analyzer-v2/ \
--output evals/results_v2.json
# 生成对比报告
python eval-viewer/generate_review.py \
--results evals/results_v1.json evals/results_v2.json \
--compare \
--output evals/comparison.html
# 版本 B:候选的新 description
# 分别运行评估
python -m scripts.run_eval \
--eval-set evals/trigger-eval.json \
--skill-path data-analyzer-v1/ \
--output evals/results_v1.json
python -m scripts.run_eval \
--eval-set evals/trigger-eval.json \
--skill-path data-analyzer-v2/ \
--output evals/results_v2.json
# 生成对比报告
python eval-viewer/generate_review.py \
--results evals/results_v1.json evals/results_v2.json \
--compare \
--output evals/comparison.html
评估应以测试集得分为准,而不是训练集得分。训练集得分高但测试集低,说明 description 过度拟合了测试用例,在真实场景中效果可能变差。
