Chapter 17

Skills System Internals: SKILL.md Format, Lazy Loading and Description Trigger Logic

Chapter 17: The Skills System โ€” SKILL.md Format, Lazy-Loading, and the description Trigger

Chapter Overview

Skills are one of OpenClaw's most original design contributions. If ACP answers the question "how do I call an external expert?", Skills answer the question "how do I inject domain knowledge into an Agent's behavior?". This chapter begins with the core metaphor, then walks through every field in the SKILL.md specification, explains the context-budget rationale behind lazy-loading, and examines how the model uses description to make activation decisions.


17.1 The Core Metaphor: Skills Are Textbooks

The best way to understand Skills is to abandon the "plugin" analogy. A plugin is executable code that extends a program's functional boundaries. Skills are fundamentally different:

Skills are textbooks, not plugins. They tell the Agent "when you encounter this kind of task, here is how you should think and operate" โ€” not "when the user invokes this command, run this code."

This distinction is critical:

Dimension Plugin mindset Skills mindset
Execution Code is called and runs Guides the Agent's reasoning
Extension goal Extend functionality Extend knowledge
Activation Explicit command Model's semantic judgment
Stored content Executable code Operational guides, workflows, best practices
Failure mode Runtime error Poor guidance quality

This metaphor implies that writing a good Skill and writing a good operations manual are fundamentally the same activity. Clear structure, precise description, concrete steps โ€” these writing principles apply equally to SKILL.md.


17.2 The Complete SKILL.md Field Specification

Every Skill is anchored by a SKILL.md file. The file consists of a YAML frontmatter block and a Markdown body.

Directory Structure

my-skill/
โ”œโ”€โ”€ SKILL.md          # Required: the core file
โ”œโ”€โ”€ scripts/          # Optional: helper scripts
โ”œโ”€โ”€ references/       # Optional: on-demand reference documents
โ””โ”€โ”€ assets/           # Optional: images, data files, etc.

Complete YAML Frontmatter Reference

---
name: my-skill-name                    # Required
description: |                         # Required (activation trigger)
  Use this Skill when the user needs to do X.
  It provides complete guidance for Y and Z.
user-invocable: true                   # Optional, default: true
disable-model-invocation: false        # Optional, default: false
command-dispatch: tool                 # Optional
command-tool: "tool_name"             # Required when command-dispatch is set
command-arg-mode: raw                  # Optional
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
---

Field Reference

name (Required)

description (Required โ€” the activation trigger)

This is the most important field in SKILL.md. The model's decision to activate a Skill depends primarily on semantic matching against the description.

# Bad description (too vague)
description: Helps with code-related things

# Good description (precisely describes the trigger scenario)
description: |
  Use this Skill when the user needs to create a GitHub Pull Request,
  conduct code reviews, manage PR labels or reviewers, or ask about
  PR best practices. Provides a complete PR workflow guide.

Description writing principles:

  1. Clearly state when the Skill should activate (trigger scenarios)
  2. Briefly state what the Skill provides (value proposition)
  3. Avoid vague terms ("various", "related", "general-purpose")
  4. Target 50โ€“150 characters: too long wastes context, too short reduces matching precision

user-invocable (Optional, default: true)

Controls whether users can invoke the Skill directly via a /skill-name slash command.

user-invocable: false   # Only the model can auto-activate; users cannot invoke directly

Use case: background support Skills, auxiliary Skills that should not be manually triggered.

disable-model-invocation (Optional, default: false)

disable-model-invocation: true  # Hide this Skill from the model's context entirely

When set to true:

command-dispatch (Optional)

command-dispatch: tool

When enabled, a slash command is routed directly to the specified tool, completely bypassing model reasoning. This means zero token consumption and minimal latency.

command-tool (Required when command-dispatch is set)

command-tool: "browser_action"  # Tool to invoke when the slash command fires

command-arg-mode (Optional)

command-arg-mode: raw   # Pass user-provided arguments verbatim to the tool

Other options:


17.3 metadata.openclaw Field Reference

metadata.openclaw contains OpenClaw-specific extension metadata controlling the Skill's platform integration behavior.

emoji

metadata:
  openclaw:
    emoji: "๐Ÿ”"

Icon displayed in ClawHub and the OpenClaw UI. Purely cosmetic; no functional impact.

os (Operating System Filter)

os: darwin        # Only available on macOS
os: linux         # Only available on Linux
os: win32         # Only available on Windows
# Omit = available on all platforms

When set, OpenClaw will not load this Skill on non-matching OS (not even metadata is injected).

