Claude Code Skill 质量检查实战:用 /skill-doctor + Plugin Evals 找出“看似能用、实际没被调用“的问题

Claude Code Skill 质量检查实战:用 /skill-doctor + Plugin Evals 找出"看似能用、实际没被调用"的问题

这周建议你把精力从"再做一个新 Skill"切换到"如何验证 Skill 真的有效"。

原因很简单:最近 Claude Code 的更新里,出现了两个正好适合做实操文章的功能------/skill-doctor (v2.1.261,2026-09-04 发布,官方文档标注需要 v2.1.252 或更高版本)和 claude plugin eval(v2.1.269,2026-09-11 发布)。前者告诉你哪些 Skill 从来没被调用过、每个 Skill 每轮花掉你多少上下文;后者让你用固定输入、可重复的方式,验证一个插件到底有没有按预期工作。

这比单纯讲"怎么写 Skill"更有价值。因为很多人真正卡住的不是不会写,而是:

  • Skill 写完以后根本没有被调用;
  • 规则写了,但 Agent 没按规则执行;
  • 装的东西越来越多,上下文越来越长,效果反而变差;
  • Plugin 能装上,但没有任何可验证的质量标准。

这篇文章用一套闭环流程把这两件事串起来:先用 /skill-doctor 做存量体检,再用 claude plugin eval 建立质量基线,最后把评测挂进 CI。


一、先理解机制:为什么 Skill 会"装了等于没装"

要修好问题,先得知道钱是怎么花出去的。

Claude Code 采用**渐进式披露(progressive disclosure)**加载 Skill:会话启动时,只有每个 Skill 的 name + description 会进入系统提示词,形成一份"技能清单"(skill listing);SKILL.md 的正文只在 Skill 被触发的那一刻才加载。听起来很省,但有一个关键事实容易被忽略:

清单里的每一个 Skill,无论用不用,每一轮对话都在消耗上下文。

官方文档明确写了:技能清单的字符预算默认是模型上下文窗口的 1% 。当你的 Skill 多到超出预算时,Claude Code 会开始裁掉部分 Skill 的 description------而且是从你调用次数最少的那些开始裁。description 恰恰是 Claude 决定"要不要用这个 Skill"的唯一依据,描述被裁掉,触发率自然进一步下降,形成恶性循环。

所以"看似能用、实际没被调用"通常有三种根因:

根因 表现 本质
description 写得弱 明确输入触发词时能跑,自然说法下不触发 匹配失败:description 是唯一的匹配依据
清单超预算被裁描述 Skill 越装越多后,老 Skill 触发率下降 关键词被预算机制丢掉了
配置性问题 显式 /skill-name 都调不起来 目录错误、SKILL.md 文件名大小写、frontmatter 写坏、设了 disable-model-invocation: true、会话没重启等

前两种是"质量问题",第三种是"安装问题"。/skill-doctor 负责把这两类问题从一堆 Skill 里筛出来,claude plugin eval 负责量化修复效果。


二、实战一:用 /skill-doctor 做存量体检

运行方式

在交互式会话里直接输入:

复制代码
/skill-doctor

几个使用细节(都来自官方文档,踩坑前先看):

  • 报告在哪里打开 :交互式会话中,报告会打开在 /plugin 管理器的 Stats 标签页;在非交互模式(claude -p)下则直接以文本形式打印。
  • 覆盖范围 :只统计你自己装的用户级、项目级、插件级 Skill,不含捆绑技能(bundled skills)和企业下发的技能。
  • 远程控制不可用 :从手机或浏览器通过 Remote Control 运行时,会回复 Skill usage reports are not available on this connection.------必须在跑会话的那台机器的终端里执行。
  • 它还会顺手列出"最近没用过的插件",这对清理插件级开销同样有用。

读懂报告:一张六列的表

报告的每个 Skill 一行,核心列含义如下:

列 含义 怎么解读
skill Skill 名称(插件来源的显示为 plugin:skill) ---
source 来源:userSettings(~/.claude/skills/)或插件名 决定你去哪里关它
context 该 Skill 在清单里占的上下文成本------每一轮都在付 ;- 表示不在清单中 清理的主要目标
7d tokens 最近 7 天本机会话中归因于该 Skill 的 token 量 它干了多少活
uses 被调用的次数 0 次是重点信号
last used 最近使用时间(never / N days / today) 排序依据:从未用过的排在最上面

决策矩阵:四类 Skill 分别怎么处理

拿到报告后不要急着全删,按四象限处理:

情况 判断 动作
context 高 + uses = 0 纯负债:每轮付钱、从不干活 优先关闭。官方建议从上下文成本最高的开始
7d tokens 高 + uses 高 高消费但物有所值 保留,可以考虑精简 SKILL.md 正文
uses = 0 但 context 很低 暂无成本压力 低优先级,观察一个周期再说
uses > 0 但表现差 被调用了却没帮上忙 这是 /skill-doctor 管不到的,交给 plugin eval(见第三节)

