一个 Skill 就是一个装着 SKILL.md 的文件夹。它把领域知识、标准作业流程、脚本与模板打包成一个能力包, 让通用智能体在需要时自动发现、按需加载、照章执行。它解决的根本矛盾是: 上下文窗口是稀缺公共资源,而能力应该是无限的。
一句话定义:Skill 是文件系统上的、可发现的、渐进加载的程序化知识包——它不是一段提示词,而是一份智能体可以自行翻阅的「入职手册」。
Skill 运行在具备文件系统的执行环境里。智能体像你一样用 ls、cat 去翻目录,因此它能携带正文之外的参考资料与可执行脚本——这是纯提示词永远做不到的。
平时只把 name + description 挂在系统提示里;任务命中时才读取正文;参考资料和脚本更是用到才读。三个层级的成本严格与使用深度挂钩。
Skill 教的是处理一类问题的方法,而不是某一个具体问题的答案。好的 Skill 应该能泛化:换个输入、换个数据集,流程依然成立。
新同事(智能体)每次开工都从零开始。你把 3000 行编码规范贴在工位墙上(塞进 system prompt),结果:
规范被封装成手册放在书架上。平时占一个书名条目(约 100 tokens);需要时智能体自己抽出来读;细节在附录里按需翻:
Skill = 可发现(元数据常驻)+ 按需加载(正文触发才读)+ 任务 SOP 模块(元数据 / 执行指令 / 示例模板 / 校验规则 / 脚本参考)。缺了任何一项,它就退化成了一段普通的提示词。
上下文窗口是智能体的公共预算。每多加载一个 token,就少一分留给真实任务的空间。Skill 的全部设计,本质上都是围绕「如何让成本与收益严格对齐」展开。
每次新对话都要重新讲一遍规则 → 触发即加载,一次封装永久生效。
今天格式 A、明天格式 B → 内置模板与校验清单兜底,输出收敛。
小王的提示词小李用不了 → 文件夹即资产,git 管理、团队共享。
无关规则挤占窗口 → 只加载相关指令,注意力聚焦。
把一切塞进 system prompt 不只浪费 token,还会降低质量。大量无关指令会互相竞争注意力,模型反而更可能漏掉关键约束。「少而准」优于「多而全」。
只有 SKILL.md 是必需的,其余三个目录是规范认可的约定。目录名必须与 name 字段完全一致。
唯一入口。含 YAML frontmatter 与 Markdown 正文,被激活时全部读入。
按需阅读的文档。智能体只在正文某一步明确指名时才打开它。
被使用的资源。模板、图片、查找表、schema,不占推理上下文。
被执行的代码。脚本源码永不进上下文,只有 stdout 进来。
画好目录树后,在每个文件旁写下「智能体应该在什么条件下加载/运行它」。答案是「总是」→ 内容应该进 SKILL.md;答案是「我说不清什么时候」→ 删掉这个文件。三个文件全被用到的技能,胜过十二个文件里一半没人打开的。
references/ 空文件夹只增加维护成本。references/npm.md 第一行写:「当仓库存在 package.json 且含 publish 脚本时读本文件」。智能体和后来的维护者都能看懂。整个文件只有两部分:上方的 YAML frontmatter(元数据区)和下方的 Markdown 正文(执行指令区)。--- 必须在文件第一行,否则整份文件会被当成正文处理。
--- name: pdf-processing description: Extracts text and tables from PDF files, fills forms, and merges documents. Use when working with PDF files or when the user mentions PDFs, forms. allowed-tools: Read, Bash(python *) license: MIT ---
只有 name 与 description 是规范必填;其余字段按运行环境而定(如 allowed-tools 用于预授权工具、model 用于指定模型)。
# PDF Processing ## Quick start Use pdfplumber to extract text: ```python import pdfplumber with pdfplumber.open("f.pdf") as pdf: text = pdf.pages[0].extract_text() ``` ## Gotchas - Encrypted PDFs: ask for password first - Scanned docs: warn that OCR is needed ## Advanced For form filling, see [forms.md](references/forms.md)
正文是流程而非说明:可执行步骤、判断分支、完成标准、反例禁忌、具体命令与真实参数。
| 字段 | 状态 | 约束与写法要点 |
|---|---|---|
name | 必填 | 最多 64 字符;仅小写字母、数字、连字符;不能含 XML 标签;不能含保留字 anthropic / claude;必须与目录名一致。推荐动名词形式:processing-pdfs、reviewing-code、testing-code。 |
description | 必填 | 最多 1024 字符,非空,不能含 XML 标签。第三人称,必须同时说清「做什么」+「何时用」,并埋入用户真实会说的触发词。这是整个文件最重要的一行。 |
allowed-tools | 可选 | 技能激活期间免确认预授权的工具。给最小集,绝不裸写 Bash,应收敛为 Bash(git status *) 这类模式。省略则继承会话默认权限模型。 |
license / metadata | 可选 | 许可信息与自定义键值对(作者、版本、标签等)。便于分发时溯源与版本比对。 |
model / effort | 可选 | 覆盖该次执行的模型与推理强度。除非实测对比过,否则不要锁死——模型退役会导致技能加载失败。 |
context: fork / agent | 可选 | 在派生的子智能体上下文中运行技能,用于隔离污染主线程的重型任务。 |
YAML 里一个 tab 代替空格、漏了冒号、或含冒号的字符串没加引号,都会导致解析失败——技能不会报错,而是被当成纯正文、元数据全部丢失。每次改动 frontmatter 后,都要用一句典型提问实测一遍能否触发。改 description 引发的「不再命中」是最隐蔽的回归。
这是整套规范里最值得抄的工程思想:像一本组织良好的手册——目录 → 章节 → 附录,智能体只在需要时才往下翻一层。下面这个演示可以逐层点击。
注意 L3 脚本那一格:一个 800 行的 Python 脚本,进上下文的只有它打印出的几十个 token 结果。这是「代码即免费能力」的来源。
| 层级 | 加载内容 | 加载时机 | 体量 | 设计意图 |
|---|---|---|---|---|
| L1 目录层 | name + description | 会话启动,全部同时加载 | 约 50–100 tokens/个 | 最小信息做判断:够用来决定「该不该用我」 |
| L2 指令层 | SKILL.md 完整正文 | 技能被匹配激活时 | 建议 < 5,000 tokens | 按需加载做执行:够用来把任务跑完 |
| L3 资源层 | references / scripts / assets | 被显式引用或执行时 | 取决于文件大小 | 无限扩展:能力上限不受上下文约束 |
三层加载 = 最小信息做判断 + 按需加载做执行 = 省上下文 + 更稳定。这条公式也解释了为什么 Skill 能替代「把全部提示词塞进 system prompt」。
当一个技能有三条互不相关的工作流时,把 SKILL.md 写成概述 + 目录索引,三条完整流程拆成三个子文件。智能体根据当前任务只读其中一个,上下文消耗与任务复杂度严格成正比。这是渐进式披露在单技能内部的二次应用。
从用户开口到交付结果,Skill 完整走过 发现 → 匹配 → 激活 → 执行 → 收尾 五个阶段。整个过程没有意图分类器、没有语义检索、没有算法路由——全靠模型自己读描述做推理判断。
启动时扫描已注册技能目录,把所有 name + description 格式化成文本,挂进系统提示。此时正文一字未读。
用户发来请求,模型阅读请求并逐条比对所有技能描述,自主判断该用哪个(也可能判断「都不需要」)。
通过内部 Skill 工具调用,用 bash 从文件系统读取 SKILL.md,把完整指令注入上下文窗口。这一刻才产生 token 成本。
按正文流程推进,需要时打开 references/、运行 scripts/、填充 assets/,并调用工具与 MCP 完成实际动作。
对照正文中的「完成标准」自检,输出符合模板的结果。加载过的内容在会话内保留,不再重复读取。
模型逐条扫过清单 → 命中 processing-pdfs(L1 元数据足够判断)→ 读取其 SKILL.md 正文(L2)→ 表格提取涉及复杂布局时,再打开 references/tables.md(L3)。
请求 B 命中 writing-docs;若两个技能都可能相关,模型会按描述的具体程度做取舍——这就是 description 必须写具体的原因。
技能激活后,其内容在本次会话余下时间一直留在上下文里,不会每轮重读——这也意味着它是一笔持续性 token 开销。这正是官方要求正文控制在 500 行 / 5k tokens 以内、把长内容下沉到 L3 的直接原因。
三者回答的是三个不同的问题,因此并不互斥。官方立场是它们可组合,生产环境的最佳解通常是三者的组合。
| 维度 | Skill(技能) | MCP(服务) | 子智能体(SubAgent) |
|---|---|---|---|
| 本质 | 注入上下文的 Markdown 指令 + 可选脚本 | 运行中的程序,提供带 JSON Schema 的工具 | 一个独立的智能体会话 |
| 回答的问题 | HOW —— 怎么做 | ACCESS —— 连什么 | WHO —— 谁来做 |
| 类比 | 标准作业手册(脑) | 感官与四肢(手和眼) | 被派出去的实习同事 |
| 运行位置 | 当前会话内 | 独立进程 / 远端 HTTP | 独立上下文窗口 |
| 能访问外部数据 | 否 | 是 | 仅通过被授予的 MCP |
| 能限制工具集 | 否(继承会话) | 间接(只暴露部分工具) | 是 |
| 能换更便宜的模型 | 否 | 不适用 | 是 |
| 上下文隔离 | 共享当前对话 | 不拥有对话 | 独立窗口 |
| 可并行 | 串行 | 异步工具调用 | 可并行 |
| 建设成本 | 几分钟(改个 md) | 数小时到数天(真代码) | 几分钟(md + YAML) |
| 最擅长 | 代码审查清单、迁移流程、风格约定、输出格式 | 数据库查询、部署状态、GitHub、实时看板 | 委派式重型任务、多专家并行、需要隔离的探索 |
| 典型反模式 | 在技能里写「查询当前状态」 | 用 MCP 服务一段本该是技能的静态提示 | 给它最强模型和全部工具,等于又一个主会话 |
智能体已经能读仓库、跑测试、开 PR,但每次做法都不一样。不需要连接什么,只需要把方法写下来。这也是最便宜的尝试——一个可以随时删掉的 Markdown 文件。
数据在数据库、SaaS 或 OAuth 后面,智能体够不着。此时才需要 MCP。注意:CLI 往往是更省的答案——模型本来就会跑 cli --help,且调用前不占上下文。
任务会往主对话灌满日志和检索结果,或需要不同模型、不同工具集,或想并行推进多件事。技能甚至可以指示智能体把活派给子智能体。
MCP 连接你的数据与仓库 → Skill 编码你团队的确切流程(静默时仅约 100 tokens)→ 子智能体在隔离上下文中执行该流程,只把结果交回来。选型的起点永远是问:我到底缺的是知识、通路,还是隔离?
团队常为一件智能体本来就能做的事造了个 MCP 服务。反过来也有:已有文档 MCP 服务连接的情况下,技能「很少被调用,且往往没带来明显更好的结果」。动手前先判断缺口在哪一侧。
启动时智能体只看得到 name + description。所以「什么情况下该用我」绝不能写在正文里——正文是命中之后才加载的,写在那里等于永远不会被读到。
# 太泛,没有触发条件 description: Helps with databases. # 第一人称,视角不一致 description: I can help you process Excel files. # 只说了做什么,没说何时用 description: Code review skill. # 把工作流写进描述,模型会走捷径跳过正文 description: Fetches PR, groups comments, presents summary, lets user select fixes.
# 做什么 + 何时用 + 用户真实会说的词 description: Reviews code changes for bugs, performance, and security problems. Use when reviewing PRs, before committing, or when user asks to review or check code. # 埋入领域术语与技术名词 description: Extracts text and tables from PDF files, fills forms, merges documents. Use when working with PDF files or when the user mentions PDFs, forms, or document extraction. # 甚至明确划出边界:Not for 近邻场景 description: ... Use when: X, Y. Not for: Z.
用「几乎总是如此」形容都不夸张。检查顺序:① 描述里有没有用户真会说的话?② 有没有漏掉同义词(如「间歇性失败」vs「flaky」)?③ 是不是太泛导致和一堆技能撞车?④ frontmatter 是否被 YAML 语法悄悄弄坏了?
验证方法:开一个全新的会话,用三到四个真实请求测试,其中必须包含一个「不该触发」的负例。
指令的具体程度要匹配任务的脆弱性与可变性。过度约束会扼杀模型的判断力,约束不足则会让易错流程翻车。
代码审查:最佳路径由代码上下文决定,给方向即可。
报表生成:给出脚本骨架与参数,允许按数据调整。
数据库迁移:必须按精确顺序执行,逐步给护栏。
编号步骤,而不是一段段建议。判断点写成条件句:「若 CI 正在失败,从失败的 job 开始」。
明确写 Done when:测试连续 20 次隔离运行通过、修复原因写进 commit message。模型才知道何时停手。
这是性价比最高的内容:反直觉的环境事实。如「users 表用软删除,查询必须带 WHERE deleted_at IS NULL」,或「用户 ID 在三处分别叫 user_id / uid / accountId」。
要特定格式就给模板——模型对具体结构的模式匹配远强于对散文描述的理解。短模板内联,长模板放 assets/ 按需引用。
每当模型犯了一个你必须纠正的错误,就把那条纠正加进 Gotchas。这是把真实执行反馈沉淀回技能的最直接路径——技能因此会越用越准。
发布前逐条自检。前六条是硬约束,后六条决定技能好不好用。
processing-pdfs / reviewing-code / testing-code;小写、数字、连字符,≤64 字符,与目录名一致。避免 helper、utils、documents 这类空泛名。references/lint-rules.md」——比笼统一句「详见 references/」有用得多。Bash。宽泛授权会被评审视为风险信号。写完正文后逐段问:「这一段提供了模型本来不知道的信息吗?」——答案是「否」,就把它移到 references/ 或直接删除。每一段都要为自己的 token 成本辩护。
这一节列的都是真实会咬人的坑,按「踩中频率 × 排查难度」排序。
| 症状 | 根因 | 修法 |
|---|---|---|
| 技能从不触发 | description 太泛,或缺少用户真实措辞的触发词 | 把「helps with testing」改成「use when a test fails intermittently or the user mentions flaky tests」;补上同义词与文件扩展名 |
| 疯狂误触发 | description 覆盖面过宽,与近邻技能撞车 | 加 Not for: Z 明确划边界;把触发条件收窄到具体动作与场景 |
| 元数据完全失效 | YAML 静默解析失败(tab、漏冒号、冒号后空格未加引号) | 用校验工具跑一遍;确认 --- 在文件第一行;改完必测触发 |
| 模型跳过正文走捷径 | description 里把完整工作流概括了一遍 | 描述只写「做什么 + 何时用」,严禁写步骤 |
| 上下文被吃满 | 正文臃肿,长内容没下沉 | 拆到 references/,正文留目录索引(菜单模式) |
| 换台机器就找不到文件 | 路径写死绝对路径 | 全部改相对路径;跨环境用技能目录变量解析 |
| 参考文件从没被打开 | 正文只写「详见 references/」,没给加载条件 | 在具体步骤处写明触发条件:「若 API 返回非 200,读 references/api-errors.md」 |
| 技能想查实时数据 | 把需要外部访问的需求写进了技能 | 这是 MCP 的活。技能负责流程,MCP 负责通路,组合使用 |
| 模型过度解释 / 过度简化 | 自由度与目标模型不匹配 | 按任务脆弱性调约束强度;对轻量模型补细节,对强推理模型减啰嗦 |
| 空目录充门面 | 为了「看起来完整」建了没人用的文件夹 | 只有 SKILL.md 必需。三个文件全被用到 > 十二个文件一半没人开 |
技能继承智能体已有的全部权限,它不单独申请权限,两者之间也没有沙箱。这不是缺陷,而是智能体之所以有用的前提——但它意味着一件重要的事。
如果你的智能体能读 ~/.aws/credentials,那么它正在遵循的任何技能指令也能读。安装一个技能,是一次与安装依赖同量级的信任决策。
公开技能仓库的审计结果显示,相当比例的技能存在安全问题,其中一部分被确认为恶意载荷(凭据窃取、后门等)。不要无审查地批量安装第三方技能。
① 安装前打开 SKILL.md 读一遍,先看 frontmatter 与脚本;② allowed-tools 只给最小集;③ 敏感信息走环境变量,绝不硬编码进技能文件。
不要在技能里请求或存储凭据、不要执行来源不明的远程代码、不要写绕过用户确认的宽泛 Bash 授权。评审者会把宽泛授权直接视为风险信号。
name:动名词、小写连字符、与目录同名。
description:第三人称,WHAT + WHEN + 触发词。技能不触发,九成是它的问题。