skill-stocktake — 技能质量审计
在单一上下文中,整体地评估所有已安装技能,并为每个技能给出判定:
保留 / 改进 / 更新 / 淘汰 / 合并。此技能不执行改进操作——一旦得出判定,它将移交给 skill-creator(改进引擎)。这一界限正是关键点:stocktake 是质量门禁,skill-creator 是修复者。
设计说明:旧版本会调用扫描脚本,并将评估分批进行(每批约 20 个技能)。在 1M 上下文环境下,这不仅没有必要,而且有害——分批处理会导致每个子代理看不到其他批次的技能,从而遗漏跨技能的重叠。现在,我们使用 Glob 枚举并读取每个技能到单一上下文中。重叠检测依赖于这种单上下文视图。
模式($ARGUMENTS)
| 参数 | 行为 |
|---|---|
无 / full | 读取并评估每个技能(默认) |
changed | 仅重新评估那些 SKILL.md 的修改时间比 results.json 中的 evaluated_at 更新的技能;其余技能继承之前的结果 |
changed 模式内联检测变更(无需脚本):
find ~/.claude/skills -name SKILL.md -newermt "$(jq -r .evaluated_at ~/.claude/skills/skill-stocktake/results.json)"
阶段 1 — 清点
使用 Glob 枚举技能定义文件(无需脚本):
~/.claude/skills/*/SKILL.md~/.claude/skills/learned/*.md- 如果当前工作目录包含
.claude/skills/,则同时扫描{cwd}/.claude/skills/*/SKILL.md(项目技能)
由于 Glob 仅匹配
SKILL.md/learned/*.md,因此.venv或.pytest_cache下的依赖项 markdown 文件被结构性地排除在外(无需修剪)。旧版find -name "*.md"引入的噪声不会发生。
使用次数统计:内联读取 ~/.claude/metrics/skill-usage.jsonl(PostToolUse 钩子 log-skill-usage.sh 向此文件追加内容——这是一个独立的测量层),并统计每个技能在 7 / 30 / 90 天内的使用事件数。每行是 JSON 格式 {ts,event,skill,path,project};同时统计 invoke 和 read 事件。使用一次性的 python3/jq 单行命令进行聚合,而不是手动计数——日志会随时间增长,手动计数每次调用都会浪费一次工具使用机会。
- 如果日志缺失或其第一个事件距今不足 90 天,则将使用次数显示为
—(未测量)。绝不能显示为 0——未测量和未使用是不同的情况。
预先说明扫描结果:扫描了哪些路径,找到了多少技能,以及使用次数是否可测量。
阶段 2 — 评估(完全内联,整体进行)
读取每个目标技能的正文,并在看到整个技能集的同时逐一评估它们。检查清单:
- 与其他技能的内容重叠(有文档记录的组织者/子技能拆分不是重叠——例如 paper-ecosystem → 其审阅者,citation-sync → release-doi/wikidata。区分有意分层与真正的重复)
- 与 MEMORY.md / CLAUDE.md / 规则的重叠
- 技术参考的新鲜度(如果 CLI 标志 / API / 工具名称看起来过时,请使用 WebSearch 确认)
- 使用频率(未测量时忽略此信号)
评估是整体判断,而非数值评分表。指导维度:可操作性(可操作的示例/步骤)、范围匹配(名称、触发条件和正文一致——不过于宽泛或狭窄)、独特性(不可被 MEMORY / 其他技能替代)、时效性(引用在当前环境中有效)。
聚合成本(技能集层面,而非每个技能): 即使单个技能本身没问题,持有它也需要成本。技能的好处是脆弱的——一个庞大且未经整理的库会降低代理选择正确技能的能力,并将行为拉回到无技能的基线水平。因此,保留的门槛随技能库规模的增长而提高:当技能集很大时,一个仅仅合格的技能(使用少、独特性低、与其他技能高度相邻)本身就是一个淘汰/合并的候选,原因就在于聚合稀释——与该技能本身是否有缺陷无关。这是一个判断输入,从来不是配额;不要为了凑数而淘汰。
| 判定 | 含义 |
|---|---|
| 保留 | 有用、当前有效、具有独特价值 |
| 改进 | 值得保留,但需要特定改进 |
| 更新 | 引用的技术已过时(需要 WebSearch 验证) |
| 淘汰 | 质量低、过时或成本不合算 |
| 合并到 [X] | 与另一个技能有大量重叠;指明目标 |
零使用规则:当使用日志的第一个事件距今至少 90 天,且某个技能的 use_90d == 0 时,必须将其作为淘汰候选提出(最终决定权在用户)。当日志年龄小于 90 天时,此规则不会触发,判定仅依赖于整体判断。
评估是来源无关的:不要根据 ECC / 自编 / 自动提取来分支判断。相同的检查清单适用于每个技能。
阶段 3 — 摘要
呈现一个表格:技能 | 7天使用 | 90天使用 | 判定 | 理由。
阶段 4 — 整合
- 淘汰 / 合并:针对每个文件,呈现 (1) 发现的特定缺陷,(2) 替代方案(淘汰:哪个现有技能/规则可以覆盖同一需求;合并:目标技能以及需要整合的内容),(3) 移除的影响(依赖的技能,MEMORY 中的引用)。仅在用户确认后执行操作。
- 改进 / 更新:提议移交——「将
<技能>移交给 skill-creator 进行改进?」——在用户同意后,调用skill-creator并传入目标技能。Stocktake 从不自行执行改进工作。 - 更新记录:读取
results.json→ 合并本次运行的判定 → 写回(evaluated_at= 来自date -u +%Y-%m-%dT%H:%M:%SZ的真实 UTC 时间)。在changed模式下,保留未重新评估技能之前的判定。 - 如果 MEMORY.md 超过 100 行,建议压缩。
理由质量(必需)
每个 reason 必须是自包含的——仅凭自身就能支持决策。不允许单独出现 "unchanged";务必重新陈述证据。
- 淘汰:说明缺陷 + 替代方案。差:
"Superseded"/ 好:"disable-model-invocation: true 已设置;continuous-learning-v2 已覆盖相同模式并增加了置信度评分。无独特内容剩余。" - 合并:指出目标 + 要整合的内容。差:
"与 X 重叠"/ 好:"42 行薄内容;chatlog-to-article 的第 4 步已覆盖此工作流。将那里的 '文章角度' 提示作为注释整合进来。" - 改进:哪个部分,什么改变(如果需要,目标大小)。差:
"太长"/ 好:"276 行;'框架比较'(L80–140)与 ai-era-architecture-principles 重复。删除它以达到约 150 行。" - 保留(
changed模式下仅 mtime 变更):重新陈述原始理由。差:"Unchanged"/ 好:"内容未变。独特的 Python 引用,由 rules/python/ 显式导入;无重叠。"
results.json(精简记录)
{
"evaluated_at": "2026-06-24T11:09:00Z",
"skills": {
"<skill-name>": {
"path": "~/.claude/skills/<name>/SKILL.md",
"verdict": "保留",
"reason": "...",
"mtime": "2026-01-15T08:30:00Z"
}
}
}
记录仅包含判定历史和上次审计时间戳。使用 Read/Writ 内联更新,而不是脚本。仅记录全局技能(项目技能从当前工作目录中新鲜读取,不在此缓存)。
相关
skill-creator— 改进引擎;将改进/更新工作移交给它。config-gc— 对技能存在性以及整个 ~/.claude(钩子/权限/MCP/缓存)进行垃圾回收;stocktake 评判技能质量。harness-sync— 用于将此技能同步到其公共仓库。- 使用统计:
~/.claude/hooks/log-skill-usage.sh→~/.claude/metrics/skill-usage.jsonl(独立于 stocktake 的测量层)。