Claude Code Skills 从项目级到全局:安装、迁移与最佳实践
1. 为什么 Skills 值得单独拿出来讲Claude Code 这个工具本身已经不算新鲜了终端里跑一个 CLI接上模型能读文件、能改代码、能执行命令很多人拿它当会动手的聊天窗口用。但真正把它用出效率差距的往往不是模型本身而是Skills这一层。我自己的感受很直接刚上手那阵子我每次开新项目都要重复交代一堆东西——这个仓库用 pnpm 不用 npm测试跑 vitest 不跑 jest提交信息按 conventional commits 写别动 legacy 目录下的文件。说一次两次还行说二十次就烦了。Skills 解决的正是这个问题它把这些重复的、项目相关的、带流程性的指令固化下来让 Claude Code 在特定场景下自动加载而不是靠你每次手动喂。那为什么标题要强调从项目级切到全局因为绝大多数人第一次接触 Skills都是被某个具体项目逼出来的——项目里有个.claude/skills目录或者同事丢给你一个 skill 文件夹让你放进去。用着用着你会发现有些 skill 是只对当前仓库有意义的比如这个项目的部署流程而有些 skill 是你走到哪都想带着的比如你的代码审查习惯、你的提交信息规范、你偏好的调试套路。前者留在项目级后者就该搬到全局。这篇东西我打算把两件事讲透一是 Skills 到底怎么装、目录结构长什么样、加载优先级怎么算二是项目级和全局这两种作用域怎么选、怎么迁移、迁移时有哪些坑。适合已经装好 Claude Code、能跑起来但还没系统用过 Skills 的人也适合用了一阵子但一直没搞明白为什么我的 skill 有时候生效有时候不生效的人。先把一个前提说清楚Skills 的机制在不同版本里细节会有微调下面讲的目录约定和优先级逻辑是基于我实际使用和官方文档的常见实践总结出来的你落地时以自己版本的claude --help和官方文档为准。但核心思路是稳定的skill 就是一份带元信息的 Markdown 指令包放在约定目录里由 Claude Code 按作用域和匹配规则决定要不要加载。2. Skills 的本质一份会被自动召回的指令包2.1 Skill 到底是什么和 CLAUDE.md 有什么区别很多人第一次看到 Skills会把它和CLAUDE.md搞混。两者确实都是给模型看的文字但定位完全不同。CLAUDE.md是常驻上下文。只要你在项目根目录它基本每次都会被读进去内容偏向这个项目是什么、整体约定是什么。它的问题是写多了会一直占上下文而且它是always on的不管你现在在干嘛它都在那儿。Skill 是按需召回。它有一个描述descriptionClaude Code 会根据你当前的任务、你输入的内容判断要不要把这个 skill 的内容加载进来。也就是说一个 skill 可以写得很长很细但只要当前任务用不上它就不占你的上下文预算。这是它比CLAUDE.md更适合承载流程性知识的根本原因。打个比方CLAUDE.md像是贴在工位上的便签抬头就能看见Skill 像是抽屉里的操作手册需要拧螺丝的时候才抽出来翻。你不会把所有手册都摊在桌上但你希望需要的时候一伸手就能拿到。2.2 一个 skill 的最小结构一个 skill 本质上就是一个目录里面至少有一个SKILL.md有些版本叫skill.md大小写敏感问题后面会专门讲。这个文件由两部分组成YAML frontmatter和正文。frontmatter 里最关键的是两个字段nameskill 的标识名通常用短横线连接的小写单词比如commit-style、api-review。description一句话说明这个 skill 干什么、什么时候该用它。这个字段是自动召回的命门写得含糊模型就不知道该不该加载。正文就是你真正想传达的指令。可以是一段规范、一套步骤、一份检查清单甚至是一堆示例。Markdown 格式随便用标题、列表、代码块都行。--- name: commit-style description: 当用户要求提交代码、生成 commit message 或整理变更时使用。规定本仓库的提交信息格式与拆分粒度。 --- 提交信息遵循 conventional commits - 类型限定为 feat / fix / refactor / docs / test / chore - 标题不超过 72 字符用中文描述做了什么 - 正文说明为什么改不重复改了什么 - 一次提交只做一件事混了多个关注点就拆开就这么简单。没有编译、没有依赖、没有注册表纯文本。这也是它好用的地方——你随时能改改完立刻生效不需要重启什么服务个别版本需要重新进入会话后面讲。2.3 为什么用 Markdown 而不是配置文件有人会问为什么不搞成 JSON 或者 YAML 配置非要 Markdown我的理解是skill 的内容是给模型读的自然语言不是给程序解析的结构化数据。你要写的是遇到 X 情况就按 Y 步骤做注意别踩 Z 坑这种东西用 Markdown 写最自然模型也最容易理解。而且 Markdown 允许你塞代码块、表格、示例对话这些都是提升指令质量的手段。你完全可以在一个 skill 里放一段错误示范 vs 正确示范的对比模型看了之后执行准确率会明显上升。用 JSON 写这些就很别扭。3. 安装 Skills 的三种路径3.1 手动放置最原始也最可控最直接的方式就是手动建目录、写文件。项目级的话在仓库根目录建.claude/skills/skill-name/SKILL.md全局的话在用户主目录下的~/.claude/skills/skill-name/SKILL.md。我一般用命令行快速搭骨架# 项目级 mkdir -p .claude/skills/commit-style touch .claude/skills/commit-style/SKILL.md # 全局 mkdir -p ~/.claude/skills/commit-style touch ~/.claude/skills/commit-style/SKILL.md然后拿编辑器把内容填进去。这种方式的好处是完全透明你知道每个文件在哪、内容是什么出问题好排查。坏处是分享麻烦得手动拷贝。注意目录名和 frontmatter 里的name最好保持一致。有些版本会以目录名为准有些以name为准不一致的时候行为可能让你困惑。统一起来最省心。3.2 从他人项目或仓库拷贝社区里已经有不少人把自己写的 skill 整理成仓库分享出来比如各种前端开发 skills代码审查 skills合集。用法通常就是把对应的 skill 目录整个拷到你的.claude/skills/或~/.claude/skills/下。拷贝的时候有几个细节要盯检查 frontmatter 是否完整。有些分享出来的 skill 只留了正文name和description被删了直接放进去可能不生效。检查有没有硬编码路径。别人写的 skill 里可能写死了他自己机器的路径比如/Users/xxx/projects/...你得改成自己的或者改成相对路径。检查语言和风格。如果 skill 正文是英文而你团队用中文交流模型执行时可能中英混杂读起来别扭建议按需翻译。3.3 用包管理或脚手架工具安装随着 Skills 生态起来也出现了一些辅助安装的工具和脚手架。常见形态是npx一把梭或者某个 CLI 提供skills add之类的子命令。这类工具的价值在于批量安装和版本管理适合你想一次性装一套 skill 集合的场景。但这里有个坑要提醒全局安装的包和全局 skill 是两码事。npm 的全局包npm install -g装的是可执行程序而 skill 是放在~/.claude/skills/下的文本目录。有些工具会帮你把 skill 写到正确位置有些只是装了个 CLI你还得自己跑命令生成 skill。装完先确认~/.claude/skills/下到底有没有东西别以为装了包就万事大吉。卸载同理。如果你用npm uninstall -g卸了工具但 skill 目录是工具之前写进去的那些目录不会自动消失得手动清。反过来如果你手动删了 skill 目录工具那边可能还记着下次更新又给你写回来。装和卸都要两头确认。4. 项目级 vs 全局作用域怎么选4.1 两种作用域的加载逻辑项目级 skill 放在仓库的.claude/skills/下只在这个仓库里生效。全局 skill 放在~/.claude/skills/下在你所有项目里都可见。当两者存在同名 skill 时项目级通常优先。这个设计很合理项目级代表这个仓库的特殊约定全局代表我的通用习惯特殊应该覆盖通用。比如你全局有个commit-style说用英文写提交信息但某个仓库要求中文你就在那个仓库的项目级放一个同名 skill 覆盖掉。实际加载时Claude Code 会把两个作用域的 skill 都纳入候选然后根据当前任务和 description 匹配度决定加载哪些。所以不是项目级存在就完全屏蔽全局而是同名冲突时项目级赢不同名的全局 skill 依然可用。4.2 什么该放项目级判断标准很简单这个 skill 的内容离开这个仓库还成立吗放项目级的典型内容这个项目的目录结构和模块划分说明这个项目特有的构建、测试、部署命令这个项目的代码风格约定比如某个老项目还在用特定 lint 规则这个项目的业务术语表模型不懂你们内部黑话这个项目的分支策略和发布流程这些东西对别的项目毫无意义甚至会产生误导。你要是把A 项目的部署流程放到全局去 B 项目时模型可能真的照着 A 的流程给你操作那就出事了。4.3 什么该放全局全局 skill 承载的是你个人的工作习惯和方法论跨项目通用你的代码审查清单不管什么语言你都会检查的那几项你的调试套路先看日志、再复现、再二分定位你的提交信息风格你偏好的解释方式比如先给结论再给理由你常用的通用工具用法我自己的全局 skill 里有一个叫review-checklist的内容就是一份我每次 review 都会过一遍的清单边界条件、错误处理、并发安全、日志埋点、测试覆盖。不管我在哪个仓库让 Claude Code 帮我 review 时它都会参考这份清单省得我每次重新描述。4.4 一张表看清怎么选判断维度放项目级放全局内容是否依赖具体仓库是否是否涉及内部业务术语是否是否跨语言跨项目通用否是是否会被团队其他人用到是随仓库共享否只属于你是否包含个人偏好一般否是冲突时谁优先优先被覆盖这张表不是死规矩但能覆盖八成场景。拿不准的时候问自己一句我把这个 skill 带到下一个完全无关的项目里它还有用吗有用就全局没用就项目级。5. 从项目级迁移到全局的完整操作5.1 迁移前的判断这个 skill 真的通用吗迁移不是简单地把文件从 A 挪到 B。先做一次通用性体检通读 skill 正文把所有提到具体项目名、具体路径、具体内部服务的地方标出来。判断这些具体信息是必须保留还是可以抽象。比如调用deploy.sh部署到 staging是项目特有的得删或改提交前跑一遍测试是通用的保留。把抽象后的版本写出来确保它在任何项目里读起来都成立。我踩过一次坑把一个写了一半的 skill 直接挪到全局里面还留着参考src/legacy/下的实现。结果在别的项目里模型真的去找src/legacy/找不到就卡住还反过来问我这个目录在哪。迁移前一定要把项目特有的引用清干净。5.2 具体迁移步骤假设你要把项目里的commit-style迁到全局# 1. 先复制不要直接移动保留项目级作为备份 cp -r .claude/skills/commit-style ~/.claude/skills/ # 2. 编辑全局版本去掉项目特有内容 # 打开 ~/.claude/skills/commit-style/SKILL.md 修改 # 3. 确认全局版本没问题后再决定项目级是否删除 rm -rf .claude/skills/commit-style为什么先复制不先移动因为迁移过程中你很可能发现全局版本改坏了或者改完之后项目里反而需要保留一个定制版。先复制两边都在验证完再删安全。5.3 迁移后必须验证的三件事第一确认加载生效。开一个新的 Claude Code 会话随便触发一下这个 skill 的场景看模型有没有按 skill 里的约定来。比如commit-style就让它生成一条提交信息看格式对不对。第二确认没有和现有全局 skill 冲突。如果你全局已经有一个同名或功能重叠的 skill迁移过去会打架。先ls ~/.claude/skills/看一眼有重名的先合并或改名。第三确认项目里没有残留依赖。有些项目可能在CLAUDE.md里写了提交规范见.claude/skills/commit-style你把目录删了这个引用就断了。搜一下项目里有没有指向这个 skill 的引用一并更新。5.4 迁移的时机选择我的建议是先项目级用一段时间确认稳定了再迁全局。刚写出来的 skill 往往有问题description 写得不准、步骤有遗漏、边界没考虑。在项目级小范围试错改起来没心理负担。等它在两三个项目里都验证过好用再迁全局。反过来如果你一上来就写全局 skill改一次影响所有项目心理压力大反而不敢改。而且全局 skill 多了之后description 之间的匹配会互相干扰模型可能加载了不该加载的 skill。全局 skill 要精项目级 skill 可以多这是我用下来的一个原则。6. 让 Skill 真正被召回的写法技巧6.1 description 是命门别糊弄skill 写得好不好一半看 description。模型判断要不要加载这个 skill主要靠它。写得含糊比如description: 帮助处理代码模型根本不知道什么时候该用等于白写。好的 description 应该包含触发场景和能力范围差description: 代码审查相关好description: 当用户要求审查代码、检查 PR、或询问某段代码是否有问题时使用。覆盖边界条件、错误处理、并发安全、日志埋点四个维度。把什么时候用写清楚比把是什么写清楚更重要。你可以想象自己在给一个新人交代遇到这种情况你就翻这份文档把这句话写进 description。6.2 正文要具体到能执行skill 正文最忌讳写空话。注意代码质量保持良好风格这种话模型看了等于没看。要写成可执行的动作空话注意错误处理。具体每个可能失败的外部调用都要有错误分支错误信息里必须包含调用参数和失败原因禁止只写console.log(error)。具体到这种程度模型执行起来才有抓手。我写 skill 的时候有个习惯每写一条规则就问自己这条能不能被验证。能被验证的规则才是好规则。6.3 用示例锚定输出格式如果 skill 涉及输出格式直接给示例。比如你要模型生成特定格式的审查报告就在 skill 里放一段输出格式示例 ## 问题清单 - [严重] 文件:行号 - 问题描述 - 建议改法 - [一般] 文件:行号 - 问题描述 - 建议改法 ## 总结 一句话说明整体质量。模型看到示例输出会稳定很多。这比用文字描述请按严重程度分级列出问题有效得多。6.4 控制单个 skill 的体量一个 skill 不要什么都往里塞。我见过有人把整个团队的编码规范、部署流程、测试策略全写进一个 skill几千字。结果就是要么模型加载了但抓不住重点要么因为太长反而不被召回。一个 skill 聚焦一件事。提交规范一个、代码审查一个、调试流程一个。需要组合的时候让它们各自被召回而不是揉成一坨。单个 skill 正文控制在几百字到一千字出头比较舒服超过两千字就该考虑拆了。7. 常见问题与排查实录7.1 skill 不生效从哪查起这是被问得最多的问题。我整理了一个排查顺序按这个走基本能定位排查项怎么查常见原因文件位置对不对ls .claude/skills/或ls ~/.claude/skills/放错目录或少了.claude这一层文件名对不对确认是SKILL.md大小写写错或写成了skill.mdfrontmatter 完整吗看开头有没有---包裹的name和description漏了 frontmatter或 YAML 格式错误description 够具体吗读一遍问自己什么场景该用它太含糊模型匹配不上有没有被同名覆盖检查项目级和全局有没有重名项目级覆盖了全局你以为在用全局会话是否刷新重开一个会话试试有些版本改动后需要新会话才生效我遇到最多的是文件名大小写和frontmatter 缺失这两个。尤其是从别人那儿拷来的 skill经常只剩正文frontmatter 被删了放进去自然不生效。7.2 全局 skill 太多导致互相干扰全局 skill 装多了之后会出现一种情况你明明想触发 A结果模型加载了 B或者两个都加载了指令打架。解决办法是精简全局 skill 数量并且让 description 之间的边界清晰。如果两个 skill 的 description 都写着处理代码相关问题它们必然互相干扰。把每个 skill 的适用范围收窄比如一个专管提交信息一个专管代码审查一个专管调试定位边界清楚就不容易误触发。实在需要很多 skill 的时候考虑把它们合并成少数几个大类 skill用正文里的小节区分场景。宁可少而精不要多而乱。7.3 迁移到全局后项目里反而不生效了这个情况通常是项目级残留导致的。你迁到全局后项目里可能还留着一个旧的同名 skill项目级优先于是模型加载的还是旧版本。检查一下项目.claude/skills/下是不是还有同名目录有就删掉或更新。还有一种可能是项目级的CLAUDE.md里写了和全局 skill 冲突的指令。CLAUDE.md是常驻的优先级往往高于按需召回的 skill所以它里面的约定会盖过 skill。检查一下CLAUDE.md有没有相关表述。7.4 团队协作时怎么共享 skill项目级 skill 跟着仓库走天然适合团队共享。但要注意两点一是别把个人偏好写进项目级 skill。项目级是团队共用的你个人的提交习惯、你偏好的解释风格不该强加给所有人。这些放你自己的全局 skill 里。二是项目级 skill 要进版本控制。.claude/skills/目录应该被 git 跟踪这样新同事 clone 下来就有。但要注意别把带敏感信息的 skill 提交上去比如包含内部密钥、内部地址的。提交前扫一眼内容。提示如果团队对 skill 有争议可以先在项目级试运行收集反馈再固化。别一上来就当成强制规范容易引起抵触。7.5 几个我踩过的具体坑坑一YAML 里的冒号。description 里如果写了中文冒号或者英文冒号后面跟空格YAML 解析可能出错。稳妥做法是把 description 用引号包起来或者避免在值里用冒号。坑二中文文件名。有些系统对中文路径支持不好skill 目录名尽量用英文小写加短横线别用中文。坑三软链接。有人为了一处修改多处生效把全局 skill 目录软链接到某个 git 仓库。这招能用但要注意 Claude Code 读取时是否跟随软链接不同版本行为可能不一样。用之前先测一下。坑四改完不生效就重启。大部分情况下改 skill 内容不需要重启但如果你改了目录结构或者增删了 skill重开一个会话是最稳的验证方式。别在旧会话里反复试浪费时间。8. 我个人的使用节奏和一些建议用到现在我的 skill 布局大概是这样全局放了五六个都是跨项目通用的——提交规范、审查清单、调试流程、解释风格、通用工具用法。项目级则看仓库一般每个活跃项目两三个都是这个项目特有的约定。我的迁移节奏是新东西先在项目级养养熟了再考虑升全局。一个 skill 我会在至少两个不同项目里用过确认它不依赖具体上下文才挪到全局。挪的时候顺手把 description 再打磨一遍因为全局的匹配范围更广description 得更精准。还有一点体会skill 不是越多越好是越准越好。我早期贪多全局塞了十几个结果互相干扰模型经常加载错。后来砍到五六个每个都打磨得边界清晰反而效果好。现在我加新全局 skill 很谨慎会先问自己这个真的每个项目都用得上吗答案是否定的就留在项目级。最后分享一个我常用的小技巧给 skill 写一个反例小节。比如提交规范 skill 里除了写应该怎么写再写一段这些写法是错的把常见的错误格式列出来。模型看到反例执行时会主动避开比只给正例效果好不少。这个技巧在审查类、格式类 skill 上尤其管用。至于后续还能怎么扩展我最近在试的是把 skill 和项目里的脚本结合起来——skill 里不只写怎么做还写调用哪个脚本做让模型直接执行现成的工具而不是每次现编命令。这条路还在摸索等跑顺了再单独聊。