如果你正在做 Agent 开发,过去一年最值得花时间理解的一个概念,可能不是某个新模型,而是一个叫 SKILL.md 的普通 Markdown 文件。它由 Anthropic 发起,2025 年 12 月 18 日以 agentskills.io 的名义发布为开放标准,到 2026 年 3 月已被 32 个平台采纳(包括 Microsoft、OpenAI、Google Gemini CLI、Cursor、GitHub),并覆盖 claude.ai、Claude Code 与 Claude 开发者平台(API)等入口。它不需要 SDK、不需要 API 集成、不需要部署流程,一个文件夹加一个 Markdown 文件就能让 Agent 学会一项新技能。这篇文章分两段:第 1 段讲清 Skill 的定义、标准演进、目录结构、字段硬约束与 25+ 平台安装路径;第 2 段进入渐进式加载的三层 Token 账本、与 MCP 的边界、FAQ 与官方最佳实践。读完你会拥有一份可以直接落地到团队项目里的 SKILL.md 手册。

Skill 到底是什么:一个装了 SKILL.md 的文件夹,为什么像给新员工发入职指南

先把定义说死:一个 Agent Skill 就是一个文件夹,文件夹里必须有一份 SKILL.md。这份文件由两部分拼成——开头是一段 YAML frontmatter 元数据,用三条横线包起来,负责声明这个 Skill 叫什么、干什么用;横线之下是 Markdown 正文,承载真正的指令、流程、示例与约束。除了 SKILL.md,文件夹里还可以放脚本、模板、参考文档等资源,供正文按需引用。

为什么说它像给新员工发一份入职指南?想象你招了一个能力很强但对你团队一无所知的新人:他不会一上来就背完你所有的内部文档,而是先拿到一页岗位说明(这个岗位负责什么、什么时候该他上场),真正接到任务时再翻对应的操作手册,需要填表时再去取模板。Agent 读 Skill 的机制完全一致:它只在任务相关时才读取并执行,不相关的时候,这份 Skill 对它的上下文几乎没有任何负担。这正是 SKILL.md 能在一份文件里塞进大量领域知识、却依然保持可扩展的根本原因。

还有一个常被忽略的定位问题:SKILL.md 是纯文本的开放标准,同一份文件可以在 25 个以上兼容平台上直接使用,不需要为每个平台写适配层。这意味着团队沉淀下来的知识资产,不会绑死在某一家工具上。

Anthropic 发起、agentskills.io 开放标准:从 2025 年 10 月到 2026 年 3 月的采纳时间线

Agent Skills 的演进节奏,用一条时间线就能看清它的分量:

  • 2025 年 10 月 16 日:Agent Skills 随 PowerPoint、Excel、Word、PDF 官方 Skill 一同发布,第一次把「用 Markdown 教 Agent 干活」这件事摆到台面上。
  • 2025 年 12 月 18 日:在 agentskills.io 上正式发布为开放标准,格式从某一家产品的内部约定,变成任何平台都可以实现的事实规范。
  • 2026 年 3 月:已有 32 个平台采纳同一套 SKILL.md 格式,名单里包括 Microsoft、OpenAI、Google Gemini CLI、Cursor、GitHub;同时入口形态也从单一 IDE 插件扩展到 claude.aiClaude CodeClaude 开发者平台(API)

这个时间线的工程含义是:2025 年写 SKILL.md 还是「尝鲜」,到 2026 年 9 月的今天,它已经变成团队知识资产的事实标准载体。你今天写下的 description,可能在十几个不同厂商的 Agent 里被同一套解析逻辑读取与匹配。

为什么值得写 Skill:领域知识打包、能力补齐、流程可审计、跨平台互操作与团队知识沉淀

官方给出的价值主张有五条,每一条都对应一类真实诉求:

  1. 领域专业知识打包。法律审查流程、数据分析流水线、财务建模方法、某个人格特质——这些原本散落在文档、口口相传或个人经验里的东西,被固化成一个可被 Agent 读取执行的包。过去你要在提示词里反复复述,现在写一次就能复用。
  2. 赋予原本不具备的能力。Agent 自己不会做演示文稿、处理 PDF、构建 MCP 服务器,也不会按你自定义的 schema 分析数据集。Skill 把「怎么做」写成步骤与脚本,能力就被补上了。
  3. 把多步骤任务变成一致可审计的流程。以数据库迁移为例:每次都走同样的验证步骤,不依赖当次对话里模型的心情和临场发挥,结果自然更稳定,也更容易回溯「哪一步出了问题」。
  4. 跨平台互操作。一次编写,25+ 平台不改动可用,沉没成本极低。
  5. 团队知识共享。把机构知识放进版本控制的包里,人离开了,知识还留在 Skill 里——这是很多团队真正下决心写 Skill 的触发点。

