OpenClaw(龙虾)Skills从零到发布的实战指南

作者:

文章目录
  • Skill 是 OpenClaw 的核心扩展机制。通过编写一个 SKILL.md 文件,你就能教会 AI Agent 新的能力。 简单理解: Tool(工具) = Agent 的手脚(文件读写、Shell 执行、网络请求等通道) Skill(技能) = 加载到这些通道上的具体能力(搜索、查票、股票分析等) Skill 的加载优先级(从高到低): 优先级 类型 路径 说明 1 工作区 Skill ~/.openclaw/workspace/skills/ 当前工作区专属 2 托管 Skill ~/.openclaw/skills/ 通过 ClawHub 安装的共享 Skill 3 内置 Skill 随 OpenClaw 分发 官方内置
  • 每个 Skill 就是一个文件夹,核心是 SKILL.md: my-skill/ ├── SKILL.md # 必须:技能定义文件(YAML frontmatter + Markdown 指令) ├── _meta.json # 可选:ClawHub 发布元数据 ├── .clawhub/ # 可选:ClawHub 安装来源信息 │ └── origin.json ├── scripts/ # 可选:可执行脚本 ├── references/ # 可选:参考文档(按需加载,不常驻上下文) └── assets/ # 可选:模板、图标等静态资源 我们来看 7 个真实案例的目录结构对比: Skill 目录结构 复杂度 summarize 仅 SKILL.md + _meta.json ⭐ 最简单 — 纯提示词 Skill skill-vetter 仅 SKILL.md + _meta.json ⭐ 纯提示词 + 流程协议 12306-query SKILL.md + scripts/query_tickets.py ⭐⭐ 单脚本 Skill tavily-search SKILL.md + search.sh ⭐⭐ 单脚本(Shell) akshare-stock SKILL.md + scripts/stock_cli.py ⭐⭐ 单脚本 + 丰富 API 文档 agent-browser 仅 SKILL.md ⭐⭐ 外部 CLI 工具封装 firecrawl SKILL.md + scripts/ × 3 + references/api.md ⭐⭐⭐ 多脚本 + 参考文档
  • SKILL.md 由两部分组成:YAML frontmatter(元数据) + Markdown body(指令正文)。
  • 假设我们要开发一个"GitHub 仓库信息查询"Skill:
  • 目录
    • 一、什么是 Skill?
    • 二、Skill 的目录结构
    • 三、SKILL.md 的核心格式
      • 3.1 Frontmatter 字段详解
      • 3.2 七个案例的 Frontmatter 对比分析
    • 四、五种 Skill 类型实战
      • 类型 1:纯提示词 Skill(无脚本)
      • 类型 2:单脚本 Skill(Python)
      • 类型 3:单脚本 Skill(Shell)
      • 类型 4:外部 CLI 工具封装 Skill
      • 类型 5:多脚本 + 参考文档 Skill
    • 五、_meta.json 与 .clawhub/ 详解
      • _meta.json — ClawHub 发布元数据
      • .clawhub/origin.json — 安装来源信息
    • 六、从零开发一个 Skill — 完整流程
      • Step 1:创建目录
      • Step 2:编写 SKILL.md
      • Step 3:编写脚本
      • Step 4:本地测试
      • Step 5:发布到 ClawHub
    • 七、开发最佳实践总结
      • description 写作技巧
      • 脚本设计模式
      • 安全检查清单
      • 开发检查清单

    基于 7 个真实 Skill 案例的深度解析,从零到发布,手把手教你开发 OpenClaw Skill。

    Skill 是 OpenClaw 的核心扩展机制。通过编写一个 SKILL.md 文件,你就能教会 AI Agent 新的能力。

    简单理解:

    • Tool(工具) = Agent 的手脚(文件读写、Shell 执行、网络请求等通道)
    • Skill(技能) = 加载到这些通道上的具体能力(搜索、查票、股票分析等)

    Skill 的加载优先级(从高到低):

    优先级 类型 路径 说明
    1 工作区 Skill ~/.openclaw/workspace/skills/ 当前工作区专属
    2 托管 Skill ~/.openclaw/skills/ 通过 ClawHub 安装的共享 Skill
    3 内置 Skill 随 OpenClaw 分发 官方内置

    每个 Skill 就是一个文件夹,核心是 SKILL.md

    my-skill/
    ├── SKILL.md           # 必须:技能定义文件(YAML frontmatter + Markdown 指令)
    ├── _meta.json         # 可选:ClawHub 发布元数据
    ├── .clawhub/          # 可选:ClawHub 安装来源信息
    │   └── origin.json
    ├── scripts/           # 可选:可执行脚本
    ├── references/        # 可选:参考文档(按需加载,不常驻上下文)
    └── assets/            # 可选:模板、图标等静态资源

    我们来看 7 个真实案例的目录结构对比:

    Skill 目录结构 复杂度
    summarize SKILL.md + _meta.json ⭐ 最简单 — 纯提示词 Skill
    skill-vetter SKILL.md + _meta.json ⭐ 纯提示词 + 流程协议
    12306-query SKILL.md + scripts/query_tickets.py ⭐⭐ 单脚本 Skill
    tavily-search SKILL.md + search.sh ⭐⭐ 单脚本(Shell)
    akshare-stock SKILL.md + scripts/stock_cli.py ⭐⭐ 单脚本 + 丰富 API 文档
    agent-browser SKILL.md ⭐⭐ 外部 CLI 工具封装
    firecrawl SKILL.md + scripts/ × 3 + references/api.md ⭐⭐⭐ 多脚本 + 参考文档

    SKILL.md 由两部分组成:YAML frontmatter(元数据) + Markdown body(指令正文)

    ---
    name: my-skill                    # 必须:技能标识符,小写字母+连字符
    description: 技能描述...           # 必须:AI 根据这个决定何时调用该技能
    version: 1.0.0                    # 可选:版本号
    author: your-name                 # 可选:作者
    user-invocable: true              # 可选:是否可通过斜杠命令手动调用
    disable-model-invocation: false   # 可选:设为 true 则禁止 AI 自动触发
    triggers:                         # 可选:触发关键词列表
      - keyword1
      - keyword2
    metadata:                         # 可选:扩展元数据
      openclaw:
        requires:
          env:
            - MY_API_KEY              # 需要的环境变量
          bins:
            - python                  # 需要的系统命令
    ---

    最关键的字段是 description — AI 完全依赖它来判断何时调用你的 Skill。

    让我们看看 7 个真实 Skill 是怎么写 frontmatter 的:

    案例 1:summarize(纯提示词 Skill)

    ---
    name: summarize-pro
    description: When user asks to summarize text, articles, documents, meetings,
      emails, YouTube transcripts, books, PDFs, reports, conversations, or any
      long content. Also handles bullet points, key takeaways, action items,
      TL;DR, ELI5, executive summaries...
    ---

    分析:description 极其详尽,列举了所有可能的触发场景。这是纯提示词 Skill 的典型写法 — 因为没有脚本,全靠 description 让 AI 知道"什么时候该用我"。

    案例 2:12306-query(API 调用 Skill)

    ---
    name: 12306-query
    description: 中国铁路 12306 火车票余票查询。使用官方 API 查询车次、票价、余票信息。
      支持按出发站/到达站/日期筛选。当用户需要查询火车票信息(余票、车次、票价、时刻表)时使用此技能。
    ---

    分析:description 用中文写,明确说明了"做什么"和"什么时候用"。最后一句"当用户需要查询火车票信息时使用此技能"是关键的触发条件描述。

    案例 3:firecrawl(需要 API Key 的 Skill)

    ---
    name: firecrawl
    description: Web search and scraping via Firecrawl API. Use when you need to
      search the web, scrape websites (including JS-heavy pages), crawl entire
      sites, or extract structured data from web pages. Requires FIRECRAWL_API_KEY
      environment variable.
    ---

    分析:在 description 中直接提到了环境变量依赖,让用户一眼就知道需要配置什么。

    案例 4:tavily-search(带 triggers 的 Skill)

    ---
    name: tavily-search-skill
    description: Tavily API integration with real-time quota management and paid mode toggle.
    version: 1.0.4
    author: JayeGT002
    triggers:
      - tavily
      - search
      - web search
    ---

    分析:使用了 triggers 字段列出触发关键词,这是除 description 之外的另一种触发机制。

    案例 5:agent-browser(外部工具封装 Skill)

    ---
    name: agent-browser
    description: Headless browser automation CLI optimized for AI agents with
      accessibility tree snapshots and ref-based element selection
    metadata: {"clawdbot":{"emoji":"🌐","requires":{"commands":["agent-browser"]}}}
    ---
    

    分析:通过 metadata.requires.commands 声明了外部依赖 agent-browser CLI 工具。

    最简单的 Skill 类型,不需要任何脚本,完全通过 Markdown 指令引导 AI 行为。

    代表案例:summarize(文本摘要)和 skill-vetter(安全审查)

    summarize 的核心设计思路:

    # Summarize Pro — Your AI Summarization Engine
    You are a powerful text summarizer...
    ## Examples
    User: "summarize this: [pastes long article]"
    User: "tldr: [pastes text]"
    User: "eli5: quantum computing"
    ## FEATURE 1: Quick Summary (Default)
    When user pastes text or says "summarize this":
    1. Analyze the text length and content type
    2. Produce a summary in the user's default format
    📝 SUMMARY
    ━━━━━━━━━━━━━━━━━━
    [3-5 bullet points capturing the main ideas]
    📊 Stats: [X] words → [Y] words ([Z]% reduction)

    这个 Skill 的精髓在于:

    1. 角色设定:开头就告诉 AI "You are a powerful text summarizer"
    2. 示例驱动:列出大量用户可能的输入方式
    3. 格式模板:为每种摘要类型定义了精确的输出格式
    4. 行为规则:明确的 Behavior Rules 约束 AI 行为

    skill-vetter 则是另一种纯提示词模式 — 流程协议型

    ## Vetting Protocol
    
    ### Step 1: Source Check
    - [ ] Where did this skill come from?
    - [ ] Is the author known/reputable?
    
    ### Step 2: Code Review (MANDATORY)
    🚨 REJECT IMMEDIATELY IF YOU SEE:
    • curl/wget to unknown URLs
    • Sends data to external servers
    • Uses eval() or exec() with external input
    ...
    
    ### Step 3: Permission Scope
    ### Step 4: Risk Classification
    

    它定义了一套完整的安全审查流程,AI 按步骤执行即可。

    纯提示词 Skill 的开发要点:

    • description 要尽可能详尽地列举触发场景
    • 正文用清晰的结构化格式(标题、列表、表格)
    • 提供输出模板,让 AI 的回复格式一致
    • 设定明确的行为边界和规则

    通过 Python 脚本调用外部 API,是最常见的 Skill 类型。

    代表案例:12306-query(火车票查询)

    核心脚本 scripts/query_tickets.py 的设计模式:

    #!/usr/bin/env python3
    """12306 火车票余票查询脚本"""
    # 1. 常量定义 — API 地址和缓存数据
    TICKET_QUERY_URL = "https://kyfw.12306.cn/otn/leftTicket/query"
    COMMON_STATIONS = {
        "北京": "BJP",
        "上海": "SHH",
        "广州": "GZQ",
        # ...
    }
    # 2. 辅助函数 — 站点编码查询
    def get_station_code(station_name):
        """先查缓存,再查 API"""
        if station_name in COMMON_STATIONS:
            return COMMON_STATIONS[station_name]
        # 从 12306 官方 JS 文件解析...
    # 3. 核心函数 — 调用 API 查询
    def query_tickets(from_station, to_station, date):
        from_code = get_station_code(from_station)
        to_code = get_station_code(to_station)
        session = requests.Session()
        params = {
            "leftTicketDTO.train_date": date,
            "leftTicketDTO.from_station": from_code,
            "leftTicketDTO.to_station": to_code,
            "purpose_codes": "ADULT",
        }
        response = session.get(TICKET_QUERY_URL, params=params, headers=headers, timeout=10)
        # 解析返回数据...
    # 4. 格式化输出 — 表格形式,AI 友好
    def format_tickets(tickets):
        print("{:<8} {:<10} {:<10} {:<8} ...".format(
            "Train", "Depart", "Arrive", "Duration", ...))
        for t in tickets:
            print(...)
    # 5. 命令行入口
    def main():
        if len(sys.argv) < 4:
            print("用法:python query_tickets.py <出发站> <到达站> <日期>")
            sys.exit(1)
        # ...
    if __name__ == "__main__":
        main()

    对应的 SKILL.md 中这样引导 AI 调用脚本:

    ## 快速开始
    
    使用脚本查询余票:
    ​```bash
    python scripts/query_tickets.py <出发站> <到达站> <日期>
    ​```
    
    日期格式:YYYY-MM-DD(如 2026-04-01)
    

    单脚本 Skill 的设计四原则:

    原则 做法 原因
    输出结构化 表格/Markdown/JSON 格式 AI 能直接解析结构化结果
    参数校验优先 缺参数时 sys.exit(1) 让 OpenClaw 捕获错误并提示用户
    结果截断 限制输出长度 防止过长输出撑爆上下文窗口
    使用 {baseDir} 脚本路径用变量引用 运行时自动替换为实际路径

    代表案例:tavily-search(Tavily 搜索)

    Shell 脚本适合调用 REST API 的场景,search.sh 的核心结构:

    #!/bin/bash
    
    # 1. 环境变量校验 — 最重要的第一步
    if [ -z "$TAVILY_API_KEY" ]; then
        echo "ERROR: TAVILY_API_KEY environment variable is not set" >&2
        exit 1
    fi
    
    # 2. 依赖检查
    if ! command -v curl &> /dev/null; then
        echo '{"error":"curl is not installed"}'
        exit 1
    fi
    if ! command -v jq &> /dev/null; then
        echo '{"error":"jq is not installed"}'
        exit 1
    fi
    
    # 3. 核心搜索函数 — 带重试机制
    perform_search() {
        local query="$1"
        local max_results="${2:-5}"
        
        local response=$(curl -s -X POST "$TAVILY_ENDPOINT" 
            -H "Content-Type: application/json" 
            -d "{
                "api_key": "$TAVILY_API_KEY",
                "query": "$query",
                "max_results": $max_results
            }")
        
        # 输出 JSON 格式结果
        echo "$body" | jq '{query: .query, results: .results, quota_info: ...}'
    }
    
    # 4. 子命令路由
    case "$1" in
        --usage)        show_usage ;;
        --status)       show_status ;;
        --toggle-paid-mode) toggle_paid_mode ;;
        *)              perform_search "$1" "$2" "$3" ;;
    esac
    

    这个 Skill 的亮点是配额管理:每次搜索后自动查询剩余配额,避免超额使用。

    代表案例:agent-browser(浏览器自动化)

    这类 Skill 不自带脚本,而是封装已有的 CLI 工具。SKILL.md 的核心是命令手册

    ## Core Workflow
    ​```bash
    # 1. Navigate and snapshot
    agent-browser open https://example.com
    agent-browser snapshot -i --json
    
    # 2. Parse refs from JSON, then interact
    agent-browser click @e2
    agent-browser fill @e3 "text"
    
    # 3. Re-snapshot after page changes
    agent-browser snapshot -i --json
    ​```
    
    ## Key Commands
    ### Navigation
    ​```bash
    agent-browser open <url>
    agent-browser back | forward | reload | close
    ​```
    
    ### Interactions (Ref-based)
    ​```bash
    agent-browser click @e2
    agent-browser fill @e3 "text"
    agent-browser hover @e4
    ​```
    

    封装型 Skill 的写法要点:

    • 提供完整的命令参考,让 AI 知道有哪些命令可用
    • 给出典型工作流(Workflow),而不只是命令列表
    • 说明何时用这个工具、何时用其他替代方案
    • 声明安装方式,让用户知道如何获取外部工具

    代表案例:firecrawl(网页抓取)

    这是最完整的 Skill 结构:

    firecrawl/
    ├── SKILL.md              # 简洁的入口文档
    ├── scripts/
    │   ├── search.py         # 搜索脚本
    │   ├── scrape.py         # 单页抓取脚本
    │   └── crawl.py          # 全站爬取脚本
    └── references/
        └── api.md            # 详细 API 文档(按需加载)
    

    SKILL.md 保持简洁,只提供快速入口:

    ## Quick Start
    
    ### Search the web
    ​```bash
    firecrawl_search "your search query" --limit 10
    ​```
    
    ### Scrape a single page
    ​```bash
    firecrawl_scrape "https://example.com"
    ​```
    
    ## API Reference
    See [references/api.md](references/api.md) for detailed API documentation.
    

    详细的 API 文档放在 references/api.md 中,只在需要时加载。这利用了 OpenClaw 的三级加载机制

    层级 内容 加载时机 建议大小
    第 1 级 name + description 始终在上下文中 ~100 词
    第 2 级 SKILL.md 正文 技能被触发时 < 500 行
    第 3 级 references/ 中的文件 正文指示读取时 不限

    三个脚本共享相同的设计模式:

    # 所有脚本的统一模式
    def main_function(params):
        # 1. 读取 API Key
        api_key = os.environ.get("FIRECRAWL_API_KEY")
        if not api_key:
            print("Error: FIRECRAWL_API_KEY not set", file=sys.stderr)
            sys.exit(1)
        # 2. 构建请求
        data = json.dumps({"url": url, "formats": ["markdown"]}).encode()
        req = urllib.request.Request(url, data=data, headers={...})
        # 3. 发送请求 + 错误处理
        try:
            with urllib.request.urlopen(req, timeout=30) as resp:
                result = json.loads(resp.read().decode())
                return result
        except HTTPError as e:
            print(f"Error: {e.code}", file=sys.stderr)
            sys.exit(1)
    # 4. argparse 命令行接口
    def main():
        parser = argparse.ArgumentParser()
        parser.add_argument("url", help="URL to scrape")
        parser.add_argument("--json", action="store_true")
        args = parser.parse_args()
        # ...

    注意:firecrawl 的脚本只用了标准库 urllib.request,没有引入 requests 等第三方依赖,这降低了安装门槛。

    当你通过 ClawHub 发布 Skill 后,会自动生成 _meta.json

    {
      "ownerId": "kn78ns1svg36jybcqfkxhtvcp182kf18",  // 作者 ID
      "slug": "tavily-search-skill",                    // URL 标识符
      "version": "1.0.4",                               // 当前版本
      "publishedAt": 1773128020068                       // 发布时间戳
    }

    通过 clawhub install 安装的 Skill 会有这个文件:

    {
      "version": 1,
      "registry": "https://clawhub.ai",          // 注册中心地址
      "slug": "tavily-search-skill",             // Skill 标识
      "installedVersion": "1.0.4",               // 安装的版本
      "installedAt": 1774932128743               // 安装时间戳
    }

    假设我们要开发一个"GitHub 仓库信息查询"Skill:

    mkdir -p ~/.openclaw/workspace/skills/github-repo-info
    

    ---
    name: github-repo-info
    description: 查询 GitHub 仓库信息,包括 star 数、fork 数、最近更新时间、主要语言等。
      当用户询问某个 GitHub 仓库的信息、统计数据或状态时使用此技能。
    metadata:
      openclaw:
        requires:
          bins:
            - curl
    ---
    # GitHub 仓库信息查询
    查询任意 GitHub 公开仓库的基本信息。
    ## 使用方式
    ​```bash
    bash {baseDir}/scripts/query.sh <owner> <repo>
    ​```
    示例:
    ​```bash
    bash {baseDir}/scripts/query.sh facebook react
    bash {baseDir}/scripts/query.sh microsoft vscode
    ​```
    ## 输出内容
    - 仓库名称和描述
    - Star / Fork / Issue 数量
    - 主要编程语言
    - 最近更新时间
    - 开源协议
    ## 注意事项
    - 仅支持公开仓库
    - GitHub API 未认证时限制 60 次/小时
    - 如需更高频率,可设置 GITHUB_TOKEN 环境变量

    #!/bin/bash
    # scripts/query.sh — GitHub 仓库信息查询
    
    if [ -z "$1" ] || [ -z "$2" ]; then
        echo "用法: query.sh <owner> <repo>"
        echo "示例: query.sh facebook react"
        exit 1
    fi
    
    OWNER="$1"
    REPO="$2"
    AUTH_HEADER=""
    
    if [ -n "$GITHUB_TOKEN" ]; then
        AUTH_HEADER="-H "Authorization: token $GITHUB_TOKEN""
    fi
    
    RESPONSE=$(curl -s "https://api.github.com/repos/$OWNER/$REPO" $AUTH_HEADER)
    
    if echo "$RESPONSE" | jq -e '.message' > /dev/null 2>&1; then
        echo "Error: $(echo $RESPONSE | jq -r '.message')"
        exit 1
    fi
    
    # 输出结构化结果
    echo "$RESPONSE" | jq '{
      name: .full_name,
      description: .description,
      stars: .stargazers_count,
      forks: .forks_count,
      open_issues: .open_issues_count,
      language: .language,
      license: .license.name,
      updated_at: .updated_at,
      homepage: .homepage
    }'
    

    # 检查 Skill 状态
    openclaw skills check
    openclaw skills info github-repo-info
    
    # 在 OpenClaw 对话中测试
    # 输入:"帮我查一下 facebook/react 这个仓库的信息"
    # AI 应该自动触发 github-repo-info Skill
    

    1. 访问 clawhub.ai,用 GitHub 账号登录
    2. 点击 "Publish",填写 Slug、Display Name、Version
    3. 上传包含 SKILL.md 的文件夹
    4. 系统自动校验格式
    5. 确认 MIT-0 许可证,点击发布

    从 7 个案例中提炼的 description 写作模式:

    [做什么] + [使用什么技术/API] + [什么时候用/触发条件]
    

    好的例子:

    • ✅ "中国铁路 12306 火车票余票查询…当用户需要查询火车票信息时使用此技能"
    • ✅ "Web search and scraping via Firecrawl API. Use when you need to search the web…"
    • ✅ "Security-first skill vetting for AI agents. Use before installing any skill…"

    从 7 个案例中总结的通用脚本模板:

    #!/usr/bin/env python3
    """脚本描述"""
    import sys, json, os
    # 1. 环境变量/参数校验(失败时 exit(1))
    api_key = os.environ.get("MY_API_KEY")
    if not api_key:
        print("Error: MY_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    # 2. 核心逻辑(API 调用 + 数据处理)
    def do_work(params):
        try:
            response = requests.get(API_URL, params=params, timeout=10)
            return response.json()
        except Exception as e:
            print(f"Error: {e}", file=sys.stderr)
            sys.exit(1)
    # 3. 格式化输出(Markdown/JSON/表格)
    def format_output(data):
        print(json.dumps(data, indent=2, ensure_ascii=False))
    # 4. CLI 入口(argparse 或 sys.argv)
    if __name__ == "__main__":
        # ...

    参考 skill-vetter 的审查标准,你的 Skill 应该:

    • ❌ 不要向未知 URL 发送数据
    • ❌ 不要硬编码 API Key 或密码
    • ❌ 不要使用 eval() / exec() 处理外部输入
    • ❌ 不要访问 ~/.ssh~/.aws 等敏感目录
    • ✅ 使用环境变量存储敏感信息
    • ✅ 最小化权限范围
    • ✅ 所有网络请求设置超时
    • ✅ 完善的错误处理

    [ ] SKILL.md frontmatter 包含 name 和 description
    [ ] description 清晰描述触发条件和能力
    [ ] 环境变量依赖声明在 metadata.requires.env
    [ ] 系统命令依赖声明在 metadata.requires.bins
    [ ] 脚本输出为结构化格式(Markdown/JSON/表格)
    [ ] 敏感信息使用环境变量,不硬编码
    [ ] 错误处理完善(缺参数 exit(1),API 失败有清晰提示)
    [ ] 本地测试通过
    [ ] 发布前文件夹只包含 SKILL.md 和纯文本文件
    

    以上就是OpenClaw(龙虾)Skills从零到发布的实战指南的详细内容,更多关于OpenClaw Skills开发指南的资料请关注风君子博客其它相关文章!

    站内搜索