1. 从"skills"这个模糊词说起:它到底指什么
第一次看到"skills"这个标题,很多人会懵——这词太泛了。技能?技巧?还是某个具体产品的功能模块?结合热搜词里高频出现的 Claude Code、Codex、agents、plugin 这几个词,基本可以锁定:这里说的 skills,是围绕 AI 编程助手(尤其是 Claude Code 和 Codex 这类命令行/编辑器内的 agent 工具)构建的一套"可插拔能力单元"。
打个比方。传统的 AI 编程助手像是一个刚入职的应届生,脑子聪明、知识面广,但对你们团队的代码规范、部署流程、日志格式一无所知。你每次都得在对话里反复交代"我们项目用 pnpm 不用 npm""提交信息要遵循 Conventional Commits""测试文件放在tests目录下"。而 skills 就是给这个应届生发的一本《团队作业手册》,里面写清楚每件事该怎么做,他遇到对应场景就自动翻手册,不用你每次重复。
从技术形态上看,一个 skill 通常是一个目录,里面包含一份描述文件(声明这个 skill 叫什么、什么时候触发、需要哪些工具权限)加上若干脚本或提示词模板。Claude Code 和 Codex 都支持这种机制,只是叫法和加载方式略有差异。Claude Code 里叫 Agent Skills,Codex 里更偏向 plugin 化的组织方式,但核心思想一致:把"怎么做某件事"从一次性对话里抽出来,变成可复用、可版本管理、可分享的资产。
为什么这个方向突然火了?因为大家用 AI 写代码用了一段时间后发现,模型能力本身不是瓶颈,上下文和流程才是。同一个模型,你给它一份清晰的 skill 定义,产出质量能差出一个档次。热搜里"claude agent skills: a first principles deep dive""agent skills测试""skills开发"这些词扎堆出现,说明社区已经从"尝鲜"进入"自己造轮子"的阶段了。
这篇文章面向三类人:一是刚装上 Claude Code 或 Codex、还在摸索怎么让它更听话的新手;二是想把自己团队的规范沉淀成 skill 的中级用户;三是想开发、分发 skill 给别人的进阶玩家。我会从概念、安装、编写、调试、避坑几个层面把这件事讲透,尽量给到能直接抄的操作。
2. Claude Code 与 Codex 的 skills 机制差异
2.1 两者的加载逻辑并不一样
很多人以为 skills 是个统一标准,装到哪都一样。实际不是。Claude Code 的 Agent Skills 走的是"目录扫描 + 描述匹配"路线:你把 skill 目录放到指定位置(项目级或用户级),启动时它会读取每个 skill 的元信息,当你的对话内容触发了某个 skill 的描述条件,它才把该 skill 的完整内容加载进上下文。这个设计的好处是省 token——没触发的 skill 不占上下文。
Codex 这边更接近传统 plugin 的思路,热搜里"dsh plugin --profile web add dshmarket""idea设置plugin中插件仓库地址"这些词能看出,它的生态更偏向"仓库 + 安装命令"的模式。Codex 的 skill/plugin 往往需要显式声明依赖、权限,加载时机也更靠前。两者对比大致是这样:
| 维度 | Claude Code Agent Skills | Codex Plugin/Skills |
|---|---|---|
| 组织方式 | 目录 + 描述文件 | 仓库 + 清单文件 |
| 触发机制 | 描述匹配,按需加载 | 声明式,启动或调用时加载 |
| 作用范围 | 项目级 / 用户级 | 项目级 / 全局配置 |
| 分发方式 | 复制目录或从市场安装 | 从插件仓库安装 |
| 权限模型 | 工具白名单 | 清单声明权限 |
这个差异直接影响你的选型。如果你只是想让 AI 遵守团队代码规范,Claude Code 的 skill 更轻量,写个描述文件加提示词就行。如果你要做的是"接入某个内部系统""调用特定 CLI 工具链"这种重活,Codex 的 plugin 模型在依赖管理和权限控制上更规范。
2.2 为什么会有"国内安装 skills 官方市场"这类需求
热搜里"claude 国内安装skills 官方市场""前任skills官方下载"这类词,反映的是一个现实问题:官方市场的访问和安装体验,在不同网络环境下差异很大。这里我不展开网络层面的东西,只说工程上的应对思路——把 skill 当成普通代码资产来管理。
具体做法是:不要依赖"在线一键安装"这一条路。把常用的 skill 目录 clone 到本地一个统一的仓库里,用 git 做版本管理,需要的时候软链接或复制到 Claude Code / Codex 的 skills 目录。这样即使市场访问不稳定,你的核心 skill 资产也不受影响。我自己的做法是建了一个~/ai-skills仓库,里面按claude/和codex/分目录,每个 skill 一个子目录,用 git submodule 管理第三方 skill。升级就是git pull,回滚就是git checkout,比在图形界面里点来点去可靠得多。
2.3 安装路径这件事,坑比想象中多
Claude Code 的 skill 目录位置,项目级一般在项目根目录下的.claude/skills/,用户级在~/.claude/skills/。Codex 的配置目录则通常在~/.codex/下。热搜里"ubuntu配置claude code""vscode配置claude code""claude code windows"这些词说明跨平台配置是高频痛点。
Windows 上尤其要注意路径分隔符和大小写。我遇到过 skill 目录名写成MySkill但描述文件里引用的是myskill,在 Linux 上没事,到 Windows 上就加载失败。统一用小写加连字符命名(my-skill)能避开这类问题。另外,如果你用 WSL,要注意 Claude Code 是装在 WSL 里还是 Windows 侧,两边的~指向不同目录,skill 放错地方就会"明明装了却不生效"。
3. 一个 skill 的最小可用结构长什么样
3.1 描述文件是整个 skill 的大脑
skill 能不能被正确触发,八成取决于描述文件写得好不好。它一般包含几个关键字段:名称、描述(什么时候用)、允许使用的工具、以及正文指令。描述字段是触发匹配的核心,写法上有个诀窍——用"当用户……时"的句式,把触发场景写具体。
反面例子:description: 帮助处理代码。这种描述几乎匹配不到任何具体场景,等于没写。
正面例子:description: 当用户要求生成数据库迁移脚本、修改表结构或讨论 schema 变更时使用。适用于使用 Prisma 或 TypeORM 的项目。这样写,模型在判断"当前对话是否该加载这个 skill"时就有明确依据。
3.2 正文指令要像写给新人的 SOP
描述文件里的正文部分,本质是一份标准作业程序。我建议按这个顺序组织:先说要做什么(目标),再说分几步(流程),然后给每步的具体命令或代码模板,最后列禁止事项。
举个真实例子。我们团队有个"生成 API 接口"的 skill,正文大致是这样:
## 目标 为现有项目新增一个 REST 接口。 ## 流程 1. 在 src/routes/ 下新建路由文件,命名用 kebab-case。 2. 在 src/controllers/ 下实现处理逻辑,必须做入参校验。 3. 在 src/services/ 下写业务逻辑,数据库操作只在这一层。 4. 补充对应的单元测试到 tests/routes/。 ## 模板 路由文件模板见 templates/route.ts 控制器模板见 templates/controller.ts ## 禁止 - 不要在控制器里直接写 SQL。 - 不要跳过入参校验。 - 不要修改已有的数据库迁移文件。这份 SOP 写清楚之后,AI 生成的接口代码风格基本和我们手写的一致,review 成本大幅下降。
3.3 脚本和模板怎么放
skill 目录里除了描述文件,通常还有scripts/和templates/两个子目录。脚本用于执行确定性操作(比如跑 lint、生成文件),模板用于给 AI 提供代码骨架。这里有个经验:能用脚本做的确定性事情,就别让 AI 自由发挥。比如"格式化代码"这种活,写个脚本调用 prettier,比让 AI 手动调整缩进可靠一万倍。
模板文件建议用真实项目里已经 review 过的代码,去掉业务细节,保留结构。这样 AI 生成的代码天然符合团队习惯。我见过有人模板里留了一堆TODO和占位符,结果 AI 把占位符原样输出到生产代码里,这种低级错误完全可以通过"模板即真实代码"来避免。
4. 从零写一个 skill 的完整过程
4.1 先想清楚"这件事值不值得做成 skill"
不是所有重复劳动都值得 skill 化。判断标准有三条:第一,这件事是否高频发生(一周至少几次);第二,这件事是否有明确的、可复现的步骤;第三,这件事的产出是否有统一标准。三条都满足,才值得投入时间写 skill。
反例:一次性的大重构、需要大量人工判断的架构决策,这些做成 skill 收益很低,因为触发场景太窄,写描述文件的成本比直接用对话还高。
正例:新增 CRUD 接口、写单元测试、生成 changelog、按规范提交代码、把某个日志格式解析成结构化数据。这些事高频、步骤固定、产出有标准,skill 化收益极高。
4.2 目录结构和命名约定
我推荐的目录结构:
my-skill/ ├── SKILL.md # 描述文件,含元信息和正文指令 ├── scripts/ │ └── format.sh # 确定性操作脚本 ├── templates/ │ └── component.tsx # 代码模板 └── README.md # 给人看的说明,AI 不读命名统一用小写加连字符,动词开头更直观,比如gen-api-route、write-unit-test、parse-access-log。避免用helper、utils这种无信息量的名字,因为描述匹配时名字也会参与判断。
4.3 描述文件的字段逐个拆解
以 Claude Code 的 Agent Skills 为例,描述文件头部通常是 YAML 格式的元信息:
--- name: gen-api-route description: 当用户要求新增 REST 接口、添加路由或实现某个 API 端点时使用。适用于使用 Express 或 Fastify 的 Node.js 项目。 allowed-tools: - Read - Write - Edit - Bash ---allowed-tools这个字段很关键,它决定了这个 skill 能调用哪些工具。原则是最小权限——只给必需的。比如一个纯生成代码的 skill,不需要Bash权限,就别给,避免它执行意料之外的命令。热搜里"agentpoison: red-teaming llm agents via poisoning memory"这类词提醒我们,skill 的权限边界是安全的第一道防线,给太宽等于把家门钥匙随便发。
4.4 正文指令的写法:把"隐性知识"显性化
写正文指令最难的地方,是把老员工脑子里的"隐性知识"写出来。比如"我们项目的错误处理要统一用 AppError 类",这种话老员工觉得理所当然,但新人(和 AI)不知道。写 skill 的过程,其实就是一次团队知识的梳理。
我建议用"如果……就……"的句式覆盖分支情况。比如:
- 如果接口需要鉴权,在路由定义里加
authMiddleware。 - 如果涉及金额计算,必须用
decimal.js,禁止用浮点数。 - 如果新增了环境变量,同步更新
.env.example和部署文档。
这些分支写全了,AI 的产出才稳定。写的时候可以边写边问自己:"上次新人在这件事上犯的错是什么?"把那些错都变成禁止事项。
4.5 本地测试:别等上线才发现触发不了
skill 写完必须测。测试分两层:触发测试和产出测试。
触发测试就是看描述匹配准不准。方法是构造几种典型对话,看 skill 是否被正确加载。比如你的 skill 是"生成单元测试",那就试试说"帮我给这个函数写测试""补一下测试覆盖""这个模块缺测试",看三种说法是否都能触发。如果某种说法触发不了,说明描述文件里的关键词覆盖不够,回去补。
产出测试就是看生成结果是否符合预期。这里有个技巧:故意给一些边界输入,比如空函数、超长函数、有副作用的函数,看 AI 是否按 skill 里的规则处理。我测"生成单元测试"这个 skill 时,专门给了一个依赖外部 API 的函数,看它是否会正确地 mock 掉外部调用——结果第一次就翻车了,它直接真实调用了 API。后来在 skill 里补了一条"涉及外部依赖必须 mock",问题才解决。
5. 调试 skill 时最常撞上的几类问题
5.1 skill 装了但完全不触发
这是最高频的问题。排查顺序建议这样走:
第一步,确认目录位置对不对。项目级 skill 必须在项目根目录的.claude/skills/下,用户级在~/.claude/skills/下。放错层级是最常见的原因。
第二步,确认描述文件格式对不对。YAML 头部的---必须成对出现,字段名大小写敏感。我见过有人把description写成Description,结果整个元信息解析失败,skill 静默不加载。
第三步,确认描述是否太窄。如果描述里写死了"当用户说'生成接口'时使用",那用户说"加个 API"就触发不了。描述要覆盖同义表达。
第四步,看是否有语法错误导致整个 skills 目录加载中断。一个 skill 的描述文件坏了,有可能影响同目录下其他 skill 的加载。这种情况建议逐个禁用排查。
5.2 触发了但行为不符合预期
这种情况通常是正文指令写得不够明确。AI 会"合理发挥",而它的合理和你的合理不一定一致。解决办法是把模糊表述改成确定性指令。
模糊:代码要写得清晰。 确定:函数不超过 30 行,超过则拆分;变量名用完整单词,禁止缩写(循环变量 i、j 除外)。
另一个原因是 skill 之间冲突。如果你装了两个都涉及"写测试"的 skill,模型可能混用两者的规则。这时候要么合并,要么在描述里把触发边界划清楚。
5.3 权限报错和工具不可用
热搜里"codex无法加载组织设置""your organization has disabled claude subscription access"这类词,反映的是权限和账号层面的问题。这类问题往往不在 skill 本身,而在运行环境。排查时先确认基础功能是否正常——如果连普通对话都报权限错,那跟 skill 无关,先解决账号或配置问题。
skill 层面的权限问题,通常是allowed-tools里没声明某个工具,但正文指令里又要求用它。比如正文说"运行测试",但没给Bash权限,执行时就会失败。解决办法是把需要的工具补进白名单,同时遵循最小权限原则。
5.4 跨平台路径问题
Windows、macOS、Linux 三套系统的路径处理差异,是 skill 脚本翻车的重灾区。脚本里尽量用相对路径,必须用绝对路径时通过环境变量传入。文件路径拼接用编程语言提供的 API(如 Node 的path.join),别手写字符串拼接。换行符也要注意,脚本文件统一用 LF,避免在 Windows 上出现\r导致的解析问题。
6. 让 skill 真正好用的几个进阶思路
6.1 把 skill 当代码一样做版本管理和 code review
skill 是团队资产,就该走代码流程。每次修改 skill,提交 PR,让同事 review。review 的重点是:描述是否覆盖了新的触发场景、禁止事项是否补充了新的踩坑、模板是否和当前项目结构一致。我们团队的做法是,每次有人发现 AI 产出有问题,第一反应不是"这次手动改一下",而是"这个 skill 该补一条规则了"。久而久之,skill 越来越厚,AI 的产出越来越稳。
6.2 用组合而非单体
不要试图写一个"什么都能干"的巨型 skill。skill 之间应该职责单一、可以组合。比如"生成接口"和"生成测试"是两个 skill,"生成接口"的正文里可以提示"完成后建议调用 write-unit-test skill 补充测试"。这种组合方式比把所有逻辑塞进一个文件更易维护,也更容易复用。
6.3 给 skill 加"自检"环节
好的 skill 会在产出后自我检查。比如生成代码的 skill,最后一步可以是"运行 lint 和类型检查,如果有错误则修复后重新检查"。这一步能拦掉大量低级错误。实现方式是在正文指令里明确写出自检命令,并给对应的工具权限。
6.4 关注 skill 的"上下文成本"
每个被加载的 skill 都会占用上下文窗口。skill 写得太长,会挤占对话本身的空间,反而降低效果。经验值是单个 skill 正文控制在 500 到 1500 字之间,超出的部分拆成多个 skill 或放到外部文档里按需读取。热搜里"claude agent skills: a first principles deep dive"这类深度文章,讨论的核心之一就是上下文预算的分配。
6.5 建立团队内部的 skill 市场
当 skill 数量超过十几个,就需要一个索引。最简单的做法是维护一个SKILLS.md,列出每个 skill 的名称、用途、维护人、最近更新时间。进阶一点可以做个内部网页,支持搜索。热搜里"find skills""skills推荐"说明社区对发现和筛选 skill 有强需求,团队内部同样如此。没有索引的 skill 库,等于没有。
7. 我踩过的几个真实坑
说几个具体的,都是文档里不会写、只有实际用过才知道的。
第一个坑:skill 描述里用了中文标点。有次我写描述时用了中文逗号,结果 YAML 解析报错,整个 skill 静默失效,排查了半小时才发现是标点问题。现在我的习惯是描述文件里所有标点都用英文半角。
第二个坑:模板文件里留了注释掉的旧代码。AI 有时候会把注释里的代码也当成参考,生成出已经废弃的写法。后来我定了个规矩:模板文件里不留任何注释掉的代码,废弃写法直接删。
第三个坑:skill 更新后没重启会话。Claude Code 和 Codex 通常在会话启动时加载 skill,改了 skill 文件后如果还在旧会话里,改动不生效。必须开新会话。这个坑我踩过不止一次,每次都是"明明改了怎么没用",最后发现是没重启。
第四个坑:多个 skill 抢同一个触发场景。有段时间我装了两个都涉及"提交代码"的 skill,一个要求用 Conventional Commits,一个要求用团队自定义格式,结果 AI 每次提交信息格式都不一样。后来合并成一个,冲突才消失。skill 之间触发场景重叠时,要么合并,要么明确划界。
第五个坑:脚本里的硬编码路径。早期写的 skill 脚本里写死了/Users/xxx/project,换台机器就废了。现在所有脚本都用相对路径或环境变量,可移植性好了很多。
8. 关于 skill 生态的一点个人观察
从热搜词的变化能看出一个趋势:skills 正在从"个人玩具"变成"团队基础设施"。早期大家讨论的是"怎么装""哪个好用",现在讨论的是"怎么开发""怎么测试""怎么防投毒"。这个转变说明 AI 编程助手已经进入生产环境,围绕它的工程化配套必须跟上。
我的判断是,未来 skill 会像 npm 包一样,形成分发、版本、依赖管理的完整生态。现在已经能看到苗头——有 skill 市场、有 skill 仓库、有 skill 的测试框架。对开发者来说,学会写 skill 会变成一项基础技能,就像当年学会写 npm 包、写 Dockerfile 一样。
但也要清醒:skill 不是银弹。它解决的是"流程标准化"问题,解决不了"模型能力边界"问题。一个 skill 写得再好,也救不了一个本身就不适合用 AI 做的任务。判断什么该 skill 化、什么该人工做,这个判断力比写 skill 的技术本身更重要。
最后分享一个我一直在用的小习惯:每次用 AI 完成一个任务后,花两分钟想想"这件事下次还会不会遇到,如果会,能不能沉淀成 skill"。大部分时候答案是"不会",那就跳过;偶尔答案是"会",那就顺手写个 skill。日积月累,你的 skill 库就成了你个人和团队效率的复利资产。这比追求"装了多少个 skill"有意义得多。