最小目录与完整目录:SKILL.md 必需,scripts/、references/、assets/ 三者皆可选

目录结构没有想象中复杂,只有两层形态:

形态目录构成承载内容是否必需
最小结构my-skill/ 下只有 SKILL.md元数据 + Markdown 指令SKILL.md 必需
完整结构SKILL.md + scripts/ + references/ + assets/指令 + 可执行代码 + 文档 + 模板与静态资源后三者均可选

三类可选目录各有明确分工:scripts/ 放可执行代码,是 Agent 在需要时真正去「跑」的东西;references/ 放文档,是 Agent 需要时去「读」的补充知识;assets/ 放模板与静态资源,比如表单模板、样式文件。**这里有个高频坑:**正文里必须明确写清楚某个资源是要「读」还是「跑」,否则 Agent 可能把一份参考文档当脚本执行,或者把一个脚本当文档通读一遍,浪费掉大量 token。

四步创建流程:建目录、写 SKILL.md、按需加资源、复制进 skills 目录

落地路径只有四步:

  1. 建目录mkdir my-skill && cd my-skill。目录名只能用小写字母、数字、连字符,因为稍后要拿它和 frontmatter 里的 name 做一致性校验。
  2. 写 SKILL.md:frontmatter 里必填 namedescription,分隔符之后写 Markdown 指令正文。
  3. 可选加资源:按需补 scripts/references/assets/ 三类目录,并在正文中引用。
  4. 复制到目标平台的 skills 目录:这里要区分两个作用域——项目级 Skill 随 git 共享给整个团队,用户级 Skill 只在本人机器上可用。

最小可用示例拆解:code-review 的 frontmatter 与 When to use / Process 正文

下面这份 code-review 就是一个可以立刻用的最小 Skill:

---
name: code-review
description: 审查代码改动并给出可执行反馈。当用户提交 PR、请求代码审查、或要求检查某段代码质量时使用。
---

## When to use

当用户提交 pull request、要求 review 某个文件、或提到「帮我看看这段代码有没有问题」时使用。

## Process

1. 读取目标代码,先建立对整体意图的理解。
2. 查找缺陷与边界条件:空值、越界、并发、错误处理遗漏。
3. 检查安全漏洞:注入、越权、敏感信息泄露、不安全的反序列化。
4. 给出可执行反馈:每条问题配一个最小修复示例,并标注严重程度。

要点有三:第一,description 要同时说清「做什么」和「何时触发」——「审查代码改动并给出可执行反馈」是做什么,「当用户提交 PR……时使用」是何时用,两部分缺一不可。第二,正文用 ## When to use 再交代一次触发场景,帮助模型在加载后的正文里也不跑偏。第三,## Process 用编号列表把流程钉死:读代码 → 查缺陷与边界 → 找安全漏洞 → 给出可执行反馈与示例,**步骤越具体,多次执行的一致性越高**。

必填字段硬约束:name 的 64 字符与连字符规则、description 的 1024 字符双要素

校验规则是可以被程序化检查的,因此不要靠记忆:

  • name:最多 64 个字符;只允许小写字母、数字、连字符;必须与父目录名一致;不允许出现连续连字符;不能以连字符开头或结尾。
  • description:最多 1024 个字符;必须同时描述「这个 Skill 做什么」与「什么时候激活它」,两部分都对可靠的 Skill 发现至关重要。

description 之所以是硬性双要素,是因为它会在启动时被注入系统提示,直接参与路由决策。很多「Skill 明明存在却总不被触发」的问题,根因都出在 description 只写了能力、没写触发场景。

可选字段怎么用:license、compatibility、metadata 各自承载什么信息

三个可选字段解决的是「合规、环境、归属」这三类工程问题:

  • license:写许可证名称,例如 MITApache-2.0;也可以写成指向随包许可证文件的路径引用,便于分发时合规审计。
  • compatibility:声明环境需求,包括目标平台、所需依赖包、是否需要网络访问等,让 Agent 或使用者在加载前就知道自己能不能跑得起来。
  • metadata:任意键值映射,用来存作者、版本、主页等附加属性,是团队做资产管理和版本追踪时的落点。

完整示例 pdf-processing:license、compatibility、metadata 与 Quick start / Advanced features 组织方式

