你在 ~/.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 开头,至少要有 name 和 description。少了收尾的 ---、从文档里粘了智能引号、或者用 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 里调用了 Edit 或 Bash,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 -a加echo $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
在启动日志里搜 skill、SKILL.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.md或Skill.md在大小写敏感的文件系统上不会被识别。 - 两个 skill 能同名吗? 不能,一个会盖过另一个。加个前缀避开插件冲突。
相关
- Claude Code settings.json 不生效
- Claude Code subagent 结果回传不到主会话
- Claude Code hook 莫名其妙拦下 Edit
- Claude Code permissions 弹窗循环
- Claude Code 工具执行卡住
标签: #Claude Code #Skills #排查 #CLI