在哪里关

报告会告诉你每个 Skill 该去哪里关:

  • 用户/项目级 Skill:在 /skills 界面里切换可见性,或直接移走目录;
  • 插件级 Skill:在 /plugin 里管理整个插件;
  • 想保留但少花钱:在 skillOverrides 里把低优先级条目设为 "name-only"------只列名字、不带描述,把预算让给别的 Skill;
  • 预算本身太紧:用 skillListingBudgetFraction(如 0.02 = 2%)或环境变量 SLASH_COMMAND_TOOL_CHAR_BUDGET 调整。

和 /doctor 的分工

别混淆这两个命令:/doctor 是整机体检 ------安装健康、PATH、设置文件、慢 hook、CLAUDE.md 去重和瘦身、新版本检查,"找没用的 Skill"只是其中一小项;/skill-doctor 是把"Skill 的使用情况与上下文成本"这一件事单独抽出来的专项报告 。日常维护用 /skill-doctor,搬家、升级、环境出问题时用 /doctor。

⚠️ 一个诚实的提醒:/skill-doctor 记录的是"这个 Skill 有没有跑过 ",而不是"跑了有没有帮助"。一个每周都被调用但产出很差的 Skill,在这张表里看起来完全健康。这就是下一节要解决的问题。


三、实战二:用 claude plugin eval 建立可重复的质量基线

它解决什么问题

在 v2.1.269 之前,验证一个插件只有两条路:claude plugin validate(检查文件语法和 schema------包是好的 ),和手动开几个会话试试看(感觉能用)。前者不管行为,后者不可重复。

claude plugin eval 补上的是行为层:用一组固定的测试用例(case)跑你的插件,用评分器(grader)打分,并且默认再做一组"不装插件"的对照,让你看到插件的真实贡献。

核心概念一句话版:

  • Case = 一个真实的用户 prompt + 一个或多个 grader;
  • Grader = 对产出的通过/失败检查:比如对回复跑正则、检查某个工具有没有被调用(tool_used)、检查文件是否被创建(file_exists),或者让另一个模型按评分标准(rubric)打分(llm);
  • 消融对照(ablation):默认每个 case 跑 3 次带插件 + 3 次不带插件,共 6 次。两者分差 Δ 才是插件真正带来的提升。

最小工作流:四条命令

前提:Claude Code v2.1.269 或更高 ,终端位于插件根目录(含 plugin.json 或 .claude-plugin/plugin.json)。

bash 复制代码
# 1. 让 Claude 帮你起草评测套件(交互式)
claude plugin eval init
# Claude 会读你的插件,问你"好的结果长什么样",
# 提出应该触发 / 不应该触发的 prompt,设计 grader,
# 试跑一遍确认可用后,把每个 case 写进 evals/ 目录。
# 完成后 /exit 退出该会话。

# 2. 跑整个套件
claude plugin eval .

# 3. 便宜地迭代单个 case(单臂、跑一次------有噪声,只用于快速验证方向)
claude plugin eval . --case <case-name> --runs 1 --ablation none

# 4. 确认修改效果时,回到默认 3 次运行再下结论
claude plugin eval .

跑完会看到这样的汇总表(WITH = 带插件得分,W/OUT = 不带插件得分,Δ = 差值):

复制代码
CASE        WITH  W/OUT Δ      RUNS COST    NOTES
first-case  1.00  0.33  +0.67  6    $0.41

1 case(s) · mean Δ +0.67 · 74s · $0.41
Report: /Users/you/my-plugin/evals/results/2026-09-10T17-02-11-482Z/report.html

详细报告写在 evals/results/<时间戳>/report.html,里面能看到每个 grader 的判定、判定理由,以及 llm 类 grader 的评委投票和它评审的回复片段。下面这张社区文章的示例图很能说明问题------注意 05-rewrite-request 这一行:

最重要的读数:Δ ≈ 0 意味着什么

官方文档直接点破了新手最常见的发现:

Δ 接近 0,且 tool_used: Skill 这个 grader 失败------通常说明在自然说法下,Claude 根本没选你的 Skill。

这就是把"感觉 Skill 没被调用"变成可量化证据 的时刻。修复路径也很明确:重写 Skill 的 description(写清楚具体触发场景和用户真实会用的措辞,而不是只写主题),重跑同一个套件,对比 Δ。

顺便说两个官方文档里的典型坑:

  • 所有 grader 都是 0 分但文件明明生成了 :大概率是 grader 的 target 指到了 files(路径列表)而不是文件内容,改用 { source: file, path: <path> };另外 file_exists 只统计运行期间新建 的文件,被编辑的已有文件它看不见,这种情况用 tool_used 检查 Edit。
  • 汇总表里没有 W/OUT 列 :说明 case 没找到插件,在 case 里加 plugins: ["../.."](从 case 目录指向插件目录的相对路径)。

