第 17 章

Skills 系统原理:SKILL.md 格式、懒加载机制与 description 触发逻辑

第17章:Skills 系统原理——SKILL.md 格式、懒加载机制与 description 触发逻辑

本章概览

Skills 是 OpenClaw 中最具独创性的设计之一。如果说 ACP 解决了"如何调用外部专家"的问题,那么 Skills 解决的是"如何将专业知识注入 Agent 行为"的问题。本章从核心隐喻出发,逐字段解析 SKILL.md 规范,深入理解懒加载机制的 context 预算保护原理,以及模型如何根据 description 做出触发决策。


17.1 核心隐喻:Skills 是"教科书"

理解 Skills 的最好起点是放弃"插件"这个类比。插件是可执行代码,它扩展程序的功能边界。Skills 完全不同:

Skills 是教科书,不是插件。 它告诉 Agent "当遇到这类任务时,你应该这样思考、这样操作",而不是"当用户调用这个命令时,执行这段代码"。

这个区别至关重要:

维度 插件思维 Skills 思维
执行方式 代码被调用执行 指导 Agent 的推理过程
扩展目标 扩展功能 扩展知识
激活方式 显式命令触发 模型语义判断触发
存储内容 可执行代码 操作指南、工作流、最佳实践
失效方式 运行时错误 指导质量不佳

这个隐喻意味着:写一个好的 Skill,和写一本好的操作手册,在本质上是同一件事。清晰的结构、精准的描述、具体的步骤——这些写作原则同样适用于 SKILL.md。


17.2 SKILL.md 完整字段规范

每个 Skill 都以 SKILL.md 文件为核心载体。文件由 YAML 前置字段(frontmatter)和 Markdown 正文两部分组成。

目录结构

my-skill/
├── SKILL.md          # 必需:核心文件
├── scripts/          # 可选:辅助脚本
├── references/       # 可选:按需加载的参考文档
└── assets/           # 可选:图片、数据文件等

YAML 前置字段完整参考

---
name: my-skill-name                    # 必需
description: |                         # 必需(触发核心)
  当用户需要做 X 时,使用此 Skill。
  它提供了 Y 和 Z 的完整指导。
user-invocable: true                   # 可选,默认 true
disable-model-invocation: false        # 可选,默认 false
command-dispatch: tool                 # 可选
command-tool: "tool_name"             # command-dispatch 时必需
command-arg-mode: raw                  # 可选
metadata:
  openclaw:
    emoji: "🔧"
    os: darwin
    requires:
      bins:
        - git
        - node
      anyBins:
        - yarn
        - npm
      env:
        - GITHUB_TOKEN
      config:
        - tools.git.enabled
    primaryEnv: node
    homepage: https://example.com
    install:
      - type: brew
        pkg: my-tool
---

字段详解

name(必需)

description(必需,触发核心)

这是整个 SKILL.md 中最重要的字段。模型在决定是否激活某个 Skill 时,主要依赖 description 进行语义匹配。

# 差的 description(太模糊)
description: 帮助做代码相关的事情

# 好的 description(精准描述触发场景)
description: |
  当用户需要创建 GitHub Pull Request、进行代码审查、
  管理 PR 标签/审查者,或者询问 PR 最佳实践时,
  使用此 Skill。包含完整的 PR 工作流指南。

description 写作原则:

  1. 明确描述何时应该激活(触发场景)
  2. 简要说明 Skill 能提供什么(价值主张)
  3. 避免模糊词汇("各种"、"相关"、"通用")
  4. 长度控制在 50-150 字符最佳(太长占 context,太短难以精准匹配)

user-invocable(可选,默认 true)

控制用户是否可以通过 /skill-name 斜杠命令直接调用。

user-invocable: false   # 仅允许模型自动激活,用户无法直接调用

适用场景:background support Skill,不希望用户手动触发的辅助性 Skill。

disable-model-invocation(可选,默认 false)

disable-model-invocation: true  # 从模型 prompt 中完全隐藏此 Skill

设为 true 后:

command-dispatch(可选)

command-dispatch: tool

启用后,斜杠命令直接路由至指定工具,完全绕过模型推理。这意味着零 token 消耗,延迟极低。

command-tool(command-dispatch 时必需)

command-tool: "browser_action"  # 斜杠命令触发时调用的工具名

command-arg-mode(可选)

command-arg-mode: raw   # 将用户输入的参数原样传递给工具

其他选项:


17.3 metadata.openclaw 字段详解

metadata.openclaw 是 OpenClaw 特定的扩展元数据,控制 Skill 的平台集成行为。

emoji

metadata:
  openclaw:
    emoji: "🔍"

在 ClawHub 和 OpenClaw UI 中显示的图标。纯展示用途,不影响功能。

os(操作系统过滤)

os: darwin        # 仅在 macOS 上可用
os: linux         # 仅在 Linux 上可用
os: win32         # 仅在 Windows 上可用
# 不设置 = 所有平台