把可选字段和分层正文放在一起,就是一份生产级 SKILL.md 的样子:

---
name: pdf-processing
description: 从 PDF 中提取文本与表单数据并生成结构化输出。当用户需要解析 PDF、批量抽取字段或填写 PDF 表单时使用。
license: Apache-2.0
compatibility: 需要 Python 3.10+,依赖 pdfplumber 与 pypdf,无需网络访问
metadata:
  author: platform-team
  version: 1.4.0
---

## Quick start

```python
import pdfplumber

with pdfplumber.open("input.pdf") as pdf:
    for page in pdf.pages:
        print(page.extract_text())
```

## Advanced features

表单填写请见 [FORMS.md](FORMS.md)。

这份示例的教学点在于分层:frontmatter 用 license 交代许可证、用 compatibility 写明依赖 pdfplumberpypdf 以及适配的宿主环境、用 metadata 记录 author 与 version;正文则把「最常走的路径」放进 ## Quick start 给出一段可直接复制的代码,把低频但复杂的能力收进 ## Advanced features,以链接形式指向 FORMS.md 表单填写指南。这样默认加载的正文很短,重文档只在真正需要时才被读取。

description 才是触发器:Agent 靠它决定是否激活这个 Skill

必须把这句话单独强调一次:description 是任何 Skill 中最关键的部分。Agent 正是依据它决定是否激活该 Skill,而不是靠 name、也不是靠正文。无数工程实践反复验证同一个结论:Skill 写得再好,如果 description 没有把触发场景写足,它就等于不存在。

更狠的是,这件事已经被量化验证过。2026 年 8 月的 arXiv 论文《What Keeps Agent Skills from Being Reusable?》分析了 138,133 份公开 SKILL.md,把缺陷分成两层:Tier 1「规范符合性」共 14 项检查,Tier 2「最佳实践符合性」共 17 项检查;结论是规范符合性缺陷占主导,而路由(触发)类缺陷会直接降低 Skill 被发现的质量。论文还给出一个非常具体的实证:description 采用「[动词] [做什么]. Use when [触发场景]」句式的 Skill,平均检出缺陷 1.83 个;而「不感知规范」的写法平均 3.00 个,Cliff's δ = −0.40,属于中等效应量。也就是说,按模板写 description 是一项可被量化验证的质量收益,不是风格偏好。此外,被标注为 AI 生成的 Skill 与未标注者在质量分布上也存在差异,说明标注与人工复核仍有价值。

下面这段 Python 校验脚本可以直接放进 CI,把上面所有硬约束和双段式句式都查一遍:

import os
import re
import sys

NAME_RE = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$")
TRIGGER_HINT = ("use when", "when the user", "当用户", "当任务")

def parse_frontmatter(text):
    if not text.startswith("---"):
        raise ValueError("SKILL.md 必须以 YAML frontmatter 开头")
    parts = text.split("---", 2)
    if len(parts) < 3:
        raise ValueError("frontmatter 未正确闭合")
    meta = {}
    for line in parts[1].strip().splitlines():
        if ":" in line:
            key, value = line.split(":", 1)
            meta[key.strip()] = value.strip()
    return meta, parts[2]

def validate(skill_path):
    errors = []
    skill_dir = os.path.dirname(os.path.abspath(skill_path))
    dir_name = os.path.basename(skill_dir)
    meta, body = parse_frontmatter(open(skill_path, encoding="utf-8").read())

    name = meta.get("name", "")
    desc = meta.get("description", "")

    if not name:
        errors.append("缺少必填字段 name")
    else:
        if len(name) > 64:
            errors.append("name 超过 64 字符")
        if not NAME_RE.match(name):
            errors.append("name 只允许小写字母/数字/连字符,且不能首尾为连字符")
        if name != dir_name:
            errors.append(f"name({name}) 与父目录名({dir_name}) 不一致")

    if not desc:
        errors.append("缺少必填字段 description")
    else:
        if len(desc) > 1024:
            errors.append("description 超过 1024 字符")
        full = (desc + body).lower()
        if not any(hint in full for hint in TRIGGER_HINT):
            errors.append("description 未体现触发场景,建议写成「[动词] [做什么]. Use when [触发场景]」")

    return errors

if __name__ == "__main__":
    issues = validate(sys.argv[1])
    if issues:
        print("校验未通过:")
        for item in issues:
            print(" - " + item)
        sys.exit(1)
    print("校验通过")

这段脚本覆盖了四类高频翻车点:name 长度与字符集name 与父目录同名description 长度、以及「做什么 + 何时用」两段式句式是否缺失。把它挂进 CI,比事后靠人眼 review 可靠得多。