requires (Dependency Gating)

The most complex and important sub-field. See section 17.4 for full coverage.

primaryEnv

primaryEnv: node    # node / python / go / rust / java / etc.

Declares the Skill's primary technical environment. Used for ClawHub categorization and search filtering.

homepage

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

URL of the Skill's documentation or source code.

install (Auto-install Scripts)

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"

When a binary listed in requires.bins is missing, OpenClaw can automatically install the dependency using the install configuration.


17.4 requires: Four Types of Dependency Gating

The requires field defines the prerequisites for Skill activation. If conditions are not met, the Skill is not injected into context.

requires.bins (ALL must exist in PATH)

requires:
  bins:
    - git
    - node
    - docker

Every listed executable must be present in PATH; otherwise the Skill does not load. Use for Skills with hard binary dependencies.

requires.anyBins (AT LEAST ONE must exist)

requires:
  anyBins:
    - yarn
    - npm
    - pnpm

At least one must be present. Use for Skills that support multiple toolchains ("any package manager will work").

requires.env (Environment variables must be set)

requires:
  env:
    - GITHUB_TOKEN
    - OPENAI_API_KEY

All listed environment variables must be set (non-empty). Common for Skills that require API keys.

requires.config (openclaw.json paths must be truthy)

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

All listed openclaw.json config paths must exist and be truthy. Used for feature-flag control.

Comparison Table

Type Logic Typical Use
bins AND (all must exist) Hard binary dependencies
anyBins OR (at least one) Multi-toolchain compatibility
env AND (all must be set) API key gating
config AND (all must be truthy) Feature flag control

17.5 Lazy-Loading: Protecting the Context Budget

This is one of the most elegant engineering decisions in the Skills system.

The Problem: Context Budget Scarcity

A typical OpenClaw instance may have dozens or even hundreds of Skills installed. If every Skill's full content were injected into the model's context, it would consume a massive number of tokens โ€” crowding out genuinely useful content (code, conversation history, task descriptions).

The Solution: Lazy Loading

OpenClaw's loading strategy has two phases:

Phase 1: Metadata injection (always executed)

[Skill list in system prompt]
- git-helper: Use for Git operations (emoji: ๐ŸŒฟ, os: any)
- image-lab: Use for image processing (emoji: ๐Ÿ–ผ๏ธ, os: darwin)
- browser: Use for browser interactions (emoji: ๐ŸŒ, os: any)
...

Only injects: name + description + emoji (minimal tokens)

Phase 2: On-demand loading (only when needed)

When the model determines a Skill needs to be activated, OpenClaw reads the full SKILL.md content and injects it into context.

[Model determines git-helper should activate]
  โ†“
OpenClaw reads git-helper/SKILL.md in full
  โ†“
Full guidance content injected into current context
  โ†“
Model continues with complete Skill knowledge

On-Demand Loading of references/ Files

Going further, files in the references/ directory are not injected even as metadata by default. They are only loaded when a Skill is activated and the Skill body explicitly references them.

my-skill/
โ”œโ”€โ”€ SKILL.md           โ† Phase 1: only name+description injected
โ”œโ”€โ”€ references/
โ”‚   โ”œโ”€โ”€ api-spec.md    โ† Phase 3: loaded only when SKILL.md explicitly requests it
โ”‚   โ””โ”€โ”€ examples.md    โ† Phase 3: loaded only when SKILL.md explicitly requests it

Reference in SKILL.md body:

## Detailed API Specification
For the full API specification, read {baseDir}/references/api-spec.md

The model will proactively request this file when needed, implementing true Progressive Disclosure.

Quantifying Lazy-Loading Benefits

Assume 50 installed Skills, averaging 2,000 tokens each:

Loading strategy Context consumed Remaining usable context (128k window)
Full load 100,000 tokens 28,000 tokens
Lazy load (metadata only) ~2,500 tokens ~125,500 tokens
Lazy load (after activation) ~4,500 tokens ~123,500 tokens

Lazy loading improves context efficiency by roughly 44x.


17.6 description as a Trigger: The Model's Decision Logic

Understanding how the model decides to activate a Skill is essential for writing high-quality Skills.

The Trigger Decision Flow

User sends a message
    โ†“
OpenClaw injects all Skills' name+description into the system prompt
    โ†“
Model analyzes user intent
    โ†“
Model evaluates semantic relevance for each Skill
    โ†“
Relevance exceeds threshold โ†’ request loading of full Skill content
    โ†“
Loading complete โ†’ model generates response guided by Skill content

