1. 从“skills”这个热词说起:它到底是什么,为什么突然火了
最近半年,不管是在开发者社区还是各种技术群里,“skills”这个词出现的频率高得离谱。很多人第一次看到它,会以为是某个新出的前端框架,或者某个插件市场的名字。其实不是。这里的skills,指的是围绕 AI 编程助手(尤其是 Claude Code、Codex 这类终端里的智能体)构建的一套可复用能力单元。你可以把它理解成给 AI 助手装的“技能包”——每个 skill 就是一段封装好的指令、脚本或者工作流,让 AI 在特定场景下知道该怎么做、按什么规范做、调用哪些工具去做。
我最早接触这个概念,是在折腾 Claude Code 的时候。当时我让它帮我改一个 Flutter 项目的 Gradle 配置,结果它给出的方案总是差那么点意思,要么漏了 plugin 的声明顺序,要么把apply plugin的写法搞混。后来我才意识到,问题不在于模型不够聪明,而在于它缺少这个项目、这个技术栈的“上下文技能”。于是我开始研究怎么把常用的操作规范、项目约定、工具调用方式沉淀成 skill,让 AI 每次都能按我期望的方式来干活。这一研究就停不下来了,因为 skills 这套机制一旦用顺,效率提升是肉眼可见的。
这篇文章我想聊的,不是某个官方文档的复述,而是我自己从零开始搭建、调试、踩坑、优化 skills 的完整经验。内容包括 skills 的核心设计思路、怎么写出一个好用的 skill、在 Claude Code 和 Codex 里怎么落地、遇到报错怎么排查,以及我整理出来的一套常见问题速查表。不管你是刚听说 skills 想入门,还是已经在用但总觉得效果不稳定,应该都能从里面找到能直接抄作业的东西。
提示:本文提到的所有操作均基于公开的开发者工具和本地环境配置,不涉及任何特殊网络手段。如果你在安装或配置过程中遇到环境问题,优先检查本地依赖版本和官方文档的说明。
2. skills 的核心设计思路:为什么不是简单的提示词
2.1 从“一次性提示”到“可复用能力”的转变
很多人用 AI 编程助手的方式,还是停留在“我问一句,它答一句”的阶段。这种方式在简单任务上没问题,但一旦任务变复杂,比如要改一个多模块项目的构建脚本,或者要按团队规范生成一套测试代码,纯靠临时提示词就会非常不稳定。原因很简单:每次对话都是独立的,AI 不知道你上次是怎么做的,也不知道你们团队的代码规范是什么。
skills 要解决的就是这个问题。它把“怎么做某件事”的知识从一次性的对话里抽出来,变成一个持久化的、可被反复调用的能力单元。这个单元里可以包含自然语言指令、示例代码、参数模板、甚至是对外部工具的调用逻辑。当 AI 遇到相关任务时,它会自动加载对应的 skill,按照里面定义的流程来执行。
我打个比方:临时提示词就像你每次去一家新餐厅,都要跟服务员从头解释你想吃什么、忌口什么、口味偏好如何;而 skill 就像你在这家餐厅办了一张会员卡,卡里存好了你的所有偏好,下次来直接刷卡就行。效率差距不是一点半点。
2.2 skills 的组成结构:一个 skill 里到底装了什么
根据我的实际使用经验,一个完整的 skill 通常包含以下几个部分:
- 触发条件:定义这个 skill 在什么情况下被激活。可以是指令关键词,也可以是任务类型,比如“当用户要求修改 Gradle 配置时”。
- 执行指令:告诉 AI 具体要做什么、按什么顺序做、每一步的输入输出是什么。
- 参考示例:给出正确和错误的示例,帮助 AI 理解边界。这一步非常关键,我后面会详细讲。
- 工具依赖:声明这个 skill 需要调用哪些外部命令或工具,比如
dsh plugin --profile web add dshmarket这类插件管理命令。 - 校验规则:定义执行完成后如何验证结果是否正确,比如检查某个配置文件是否被正确修改。
这五个部分里,参考示例和校验规则是最容易被忽略但最重要的。很多人写 skill 只写“你要做什么”,不写“做对了长什么样、做错了长什么样”,结果 AI 执行出来的东西时好时坏。我的经验是,一个好的 skill 里,示例代码的篇幅应该占到整个 skill 内容的三分之一以上。
2.3 为什么 skills 对 Claude Code 和 Codex 特别重要
Claude Code 和 Codex 这类工具的运行环境是终端,它们能直接读写文件、执行命令、查看输出。这个能力很强,但也意味着一旦出错,影响是直接的——可能改坏你的项目文件,可能执行了不该执行的命令。skills 在这里起到的作用,相当于给 AI 加了一层“操作规范护栏”。
举个例子,我在用 Codex 接入本地模型(比如通过 LM Studio)的时候,如果没有 skill 约束,它可能会尝试用一些不兼容的 API 格式去请求,导致cc switch local proxy failed while handling codex endpoint /responses这类报错。后来我写了一个专门的 skill,在里面明确规定了本地模型的 endpoint 格式、请求头设置、以及失败后的重试逻辑,这个问题就再也没出现过。
另外,skills 还能解决“组织设置无法加载”这类问题。Codex 在某些环境下会提示codex无法加载组织设置,这通常是因为配置文件路径或者权限不对。我在 skill 里加了一段环境检查逻辑,让 AI 在执行任务前先确认配置文件是否存在、是否有读权限,如果没有就给出明确的修复步骤,而不是直接报错退出。
3. 动手写第一个 skill:从需求拆解到落地
3.1 先想清楚:这个 skill 要解决什么具体问题
写 skill 最忌讳的就是“大而全”。我见过有人试图写一个“万能前端开发 skill”,结果里面塞了几百行指令,AI 加载后反而不知道该听哪条。正确的做法是一个 skill 只解决一个具体问题,问题越具体,skill 的效果越好。
比如,与其写“帮我处理 Flutter 项目的构建问题”,不如拆成几个独立的 skill:
flutter-gradle-plugin-order:专门处理 Gradle plugin 声明顺序问题flutter-build-variant-config:专门处理构建变体配置flutter-dependency-conflict:专门处理依赖冲突排查
这样拆的好处是,每个 skill 的触发条件清晰,执行指令短小精悍,AI 不容易混淆。而且当某个 skill 效果不好时,你可以单独调试它,不会影响其他 skill。
3.2 写 skill 的实操步骤:以 Gradle 配置为例
下面我以“修复 Flutter 项目中 Gradle plugin 声明顺序”这个具体问题为例,完整走一遍写 skill 的流程。
第一步:收集正确和错误的示例。
我先在项目里找到一段有问题的 Gradle 配置,它长这样:
// 错误示例:plugin 声明顺序不对 apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'flutter' // 正确示例:Flutter 的 plugin 应该在最前面 apply plugin: 'flutter' apply plugin: 'com.android.application' apply plugin: 'kotlin-android'这个顺序问题会导致you are applying flutter's main gradle plugin imperatively using the apply s这类警告,严重时构建会失败。
第二步:把问题描述和示例写成 skill 内容。
我的 skill 文件大概长这样:
# Skill: flutter-gradle-plugin-order ## 触发条件 当用户要求修改 Flutter 项目的 build.gradle 文件,或者构建时出现 plugin 声明顺序相关警告时激活。 ## 执行指令 1. 读取项目根目录和 android/app 目录下的 build.gradle 文件。 2. 检查 `apply plugin` 语句的顺序。 3. 确保 `apply plugin: 'flutter'` 出现在所有其他 plugin 声明之前。 4. 如果顺序不对,调整后保存文件。 5. 运行 `flutter clean` 和 `flutter pub get` 验证。 ## 正确示例 (此处放入上面那段正确代码) ## 错误示例 (此处放入上面那段错误代码) ## 校验规则 - 调整后再次读取文件,确认 flutter plugin 在第一位。 - 运行构建命令,确认没有 plugin 顺序相关警告。第三步:在 Claude Code 或 Codex 中注册这个 skill。
不同工具的注册方式略有不同。Claude Code 通常是通过配置文件或者项目根目录下的特定文件夹来识别 skill。Codex 则可能需要通过插件机制或者环境变量来加载。我一般会把 skill 文件放在项目根目录的.skills/文件夹下,然后在工具的配置里指向这个目录。
注意:skill 文件的命名要清晰,最好用英文小写加连字符,避免空格和特殊字符。我踩过一次坑,用中文命名 skill 文件,结果在某些环境下加载失败,排查了半天才发现是编码问题。
3.3 让 skill 真正好用的三个细节
写完第一个 skill 后,我发现效果并没有想象中那么好。AI 有时候会加载 skill,有时候不会;加载了之后,执行结果也时对时错。后来我总结了三个关键细节,调整之后效果明显提升。
细节一:触发条件要写得“窄”而不是“宽”。
一开始我把触发条件写成“当用户要求修改 Gradle 文件时”,结果 AI 在任何跟 Gradle 相关的任务里都会加载这个 skill,包括那些跟 plugin 顺序无关的任务。后来我改成“当用户要求修改 Gradle 文件,且任务涉及 plugin 声明或构建警告时”,精准度就上来了。
细节二:执行指令要分步骤,每步都有明确的输入输出。
不要写“检查并修复 plugin 顺序”这种笼统的指令。要写成“第一步读取文件,第二步定位 apply plugin 语句,第三步比较顺序,第四步调整,第五步验证”。每一步都清楚,AI 执行起来才不会跳步。
细节三:校验规则要可执行,不能是“确认没问题”这种主观判断。
“确认没问题”这种校验等于没校验。要写成具体的命令或检查项,比如“运行flutter build apk --debug,确认退出码为 0”。这样 AI 才能真的去验证,而不是假装验证。
4. 在 Claude Code 和 Codex 中落地 skills 的完整流程
4.1 Claude Code 的 skills 加载机制与配置要点
Claude Code 对 skills 的支持相对成熟,它会在启动时扫描指定目录下的 skill 文件,并在对话过程中根据触发条件自动加载。我在 Ubuntu 和 Windows 上都配置过,流程基本一致,但有几个细节需要注意。
在 Ubuntu 上,我通常把 skill 目录放在~/.claude/skills/下,然后在 Claude Code 的配置文件里加上一行指向这个目录。Windows 上则是放在%USERPROFILE%\.claude\skills\。如果你用的是 VS Code 里的 Claude Code 插件,配置路径可能会有所不同,需要看插件的文档。
一个常见的坑是:skill 文件写好了,但 Claude Code 启动时没有加载。这通常是因为文件权限不对,或者目录路径里有中文。我建议 skill 目录和文件名全部用英文,权限设置为当前用户可读写。
另外,Claude Code 在加载 skill 时会解析文件内容,如果文件里有语法错误(比如 Markdown 格式不对),它可能会静默跳过这个 skill。所以写完 skill 后,最好用 Markdown 预览工具检查一下格式。
4.2 Codex 的 skills 接入方式与本地模型适配
Codex 的 skills 机制跟 Claude Code 不太一样,它更依赖插件系统。我一般是通过dsh plugin --profile web add dshmarket这类命令来安装和管理插件,然后把 skill 作为插件的一部分来加载。
Codex 接入本地模型(比如通过 LM Studio 提供的本地推理服务)时,skills 的作用尤其明显。因为本地模型的指令遵循能力通常不如云端大模型,如果没有 skill 约束,它很容易跑偏。我在 skill 里会明确写出本地模型的 endpoint 格式、请求参数、以及超时重试逻辑。
这里有一个我踩过的坑:Codex 在请求本地模型时,如果 endpoint 配置不对,会报cc switch local proxy failed while handling codex endpoint /responses。这个报错的字面意思是代理在处理/responses端点时失败了,但实际原因可能是 endpoint 路径写错、端口不对、或者本地服务没启动。我在 skill 里加了一段前置检查,让 AI 先确认本地服务是否在运行、端口是否可访问,再去发请求,这样就能在早期发现问题,而不是等到报错。
4.3 跨工具通用的 skill 设计原则
虽然 Claude Code 和 Codex 的加载机制不同,但 skill 的内容设计原则是通用的。我总结了几条:
- 指令要短:单个 skill 的执行指令最好控制在 20 行以内,太长了 AI 容易漏读。
- 示例要全:正确示例和错误示例都要有,而且错误示例要标注清楚错在哪里。
- 依赖要明:skill 里用到的外部命令、环境变量、文件路径,都要明确写出来。
- 版本要标:如果 skill 是针对特定版本的工具有效的,要在文件头部标注版本号,避免升级后失效。
下面这张表是我整理的 Claude Code 和 Codex 在 skills 支持上的对比,方便你根据自己的工具选择配置方式:
| 对比项 | Claude Code | Codex |
|---|---|---|
| skill 存放位置 | ~/.claude/skills/或项目内.skills/ | 插件目录或通过插件命令注册 |
| 加载方式 | 启动时扫描,对话中自动加载 | 通过插件系统加载 |
| 触发机制 | 基于关键词和任务类型 | 基于插件激活条件 |
| 本地模型适配 | 支持,需配置 endpoint | 支持,需注意 endpoint 格式 |
| 常见报错 | skill 未加载、格式解析失败 | 插件未激活、endpoint 请求失败 |
5. 常见问题与排查技巧实录
5.1 skill 不生效的排查思路
skill 不生效是最常见的问题,表现是 AI 完全没有按照 skill 里的指令执行。我一般按以下顺序排查:
- 确认 skill 文件是否被加载:在 Claude Code 里,可以通过查看启动日志确认;在 Codex 里,可以通过插件列表确认。
- 检查触发条件是否匹配:有时候 skill 加载了,但触发条件写得太窄,当前任务没有命中。可以临时把触发条件放宽,测试是否能激活。
- 检查文件格式:Markdown 格式错误、编码问题、特殊字符都可能导致解析失败。用纯文本编辑器打开确认。
- 检查权限:文件是否可读,目录是否可访问。
- 检查版本兼容性:工具升级后,skill 的加载机制可能变化,需要对照最新文档调整。
5.2 常见报错速查表
下面这张表是我在实际使用中整理出来的常见报错和对应的排查方向,覆盖了 Claude Code、Codex 以及相关插件环境:
| 报错信息 | 可能原因 | 排查方向 |
|---|---|---|
cc switch local proxy failed while handling codex endpoint /responses | endpoint 配置错误或本地服务未启动 | 检查本地模型服务状态、endpoint 路径和端口 |
codex无法加载组织设置 | 配置文件路径错误或权限不足 | 检查配置文件位置、读权限、格式 |
you are applying flutter's main gradle plugin imperatively | Gradle plugin 声明顺序不对 | 调整 apply plugin 顺序,flutter 放最前 |
in order to access this application, you must install the j2se plugin | 缺少 J2SE 插件依赖 | 安装对应插件版本,检查环境变量 |
qt.qpa.plugin: could not find the qt platform plugin "windows" | Qt 平台插件缺失或路径不对 | 检查 Qt 安装、插件路径、环境变量 |
your organization has disabled claude subscription access | 组织策略限制 | 检查账号权限和组织设置 |
| skill 加载后无效果 | 触发条件不匹配或指令不清晰 | 放宽触发条件,拆分指令步骤 |
5.3 我踩过的三个典型坑
坑一:skill 文件里用了中文标点。
这个问题看起来很小,但影响很大。我在一个 skill 里用了中文的冒号和引号,结果 Claude Code 解析时把整段指令当成了一个字符串,完全没有按步骤执行。后来全部改成英文标点,问题解决。建议写 skill 时全程用英文标点,中文只出现在注释和说明文字里。
坑二:skill 之间互相冲突。
我有两个 skill,一个负责“修改 Gradle 配置”,一个负责“检查构建警告”。结果在一次任务中,两个 skill 同时被激活,一个让 AI 改配置,一个让 AI 先检查再改,AI 在两条指令之间来回跳,最后什么都没做成。后来我给每个 skill 加了优先级标记,并在触发条件里明确互斥关系,才解决这个问题。
坑三:本地模型不支持 skill 里的某些指令格式。
我在 skill 里用了一种比较复杂的嵌套列表格式,云端模型能正确解析,但本地模型(通过 LM Studio 加载的)解析不了,导致 skill 执行到一半就停了。后来我把嵌套列表改成扁平列表,本地模型就能正常处理了。如果你也在用本地模型,建议 skill 的格式尽量简单,避免多层嵌套。
5.4 提升 skill 稳定性的几个实操技巧
除了上面说的,还有几个技巧是我在实际使用中总结出来的,能明显提升 skill 的稳定性:
- 给 skill 加版本号:在文件头部写上
version: 1.0,每次修改后更新版本号。这样当 skill 行为异常时,你能快速确认是不是最近改过。 - 给 skill 加测试用例:写一个简单的测试任务,每次修改 skill 后跑一遍,确认行为符合预期。
- 给 skill 加日志输出:在关键步骤让 AI 输出当前执行到哪一步,方便排查问题。
- 定期清理不再使用的 skill:skill 太多会拖慢加载速度,也会增加冲突概率。我一般每个月清理一次。
6. 关于 skills 的一些个人体会和后续扩展方向
用 skills 这套机制大概半年多,最大的感受是:它把 AI 编程助手从“一个聪明的聊天对象”变成了“一个能按规范干活的团队成员”。以前我要反复解释需求、纠正错误、检查结果,现在很多重复性的任务,只要 skill 写好了,AI 就能稳定地完成,我只需要做最后的审核。
当然,skills 也不是万能的。它适合处理那些流程明确、规范清晰、重复性高的任务。对于需要大量创造性判断的任务,skill 的作用有限,还是得靠人来主导。我现在的做法是,把日常工作中那些“每次都要跟 AI 解释一遍”的事情写成 skill,把精力省下来处理真正需要思考的问题。
后续我打算继续扩展的方向有几个:一是把更多项目级的规范沉淀成 skill,比如代码风格检查、提交信息格式、分支命名规则;二是研究怎么让 skill 之间更好地协作,比如一个 skill 的输出直接作为另一个 skill 的输入;三是把 skill 和 CI 流程结合起来,让 AI 在提交代码前自动跑一遍相关 skill 做预检。
如果你也在用 Claude Code 或 Codex,我建议你从最小的 skill 开始写起,不要一上来就搞大而全的。先解决一个你每天都会遇到的具体问题,把 skill 写出来、跑通、优化到稳定,然后再扩展。这个过程本身就会让你对 AI 编程助手的能力边界有更清晰的认识。