Claude Code Skill 没被发现或不会自动触发

你在 ~/.claude/skills/ 下加了 Skill,/<name> 却说找不到,或者一直不自动触发。多半是 SKILL.md frontmatter、路径或 description 写得不够具体。

你在 ~/.claude/skills/my-skill/ 下放了一个 SKILL.md,重启 Claude Code,然后输入 /my-skill,CLI 直接报「skill not found」。更糟的是:/help 里能看到它,但你用自然语言描述同样的任务时它从来不自动触发。Skill 是会话启动时从固定目录扫描的,要过 frontmatter 校验,再通过 description block 暴露给模型。这条链上任何一环断了——路径错、name 漏了、YAML 写坏、description 太泛——这个 skill 就会静默隐身。定位到具体是哪一步,改一行就能修好。

常见原因

按命中率从高到低。

1. Skill 文件没放在期望的路径

Claude Code 只扫这几个目录:~/.claude/skills/<skill-name>/SKILL.md、项目本地的 .claude/skills/<skill-name>/SKILL.md、以及插件自带的 skill。如果你放成了 ~/.claude/skills/my-skill.md(扁平文件,没有文件夹)或者 ~/.claude/skill/...(目录名错),它永远不会被加载。

怎么判断ls ~/.claude/skills/ 看一下,每一项应该都是文件夹,里面正好有一个 SKILL.md

2. Frontmatter 缺失或格式坏了

SKILL.md 必须以 YAML frontmatter 开头,至少要有 namedescription。少了收尾的 ---、从文档里粘了智能引号、或者用 tab 不是空格,解析器都会跳过这个文件。

怎么判断:打开 SKILL.md,确认第一行是 ---、第二行是 name: my-skill、body 前面有收尾的 ---

3. Skill name 和文件夹名对不上

name: 字段和文件夹名必须完全一致——大小写、连字符都要对得上。文件夹是 my-skill、frontmatter 写成 name: MySkill,斜杠命令就解析不出来。

怎么判断:把 basename $(dirname SKILL.md)name: 字段一个字符一个字符地比。

4. description 太泛、自动触发不了

要让模型自动调用,Claude Code 是拿用户请求去 match 每个 skill 的 description。如果你写了「helper」或者「stuff」这种一两个词的描述,模型完全没东西可匹配,只能靠 slash invoke 才能跑。

怎么判断:把 description 读出来。如果没有提到具体触发场景(「用户要求部署时」、「SQL migration 的时候」),就是太泛了。

5. allowed-tools 漏了 skill 实际要用的工具

如果你 frontmatter 里写 allowed-tools: [Read],但 skill body 里调用了 EditBash,Claude Code 要么拒绝加载,要么静默跳过那些需要受限工具的步骤。

怎么判断:把 allowed-tools 列表跟 skill body 里出现的每个工具名比对一下。

6. 重名 skill 把你的覆盖了

如果 ~/.claude/skills/foo/ 和某个插件里都有叫 foo 的 skill,只有一个赢、另一个被藏起来。项目本地 vs 用户全局也是同理。

怎么判断:启动时跑 claude --debug,grep 「skill」,loader 日志会告诉你哪条路径胜出。

开始前

  • 确认你用的是 CLI 版本的 Claude Code,不是 Claude.ai web(两边的 Skill 机制不一样)。
  • 把 skill 文件夹路径准备好、随时能看。
  • 加完 skill 之后至少重启一次 Claude Code(Skill 是启动时加载的)。
  • 想清楚你是要 slash 调用、还是要自动触发,还是两个都要。

需要收集的信息

  • Claude Code 版本:claude --version
  • 系统和 shell:uname -aecho $SHELL
  • ls -la ~/.claude/skills/ 和项目根目录下 ls -la .claude/skills/ 的输出。
  • SKILL.md 的完整内容,特别是 frontmatter 部分。
  • 启动 debug 日志:claude --debug 2>&1 | head -200
  • 输入 /your-skill-name 时打印的任何报错。

一步一步修复

Step 1:核对磁盘上的目录结构

