跳到主要内容

创建日期:2026-09-23 | 最近更新:2026-09-23 事实核对基于可抓到正文的官方文档(抓取日期 2026-09-23,curl):Claude Code 的 code.claude.com/docs/en/skills.md + features-overview.md、OpenClaw 的 docs.openclaw.ai/tools/*.md。逐字引文与 URL 留档于 source/skills-lab/official-sources.md。带数字的结论分 [实测](本机真实文件/真查 PATH)与 [模拟](按文档规则推算)两类,正文中分别标注。

Agent Skills 入门:SKILL.md 怎么工作,OpenClaw 与 Claude Code 的差别,Skill 与 MCP 的关系

一句话:Skill 就是"一个装着 SKILL.md 的文件夹"——文件开头是 YAML 元数据(name / description),后面是给模型看的 markdown 说明书。它的全部设计目的只有一个词:按需加载(progressive disclosure)。

理解 Agent Skills 最快的方式,是把它放进"给 Agent 加东西"的几种手段里对比:

你想加的东西该用什么什么时候进上下文
项目约定、每次都要遵守CLAUDE.md / AGENTS.md每次请求都在(常驻)
"怎么做某件事"的知识与流程Skill描述常驻,正文命中才载入
连接外部系统(数据库、Slack、浏览器)MCP工具名常驻,完整 schema 按需
必须每次都发生的动作(格式化、拦截)Hook触发时才跑,零上下文

这张表是官方文档的框架(逐字留档见来源文件)。本文要回答三个问题:Skill 本身怎么工作、OpenClaw 和 Claude Code 的 skills 差在哪、Skill 与 MCP 到底是什么关系。

1. 一个 Skill 长什么样​

最小可用形态就是一个文件夹 + 一个 SKILL.md:

my-skill/
├── SKILL.md ← 必需:元数据 + 说明书
├── reference.md ← 可选:细节文档,需要时才读
├── examples.md ← 可选:例子,需要时才读
└── scripts/
└── helper.py ← 可选:脚本,**被执行**,不载入上下文

SKILL.md 本体:

---
name: api-conventions
description: API design patterns for this codebase
---

When writing API endpoints:
- Use RESTful naming conventions
- Return consistent error formats
- Include request validation

就这么多。没有编译、没有注册、没有 SDK——放进 skills 目录就生效。

2. 核心机制:渐进式披露的三层​

这是整个 Skills 设计里唯一需要真正理解的东西。官方原文:

【官方原文】"Skills can include multiple files in their directory. This keeps SKILL.md focused on the essentials while letting Claude access detailed reference material only when needed. Large reference docs, API specifications, or example collections don't need to load into context every time the skill runs."

它把成本切成三层:

层内容何时进入上下文本机实测字节数
L1 常驻name + description会话开始,用于"模型判断该不该用"288 ~ 451
L2 触发SKILL.md 正文被命中、载入后1,950 ~ 47,333
L3 按需附属文件(references/examples)真的需要时才读0 ~ 6,629(fixture)

**【实测】**我扫了本机能扫到的真实 skill(source/skills-lab/harness.mjs):

skill L1 常驻 L2 触发 L3 按需 L2/L1
----------------------------------------------------------------------
123 288 1,950 0 6.8x
inkos 451 47,333 0 105.0x
videocaptioner 235 6,831 0 29.1x
demo-fixture (fixture) 84 202 6,629 2.4x
----------------------------------------------------------------------
合计 1,058 56,316 6,629 53.2x

inkos 那个 skill 的正文是 47KB,是它常驻部分的 105 倍。 如果没有这套机制,这 47KB 每轮请求都要付费;有了它,平时只花 451 字节。

2.1 两个容易忽略的规则​

① 正文载入后会一直留着,不是用完就丢。 官方原文:

【官方原文】"Keep the body itself concise. Once a skill loads, its content stays in context across turns, so every line is a recurring token cost."

所以 SKILL.md 正文要"薄"——把细节推到 L3。反过来说,L2 也不是免费的,写太厚等于每轮都在付它。

② 脚本是"被执行"而不是"被读进上下文"。 官方给的目录树里写得很直白:

【官方原文】scripts/helper.py (utility script - executed, not loaded)

这就是为什么"需要精确执行的东西"该写成脚本,而不是写成一大段自然语言步骤。

3. Claude Code 的 Skills 细节​

3.1 放哪儿、怎么触发​

  • 项目级 .claude/skills/<name>/SKILL.md;用户级 ~/.claude/skills/;也能随 plugin 分发。
  • 触发两条路:模型按 description 判断该不该用;或你直接打 /<name>。
  • 只想要手动触发:disable-model-invocation: true。

3.2 frontmatter 字段(挑重点)​

字段作用
name / description标识 + 给模型判断用的唯一线索
when_to_use补充"什么时候用",一起进列表
disable-model-invocation只允许手动 /name 触发
allowed-tools / disallowed-tools预授权/限制这个 skill 能用哪些工具
context: fork把 skill 丢进一个独立子代理上下文里跑
paths限定生效的路径范围
model / effort这个 skill 用哪个模型 / 多少推理预算
hooks随 skill 带 hook

参数占位用 $ARGUMENTS / $ARGUMENTS[N]。

一个硬规则(踩了就静默失效):

【官方原文】"Claude Code reads the frontmatter only when the opening --- is the file's first line. Otherwise it treats the whole file, --- markers included, as skill content."

即:--- 必须是文件第一行,前面不能有空行、注释、标题。

3.3 描述列表也有预算,而且会"按使用频率淘汰"​

这条很多人不知道:所有 skill 的名字和描述会组成一个列表进上下文,这个列表有预算上限。

【官方原文】"The budget scales at 1% of the model's context window. When the listing overflows, Claude Code drops descriptions starting with the skills you invoke least, so the skills you use most keep their full text."

细节:

  • 单条(name + description + when_to_use)合并上限 1,536 字符;
  • 可调:skillListingBudgetFraction(按比例)、SLASH_COMMAND_TOOL_CHAR_BUDGET(固定字符数)、skillListingMaxDescChars(单条上限);
  • 把低优先级 skill 设成 "name-only"(skillOverrides),可以"只留名字、让出预算";
  • 观测:/context 看 Skills 行的实际占用、/doctor 估算、--debug 看截断告警。

实践含义:description 要写"能被打中的关键词",而且把最关键的用途放最前面——因为溢出时是从后往前砍的。

4. OpenClaw 的 Skills 细节​

OpenClaw(openclaw/openclaw,个人 Agent 项目,前身 Clawdbot/Moltbot)也是同一套 SKILL.md 约定,但它把 skills 当成一个平台能力来做,多了几个层次。

它的三类扩展分工是这么定义的:

【官方原文】"Tools are callable actions, skills teach agents how to work, and plugins add runtime capabilities such as tools, providers, channels, hooks, and packaged skills."

4.1 七级加载优先级​

同名 skill 出现在多处时,优先级高的赢(逐字表见来源文件):

优先级来源路径
1(最高)Workspace skills<workspace>/skills
2Project agent skills<workspace>/.agents/skills
3Personal agent skills~/.agents/skills
4Managed / local<state-dir>/skills
5Workshop skills<state-dir>/agents/<agentId>/agent/workshop-skills
6Bundled / Custodian skills随安装包
7(最低)Extra dirs + plugin skillsskills.load.extraDirs

4.2 ★ 门控(Gating):加载期就把不适用的摘掉​

这是 OpenClaw 最有辨识度的一层。skill 可以在 metadata.openclaw 里声明运行前提:

---
name: image-lab
description: Generate or edit images via a provider-backed image workflow
metadata:
{
"openclaw":
{
"requires": { "bins": ["uv"], "env": ["GEMINI_API_KEY"], "config": ["browser.enabled"] },
"primaryEnv": "GEMINI_API_KEY",
},
}
---

【官方原文】"OpenClaw filters skills at load time using metadata.openclaw. A skill with no metadata.openclaw block is always eligible unless explicitly disabled."

门控键:requires.bins(全部二进制必须在 PATH)、requires.anyBins(至少一个)、requires.env、 requires.config、os(平台过滤)、always(配合 os 时绕过其余检查)。

而且它还能声明怎么装依赖(install 规格,支持 brew / node / go / uv):

metadata:
openclaw:
install:
- kind: brew
formula: jq
bins: [jq]

**【实测】**本机真查一遍:某 skill 声明 requires.bins: ["uv","jq"] → jq 在 PATH 上(通过), uv 不在(这个 skill 直接在加载期被摘掉,连描述都不占上下文),GEMINI_API_KEY 未设置。 这就是门控和"写进描述里提醒模型"的本质区别:一个在加载期过滤,一个在推理期祈祷。

4.3 直连工具:绕过模型​

OpenClaw 的 skill 可以声明把斜杠命令直接接到某个工具,中间不过模型:

【官方原文】"command-dispatch … Set to tool to route the slash command directly to a tool, bypassing the model."

(配合 command-tool 指定工具名。)这相当于把"确定性的快捷命令"从"让模型理解"里摘出来。

4.4 Token 开销模型:写得比 Claude Code 更"白盒"​

OpenClaw 把上下文成本算成了公式:

【官方原文】"When skills are eligible, OpenClaw injects a compact XML block into the system prompt. The cost is deterministic and scales linearly per skill:

  • Base overhead … a fixed block of intro prose plus the <available_skills> wrapper.
  • Per skill: ~97 characters + your name, description, and location field lengths.
  • At ~4 chars/token, 97 chars ≈ 24 tokens per skill before field lengths."

溢出时降级的顺序也写明了:先保住"名字 + location"的紧凑格式 → 再用剩余预算放截短的描述 → 再不够就整条不写描述。预算由 skills.limits.maxSkillsPromptChars 控制。

4.5 分发与治理:ClawHub + Skill Workshop​

  • ClawHub 注册表:像 npm 一样发布/发现 skill——clawhub skill publish,semver 版本 + latest 标签, owner/scope 归属;所有发布到 ClawHub 的 skill 一律 MIT-0(官方原文,且不支持付费 skill); 服务端限制总包 50MB,忽略规则用 .clawhubignore。
  • 元数据一致性会审计:官方原文——如果代码里用了 TODOIST_API_KEY 但 frontmatter 没声明, "the analysis will flag a metadata mismatch"。
  • Skill Workshop:agent 起草的 skill 走提案队列(propose-create → inspect → evaluate → apply), 人工审核后才生效。还有 self-learning(把纠正与成功经验沉淀成 skill)与 Custodian skills (只有指定 agent 能发现和使用的运维 skill)。
  • CLI:openclaw skills search / install / update / verify / list / info / check / library / workshop。

5. ★ OpenClaw 与 Claude Code 的 skills 差在哪​

先说共同点(很重要):两者都遵循同一套可移植约定——目录即 skill、SKILL.md、 frontmatter 里 name + description、小写连字符命名。OpenClaw 甚至专门写明要跟这个约定对齐:

【官方原文】"For portable Agent Skills, name should match the parent directory and use 1–64 lowercase letters, numbers, or hyphens."

所以一个 skill 基本可以两边搬。差别在"平台那一层":

维度Claude CodeOpenClaw
定位编码 Agent 的可扩展点(与 CLAUDE.md / hooks / subagents / MCP / plugins 并列)自托管网关平台的能力面(tools / skills / plugins 三分)
加载来源项目 .claude/skills、用户 ~/.claude/skills、plugin七级优先级(workspace → agents → personal → managed → workshop → bundled → extra)
依赖门控❌ 无 requires.*(有 allowed-tools / paths / disable-model-invocation)✅ requires.bins/anyBins/env/config/os + always
声明式装依赖❌✅ install 规格(brew / node / go / uv)
命令直连工具❌(确定性交给 hook)✅ command-dispatch: tool,绕过模型
上下文预算口径上下文窗口的 1%,超了按使用频率淘汰描述固定字符预算 maxSkillsPromptChars,超了逐级降级(名字 → 短描述 → 无描述)
分发plugin + marketplace / git 仓库 / 目录同步ClawHub 注册表(npm 式发布、版本、owner scope)
授权随仓库/plugin 各自的许可强制 MIT-0,不支持付费 skill
治理/生命周期evals(skill-creator)、/skill-doctor 查闲置、skillOverrides、回收站、claude.ai 同步Skill Workshop 提案队列、self-learning、Custodian skills、加载快照与刷新
跨端终端 / IDE / 桌面 / 浏览器 / SDKGateway + 各聊天渠道(Discord/Slack/Telegram/…)+ macOS 面板
运行隔离context: fork 跑在子代理上下文per-agent 可见性 + 沙箱 + workspace 访问模式

一句话总结差异:Claude Code 把 skill 当作"给我这个编码助手加知识",OpenClaw 把 skill 当作"一个要分发、要审计、要按环境门控的软件包"。 前者赢在轻,后者赢在"装上就能跑"的确定性——requires + install 让"这个 skill 在这台机器上到底能不能用"变成了加载期事实,而不是运行期的惊喜。

6. ★ Skill 与 MCP 是什么关系​

这是最容易搞混的一对。官方给的定性非常清楚:

【官方原文】"MCP connects Claude to external services. Skills extend what Claude knows, including how to use those services effectively."

对照表(逐字):

维度MCPSkill
是什么连接外部服务的协议知识、工作流、参考材料
提供什么工具与数据访问知识、工作流、参考材料
例子Slack 集成、数据库查询、浏览器控制代码评审清单、部署流程、API 风格指南

6.1 它们是互补,不是替代​

【官方原文】"MCP gives Claude purpose-built tools for an external system, with the connection and authentication handled by the server." "Skills give Claude knowledge about how to use those tools effectively, plus workflows you can trigger with /<name>."

官方给的组合范例:

【官方原文】"MCP provides the connection; a skill teaches Claude how to use it well —— MCP connects to your database, a skill documents your schema and query patterns."

换句话说:MCP 给"手"(能做什么),Skill 给"脑子里的做法"(该怎么用)。 只有 MCP,模型知道有个 query_database 工具,但不知道你们库的表怎么设计、该避开哪些慢查询;只有 Skill,模型知道规范,却没有连接能力去执行。

6.2 两者的上下文成本不是一个量级​

**【实测】**一个含 3 个参数的 MCP 工具 schema,序列化后 445 字节;一个 skill 的常驻部分(名字+描述) 111 字节,4.0 倍差距。工具一多,常驻压力主要来自 schema。

而官方给的应对机制也是同一路子——把重的往后推:

【官方原文】(上下文加载表)Skills:"Descriptions at start, full content when used"; MCP servers:"Tool names; full schemas on demand"。 补充:"Tool search is on by default, so idle MCP tools consume minimal context."

常驻什么按需什么
Skill名字 + 描述SKILL.md 正文 → 附属文件
MCP工具名完整 schema

6.3 那 Hook 呢?三个一起看才完整​

护栏到底该放 skill 还是 hook?官方有一句非常关键的话:

【官方原文】"Put guardrails in hooks. An instruction like 'never edit .env' in CLAUDE.md or a skill is a request, not a guarantee. A PreToolUse hook that blocks the edit is enforcement. If a rule must hold every time, make it a hook rather than a prompt instruction."

三方分工可以浓缩成一句:

本质确定性上下文成本
Hook事件触发的动作保证执行零(除非回传内容)
Skill模型读的说明书模型"尽力遵守"描述常驻 + 正文按需
MCP外部系统的接口工具调用是确定的名字常驻 + schema 按需

所以"用 skill 替代 MCP"是错的(skill 建立不了连接、做不了鉴权);"用 MCP 替代 skill"也是错的(schema 不等于"怎么用得好")。而**"用 skill 当护栏"要小心**——它是请求,不是强制。

7. 写一个好 Skill 的清单​

□ name/description:description 写"能被打中的关键词",关键用途放最前(溢出时从后往前砍)
□ 首行必须是 ---(前面不能有空行),否则 frontmatter 整体失效
□ 正文要薄:载入后跨轮留存,每行都是重复成本 —— 细节推到附属文件
□ 需要精确执行的步骤 → 写成脚本(脚本是"执行",不进上下文)
□ 手动专用就 disable-model-invocation: true;只给名字省预算用 skillOverrides: "name-only"
□ 要隔离上下文 → context: fork(Claude Code)
□ 依赖环境才能跑的 → 用门控声明(OpenClaw 的 requires.*),别让模型自己发现"没装"
□ 必须每次都发生的规则 → 放 hook,不是放 skill
□ 连外部系统的 → 那是 MCP 的活;skill 负责写"用它的正确姿势"
□ 分发前想清楚授权与审计(ClawHub 强制 MIT-0;自建则随仓库许可)

8. 本文的局限​

  • 两家的"内部实现"没实测:listing 到底怎么截断、注入的 XML 块具体长什么样,外部无法验证。 实验 2 是按官方文档描述的规则推算的(正文标 [模拟]),只说明规则量级,不是实测值;
  • 实验 1 只覆盖本机可扫到的 3 个真实 skill + 1 个演示 fixture,不代表一般分布; L1 我按"名字+描述"计,不同实现的常驻内容并不完全一致,只用于量级比较;
  • 实验 3 验证的是"本机有没有该二进制",不代表 OpenClaw 门控实现的全部细节;
  • 实验 4 的工具 schema 是手写样例,不是从真实 MCP server 抓的;
  • 文档条款为官方原文(逐字),与[实测]/[模拟]是三类陈述,正文已分别标注; 逐字引文、URL、抓取方式留档在 source/skills-lab/official-sources.md。

关联​

  • 本仓库里就跑着一个 Claude Code Skill:.claude/skills/123/SKILL.md(发布快捷键,288 字节常驻 / 1,950 字节正文)
  • 装 skill 的仓库实例:InkOS(其 skills/SKILL.md 是本机实测里最大的那个,47KB)、 vgpu(随包一个 skill);本站 Agent 工程化 讲的是另一条路(把控制杆写进代码)
  • 工具协议那一侧:MCP 系列
  • 上下文为什么会"满":大模型流式 chunk 会因网络波动乱序吗(讲的是传输;这里是上下文预算)
  • 实测脚本与逐字来源:仓库内 source/skills-lab/

自测​

  1. Skill 设计里那个"唯一需要真正理解的机制"是什么?它把成本切成哪三层?
  2. 为什么 SKILL.md 正文必须写薄?官方给的理由是哪一句?
  3. 官方为什么说"脚本是被执行,不是被载入"?这对你写 skill 有什么指导?
  4. Claude Code 的 skill 描述列表预算怎么算、溢出了怎么办?为什么 description 要把关键词放前面?
  5. OpenClaw 的"门控"解决了什么问题?它和"在描述里提醒模型"有什么本质区别?
  6. command-dispatch: tool 绕过了什么?什么时候你希望绕过模型?
  7. 用一句话说清 Skill 与 MCP 的分工。为什么"用 skill 替代 MCP"是错的?
  8. 护栏(比如"不许改 .env")该放在 CLAUDE.md、skill,还是 hook?官方原文怎么说的?

参考​