设置后,OpenClaw 在非目标 OS 上不会加载此 Skill(元数据都不会注入)。

requires(依赖门控)

这是最复杂也最重要的子字段,详见第17.4节。

primaryEnv

primaryEnv: node    # node / python / go / rust / java 等

声明 Skill 的主要技术环境,用于 ClawHub 分类和搜索过滤。

homepage

homepage: https://github.com/org/skill-repo

Skill 文档或源码的主页 URL。

install(自动安装脚本)

install:
  - type: brew
    pkg: ffmpeg
  - type: node
    pkg: "@scope/package"
  - type: go
    pkg: github.com/org/tool@latest
  - type: uv
    pkg: my-python-tool
  - type: download
    url: https://releases.example.com/tool-v1.0-darwin-arm64
    dest: ~/.local/bin/tool
    chmod: "0755"

requires.bins 中的工具不存在时,OpenClaw 可以根据 install 配置自动安装依赖。


17.4 requires:依赖门控的四种类型

requires 字段定义了 Skill 激活所需的前置条件。如果条件不满足,Skill 不会被注入 context

requires.bins(PATH 中必须全部存在)

requires:
  bins:
    - git
    - node
    - docker

所有列出的可执行文件都必须在 PATH 中存在,否则 Skill 不加载。适合有硬性依赖的 Skill。

requires.anyBins(至少存在其中一个)

requires:
  anyBins:
    - yarn
    - npm
    - pnpm

至少有一个存在即可。适合支持多种工具链的 Skill("有任何一个包管理器就可以运行")。

requires.env(环境变量必须存在)

requires:
  env:
    - GITHUB_TOKEN
    - OPENAI_API_KEY

指定的环境变量必须已设置(值不为空)。常用于需要 API Key 的 Skill。

requires.config(openclaw.json 中的配置路径)

requires:
  config:
    - tools.git.enabled
    - features.experimental.acp

指定的 openclaw.json 配置路径必须存在且为真值(truthy)。用于功能开关控制。

四种类型对比

类型 逻辑 典型用途
bins AND(全部必须存在) 硬性工具依赖
anyBins OR(至少一个存在) 兼容多工具链
env AND(全部必须设置) API Key 门控
config AND(全部必须为真) 功能开关

17.5 懒加载原理:context 预算保护

这是 Skills 系统最精妙的工程设计之一。

问题:context 预算稀缺

一个典型的 OpenClaw 实例可能加载数十个甚至上百个 Skill。如果每个 Skill 的完整内容都注入到模型 context 中,将占用大量 token,挤压真正有用的内容(代码、对话历史、任务描述)。

解决方案:懒加载(Lazy Loading)

OpenClaw 的加载策略分为两个阶段:

阶段一:元数据注入(始终执行)

[系统 prompt 中的 Skill 列表]
- git-helper: 当用户需要 Git 操作时使用(emoji: 🌿, os: any)
- image-lab: 当用户需要处理图片时使用(emoji: 🖼️, os: darwin)
- browser: 当用户需要浏览器操作时使用(emoji: 🌐, os: any)
...

只注入:name + description + emoji(极少量 token)

阶段二:按需加载(仅在需要时执行)

当模型判断某个 Skill 需要激活时,OpenClaw 才读取该 Skill 的完整内容并注入 context。

[模型判断需要激活 git-helper]
  ↓
OpenClaw 读取 git-helper/SKILL.md 完整内容
  ↓
将完整指导内容注入当前 context
  ↓
模型继续处理,现在有了完整的 Skill 知识

references/ 目录的按需加载

更进一步,references/ 目录中的文件连元数据都不会默认注入。只有当 Skill 被激活、且 Skill 正文中明确引用了 references 文件时,才会加载。

my-skill/
├── SKILL.md           ← 阶段一:只注入 name+description
├── references/
│   ├── api-spec.md    ← 阶段三:仅当 SKILL.md 明确请求时加载
│   └── examples.md    ← 阶段三:仅当 SKILL.md 明确请求时加载

在 SKILL.md 正文中引用:

## 详细 API 规范
如需查看完整 API 规范,请读取 {baseDir}/references/api-spec.md

模型在需要时会主动请求读取该文件,实现真正的 Progressive Disclosure(渐进式披露)。

懒加载的量化收益

假设有 50 个已安装 Skill,每个 Skill 平均 2000 tokens:

加载策略 Context 消耗 剩余可用 context(128k 窗口)
全量加载 100,000 tokens 28,000 tokens
懒加载(元数据) 约 2,500 tokens 约 125,500 tokens
懒加载(激活后) 约 4,500 tokens 约 123,500 tokens

懒加载让 context 效率提升约 44 倍。


17.6 description 是触发器:模型的决策逻辑

理解"模型如何决定激活哪个 Skill"是编写高质量 Skill 的关键。

触发决策流程

用户发送消息
    ↓
OpenClaw 将所有 Skill 的 name+description 注入系统 prompt
    ↓
模型分析用户意图
    ↓