ls -la ~/.claude/skills/
ls -la ~/.claude/skills/my-skill/

应该看到一个 my-skill/ 文件夹、里面装着 SKILL.md。如果看到的是扁平的 my-skill.md,搬一下:

mkdir -p ~/.claude/skills/my-skill
mv ~/.claude/skills/my-skill.md ~/.claude/skills/my-skill/SKILL.md

Step 2:校验 frontmatter

打开 SKILL.md,看最上面这一块:

---
name: my-skill
description: 用户要求把 API 服务部署到 staging 时调用。
---

开头和结尾的 --- 必须有。name 必须和文件夹名对上。别用 tab、别用智能引号。

Step 3:用 debug 模式跑 Claude Code

claude --debug

在启动日志里搜 skillSKILL.md、或者你的 skill 名字。要么看到「loaded skill my-skill」,要么看到「failed to parse frontmatter」这样的报错。

Step 4:明确测一下 slash 调用

在会话里输入 /my-skill 然后按 Tab。skill 存在的话,自动补全会显示出来。什么都没出来,就是 loader 拒了它——回到 Step 2。

Step 5:把 description 改得更适合自动触发

重写 description,加上具体的触发短语:

description: |
  用户要求部署服务、跑数据库 migration、刷新 CDN 缓存
  时调用。例子:
  「把 api 部署到 staging」、「跑一下 migration 0042」。

具体的触发场景能显著提高自动命中率。

Step 6:检查 allowed-tools 覆盖完整

如果 skill body 里用了 Bash、Read、Edit、Write,frontmatter 应该都列上:

allowed-tools: [Bash, Read, Edit, Write]

或者干脆不写 allowed-tools,继承会话默认。

Step 7:解决重名覆盖

如果插件和你的用户全局 skill 重名了,改一个。最简单是给你的 skill 文件夹加前缀,比如改成 my-deploy 而不是 deploy

怎么验证修好了

  • /my-skill 在 tab-complete 里出现,跑起来也输出预期内容。
  • 用一句自然语言描述匹配 description 的任务,一两轮内能自动触发。
  • claude --debug 输出里 skill 出现在加载列表里、没有 warning。
  • 在一个全新的会话里也能用,不是只在改完那一次的会话里能用。

长期预防

  • dotfiles 里维护一个 skills/README.md,列出每个 skill 和它的触发短语,省得忘了装了啥。
  • 写个 lint 脚本遍历 ~/.claude/skills/,校验每个 SKILL.md 的 frontmatter。
  • skill 名字加个个人前缀,避开插件冲突。
  • 调 description 的时候,用两三种说法测一下自动触发再算搞定。
  • ~/.claude/skills/ 目录纳入版本控制。

容易踩的坑

  • 改完 SKILL.md 忘了重启 Claude Code;skill 只在会话启动时加载。
  • 从博客复制 frontmatter 把智能引号一起带进来。
  • 文件夹名用大写或带空格;老老实实小写加连字符。
  • description 写 200 字觉得越多越好;模型会截断,关键是 60 字内、但要具体。
  • 把 skill 放进 ~/.claude/skill/(单数)这种 typo 目录。

常见问答

  • Claude Code 去哪里找 skill? 用户全局是 ~/.claude/skills/<name>/SKILL.md,项目本地是 .claude/skills/<name>/SKILL.md,再加上插件提供的 skill。
  • 加了 skill 要重启吗? 要。Skill 在会话启动时扫描。已有 skill 改 body 也要等下个会话生效。
  • 我的 skill 在 /help 里能看到,但永远不自动触发? description 太泛。重写它,写上具体触发短语和示例用户消息。
  • 能列出所有加载的 skill 吗?claude --debug,grep 「skill」,loader 会逐个打印它接受了哪个。
  • SKILL.md 这个文件名重要吗? 重要,必须正好是 SKILL.md(大写)。skill.mdSkill.md 在大小写敏感的文件系统上不会被识别。
  • 两个 skill 能同名吗? 不能,一个会盖过另一个。加个前缀避开插件冲突。

相关

标签: #Claude Code #Skills #排查 #CLI