25+ 平台兼容矩阵与默认安装目录:.claude/skills/、.cursor/skills/、.agents/skills/、.windsurf/skills/

兼容平台清单先全量点名:Claude Code、Claude.ai、Cursor、OpenAI Codex、VS Code / GitHub Copilot、Windsurf、Gemini CLI、Amp、Roo Code、Goose、Cline、OpenCode、TRAE、Kiro、JetBrains、OpenHands、Replit、Factory、Manus、Zed、Qodo、Letta、Mistral Vibe、Agentman、VT Code、Piebald。同一份 SKILL.md 复制过去即可使用,不需要为每个平台改写内容。

平台默认安装目录典型安装命令
Claude Code.claude/skills/~/.claude/skills/cp -r my-skill .claude/skills/
Cursor.cursor/skills/cp -r my-skill .cursor/skills/
OpenAI Codex.agents/skills/~/.agents/skills/cp -r my-skill .agents/skills/
Windsurf.windsurf/skills/cp -r my-skill .windsurf/skills/

注意点级与用户级的差别:项目级目录(如 .claude/skills/)随 git 提交,团队成员拉取后自动获得同一套 Skill;用户级目录(如 ~/.claude/skills/)只对当前用户生效,适合放个人偏好类的 Skill。**一个常见坑:**如果你在项目里同时放了项目级和用户级同名 Skill,要确认目标平台的优先级约定,避免出现「我明明更新了 Skill 却好像没生效」。Claude Code 侧还提供了一个校验入口:claude plugin validate 可以用来检查结构合法性,建议在提交前跑一次。

另外值得一提的是 Claude Code 的最新变化:Skill 与斜杠命令已经统一为同一套系统——.claude/commands/review.md.claude/skills/review/SKILL.md 都会产生 /review,同名时 Skill 优先,且 Skill 支持附带文件与更多 frontmatter 字段。除了开放标准字段(name / description / license / compatibility / metadata / allowed-tools),Claude Code 还提供了一批扩展字段:allowed-tools(工具白名单)、model(指定模型)、context: fork(派生独立上下文)、agent(指定子代理)、user-invocabledisable-model-invocationargument-hint,以及 hooks 生命周期钩子(PreToolUse / PostToolUse / Stop)。这些扩展字段不改变 SKILL.md 的可移植性,因为其他平台会忽略不认识的可选字段,但在 Claude Code 里能解锁更精细的控制。

到这里,你已经掌握了 Skill 的定义、标准演进、目录结构、字段约束、示例写法与安装路径。但真正决定一个 Skill 库能不能长期维护下去的,不是格式,而是 Token 预算——下一段我们进入渐进式加载的三层账本,把每一层该花多少 token 算清楚,再对比 Skill 与 MCP 的边界、回答六个高频 FAQ,并落定官方四条最佳实践与社区的第二波实践主题:审计、修剪与重建 Skill 库。

上一段我们已经把 SKILL.md 的目录结构、frontmatter 字段规范与跨平台安装路径逐一拆开,也亲手跑通了第一个 Skill 的四步创建流程。这一部分我们把视角切到运行时的“账本”上:Agent 到底在什么时刻读了多少 token、为什么 25+ 平台能把同一份文件用得如此之轻、以及 2026 年生态里最新出现的工程纪律与校验手段。

渐进式加载三层与 Token 账本:元数据约 100 tokens、正文建议不超 5000 tokens、资源近乎无上限

Skill 之所以能在不拖垮上下文的前提下越装越多,靠的不是压缩,而是渐进式披露(progressive disclosure)这一加载机制。它把一份 Skill 拆成三个不同时机、不同成本的层次:启动时只读“目录”,触发时才读“正文”,正文里点名要用的东西才读“资源”。

层级加载时机Token 预算承载内容
第一层:元数据始终加载 · Agent 启动时注入系统提示100 tokens/Skillfrontmatter 里的 namedescription,让 Agent 知道“有哪些能力、何时该用”
第二层:指令用户请求与 Skill 描述匹配、Skill 被触发时读入 context建议 不超过 5000 tokensSKILL.md 的 Markdown 正文——真正的流程、最佳实践与示例
第三层:资源按需加载 · 仅当 SKILL.md 指令显式引用时实际上无上限脚本、参考文档、模板、schema、静态资源

