拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Claude Code Skills 从项目级到全局:安装、迁移与最佳实践

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 是按需召回。它有一个描述(description),Claude Code 会根据你当前的任务、你输入的内容,判断要不要把这个 skill 的内容加载进来。也就是说,一个 skill 可以写得很长很细,但只要当前任务用不上,它就不占你的上下文预算。这是它比CLAUDE.md更适合承载"流程性知识"的根本原因。

打个比方:CLAUDE.md像是贴在工位上的便签,抬头就能看见;Skill 像是抽屉里的操作手册,需要拧螺丝的时候才抽出来翻。你不会把所有手册都摊在桌上,但你希望需要的时候一伸手就能拿到。

2.2 一个 skill 的最小结构

一个 skill 本质上就是一个目录,里面至少有一个SKILL.md(有些版本叫skill.md,大小写敏感问题后面会专门讲)。这个文件由两部分组成:YAML frontmatter和正文。

frontmatter 里最关键的是两个字段:

  • name:skill 的标识名,通常用短横线连接的小写单词,比如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。先做一次"通用性体检":

  1. 通读 skill 正文,把所有提到具体项目名、具体路径、具体内部服务的地方标出来。
  2. 判断这些具体信息是"必须保留"还是"可以抽象"。比如"调用deploy.sh部署到 staging"是项目特有的,得删或改;"提交前跑一遍测试"是通用的,保留。
  3. 把抽象后的版本写出来,确保它在任何项目里读起来都成立。

我踩过一次坑:把一个写了一半的 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.md
frontmatter 完整吗看开头有没有---包裹的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 里不只写"怎么做",还写"调用哪个脚本做",让模型直接执行现成的工具,而不是每次现编命令。这条路还在摸索,等跑顺了再单独聊。

返回列表