The Semantic Matching Mechanism

The model performs semantic similarity judgment, not keyword matching. This means:

# Example 1: Keyword-dependent (not recommended)
description: For git commit and git push operations

# Example 2: Semantic coverage (recommended)
description: |
  Use when the user needs to commit code changes, push to a remote
  repository, create version tags, or ask about Git workflow best
  practices. Covers commit message conventions, branch naming, and
  conflict resolution.

Example 2 will also trigger when the user says "help me save these changes" (semantically related), while Example 1 will not.

description Optimization Techniques

Technique 1: Scenario-driven description Don't describe what the Skill is โ€” describe when the user needs it.

# Wrong approach
description: A collection of Docker container management tools

# Right approach
description: |
  Use when the user needs to build Docker images, manage container
  lifecycle, troubleshoot container crashes, optimize image size,
  or design docker-compose configurations.

Technique 2: Include synonyms and hypernyms

description: |
  Handle image and photo tasks: cropping, resizing, format conversion,
  batch processing, watermarking, image compression and optimization.
  (Applies to pictures / images / photos / screenshots)

Technique 3: Avoid excessive breadth

# Dangerous: too broad โ€” matches almost any task
description: Help users with various programming tasks

# Appropriate: clear scope boundaries
description: |
  Specifically handles Python type annotation tasks: adding type hints,
  running mypy type checking, fixing type errors, and understanding
  generic syntax.

17.7 Five-Level Loading Priority and Override Rules

When a Skill with the same name exists in multiple locations, priority determines which version is active:

Priority Levels (Highest to Lowest)

1. Workspace-specific Skills
   Location: <project-root>/.openclaw/skills/
   Note: Project-specific; highest priority; fully overrides same-named global Skills

2. Workspace Agent Skills
   Location: <project-root>/.openclaw/agents/<agent-name>/skills/
   Note: Skills configured for a specific Agent

3. Shared Agent Profile Skills
   Location: ~/.openclaw/profiles/<profile-name>/skills/
   Note: Skills in a shared Agent Profile used across projects

4. Global OpenClaw Skills
   Location: ~/.openclaw/skills/
   Note: User's globally installed Skills (default location for clawhub install)

5. Bundled Skills + Custom Dirs
   Location: OpenClaw built-ins + extraSkillDirs in openclaw.json
   Note: OpenClaw's baseline Skill set

Override Example

Scenario: User has globally installed git-helper (priority 4)
          Project has a custom git-helper at .openclaw/skills/ (priority 1)

Result: The project-level git-helper completely overrides the global one.
        Within this project, the project-level version is loaded.
        When switching to another project, the global version is loaded.

This design allows teams to customize Skill behavior per project without affecting other projects.


17.8 The {baseDir} Placeholder

{baseDir} is a special runtime placeholder in SKILL.md that is replaced with the absolute path of the Skill's directory when the Skill is activated.

Use Cases

Referencing files in references/:

## API Reference
For the full list of API parameters, see: {baseDir}/references/api-params.md

## Automation Script
The migration automation script is at: {baseDir}/scripts/run-migration.sh

Referencing assets:

## Architecture Diagram
Reference architecture: {baseDir}/assets/architecture.png

Scripts referencing other scripts:

# SKILL.md instructs the model to execute this script
bash {baseDir}/scripts/setup.sh

Why {baseDir} Is Necessary

Because a Skill can be installed in any location (global, project-level, custom directory), its absolute path cannot be determined at authoring time. {baseDir} ensures path references are always correct regardless of where the Skill is installed.


17.9 The Progressive Disclosure Design Philosophy

The entire Skills system embodies a core design principle: Progressive Disclosure.

Three-Layer Disclosure Structure

Layer 1 (always visible): name + description
  โ†’ The model knows "this capability exists"

Layer 2 (visible after activation): full SKILL.md body
  โ†’ The model knows "how to exercise this capability"

Layer 3 (visible on demand): references/ file content
  โ†’ The model gets "specific reference material needed during execution"

Design Intent

The three-layer structure's intent is: consume context only when needed. Most conversations only need Layer 1. Using a Skill consumes Layer 2. Only when deep reference material is truly required does the model consume Layer 3.

This mirrors the lazy-loading principle in software engineering, applied to AI context management.


17.10 Chapter Summary

The next chapter moves into hands-on practice: complete SKILL.md code examples for all five writing patterns, guiding you through writing high-quality Skills from scratch.

Rate this chapter
4.9  / 5  (15 ratings)

๐Ÿ’ฌ Comments