关键工程含义有三点。第一,启动成本与 Skill 数量近似线性但极低——装 40 个 Skill 也只吃掉约 4000 tokens 的元数据预算,模型对 context 的感知几乎不受影响。第二,正文是真正的成本中心,它决定了 Skill 被触发那一刻上下文里要额外塞进多少字,所以 5000 tokens 是一条需要主动防守的红线。第三,第三层的“无上限”不是免费的午餐:它无上限的前提是不预加载——脚本与参考文档只有被引用才会进入上下文,这也意味着 SKILL.md 正文必须写清楚“遇到 X 场景时去读 references/Y.md”,否则模型根本不知道那些文件存在。

一个常见的踩坑方式是:把 PDF 解析的完整 API 文档、公司几十页的编码规范全文粘贴进 SKILL.md 正文。结果是每次这个 Skill 一被触发,就要为一段只在少数任务里用得到的知识付 8000 tokens 的固定税。正确做法是把它们下沉到 references/,在正文里用一行链接指过去。

Skill 与 MCP 的五维对照表:指令与知识 vs 外部工具连接,以及两者如何组合

Skill 出现后最常被问的问题是“它是不是要取代 MCP”。答案是否定的——它们解决的是两类完全不同的工程问题。

维度SkillMCP
用途指令与知识:教 Agent 怎么把活干好外部工具连接:给 Agent 一个能调用的外部能力
格式Markdown 文件(带 YAML frontmatter)JSON-RPC 协议
复杂度低——本质上只是文件较高——需要常驻服务器
适用场景工作流、人格蒸馏、最佳实践沉淀API、数据库、实时数据接入
状态无状态有状态连接

二者是互补关系,许多真实工作流同时使用两者:MCP 负责连上 BigQuery,Skill 负责告诉 Agent “查数时先确认时间分区、再按业务口径过滤、最后用哪个模板输出报表”。更进一步,Skill 可以通过完整限定名称引用 MCP 工具,比如在正文里写“数据核对阶段调用 BigQuery:query 拉取基础表”,从而让同一个 Agent 在一次任务里把知识层与工具层串起来。

这也是为什么 Skill 的移植性如此重要:一份描述“如何做财务建模”的 Skill,在 claude.ai、Claude Code 与 API 三种入口下应当表现一致,前提只是运行环境满足它声明的依赖。工具侧换不换 MCP 实现,通常不影响 Skill 正文的逻辑。

13.8 万份 SKILL.md 的缺陷研究:Tier 1 规范符合性与 Tier 2 最佳实践符合性

当 Skill 从少数人写变成几十万人写,质量问题就不再是个人风格问题,而是可测量的语料问题。2026 年 8 月 arXiv 论文《What Keeps Agent Skills from Being Reusable?》分析了 138,133 份公开 SKILL.md,把缺陷分为两类:

  • Tier 1「规范符合性」:共 14 项检查,对应 open standard 明确规定的硬约束,例如 name 的长度与字符集、是否与父目录一致、description 是否超长等。
  • Tier 2「最佳实践符合性」:共 17 项检查,对应官方与社区总结的写法建议,例如是否包含触发场景、正文是否过长、资源引用是否清晰等。

论文的一个核心发现是:规范符合性缺陷在公开语料中占主导。也就是说,大量 Skill 连“能被稳定发现”这一关都没过。更值得工程团队警惕的是路由(触发)类缺陷——当 description 写得模糊、既不说明做什么也不说明何时用,Agent 的匹配就会失准,Skill 也许写得很详细,却几乎从不被激活,最终“被发现的质量”被直接拉低。这与上一段强调的“description 是任何 Skill 中最关键的部分”形成了实证呼应。

description 句式的量化收益:[动词] [做什么]. Use when [触发场景] 平均缺陷 1.83 vs 3.00

论文最有传播度的数据来自句式对比。研究者把 description 的写法分为两类:一类采用「[动词] [做什么]. Use when [触发场景]」的结构化模板,另一类是“不感知规范”的自由写法。统计结果是:

  • 采用模板句式的 Skill,平均检出缺陷 1.83 个
  • 不感知规范的写法,平均检出缺陷 3.00 个
  • 效应量 Cliff’s δ = −0.40,属中等效应量

换句话说,按模板写 description 是一项可被量化验证的质量收益,不是审美偏好。对团队而言,这意味着把句式写进代码评审清单是划算的:它把“description 写得好不好”从主观判断变成可自动检查的规则。论文还提到,被标注为 AI 生成的 Skill 与未标注者在质量分布上存在差异——这提示我们,自动化生成 Skill 的团队更需要显式的校验工具,而不是依赖模型一次成型。