成本与 CI

两个必须知道的现实约束:

  1. 评测是真金白银的模型调用 。每次运行、每个 llm grader 的评委打分,都走你账户的额度或 API 账单(命令会给出按刊例价估算的 COST)。参考量级:社区报道一个 7-case 套件、每 case 6 次运行,总成本约 $9.59。建议把便宜的确定性检查(regex、tool_used、file_exists)放在日常迭代,大套件留给 nightly 或发版前。
  2. CI 门禁是官方支持的主要场景 。case 就是 evals/ 下的普通文件,可以随仓库版本管理;用 --json 输出结果,在流水线里对 Δ 或通过率设阈值,卡住那些"改了插件/换了模型后悄悄退化"的提交。

另外两个实用能力:

  • Mock MCP 服务器 :Skill 依赖 MCP 工具时,不必连真实服务。在 evals/mocks/<server>/<tool>.md 放 Markdown 文件即可提供假的返回,还能用 frontmatter 里的 expect 校验 Claude 传参是否正确。
  • 自定义评测目录 :evals/ 被占用时,在 plugin.json 里写 "experimental": { "evals": "quality/evals" },或用 --eval-dir 指定。

⚠️ 安全提醒:评测会话会加载插件并运行,插件的 hooks 和 MCP 服务器是以你的身份执行的------只评测你信任的插件。


四、组合拳:一个完整的 Skill 质量闭环

把两个工具串起来,就是一个可以周期性执行的工作流:

复制代码
写/装 Skill
   │
   ▼
claude plugin eval ──► 量化触发率与行为质量(Δ、grader 判定)
   │                       │
   │                       ├─ Δ≈0 且 Skill 未触发 → 改 description → 重跑
   │                       └─ Δ>0 → 通过,进入日常使用
   ▼
日常使用 1~2 周
   │
   ▼
/skill-doctor ──► 真实环境的使用审计(uses / last used / context)
   │                  │
   │                  ├─ uses=0 且 context 高 → 关闭或 name-only
   │                  ├─ 高频使用 → 保留,考虑精简正文
   │                  └─ 从未触发的插件 → 整个卸载
   ▼
改动了 Skill/插件,或模型升级了
   │
   ▼
CI 里跑 claude plugin eval ──► 防回归,回到第一步

两者分工一句话总结:eval 回答"它能不能被正确触发、触发了有没有用"(事前、受控、可重复);/skill-doctor 回答"它在真实使用里到底有没有被用到、成本多少"(事后、真实、按机器统计)。 只用前者,你会漏掉"评测里表现好但真实场景没人这么提问"的 Skill;只用后者,你会分不清"没被调用"是描述问题还是需求根本不存在。


五、动手前的检查清单

  • 版本确认:claude --version,/skill-doctor 需要 ≥ v2.1.252,claude plugin eval 需要 ≥ v2.1.269
  • 在本机终端 (非 Remote Control)跑 /skill-doctor
  • 按"四象限"处理:高成本低使用优先关,skillOverrides: "name-only" 处理低优先级条目
  • 给核心插件建最小评测套件:3~5 个"应该触发"的 prompt + 1~2 个"不应该触发"的负例
  • 每个 case 至少配一个 tool_used: Skill grader------这是"没被调用"问题最直接的探测器
  • 迭代用 --runs 1 --ablation none,下结论用默认 3 次运行
  • 套件进版本库,CI 用 --json 做阈值门禁
  • 只评测信任的插件;大套件注意模型调用成本

相关推荐
a努力。1 小时前
LangGraph进阶:用子图与人机交互打造生产级Agent
人工智能
Leo.yuan1 小时前
从“看全局“到“评成效“:央国企穿透式监管六步链路,哪些厂商能真正闭环
java·大数据·人工智能
狂奔solar1 小时前
眨眼检测——OCEC 112KB 模型重新定义实时眼部状态分类
大数据·人工智能·分类
shxjnpl1 小时前
高保密单位选AI会议助手,真正要看的不是功能多少
人工智能·语音识别
秦先生在广东1 小时前
OpenRig:将离散 AI Agent 编织为持久化协作系统的多智能体编排实践
人工智能
秦先生在广东1 小时前
Skills Manager:统一54+ AI编程工具Agent技能的跨平台桌面中枢
人工智能
科研online1 小时前
用可解释机器学习XGBoost+SHAP发SCI期刊的优势?
人工智能·机器学习·学习方法
秦先生在广东2 小时前
Hindsight:突破RAG瓶颈的仿生记忆系统,如何在Agent长期记忆中实现SOTA性能
人工智能