模型对每个 Skill 进行语义相关度评估
    ↓
相关度超过阈值 → 请求加载该 Skill 完整内容
    ↓
加载完成 → 模型基于 Skill 指导生成回复

description 的语义匹配机制

模型执行的是语义相似度判断,而非关键词匹配。这意味着:

# 示例1:关键词依赖(不推荐)
description: 用于 git commit 和 git push 操作

# 示例2:语义覆盖(推荐)
description: |
  当用户需要提交代码变更、推送到远程仓库、
  创建版本标签,或者询问 Git 工作流最佳实践时使用。
  涵盖 commit 消息规范、branch 命名、冲突解决。

示例2 会在用户说"帮我保存这些改动"时也能触发(语义相关),而示例1 不会。

description 触发优化技巧

技巧1:场景驱动描述 不要描述 Skill 是什么,而是描述用户在什么情况下需要它

# 错误方式
description: 一个 Docker 容器管理工具集合

# 正确方式
description: |
  当用户需要构建 Docker 镜像、管理容器生命周期、
  排查容器崩溃、优化镜像大小,或者设计 docker-compose
  配置时,使用此 Skill。

技巧2:包含同义词和上位词

description: |
  处理图像和照片相关任务:裁剪、调整尺寸、格式转换、
  批量处理、添加水印、图片压缩优化。
  (picture / image / photo / screenshot 处理均适用)

技巧3:避免过度宽泛

# 危险:太宽泛,会与几乎所有任务匹配
description: 帮助用户完成各种编程任务

# 合适:有明确边界
description: |
  专门处理 Python 类型注解相关任务:添加类型提示、
  运行 mypy 类型检查、修复类型错误、理解泛型语法。

17.7 五级加载优先级与覆盖规则

当同名 Skill 在多个位置存在时,优先级决定哪个版本生效:

优先级从高到低

1. Workspace-specific Skills
   位置:<project-root>/.openclaw/skills/
   说明:项目专属,最高优先级,可以完全覆盖全局同名 Skill

2. Workspace Agent Skills
   位置:<project-root>/.openclaw/agents/<agent-name>/skills/
   说明:特定 Agent 配置的 Skills

3. Shared Agent Profile Skills
   位置:~/.openclaw/profiles/<profile-name>/skills/
   说明:跨项目共享的 Agent Profile 中的 Skills

4. Global OpenClaw Skills
   位置:~/.openclaw/skills/
   说明:用户全局安装的 Skills(clawhub install 默认位置)

5. Bundled Skills + Custom Dirs
   位置:OpenClaw 内置 + openclaw.json 中的 extraSkillDirs
   说明:OpenClaw 自带的基础 Skill 集

覆盖规则实例

场景:用户全局安装了 git-helper(优先级4)
      项目 .openclaw/skills/ 中有自定义 git-helper(优先级1)

结果:项目级 git-helper 完全覆盖全局 git-helper
      在此项目中,加载的是项目级版本
      切换到其他项目,加载的是全局版本

这个设计使得团队可以为特定项目定制 Skill 行为,而不影响其他项目。


17.8 {baseDir} 占位符

{baseDir} 是 SKILL.md 中一个特殊的运行时占位符,它在 Skill 被激活时替换为该 Skill 目录的绝对路径

使用场景

引用 references/ 中的文件:

## API 参考
完整的 API 参数列表请见:{baseDir}/references/api-params.md

## 示例脚本
自动化脚本位于:{baseDir}/scripts/run-migration.sh

引用 assets/ 中的资源:

## 架构图
参考架构图:{baseDir}/assets/architecture.png

在 scripts 中引用其他 scripts:

# SKILL.md 告诉模型执行此脚本
bash {baseDir}/scripts/setup.sh

为什么需要 {baseDir}?

因为 Skill 可以安装在任何位置(全局、项目级、自定义目录),其绝对路径在编写时无法确定。{baseDir} 确保路径引用始终正确,无论 Skill 安装在何处。


17.9 Progressive Disclosure 设计哲学

OpenClaw 的整个 Skills 系统体现了一个核心设计原则:Progressive Disclosure(渐进式披露)

三层披露结构

Layer 1(始终可见):name + description
  → 模型知道"有这个能力"

Layer 2(激活后可见):SKILL.md 完整正文
  → 模型知道"如何执行这个能力"

Layer 3(按需可见):references/ 文件内容
  → 模型获取"执行时需要的具体参考资料"

设计意图

这个三层结构的设计意图是:只在需要时消耗 context。大多数对话只需要 Layer 1;需要 Skill 时消耗 Layer 2;只有真正需要深度参考时才消耗 Layer 3。

这与软件工程中的"按需加载"(lazy loading)原理完全一致,只是应用在了 AI context 管理领域。


17.10 本章小结

下一章将进入实战环节:5 种模式的完整 SKILL.md 代码示例,手把手教你从零编写高质量 Skills。

本章评分
4.9  / 5  (15 评分)

💬 留言讨论