下面是一份可直接跑在 CI 里的校验脚本,检查的就是 Tier 1 里最常被忽略的三类:name 长度与字符集、name 是否与父目录同名、description 长度与“做什么 + 何时用”两段式结构。

#!/usr/bin/env python3
"""validate_skill.py — 在 CI 中校验 SKILL.md 的 Tier 1 规范符合性"""
import re
import sys
from pathlib import Path

import yaml  # pip install pyyaml

NAME_MAX = 64
DESC_MAX = 1024
WHEN_RE = re.compile(r"(use when|when to use|何时使用|适用于)", re.IGNORECASE)


def fail(msg: str) -> None:
    print(f"[FAIL] {msg}")
    sys.exit(1)


def load_frontmatter(skill_md: Path) -> dict:
    text = skill_md.read_text(encoding="utf-8")
    if not text.startswith("---"):
        fail("SKILL.md 必须以 YAML frontmatter 分隔符 '---' 开头")
    _, fm, _ = text.split("---", 2)
    return yaml.safe_load(fm) or {}


def check(skill_md: Path) -> None:
    fm = load_frontmatter(skill_md)
    name = fm.get("name", "")
    desc = fm.get("description", "")

    # 1) name 长度与字符集
    if not isinstance(name, str) or not name:
        fail("name 必填且必须是字符串")
    if len(name) > NAME_MAX:
        fail(f"name 超长:{len(name)} > {NAME_MAX}")
    if not re.fullmatch(r"[a-z0-9-]+", name):
        fail("name 只允许小写字母、数字与连字符")
    if name.startswith("-") or name.endswith("-") or "--" in name:
        fail("name 不能以连字符开头/结尾,也不允许连续连字符")

    # 2) name 必须与父目录同名
    parent = skill_md.parent.name
    if name != parent:
        fail(f"name({name}) 必须与父目录名({parent}) 一致")

    # 3) description 长度 + 两段式结构
    if not isinstance(desc, str) or not desc.strip():
        fail("description 必填")
    if len(desc) > DESC_MAX:
        fail(f"description 超长:{len(desc)} > {DESC_MAX}")
    if not WHEN_RE.search(desc):
        fail("description 缺少触发场景说明,建议使用 '[动词][做什么]. Use when [场景]' 句式")
    if len(desc.strip()) < 20:
        fail("description 过短,几乎无法支撑可靠的路由判断")

    print(f"[OK] {name}: name={len(name)} chars, description={len(desc)} chars")


if __name__ == "__main__":
    target = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(".")
    md = target / "SKILL.md" if target.is_dir() else target
    check(md)

把这段脚本挂到 pre-commit 或 PR 检查里,就能在合并之前拦住最便宜也最致命的几类错误。注意它刻意只做机械可判定的检查:语义上的“这活到底该不该交给 Skill”仍然要靠人判断。

token 预算纪律与常见误区:把上下文当公共资源,社区阈值比官方更保守

官方给出的 5000 tokens 是上限,不是目标。真正成熟的团队会把上下文窗口当作公共资源来管理:每个 Skill 都从这笔公共预算里分走一块,任何一段内容写进去,都是在向其他 Skill 与当前任务本身收费。所以每次落笔都值得自问三句:

  1. 模型真的需要这条信息才能完成任务吗?
  2. 能否合理假设它已经从训练中学到了?
  3. 这段内容的 token 成本是否值回票价?

社区工具在此基础上给出了比官方更保守的参考阈值,值得作为内部规范的默认值:

  • 第一层 name + description:目标 < 200 字符 / < 30 tokens
  • 第二层正文:目标 < 50 行 / < 1,000 词 / < 680 tokens

典型误区有几个:把“示例输出”整段贴进正文(应下沉到 references/);把互斥场景塞进同一份 Skill(比如同时教代码审查与代码生成,导致 description 无法准确路由);没有写明脚本是“读”还是“跑”(模型可能把一份应当阅读的参考实现当成可执行命令);以及过度依赖“模型应该懂”的隐含知识,结果被触发后仍然缺关键上下文。

Claude Code 最新实践:Skill 与斜杠命令统一、扩展字段、hooks 与 claude plugin validate

