
1. 从“skills”这个词说起它到底在解决什么问题如果你最近在折腾 Claude Code、Codex 或者各类 agents 工具大概率会频繁撞见一个词——skills。它不是一个新框架也不是某个具体产品而是一套让 AI 助手“学会做事”的能力封装机制。简单说skills 就是把一段可复用的操作流程、领域知识或者工具调用逻辑打包成一个 AI 能识别、能按需加载的模块。你给它一个名字、一段描述、一份执行说明AI 在遇到匹配场景时就会自动调用它而不是每次都要你从头解释一遍。我最初接触 skills 是因为一个很具体的痛点每次让 Claude Code 帮我处理前端项目它都要重新问一遍“你用的是什么构建工具”“目录结构是怎样的”“测试命令是什么”。问一次两次还行天天问就让人烦躁。后来我把这些信息写成一个 skill情况立刻变了——它知道该去哪里找配置知道该跑哪个命令甚至知道哪些文件不该动。这就是 skills 的核心价值把重复的上下文注入变成一次性的能力沉淀。这篇文章适合几类人看。第一类是刚装上 Claude Code 或者 Codex还在摸索怎么让它更听话的开发者第二类是已经在用 agents但觉得每次都要重复交代背景、效率上不去的人第三类是想自己写 skill、把团队内部规范固化下来的工程师。不管你用的是哪个工具skills 的底层逻辑是相通的——它本质上是一种“按需加载的提示词工程 工具编排”方案。我会从设计思路讲到实操细节再把我踩过的坑和排查经验一并倒出来尽量让你看完就能动手做一个自己的 skill。2. skills 的整体设计与核心思路拆解2.1 为什么是“技能”而不是“配置”或“插件”很多人第一次听到 skills会下意识把它类比成 VS Code 的插件或者 ESLint 的配置文件。这个类比有一半对但关键差异在于插件是给编辑器用的配置是给工具链用的而 skill 是给 AI 助手用的。它的消费者不是编译器也不是运行时而是一个语言模型。这就决定了 skill 的设计必须围绕“模型怎么理解、怎么触发、怎么执行”来展开而不是围绕“机器怎么解析”来展开。我试过用纯配置文件的方式给 Claude Code 注入项目信息比如写一个.claude-context.md放在根目录。效果有但很笨——模型每次都要把整个文件读一遍不管当前任务是否相关。skills 的聪明之处在于它是按需加载的每个 skill 有一个简短的描述模型先看描述判断“这个任务需不需要我”需要才加载完整内容。这就像你办公室里有一排工具柜每个柜子外面贴着标签你不需要把所有柜子都打开只看标签就知道该拿哪个。另一个差异是 skills 天然支持工具调用编排。一个 skill 不只是“告诉模型一些知识”它还可以定义“模型应该按什么顺序调用哪些工具”。比如一个“部署前端项目”的 skill可以规定先跑测试、再构建、再上传、最后验证。这种流程化的能力是单纯配置文件做不到的。2.2 skill 的组成结构描述、指令、资源三件套一个标准的 skill 通常由三部分组成。第一部分是元信息包括名称和描述。名称要短、要唯一描述要精准到让模型一眼判断出适用场景。我见过有人把描述写成“帮助处理前端相关事务”这种描述太模糊模型根本不知道该不该触发。好的描述应该像“当用户需要构建、测试或部署 React 项目时使用此技能”。第二部分是执行指令也就是 skill 的主体内容。这里写的是模型在触发这个 skill 后应该遵循的步骤、规则和约束。它可以是一段自然语言说明也可以包含具体的命令示例、文件路径模板、参数说明。我个人的习惯是把指令写成“如果……则……”的形式因为模型对条件判断的理解比纯叙述更稳。第三部分是附属资源比如脚本文件、模板文件、参考文档。这些资源不会一开始就加载而是在 skill 执行过程中按需读取。这样做的好处是节省上下文窗口——你不需要把一堆用不到的代码塞进对话里。2.3 触发机制模型怎么知道该用哪个 skill这是很多人最困惑的地方。skills 的触发不是靠关键词匹配而是靠语义判断。模型会读取所有已安装 skill 的名称和描述然后根据当前对话的上下文判断哪个 skill 最相关。这个过程有点像你在搜索引擎里输入一个问题搜索引擎根据索引决定返回哪些结果。但这里有个坑如果两个 skill 的描述太相似模型可能会选错或者干脆两个都触发。我遇到过这种情况一个叫“frontend-build”一个叫“frontend-deploy”描述里都写了“前端项目”结果模型在只需要构建的时候把部署 skill 也拉进来了。后来我把描述改得更具体构建的写“仅用于编译和打包不涉及发布”部署的写“仅用于发布和验证不涉及编译”问题就解决了。还有一个经验是skill 的数量不宜过多。我一开始兴致勃勃装了二十多个结果模型的选择准确率明显下降。后来精简到八个核心 skill每个都覆盖一个明确的高频场景反而更稳。这跟人一样工具太多反而不知道用哪个。3. 核心细节解析与实操要点3.1 写一个 skill 之前先想清楚这三件事第一件事这个 skill 解决的是“知识缺失”还是“流程缺失”。如果模型只是不知道你的项目结构那 skill 里写清楚目录说明就够了。如果模型知道该做什么但总是做错顺序那 skill 里就要写流程约束。这两种 skill 的写法完全不同前者偏描述后者偏指令。第二件事这个 skill 的触发频率有多高。如果一个操作你一个月才做一次那写 skill 的投入产出比就不高。但如果一个操作你每天都要做哪怕每次只省两分钟一个月下来也是一个小时。我判断的标准是如果同一个解释我说过三遍以上就该写成 skill 了。第三件事这个 skill 会不会和其他 skill 冲突。前面提到过描述相似会导致误触发所以在写之前最好先看看已有的 skill 列表确保新 skill 的定位是独立的、不重叠的。3.2 描述字段的写法精准比华丽重要描述字段是 skill 的“广告语”它的唯一目的是让模型在正确的时候选中它。我总结了一个模板当【触发条件】时使用此技能用于【具体动作】不涉及【排除范围】。举个例子当用户需要对 React 或 Vue 项目进行本地构建和打包时使用此技能用于执行编译、产物检查和构建错误排查不涉及部署和发布。这个描述里“React 或 Vue”限定了技术栈“本地构建和打包”限定了动作“不涉及部署和发布”排除了容易混淆的场景。模型看到这个描述就能比较准确地判断该不该触发。我见过一些反面案例描述写成“一个非常有用的前端技能”或者“帮助开发者提高效率”。这种描述对模型来说等于没说因为它没有提供任何可判断的信息。记住描述不是写给人看的宣传语是写给模型看的判断依据。3.3 指令主体的组织分步骤、给示例、设边界指令主体我通常分成三块来写。第一块是前置检查告诉模型在执行之前应该确认什么。比如“先确认项目根目录存在 package.json如果不存在则停止并提示用户”。第二块是执行步骤按顺序列出每一步做什么、用什么命令、预期结果是什么。第三块是异常处理告诉模型遇到常见错误时该怎么应对。给示例非常重要。模型对抽象描述的理解远不如对具体示例的理解。比如你说“运行构建命令”不如说“运行 npm run build如果失败则检查 node_modules 是否存在”。你说“处理错误”不如说“如果看到 Module not found先检查 import 路径是否正确再检查依赖是否安装”。设边界同样关键。我吃过亏的地方是skill 里没有写“不要做什么”结果模型在执行过程中自作主张改了一些不该改的文件。后来我在每个 skill 末尾都加一段约束比如“不要修改 package.json 中的依赖版本”“不要删除 dist 目录以外的任何文件”。这些约束看起来琐碎但能避免很多意外。3.4 资源文件的组织按需加载别一股脑塞进去如果一个 skill 需要附带脚本或模板我建议单独放在一个目录里然后在指令中引用路径。比如skills/ frontend-build/ SKILL.md scripts/ check-env.sh templates/ build-report.md在 SKILL.md 里写“执行 scripts/check-env.sh 检查环境”模型就会在需要的时候去读这个脚本。不要把脚本内容直接嵌在 SKILL.md 里那样会让 skill 文件变得很长加载时占用大量上下文。还有一个细节资源文件的命名要自解释。check-env.sh比script1.sh好build-report.md比template.md好。模型在决定是否读取某个资源时文件名是重要的判断依据。4. 实操过程与核心环节实现4.1 环境准备Claude Code 和 Codex 的 skill 目录在哪里不同工具的 skill 存放位置不一样。Claude Code 通常会在用户目录下有一个配置文件夹里面有一个 skills 子目录。Codex 类似但路径可能因版本和操作系统而异。我建议你先在工具里执行一次帮助命令或者查看文档确认当前的 skill 目录路径。以我自己的环境为例Claude Code 的 skill 目录在~/.claude/skills/下面每个 skill 一个子目录。Codex 的路径略有不同但结构类似。如果你用的是 VS Code 插件版的 Claude Codeskill 目录可能在项目根目录的.claude/skills/下这样可以让 skill 跟随项目走方便团队共享。注意在 Windows 上路径分隔符和大小写敏感性可能带来问题。我建议 skill 目录名和文件名统一用小写加连字符避免空格和特殊字符。4.2 从零写一个“前端构建检查”skill我拿一个实际例子来演示。假设你经常需要检查前端项目的构建是否正常每次都要手动跑命令、看输出、判断问题。我们把它写成一个 skill。首先创建目录结构mkdir -p ~/.claude/skills/frontend-build-check/scripts然后创建 SKILL.md内容如下--- name: frontend-build-check description: 当用户需要检查前端项目构建是否正常时使用此技能用于执行构建命令、分析构建输出、定位常见构建错误不涉及部署和发布。 --- # 前端构建检查 ## 前置检查 1. 确认当前目录存在 package.json 2. 确认 node_modules 目录存在如果不存在则提示用户先运行安装命令 ## 执行步骤 1. 读取 package.json 中的 scripts 字段找到 build 命令 2. 执行该 build 命令 3. 如果构建成功报告产物目录和文件大小 4. 如果构建失败提取错误信息中的关键行 ## 常见错误处理 - Module not found检查 import 路径和依赖安装 - Syntax error定位到具体文件和行号 - Out of memory建议增加 Node 内存限制 ## 约束 - 不要修改任何源文件 - 不要自动安装依赖 - 不要删除构建产物这个 skill 写完之后你在 Claude Code 里说“帮我检查一下构建”它就会自动触发这个 skill按步骤执行。4.3 参数计算与选择构建超时和内存限制怎么定前端项目构建经常遇到超时和内存问题。我在 skill 里加了一段参数建议这里分享一下我的计算逻辑。Node 默认的内存上限大约是 1.5GB 到 2GB取决于版本。对于一个中等规模的前端项目构建时内存占用通常在 1GB 到 3GB 之间。如果项目依赖很多或者用了大量的图片处理可能超过 4GB。我的经验是如果构建时报 “JavaScript heap out of memory”就把内存限制调到 4096MBNODE_OPTIONS--max-old-space-size4096 npm run build超时方面CI 环境通常默认 10 分钟本地构建一般 1 到 3 分钟。如果超过 5 分钟还没结束可能是某个插件卡住了。我在 skill 里写了一个建议如果构建超过 5 分钟无输出提示用户检查是否有 watch 模式被误触发。这些参数不是拍脑袋定的是根据项目规模和机器配置估算的。你可以根据自己的实际情况调整但建议在 skill 里写清楚“为什么是这个值”这样以后回头看不会忘。4.4 测试 skill 是否生效三个验证方法写完 skill 后怎么知道它有没有生效我用三个方法验证。第一个方法直接问模型“你现在有哪些 skill”。如果 skill 安装正确模型应该能列出你写的那个名称和描述。如果列不出来说明目录位置不对或者文件格式有问题。第二个方法构造一个触发场景看模型是否自动调用。比如你说“帮我看看构建有没有问题”如果模型回复“我将使用 frontend-build-check 技能”或者直接开始执行构建步骤说明触发成功。如果它反问你“你用什么构建工具”说明 skill 没被识别。第三个方法检查执行结果是否符合 skill 里定义的流程。比如 skill 里写了“先检查 package.json”你就看模型有没有先做这一步。如果它跳过了前置检查直接跑命令说明指令的约束力不够可能需要把步骤写得更强硬一些。5. 常见问题与排查技巧实录5.1 skill 不触发从描述到目录逐层排查skill 不触发是最常见的问题。我的排查顺序是这样的先看描述是否足够具体再看目录结构是否正确最后看文件格式是否符合要求。描述问题占大多数。如果你写的描述是“帮助处理前端事务”模型很难判断什么时候该用。改成“当用户需要构建 React 项目时使用”就会好很多。另一个描述问题是和其他 skill 重叠模型可能选了另一个。这时候要么改描述要么合并 skill。目录问题也不少见。有些工具要求 skill 目录下必须有一个特定名称的文件比如 SKILL.md 或者 skill.md大小写敏感。还有些工具要求目录名和 skill 名称一致。我建议你第一次写的时候严格照着官方示例的目录结构来确认能触发之后再改。文件格式问题主要是元信息部分。有些工具要求用 YAML front matter有些要求用 JSON有些要求用特定标记。格式不对的话模型读不到描述自然也不会触发。5.2 skill 触发了但执行不对指令歧义的三种表现有时候 skill 确实被触发了但执行结果不是你想要的。这通常是指令有歧义。我遇到过三种典型情况。第一种是步骤顺序被忽略。我在 skill 里写了“先检查再执行”但模型直接跳到了执行。原因是我的“检查”步骤写得太弱用的是“建议检查”而不是“必须检查”。后来改成“在执行任何命令之前必须先确认以下条件”模型就老实了。第二种是条件判断被误解。我写“如果构建失败则输出错误日志”结果模型在构建成功时也输出了日志。原因是“失败”的定义不明确。后来我改成“如果命令返回非零退出码则视为失败”问题解决。第三种是约束被绕过。我写了“不要修改源文件”但模型还是改了一个配置文件。原因是这个约束放在 skill 末尾模型可能没注意到。后来我把约束提到指令开头并且用加粗标记情况好转。5.3 多个 skill 冲突优先级和合并策略当你装了多个 skill 之后可能会遇到两个 skill 同时被触发的情况。比如一个“代码格式化”skill 和一个“代码检查”skill在你说“帮我整理一下代码”时可能同时激活。我的处理策略是如果两个 skill 经常一起触发考虑合并成一个。如果只是偶尔冲突可以在描述里加排除条件。比如格式化 skill 的描述里写“不涉及代码质量检查”检查 skill 的描述里写“不涉及自动格式化”。还有一个技巧是给 skill 设优先级。有些工具支持在元信息里指定优先级数字越小越优先。如果不支持可以在描述里暗示比如“当其他技能不适用时使用此技能”。5.4 常见问题速查表问题现象可能原因排查方法解决方式skill 完全不触发描述太模糊问模型“你有哪些 skill”改写描述加入具体触发条件skill 触发但跳过步骤指令约束力弱检查步骤是否用了“必须”把关键步骤改为强制语气两个 skill 同时触发描述重叠查看两个 skill 的描述合并或加排除条件执行结果不稳定指令有歧义复现三次看是否一致补充条件判断和示例资源文件读不到路径写错检查 skill 目录结构用相对路径并确认文件名模型改了不该改的文件约束不明显检查约束位置把约束提到开头并加粗5.5 我踩过的三个坑第一个坑是 skill 名称用了中文。当时觉得中文更直观结果模型在引用时经常出现编码问题有时候触发不了。后来全部改成英文小写加连字符再也没出过问题。第二个坑是 skill 里写了太多背景知识。我一开始把整个项目的架构说明都塞进了一个 skill结果加载时占用了大量上下文模型反而变笨了。后来我把背景知识拆成独立的参考文档skill 里只保留操作指令需要时再让模型去读文档。第三个坑是忘了版本管理。skill 文件改来改去有时候改坏了想回退都找不到之前的版本。后来我把 skill 目录纳入 Git 管理每次修改都提交这样既能追溯又能共享给团队。6. 进阶玩法让 skills 真正融入日常工作流6.1 团队共享把 skill 放进项目仓库个人用的 skill 放在用户目录下没问题但如果是团队协作最好把 skill 放进项目仓库的.claude/skills/或者对应工具的约定目录里。这样每个成员拉取代码后自动获得相同的 skill不需要手动配置。我现在的做法是通用 skill 放在用户目录项目相关的 skill 放在项目仓库。项目 skill 里写清楚这个项目的特定命令、目录约定和注意事项。新成员入职时只要装好工具skill 就自动生效省去了大量口头交接。注意项目 skill 里不要写敏感信息比如密钥、内部地址。这些应该通过环境变量或者单独的配置文件管理。6.2 动态 skill根据环境变量切换行为有些 skill 需要在不同环境下表现不同。比如构建 skill在开发机上跑测试在 CI 上跳过测试直接构建。我通过在 skill 指令里读取环境变量来实现## 执行步骤 1. 检查环境变量 CI 是否存在 2. 如果 CI 存在跳过测试步骤直接执行构建 3. 如果 CI 不存在先执行测试再执行构建这样同一个 skill 就能适应不同场景不需要维护两个版本。6.3 skill 的迭代从能用 to 好用skill 不是写完就完了需要根据使用反馈不断迭代。我的习惯是每次用完 skill 后如果发现模型有一步做错了或者我自己觉得“这里应该更顺一点”就立刻记下来当天修改 skill 文件。迭代的重点通常是三个方面描述是否还能更精准步骤是否还能更简洁约束是否还能更明确。我有个 skill 改了十几版从最初的三百字改到现在的八百字但触发准确率和执行成功率都大幅提升。还有一个经验是不要一次性写太多 skill。先写一个用一周改到稳定再写下一个。同时维护多个新 skill 会让你分不清是哪个出了问题。6.4 和其他工具链的配合skill 不是孤岛skills 可以和 Git hooks、CI 流程、代码审查工具配合使用。比如你可以写一个 skill在提交代码前自动检查 skill 里定义的规范也可以在 CI 里调用 skill 来执行标准化的构建和测试流程。我目前的做法是本地开发用 skill 做快速检查提交时用 Git hook 做强制检查CI 上再用 skill 做完整验证。三层防护基本不会漏掉问题。skill 在这里扮演的是“可执行的规范文档”角色比纯文字文档更有约束力。7. 一些个人体会和后续可以尝试的方向我用 skills 大概有大半年了最大的感受是它改变了我跟 AI 助手协作的方式。以前是我告诉它做什么现在是我定义好能力边界它自己判断该做什么。这种转变听起来很小但实际体验差别很大——就像从手动挡换到自动挡你不再需要频繁地踩离合换挡可以把注意力放在路况上。如果让我给刚接触 skills 的人一个建议那就是从你最烦的那件事开始。不要想着一次性建一套完整的 skill 体系先解决一个具体痛点。我写的第一个 skill 就是“检查构建”因为那是我每天都要重复的操作。写完之后立刻感受到效率提升才有动力继续写第二个、第三个。后续我打算尝试的方向有两个。一个是把 skill 和测试框架结合让 skill 不仅能执行操作还能验证操作结果是否符合预期。另一个是探索 skill 之间的组合调用比如一个“发布”skill 自动调用“构建”skill 和“检查”skill形成更长的自动化链条。这些还在摸索阶段等有稳定经验了再分享。