AI智能体Skills:从SKILL.md到可复用技能包全解析
这几年如果只让我挑一个词来代表开发方式的变化,我肯定会选skills。注意,这里的 skills 不是你简历上写的“精通XXX”,而是AI 智能体的技能包——以文件夹 + 描述文件为核心的一套可复用能力模块。Claude 的 Agent Skills、Cursor 的 Skills 机制、各家 IDE 和 Agent 工具里越来越常见的.claude/skills、.cursor/skills目录,都在用这个词。
我把标题定为skills,就是想聊聊这套东西到底是什么、该怎么写、怎么调、怎么避坑。它能解决一个很实在的问题:把经常重复的 AI 工作流沉淀下来,让模型不靠临场发挥,每次都能稳定输出同一水平的结果。适合正在用 Claude Code、Cursor 这类工具写代码或做自动化任务的开发者,也适合想把团队的 prompt 经验固化成资产的人。
1. 技能体系的核心思路与定位
1.1 先搞清楚:skills 到底是什么
一个 skill,本质上就是一个带有特殊说明文件的文件夹。文件夹里可以放脚本、模板、参考文档、检查清单,核心入口是一个叫SKILL.md的 Markdown 文件,里面用 YAML frontmatter 写清楚这个技能的name和description。模型读到这个文件后,会知道“什么场景下该用这个技能,以及用的时候要遵循什么流程”。
用生活化的话说:普通 prompt 像口头交代,每次交代都要重新解释一遍;而 skill 像一份标准作业指导书,放进文件夹,AI 自己就知道什么时候翻出来用。
我之前看过一个团队把“代码审查”做成了 skill,里面包含审查清单、安全红线、性能检查项、还有一份历史踩坑记录。每次提交代码前,让模型跑一遍这个 skill,出来的审查意见比临时写 prompt 稳定得多。这就是 skills 最大的价值:让 AI 的“经验”可以积累、复制、版本化。
1.2 为什么 skills 比长 prompt 更值得投入
你可能想问:我把一大段 prompt 存在笔记里,每次粘贴不也一样吗?表面看一样,实际差很多。
第一,触发机制不同。长 prompt 需要你主动复制粘贴,而 skill 是由模型根据description自动判断是否调用的。只要描述写得够清晰,模型在合适的时候会自动加载执行。你甚至不用记得自己有哪些技能。
第二,结构化程度不同。prompt 是一段线性文字,而 skill 的 SKILL.md 可以指定读取辅助文件、运行脚本、按模板输出。这等于给 AI 配了一套“方法论 + 工具箱”,而不仅仅是几句指令。
第三,复用边界清晰。一个 skill 可以放在用户级目录(~/.claude/skills)让所有项目都能用,也可以放在项目级目录(.claude/skills)只给当前仓库用。团队里可以直接把 skills 目录提交到 Git,大家同步拉取就有了统一的“能力库”。
2. 核心结构解析与实操要点
2.1 SKILL.md 的格式规范(必须记牢)
SKILL.md 的开头必须是合法的 YAML frontmatter,这是整个 skill 能不能被正确识别的关键。常见的格式是这样的:
--- name: code-reviewer description: Review code changes for bugs, security issues, and performance problems. Use when asked to review a pull request or diffs. --- ## 执行流程 1. 先分析变更范围,列出受影响文件。 2. 按顺序检查:逻辑正确性、安全性、性能、可读性。 3. 输出分级问题清单:严重 / 建议 / 风格。这里最容易犯的错有两个:一是name写错或漏写,二是description写得太模糊。
name建议用英文短横线命名,比如python-unit-testing、api-doc-generator,不要用空格和中文,否则一些工具做路径匹配时容易出问题。
description是重中之重,它就是技能的“触发器”。写description时要像写给搜索引擎的索引一样,把触发场景、输入条件、技能能解决什么说清楚。举个例子,如果你写“Use for testing”,模型大概率不知道什么时候该用;如果你写“Use when the user asks to generate unit tests for Python functions or modules”,模型就能很自然地在相关请求出现时调用它。
2.2 技能包的文件组织与辅助资源
一个复杂一点的 skill 不会只有 SKILL.md,它通常还包括这些内容:
- scripts/ 目录:放可执行的 Python / Shell / JS 脚本,让 AI 在执行流程中调用。比如一个“爬取网页转 Markdown”的技能,可以内置一个抓取脚本。
- templates/ 目录:放输出模板,保证每次生成的结果格式统一。比如代码提交信息模板、周报模板、测试用例模板。
- references/ 目录:放参考文档、代码规范、历史问题记录。模型在运行 skill 时如果有疑问,会主动去读这些内容。
我自己常用的一个习惯是:在每个 skill 里放一个 CHECKLIST.md,把容易遗漏的点全列进去。模型执行完主流程后,会被要求对照清单自查。这比在 prompt 里写一堆“注意XXX”更有效,因为清单是独立的文件,模型会把它当作必读材料,而不是开头看过就忘的废话。
2.3 与 MCP 的区别(别再搞混了)
很多人第一次接触 skills 时会把它和 MCP(Model Context Protocol)弄混。我的理解是:MCP 是“连接器”,skills 是“作业指导书”。
MCP 解决的是“AI 怎么调用外部系统”的问题,比如连数据库、查工单系统、操作浏览器,它需要起服务、配凭证、做鉴权。
skills 解决的是“AI 怎么把一件事做得专业、规范”的问题,它不需要网络,不需要鉴权,就是一组静态文件和可执行脚本。
两者还能配合用:skill 里可以指示模型去调用某个 MCP 工具拿数据,再按 skill 的流程处理。比如“事故复盘”技能,可以先通过 MCP 从监控系统拉取报警记录,再按 SWOT 框架或五问法生成复盘报告。理解了这层关系,你就知道 skills 的定位是流程资产,而不是基础设施。
3. 实操过程与核心环节实现
3.1 亲手写一个“单元测试生成”技能
纸上谈兵没用,我带你从零写一个真正能用的 skill。这个技能的目标是:当用户要求为 Python 函数生成 pytest 单元测试时,模型自动套用标准流程和模板,而不是凭感觉写。
先建目录结构:
~/.claude/skills/python-unit-testing/ ├── SKILL.md ├── templates/ │ └── test_template.py └── references/ └── test_style_guide.md注意我放在了~/.claude/skills用户级目录,这样所有项目都能用。如果你想只对当前仓库生效,就放到项目的.claude/skills目录下。
SKILL.md 内容如下:
--- name: python-unit-testing description: Generate pytest unit tests for Python functions and classes. Use when the user asks to write tests, increase coverage, or verify function behavior. --- # Python 单元测试生成技能 ## 目标 生成符合项目风格的 pytest 测试代码,覆盖正常路径、边界条件和异常分支。 ## 执行步骤 1. 读取目标函数源码,识别输入参数、返回值、可能抛出的异常。 2. 列出测试用例矩阵:正常输入、空值、边界值、非法类型、异常触发条件。 3. 根据 templates/test_template.py 生成测试文件。 4. 运行 pytest,如失败则分析原因并修复测试或报告代码缺陷。templates/test_template.py 的骨架长这样:
import pytest import sys sys.path.append("src") def test_normal_case(): """正常路径测试""" ... def test_boundary_case(): """边界条件测试""" ... def test_exception_case(): """异常分支测试""" with pytest.raises(ValueError): ...references/test_style_guide.md 里写团队约定,比如“测试用例名必须用 test_ 开头”“使用 assert 而不是裸 assert False”“monkeypatch 优先于 mock”等。模型会自动读取这些约束。
3.2 调试与验证:看看技能到底有没有被加载
写完 skill 后,最怕的就是“我写了但 AI 没用上”。这时候需要检查两件事:技能是否被正确识别,以及描述是否能触发。
打开 Claude Code 的调试模式(一般用claude --debug),启动后可以查看模型加载了哪些 skill、读取了哪些文件。如果发现你的 skill 没加载,优先排查:
- SKILL.md 文件是不是放在正确的目录层级,有没有被其他同名 skill 覆盖。
- frontmatter 有没有语法错误,
name和description是不是顶格写的。 - 描述里是否包含该触发场景的常用词。
验证触发是否有效,可以先用一个非常直白的请求测试,比如“请帮我为 utils.py 里的函数生成 pytest 测试”。如果模型没反应,不要急着改代码,先反复调整description里的关键词,直到它能稳定命中。
3.3 从零到落地:完整实操路径参考
如果你想把 skills 用进日常开发,我的建议路径是这样的:
第一步,盘点高频重复操作。你每周让 AI 干得最多的活是什么?写测试、写接口文档、查日志、做代码审查、写提交信息、生成 SQL?挑一个最频繁的开始。
第二步,把现有流程文档化。把你平时在 prompt 里反复写的要求整理成结构化的步骤清单。这就是 SKILL.md 的核心内容。
第三步,建文件夹、写 frontmatter、放模板。不用一次做得太复杂,能跑起来就行。
第四步,迭代优化。每次使用时记录模型的输出和你手动修改的部分,把“你改了什么”反哺到 skill 里。比如你发现 AI 生成的测试没用parametrize,就在 test_style_guide.md 里加一条“必须检查是否存在可参数化的用例组”。
4. 常见问题与排查技巧实录
4.1 技能不触发的真正元凶
我调试过几十个失败案例,绝大多数问题出在description太“自嗨”。举个例子:
description: Excellent code audit skill that ensures high quality and best practices.这种描述全是形容词,完全没告诉模型“什么时候调用”。模型虽然理解语义,但它需要一个调用条件。改成这样就好很多:
description: Review code changes for logic errors, security vulnerabilities, and performance regressions. Trigger when analyzing git diffs or before commit.还有个容易被忽略的细节:如果 description 太长,也会稀释触发效果。把核心触发词放在开头 50 个字以内,后面的信息作为补充。
4.2 脚本依赖与运行环境问题
skill 里如果放了 Python 脚本,要注意运行环境。比如脚本依赖了第三方库,但 skill 运行时不一定安装了,模型就会卡住。我的经验是:在 SKILL.md 里明确写清楚依赖和安装命令,或者直接用标准库实现。
更保险的做法是:脚本里加一个错误捕获,提示缺了什么依赖。这样 AI 看到报错能自己处理,而不是反复试错。
4.3 版本管理与团队同步
skills 目录一旦提交到 Git 仓库,自然而然就面临版本管理问题。我见过不少团队把.claude/skills放进.gitignore,理由是“这是个人配置”。这个做法对了一半:如果你想沉淀团队级技能,一定要提交并共享;如果你有些私有技能不想被同事看到,再考虑用用户级目录。
团队协作时,我建议在 skills 目录里加一个README.md,写清楚每个技能的用途、适用场景、维护人。否则几个月后没人记得哪个技能是干嘛的,就会有人随手改坏。
4.4 实测踩过的三个坑
第一个坑是frontmatter 里name使用了中文或空格,导致模型加载了技能但引用路径出错。后来统一改成纯英文短横线命名。
第二个坑是在一个 skill 里塞了太多职责,比如既做代码审查又做测试又做文档生成。模型执行时经常顾此失彼,流程混乱。后来我把它们拆成三个独立技能,效果立刻好了。记住:skill 的职责应该像函数一样单一。
第三个坑是模板文件命名不够直观,模型不知道该读哪个模板。这个问题的解决方式是:在 SKILL.md 的步骤里明确写出“读取 templates/test_template.py”,而不是只说“读取模板目录”。
5. 让 skill 真正融入工作流的进阶思路
技能写多了之后,你会慢慢感到它不只是“prompt 的升级版”,更像是在给 AI 搭建一套可积累的操作系统。我个人最推荐的一个进阶玩法是:围绕一个完整业务场景,把多个 skill 串成一条流水线。
比如发布前的质量检查流程,由三个技能组成:
unit-testing:生成测试并执行。code-reviewer:对变更代码做逻辑、安全和性能检查。release-note:根据提交记录生成发布说明。
每个技能保持独立可复用,但在 SKILL.md 里可以互相引用。比如 code-reviewer 的流程末尾写一句“如果发现问题涉及测试缺失,调用 python-unit-testing 技能补测试”。这样模型在编排任务时就能自己“技能接力”。
还有一个心得:不要把 skill 当成静态文件,要当成活文档。我每两周会看看哪些技能用得最多,哪些几乎没被触发。用得多的技能值得花时间打磨,没被触发的要么是场景变了,要么是描述写得不准,干脆删掉或重写。这种“代码库式”的维护方式,才是 skills 体系能持续产生价值的关键。
最后分享一个判断标准:如果你写了一堆 skill 但从来没有主动打开看过它们的文件夹,说明它已经被模型内化成了习惯。好的技能系统应该是越用越顺、越沉淀越厚——就像带了一个渐渐长成你专业品味的副驾驶。