2026 年的 Claude Code 把 Skill 与斜杠命令合并成了同一套系统:.claude/commands/review.md.claude/skills/review/SKILL.md 都会产生 /review;两者同名时Skill 优先,因为 Skill 支持附带文件与更丰富的 frontmatter 字段。除开放标准字段(name / description / license / compatibility / metadata / allowed-tools)之外,Claude Code 还提供了若干扩展字段与生命周期钩子:

  • allowed-tools:工具白名单,限定该 Skill 可调用的工具范围;
  • model:为该 Skill 指定模型;
  • context: fork:派生独立上下文,避免污染主对话;
  • agent:指定子代理来承接任务;
  • user-invocabledisable-model-invocation:控制是由用户显式调用,还是禁止模型自动激活;
  • argument-hint:给斜杠命令的入参提示;
  • hooksPreToolUse / PostToolUse / Stop 三个生命周期钩子,用于在工具调用前后与结束点插入校验或日志。

结构层面可以用 claude plugin validate 做校验,把字段拼写、目录布局等低级错误挡在提交之前。下面是一份包含全部 frontmatter 字段的 SKILL.md 示例,可直接作为模板。

---
name: pdf-processing
description: Extract structured data from PDF documents and fill in forms. Use when the user provides a PDF and asks for text extraction, table parsing, or form completion.
license: Apache-2.0
compatibility: Requires Python 3.10+, pdfplumber and pypdf installed, host agent supporting the agentskills.io standard.
metadata:
  author: data-platform-team
  version: 1.3.0
  homepage: https://example.internal/skills/pdf-processing
allowed-tools:
  - Read
  - Bash
  - Write
---

# PDF Processing

## Quick start

Use pdfplumber to extract text page by page, then normalize whitespace.

```python
import pdfplumber

with pdfplumber.open("input.pdf") as pdf:
    for page in pdf.pages:
        print(page.extract_text() or "")
```

## Advanced features

- Form filling and AcroForm handling: see [FORMS.md](references/FORMS.md)
- Table extraction edge cases: see [TABLES.md](references/TABLES.md)
- When the user asks to *run* a batch job, execute exactly one script:
  `scripts/batch_extract.py` — do not treat the snippets above as runnable files.

## When to use

- The user uploads a PDF and asks for its contents.
- The user needs specific fields pulled from a filled form.

## Process

1. Confirm the PDF path and whether forms or plain text are needed.
2. Extract text with pdfplumber; fall back to pypdf for encrypted files.
3. Validate extracted fields against the requested schema.
4. Return results plus any pages that failed, with the reason.

Microsoft Agent Framework 的四阶段披露:Advertise、Load、read_skill_resource、run_skill_script

Microsoft Agent Framework 采用了一种更细粒度的“四阶段”渐进式披露表述,把学术界常说的三层拆得更贴近运行时动作:

  1. Advertise:约 100 tokens/Skill,把名称与描述注入系统提示,让 Agent 知道能力清单;
  2. Load:任务匹配时通过 load_skill 工具取回完整 SKILL.md,官方建议 < 5,000 tokens
  3. read_skill_resource:读取资源文件的独立动作;
  4. run_skill_script:执行脚本的独立动作。

把“读取资源”与“执行脚本”拆成两个独立动作建模,是一个很重要的安全与可观测性设计——读一份参考文档和跑一段代码,风险等级完全不同,审计时也应当分开记录。该框架同时支持四种 Skill 来源:文件型(目录里的 SKILL.md)、代码定义型类定义型,以及基于 MCP 型。前三者偏静态分发,最后一者则把 Skill 也变成可由服务器动态提供的对象,适合企业内集中托管与灰度发布。

官方最佳实践与设计原则:从评测开始、为规模而结构、站在模型视角、与模型一起迭代

官方给出的四条最佳实践,本质上是一套迭代方法论:

  1. 从评测开始:先在真实任务上跑,观察 Agent 在哪里卡住、缺什么上下文,再增量地造 Skill,而不是先设计一套完美的知识体系;
  2. 为规模而结构:SKILL.md 臃肿时就拆到独立文件并引用,正文控制在约 5k 词以内,把互斥场景拆开,并明确写清脚本是要“读”还是“跑”;
  3. 站在模型视角:name 与 description 决定触发,要观察真实使用轨迹,而不是凭假设判断它会不会被调用;
  4. 与模型一起迭代:把成功做法与常见坑点沉淀回 Skill,让它随实践演进。

三条设计原则与之配套:渐进式披露(最小化 token 占用)、可组合性(多个 Skill 会被同时加载,不要假设自己独占能力)、可移植性(同一 Skill 在 claude.ai / Claude Code / API 表现一致,前提是运行环境满足其依赖)。可组合性尤其容易被忽略:一份 Skill 若在正文里断言“本 Agent 只负责 X”,就会在与其他 Skill 共存时产生冲突;更好的写法是把边界写成前置条件与检查步骤。

