关于 skills-best-practices
为 Agent Skills 编写与组织提供实践指南,适用于跨 Agent 构建技能的开发者。内容涵盖文件结构、触发描述、渐进式加载、可移植性及 Claude Code 专项注意事项。
主要功能
- 01指导 SKILL.md 结构设计
- 02编写触发描述与负向触发
- 03规划按需加载参考资料
- 04说明技能的可组合性与可移植性
- 05介绍 Claude Code 行为注意事项
适用场景
- 01从零创建 Agent Skill
- 02精简过长的技能说明
- 03为技能选择单文件或拆分结构
- 04检查技能发布与加载限制
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tenequm/ skills --skill skills-best-practices安装后在 Claude Code 中输入/skills-best-practices确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdLICENSE.txtreferences/clawhub-publishing.md详细介绍
Skills 最佳实践
这是一份面向任意 Agent 构建 Agent Skills 的实用指南,内容提炼自 Agent Skills 开放标准、Anthropic 官方指导和生产实践,并在偏离官方建议之处加以标注。Skill 是包含说明、脚本和资源的文件夹(通常只有一个文件),用于教会 Agent 如何处理特定任务。
快速入门
最简 Skill 是一个包含 SKILL.md 文件的目录:
my-skill/
├── SKILL.md # Required - instructions with YAML frontmatter
├── references/ # Optional - detailed docs loaded on demand
├── scripts/ # Optional - executable code
└── assets/ # Optional - templates, fonts, icons
最简 SKILL.md:
---
name: my-skill-name
description: What it does. Use when [specific triggers].
---
# My Skill Name
[Instructions here]
frontmatter 中只有 name 和 description 是必需的。
核心设计原则
单文件与 references/(最重要)
默认使用单个 SKILL.md。 一个文件可以粘贴给他人、发布到 gist、嵌入 CLI 二进制文件,也可以通过 <tool> skill 子命令打印出来,而目录做不到。只有在同时满足以下条件时,才拆分到 references/:
- 按需加载:有意义的一部分内容仅用于部分调用(例如,大多数 DOCX 任务都不会用到的修订跟踪文档)。如果每次调用都会读取所有内容,拆分只会增加 Read 往返次数、降低可分享性,却毫无节省。
- 大小压力:正文超出下方建议的篇幅。
分发方式拥有一票否决权。 如果 Skill 必须以单个文件的形式分发——随 CLI 一起发布、通过命令打印,或通过粘贴分享——无论大小如何,都应保持单文件并进行精简。精简是指删去冗余、填充内容和过度解释,同时保留所有关键指令;为了达到行数要求而丢失实质内容才是问题,而非解决方案。参见 模式 中嵌入 CLI 的单文件模式。
大小建议(基于经验的主观阈值,并非规范强制限制)——使用 wc -c SKILL.md 测量。字符数与 token 成本密切相关(约每 4 个字符对应 1 个 token);行数不是衡量标准——相同内容因格式风格不同,行数可能相差 2 倍:
| 层级 | 字符数 | 超出后 |
|---|---|---|
| 建议值 | 25k | 谨慎精简;仅在通过按需加载测试时拆分 |
| 硬上限 | 50k | 必须精简或拆分 |
Anthropic 官方指导建议在 500 行时拆分。这项建议假设 Skill 通过注册表安装,且很少需要其子主题,并以一种会受格式影响的单位衡量大小——本 Skill 在这两方面都刻意有所不同。
拆分 Skill 时,信息分为三个层级加载:
| 层级 | 加载时机 | Token 成本 | 内容 |
|---|---|---|---|
| 1:元数据 | 始终(启动时) | ~chars / 4 + 25——参见长度 | frontmatter 中的 name + description |
| 2:说明 | Skill 触发时 | <5k tokens(建议值) | SKILL.md 正文 |
| 3:资源 | 按需 | 实际上不受限制 | 捆绑文件、脚本 |
在 SKILL.md 中引用详细的参考文件,以便仅在任务需要时加载它们:
## Advanced features
- **Form filling**: See [FORMS.md](FORMS.md)
- **API reference**: See [reference.md](reference.md)
可组合性
Skill 可以与其他 Skill 配合使用。不要假设只有你的 Skill 会被加载。
可移植性
Skill 无需修改即可在 Claude.ai、Claude Code、API 和 Agent SDK 中使用(前提是依赖项可用)。
编写描述(至关重要)
描述是最重要的单个字段——它决定 Skill 何时激活。Claude 会据此判断其与任务的相关性,而可用的 Skill 可能多达 100 多个。
规则
- 使用第三人称(“处理文件……”——使用第一或第二人称会影响发现)
- 说明它做什么以及何时使用
- 不要使用 XML 尖括号;尺寸目标见长度
- 语气稍微“积极推动”一些——Claude 更容易触发不足,而不是触发过度
- 加入用户自然会说的具体触发短语,并在相关时注明文件类型
- 使用自然的文字,而不是关键词堆砌——匹配基于语义,因此比起清晰的句子,冗长的“在 X、Y、Z 时触发……”列表帮助不大
- 如果该技能依赖 MCP 服务,请注明名称(“……通过 MCP。需要连接 Linear MCP 服务。”)
长度
目标为 250 个字符。规范中的 1024 是上限,不是预算。 技能描述是每个会话的每一轮都会消耗令牌的唯一部分,无论该技能是否触发。超过约 250 个字符后,你是在稀释触发信号,而不是让它更精准:描述是调度信号,不是摘要。
压缩过长描述时,通常按以下顺序最有效:
- 删掉在正文中重复列举的技术栈。 技术栈列一次就够了;再说“涵盖前端……和后端……”纯属赘述
- 删掉宣传内容。 “包含详尽的 API 表格”描述的是正文,而不是何时触发
- 合并触发条件列表。 一个清晰的从句胜过三个带引号的短语和四个“何时”从句——匹配基于语义,因此近似重复的触发条件没有帮助
- 保留排除项和消歧说明。 “不用于会话状态”“不是 LanceDB 产品”只需 30–40 个字符,却能避免错误的技能调度
好例子与坏例子
# GOOD - specific, actionable, includes triggers
description: Extract text and tables from PDF files, fill forms, merge
documents. Use when working with PDF files or when the user mentions
PDFs, forms, or document extraction.
# BAD - too vague
description: Helps with documents.
# BAD - missing triggers
description: Creates sophisticated multi-page documentation systems.
负向触发条件
当技能触发过度时,可在描述中直接添加边界:
description: Advanced data analysis for CSV files. Use for statistical
modeling, regression, clustering. Do NOT use for simple data
exploration (use data-viz skill instead).
手动调用的技能
disable-model-invocation: true 会阻止技能自动触发——其描述只会显示在 / 菜单中,因此触发短语对它不起作用,而且它也不会预加载给子 Agent 或用于计划任务。
不要默认使用它。 用户用文字描述工作流(“提交前润色一下”)的情况远比输入 /name 常见,而此标志会把这些请求变成手动拼凑的劣化版技能。仅在确实具有破坏性的单次操作中使用。设置此标志后,请写一行简单的摘要,并跳过触发条件调优。
Frontmatter 参考
必填字段
| 字段 | 规则 |
|---|---|
name | 使用 kebab-case,最多 64 个字符,仅限小写字母、数字和连字符。不得包含“claude”或“anthropic” |
description | 不得为空,最多 1024 个字符,不得包含 XML 标签。说明做什么以及何时使用 |
agentskills.io 标准和 Claude API 都要求这两个字段。Claude Code 的限制更宽松:name 默认使用目录名,description 默认使用第一个 Markdown 段落。为了保持可移植性,仍应填写这两个字段。
规范还定义了可选的 license、compatibility 和 metadata 字段。compatibility 最多 500 个字符,用于说明环境要求(预期产品、系统软件包、网络访问权限)。
可选字段(Claude Code)
| 字段 | 用途 |
|---|---|
argument-hint | 自动补全提示,例如 [issue-number] |
when_to_use | 额外的触发上下文,会附加到技能列表中的 description |
arguments | 用于 $name 替换的命名位置参数(以空格分隔的字符串或列表) |
disable-model-invocation | true = 仅用户可调用;也会阻止子 Agent 预加载和计划任务。通常不值得启用——参见手动调用的技能 |
user-invocable | false = 从 / 菜单中隐藏(后台知识) |
allowed-tools | 为当前轮次预先批准工具(不显示权限提示);以空格分隔,例如 Read Grep Glob。在规范允许列表中,但标记为**(实验性)** |
disallowed-tools | 在技能处于活动状态时,从 Claude 的工具池中移除工具;在你发送下一条消息时清除 |
model | 为此技能指定模型;接受 inherit。仅在当前轮次有效 |
effort | 覆盖工作强度级别:low、medium、high、xhigh、max |
context | fork = 在隔离的子 Agent 中运行 |
agent | context: fork 时使用的子 Agent 类型(例如 Explore、Plan) |
background | false 表示选择不让分叉的技能在后台执行(v2.1.218+) |
shell | bash(默认)或 powershell |
hooks | 作用于此技能生命周期的钩子 |
paths | 限制技能激活条件的 Glob 模式 |
发布注意事项: 除
allowed-tools外,上述所有字段都特定于 Claude Code。它们在 Claude Code 运行时有效,但 官方agentskills validate规范验证器会拒绝这些字段——它只允许name、description、license、compatibility、metadata、allowed-tools,且没有放宽标志。如果你的代码库或 CI 运行该验证器(大多数向 ClawHub 发布的代码库都会运行),使用这些字段的技能将无法通过验证,除非你从要验证或发布的副本中移除这些字段。ClawHub 注册表本身在发布时通常会容忍额外的顶层字段,但你的流水线中的参考验证器不会。参见根据规范验证。
命名约定
name(及其文件夹)必须:长度为 1–64 个字符;仅使用小写字母、数字和连字符;不能以连字符开头或结尾;不能包含连续连字符(--);并且必须与父目录名称一致。Anthropic 产品还会拒绝保留词 claude 和 anthropic。
为清晰起见,优先使用动名词形式:
processing-pdfs、analyzing-spreadsheets、managing-databases- 也可接受:
pdf-processing、process-pdfs - 避免使用:
helper、utils、tools、documents
Claude Code 特有内容
官方文档涵盖了大多数 Claude Code 技能行为:技能文档(调用控制、参数替换、发现与优先级、工具权限、skillOverrides、上下文预算)、命令参考(查看当前捆绑技能列表;该列表每隔几个版本就会变化——切勿将其硬编码),以及设置参考。以下仅介绍这些文档未提及或实际使用中容易踩坑的内容。
动态注入陷阱
Claude Code 会在加载时预处理 SKILL.md:紧贴反引号命令的感叹号会在 Claude 看到内容之前执行该命令(动态上下文注入)。预处理器不理解 Markdown:
- 即使字面示例位于代码围栏或行内代码跨度中,也会在加载时执行;占位命令若执行失败,会导致整个技能加载失败
- 行内形式仅在行首或空白之后触发;添加前缀即可规避(在
!前添加KEY=,就会将其视为字面内容) - 如果代码围栏紧接在反引号后以
!开头,它就是多行形式,同样会执行 references/文件由 Read 工具读取,不会经过预处理,是放置可执行示例的唯一安全位置。在 SKILL.md 中,应打断!与反引号的紧邻关系(像本节这样,将!单独放在自己的代码跨度中)- 在设置中将
"disableSkillShellExecution": true设为true,即可禁用用户/项目/插件技能的执行 - **发布技能时,优先使用文字说明,不要使用
!代码块。**动态注入因宿主而异:在其他界面中,该代码块会作为字面文本显示,而且还会纯粹为了抑制自身的权限提示而附带allowed-tools。指示 Agent 运行命令只需调用一次工具,而且到处都能用
未记录的行为
display-name、default-enabled和fallback前置元数据键确实存在,但未列入官方前置元数据表- 前置元数据键不区分大小写解析——kebab-case、snake_case 和 camelCase 都会解析为同一字段;布尔字段也接受
yes/no/on/off/1/0(v2.1.218+)
容易踩坑的行为
- 自 v2.1.218 起,
context: fork技能默认会在后台运行(可通过background: false禁用);后台运行的分支可用工具范围更窄,且其编辑会绕过检查点,因此/rewind无法撤销这些编辑。Explore/Plan分支会跳过 CLAUDE.md 和 git status;自 v2.1.198 起,Explore会继承会话模型 - 技能可以叠加:在一条消息中输入
/skill-a /skill-b args,最多可加载六个技能(v2.1.199+) permissions.additionalDirectories不会从这些目录加载技能——只有--add-dir标志和/add-dir命令才会加载allowed-tools的授权仅在当前轮次有效——用户发送下一条消息时就会清除,而不是等技能“完成”时才清除/command名称来自技能的目录;前置元数据中的name只是显示标签(插件技能除外)。嵌套技能可通过限定名称调用,例如/apps/web:deploy- 被调用的技能内容会在整个会话中保留在上下文里,且不会重新读取——应编写长期有效的指令,而非一次性步骤。自动压缩后,每个技能最近一次调用的内容会重新附加:从共享的 25,000 个 token 预算中,按最近调用优先填充其前 5,000 个 token;再次调用即可恢复完整内容
- 技能描述会在启动时加载,受上下文窗口 1% 的列表预算限制;最少使用的描述会优先移除(名称始终保留),每个条目最多 1,536 个字符。使用
/doctor诊断;通过skillListingBudgetFraction、skillListingMaxDescChars或SLASH_COMMAND_TOOL_CHAR_BUDGET调整
组织指令
简洁明了
Agent 很聪明。只补充它尚不了解的背景信息——解释 PDF 是什么的技能,或先罗列四个库再选出一个的技能,都是在浪费 token,告诉 Agent 它已经知道的事:
# BAD: "PDF files are a common format containing text and images. To extract
# text you need a library. There are many available..."
# GOOD: "Use pdfplumber for text extraction."
避免选项过多
提供一个默认选项,并留出变通途径,而不是列出一串选项:
# BAD: "Use pypdf, or pdfplumber, or PyMuPDF, or pdf2image..."
# GOOD: "Use pdfplumber. For scanned PDFs needing OCR, use pdf2image with pytesseract."
设置自由度
- 高自由度(文本指南):有多种可行方法,具体取决于上下文
- 中自由度(伪代码/模板):存在首选模式,但允许一定变化
- 低自由度(精确脚本):操作容易出错,一致性至关重要
推荐的 SKILL.md 结构
# Skill Name
## Quick start
[Minimal working example]
## Workflow Decision Tree
[Route to the right approach based on task type]
## Detailed Instructions
[Step-by-step for each workflow]
## Examples
[Concrete input/output pairs]
## Troubleshooting
[Common errors and fixes]
参考文件
参考文件应与 SKILL.md 保持一层深度。“深度”指的是引用链(一个文件链接到另一个文件,再链接到另一个文件),而非文件系统嵌套层级——使用 references/ 子目录也没问题。在引用链中,Claude 可能会通过部分读取(head)预览文件,从而漏掉某些内容。
# BAD: Too deep
SKILL.md -> advanced.md -> details.md -> actual info
# GOOD: One level
SKILL.md -> advanced.md (contains the info directly)
SKILL.md -> reference.md (contains the info directly)
对于超过 100 行的参考文件,请在顶部添加目录。也要注意文件大小:即使只深入一层,数百行的单个参考文件也会破坏渐进式披露,因为 Claude 会为任何子主题加载整个文件。请按子主题拆分大型参考文件,让每项任务只加载所需内容。
模式
常见工作流形式
请在正文中明确命名工作流形式,而不是默认 Agent 能自行推断:
- 顺序执行:列出编号步骤,每一步都写明要运行的确切命令
- 决策树:一开始就根据任务类型分流(“要创建新内容?→ 创建工作流”)
- 反馈循环:验证、修复、重新验证,并说明只有通过验证后才退出循环
- 检查清单:对于较长的任务,让 Agent 复制检查清单,并在执行过程中逐项勾选
嵌入 CLI 的单文件技能
对于记录 CLI 工具的技能:将 SKILL.md 作为单个文件放在 CLI 源代码旁,编译进二进制文件(go:embed、Rust include_str! 或等效方式),并添加一个 <tool> skill 子命令来打印其内容。这样打印出的指南始终与已安装版本一致,只需一条命令即可获取完整文档——playwright-cli、browser-use(browser-use skill show)和 agent-browser(agent-browser skills get core)都采用了这种形式。切勿将此类技能拆分到 references/ 中;应谨慎精简。
使用 MCP 和子 Agent
MCP 提供工具访问能力;技能提供有关如何善用这些工具的工作流知识。请使用完整限定名称引用 MCP 工具(BigQuery:bigquery_schema、GitHub:create_issue)。技能是可移植的专业知识;子 Agent 则用于隔离执行——在 Claude Code 中,context: fork 前置元数据会在子 Agent 内运行技能。
使用 Claude 开发技能(A/B 循环)
使用两个 Claude 实例来构建技能:Claude A 帮助设计和完善(它了解格式以及 Agent 需要什么);Claude B 是加载了技能并在真实任务上进行测试的全新实例。留意你在日常工作中反复提供哪些上下文,让 A 将其整理成技能,再用 B 测试,并把 B 遇到的具体问题反馈给 A(“它忘了筛除测试账号”),然后重复这一过程。根据观察到的行为迭代,而非依赖假设。对于输出风格类技能,输入/输出示例对比任何描述都更能传达期望的风格。
脚本
技能包含可执行代码时:
- 解决问题,不要推诿:明确处理错误,而不是任由其失败
- 说明常量的依据:不要使用魔法数字——记录每个值的选择理由
- 优先执行,而非加载:脚本运行时不会进入上下文;只有输出会消耗 token
- 明确意图:“运行
analyze.py”(执行)与“查看analyze.py”(作为参考阅读)含义不同 - 在 SKILL.md 中列出依赖项并确认其可用
测试
先构建评估
在编写大量指令之前,先创建评估——这能证明技能确实解决了实际问题。先在不使用技能的情况下,让 Claude 处理有代表性的任务并记录失败;构建约 3 个用于测试这些问题的场景;测量基线;然后编写通过测试所需的最少指令。根据基线反复迭代。
触发测试
Should trigger:
- "Help me set up a new project in [Service]"
- "I need to create a project" (paraphrased)
Should NOT trigger:
- "What's the weather?" (unrelated)
- "Write Python code" (too generic)
功能测试
测试正常操作、边缘情况以及超出范围的请求。对同一请求运行 3-5 次,检查一致性。
调试触发
问 Claude:“你什么时候会使用 [skill-name] 技能?”——它会复述描述内容。根据遗漏之处进行调整。
根据规范进行验证
发布前运行官方 Agent Skills 验证器:
uvx --from skills-ref agentskills validate path/to/skill
退出代码为 0 表示有效。验证器会检查 SKILL.md 格式,并强制执行规范严格的 frontmatter 允许列表(name、description、license、compatibility、metadata、allowed-tools)。大多数注册表(例如 ClawHub)和 CI 门禁都会运行此验证器,因此在本地验证可以及早发现问题。如果你依赖仅适用于 Claude Code 的 frontmatter(请参阅 Frontmatter Reference 下的发布注意事项),请从待验证的副本中移除这些字段。
发布前检查清单
根据范围调整:对于项目本地或单用户技能,可跳过触发准确性和分发规范相关项目。
- 文件夹名和
name均为 kebab-case,且两者一致;文件名必须恰好为SKILL.md - 描述:使用第三人称,说明内容和适用时机,包含具体触发条件,不超过 1024 个字符,不含尖括号
- 除非按条件加载的内容确实需要引用文件,否则使用单文件;大小在预算范围内(
wc -c) - 关键指令置于顶部;提供可用示例,而非伪代码;术语保持一致
- 如果拆分:从 SKILL.md 链接到 references/,仅深入一层;超过 100 行的文件须包含目录
- 脚本:明确处理错误,不含未解释的常量,列出依赖项,明确说明是执行还是读取
- 已测试触发效果:直接请求和改述请求均能触发;无关请求及相似但不同的请求不会触发
- 功能正常:常规情况和边缘情况均通过;连续运行 3-5 次输出一致;已在多个模型上测试
- 不含时效性信息、Windows 风格路径或已弃用的 API
- 规范验证器退出代码为 0(见上方命令)
- 上传后:在真实对话中监测触发不足或过度触发的情况,迭代改进描述;每次更改都递增版本号
故障排除
| 症状 | 原因 | 修复方法 |
|---|---|---|
| 技能从未加载 | 描述过于含糊 | 添加具体触发条件和关键词 |
| 技能针对错误的任务加载 | 描述过于宽泛 | 添加排除触发条件,进一步明确描述 |
| 未遵循指令 | 内容过于冗长或位置太靠后 | 将关键指令放在顶部,并使用标题 |
| 响应缓慢或质量下降 | SKILL.md 过大 | 先精简;仅在内容按条件加载时才拆分到 references/(参见 Single File vs. references/) |
| “Could not find SKILL.md” | 文件名错误 | 必须恰好为 SKILL.md(区分大小写) |
| “Invalid skill name” | 含空格或大写字母 | 使用 kebab-case:my-skill-name |
| 加载时整个技能被静默跳过 | 描述超过 1024 个字符 | 精简描述;加载器会拒绝整个文件,而不只是描述 |
| Frontmatter 解析失败 | 未加引号的 description 是纯 YAML 标量,其中任何冒号加空格(Triggers: 、Use when: )或直引号("quotes")都会导致解析失败 | 将冒号改为 -,或给整个值加引号 |
| 文档示例会运行 shell 命令 | 紧挨着反引号命令的 ! 会在加载时执行,即使位于代码围栏中 | 将示例移至 references/,或打断 ! 与反引号之间的相邻关系(参见 Dynamic-Injection Footgun) |
分发
| 平台 | 部署方式 |
|---|---|
| Claude.ai | Settings > Features > Upload zip |
| Claude Code (personal) | ~/.claude/skills/<name>/SKILL.md |
| Claude Code (project) | .claude/skills/<name>/SKILL.md |
| Claude Code (plugin) | <plugin>/skills/<name>/SKILL.md |
| API | 通过 Skill Management API 上传,通过 Messages API 使用 |
| Enterprise | 托管设置(组织范围) |
技能不会在各个平台之间同步,需分别部署到每个平台。
通过 API 使用 Skills
自定义 Skills 通过 Skill Management API 上传;anthropic 类型的 Skills 由 Anthropic 预先构建。两者的用法完全相同——在 Messages API 的 container 参数中传入,每个均为 {type, skill_id, version},其中 type 为 anthropic 或 custom。每个请求最多支持 8 个 Skill,上传文件总大小上限为 30 MB,且所有文件必须共享一个根目录。需要使用代码执行工具和 beta 标头 code-execution-2025-08-25、skills-2025-10-02(上传或下载文件还需要 files-api-2025-04-14)。
不同使用场景的网络访问能力有所不同。 API 代码执行环境无法访问网络,也无法在运行时安装软件包——请打包依赖项或使用预装软件包。相比之下,在 claude.ai 上,Skills 可以从 npm 和 PyPI 安装软件包,也可以从 GitHub 获取内容。
另外:pause_turn 停止原因表示 Skill 操作运行时间较长;通过 container.id 在多个轮次间复用容器;生成的文件会通过 Files API 返回;更改 Skills 列表会破坏提示词缓存;Skills 不符合 ZDR 资格。
安全性
- 仅使用来自可信来源的 skills
- 前置元数据中不得使用 XML 尖括号(存在注入风险)
- 使用第三方 skills 前,审查其捆绑的所有脚本和资源
- 谨慎使用会从外部 URL 获取内容的 skills
- 编写动态注入语法的文档本身就存在风险——加载器会在加载时执行示例,即使示例位于代码围栏中也是如此。编写任何内容前,请参阅动态注入陷阱
其他参考资料
- ClawHub 发布 - 从来源中梳理出的审核注意事项:原因代码和修复方法、通过 LLM 审核的策略,以及 ClawHub 文档中未提及的限制