厨房类比与生态信号:MCP 给厨房,Skill 给菜谱,以及正在到来的审计与修剪第二波

官方用了一个很贴切的类比:MCP 提供的是“专业厨房”——工具、食材与设备;Skill 提供的是“菜谱”——如何把这些食材做成有价值的东西。只有 MCP 而没有 Skill,用户连上连接器之后仍然不知道下一步做什么,每个会话都从零开始、结果不一致,最后还会把问题归咎于连接器。这个归因错误在实践中非常普遍:团队以为是工具不好用,其实是缺少把工具串成流程的知识层。

生态层面,早期评论者如 Simon Willison 称 Agent Skills “比 MCP 更大”——不是因为它要取代 MCP,而是因为它解决的是另一个问题:教 Agent 如何把活干好,而不只是给它一件工具。到 2026 年下半年,正在出现明显的第二波实践,主题是审计、修剪与重建此前安装的 Skill 库:团队开始盘点哪些 Skill 从未被触发(description 路由失败)、哪些正文过长(token 预算失控)、哪些与新版平台字段不再兼容。这与前面那篇 13.8 万份语料研究的结论是一致的——规模上来之后,治理比创作更稀缺。

六问速查 FAQ:要不要编程、能否跨 Claude/Cursor/Codex、与系统提示词差异、装多少、能建哪些、去哪找

  • 创建 Skill 需要编程吗?不需要。它只是一个 Markdown 文件,会写文字就能写——没有 SDK、没有构建步骤、没有部署流程;只有当正文引用脚本时,才需要有人写那段脚本。
  • 同一个 Skill 能在 Claude、Cursor、OpenAI Codex 上用吗?能。SKILL.md 是由 Anthropic 发起、在 agentskills.io 发布的开放标准,2026 年已有 32 个平台采纳同一格式,把同一个文件夹复制到各工具的 skills 目录即可。
  • Skill 与系统提示词有什么区别?系统提示词是始终加载的静态指令块;Skill 是按需加载的结构化包,只在任务相关时读入正文,多个 Skill 可共存且对 context 消耗极小。
  • 可以安装多少个 Skill?可以装任意数量——启动时每个只加载约 100 tokens 元数据,装数十个影响也极小。
  • 可以创建哪些类型的 Skill?技术类(代码审查、PDF 处理、测试)、流程类(数据库迁移、部署)、人格类(同事、名人、历史人物)皆可。
  • 去哪里找可安装的 Skill?Skill 库、GitHub,或者自己从头创建。

总结与最佳实践

把这两部分的内容压缩成一份可执行清单:

  1. 先评测、后造 Skill。在真实任务上观察 Agent 卡在哪,再决定这份 Skill 要补什么上下文。
  2. 把 description 当接口写。使用「[动词] [做什么]. Use when [触发场景]」句式,实证可将平均缺陷从 3.00 降到 1.83;它同时决定 Agent 会不会激活你。
  3. 守住 Tier 1 硬约束。name ≤ 64 字符、仅小写字母/数字/连字符、与父目录同名、无连续连字符、不以连字符开头结尾;description ≤ 1024 字符且同时回答“做什么”与“何时用”。把校验脚本挂进 CI。
  4. 用三层加载做 token 预算。元数据约 100 tokens/Skill 常驻;正文建议 < 5000 tokens,社区更保守的目标是 < 50 行 / < 1000 词 / < 680 tokens;资源按需加载、近乎无上限。
  5. 正文瘦身靠下沉。长文档、模板、schema 放入 references/ 与 assets/,正文只留一行引用;并明确写清脚本是“读”还是“跑”。
  6. 按规模拆分。SKILL.md 臃肿就拆文件,互斥场景拆成不同 Skill,避免一份 Skill 承担互相冲突的触发条件。
  7. 保持可组合与可移植。不要假设独占能力,不要把某一宿主特有的行为写死在正文里;同一 Skill 应在 claude.ai / Claude Code / API 表现一致。
  8. 用好平台扩展能力。在 Claude Code 中可借助 allowed-tools、model、context: fork、agent、user-invocable、argument-hint 与 PreToolUse/PostToolUse/Stop 钩子,并用 claude plugin validate 校验结构。
  9. 认清新旧分工。MCP 给厨房,Skill 给菜谱;Skill 可用 BigQuery:query 这样的完整限定名引用 MCP 工具,在同一 Agent 内协同。
  10. 定期做 Skill 库审计。检查哪些从未被触发、哪些正文超预算、哪些字段已过时;把成功的做法与坑点回写进 Skill,形成迭代闭环。