Skills 部署与自建

从“会安装”到“能判断、能编写、能维护”

先说结论

  1. Skill 是一份给 Agent 阅读的操作说明,可以附带脚本和参考资料;它本身不会凭空增加系统权限或工具。
  2. OpenClaw 不会把所有 SKILL.md 全文永久塞进上下文。它先提供一份精简的 Skill 清单,相关任务出现时再按需读取正文。
  3. 社区 Skill 应按第三方代码对待。平台扫描只能降低风险,不能代替人工检查。
  4. 自建 Skill 先写清适用场景、操作步骤、输出格式和失败处理,不必一开始就追求复杂。
  5. 定时任务应使用 OpenClaw 自带的 Cron;Heartbeat 更适合时间不必精确、可以合并执行的日常检查。

第一章 Skill 是什么

Skill、工具和插件不要混为一谈

这三个概念解决的问题不同:

概念 主要作用 示例
Skill 告诉 Agent 何时做、怎么做 “收到行情巡检任务时,调用接口、检查阈值并按固定格式输出”
Tool 提供真正可执行的能力 搜索网页、读取文件、调用浏览器
Plugin 向 OpenClaw 扩展工具或集成能力 浏览器、消息渠道等插件

Skill 可以指导 Agent 使用已有工具,但不能只靠一段 Markdown 创造一个系统里不存在的工具。

OpenClaw 如何加载 Skill

加载过程可以分成三步:

  1. 发现:OpenClaw 扫描 Skill 目录,读取 namedescription 和依赖条件。
  2. 列出:符合条件的 Skill 以精简清单出现在 Agent 的上下文中,内容包括名称、描述和文件位置。
  3. 按需读取:当任务与某个 Skill 相关时,Agent 再读取完整的 SKILL.md

因此,安装更多 Skill 确实会增加清单长度,也可能出现描述相近、难以选择的问题;但不能简单理解为“每个 Skill 的全文始终占用上下文”。

可以用以下命令查看实际占用:

/context list
/context detail

重点看 Skills list,而不是凭 Skill 数量猜测 Token 消耗。

Skill 的目录优先级

同名 Skill 出现在多个位置时,优先级高的版本生效。当前加载顺序如下:

优先级 来源 路径
1(最高) 当前 Workspace <workspace>/skills/
2 项目级 Agent <workspace>/.agents/skills/
3 当前机器的个人 Agent ~/.agents/skills/
4 OpenClaw Managed / Local ~/.openclaw/skills/
5 OpenClaw 内置 随安装包提供
6(最低) 额外目录和 Plugin 附带 Skill skills.load.extraDirs、插件声明目录

课程练习优先放在 <workspace>/skills/:范围清楚,也不容易影响其他 Agent。

如果两个 Skill 都与“日历”有关,优先级本身不会替 Agent 选择其中一个。只有同名时才会覆盖;不同名但描述相似时,仍需改清楚 description,或限制 Agent 可见的 Skill。

安装和查看

使用 OpenClaw 自带命令搜索、安装和更新:

# 搜索
openclaw skills search "calendar"

# 安装到当前 Workspace
openclaw skills install @owner/skill-name

# 安装为当前机器共享 Skill
openclaw skills install @owner/skill-name --global

# 更新当前 Workspace 的全部 Skill
openclaw skills update --all

聊天中可用 /commands 查看当前可调用命令,用 /skill [名称] 明确运行某个 Skill。不同渠道是否注册独立的 Skill 斜杠命令,取决于渠道和 commands.nativeSkills 配置。

本章小结

  • Skill 是操作说明,不等于可执行工具。
  • System Prompt 中常驻的是精简清单,完整正文按需读取。
  • 同名 Skill 按目录优先级覆盖;不同名 Skill 需靠清晰描述减少误选。

第二章 ClawHub 选型与安全检查

先看需求,再找 Skill

安装前先回答三个问题:

  1. 现有工具是否已经能完成任务?
  2. 是否需要一套可复用的操作流程?
  3. 这个 Skill 要读取哪些文件、凭据和外部服务?

如果只是偶尔读取一个网页,直接使用 web_fetch 可能已经足够;如果要固定搜索来源、检查结果并按模板归档,才更适合写成 Skill。

ClawHavoc 事件告诉了我们什么

2026 年初,研究人员在 ClawHub 发现大批恶意 Skill。不同报告统计口径不同,不应混成一个数字:

  • Koi Security 最初公布 341 个恶意 Skill,其中 335 个被归为同一批 ClawHavoc 活动;后续更新扩大了样本范围。
  • Antiy 后续回溯 ClawHub 历史数据,统计到至少 1,184 个恶意包,涉及多个发布者。
  • hightower6eu 在 1 月 31 日的一次集中上传中提交了 354 个恶意 Skill;Antiy 对其历史上传的统计为 677 个。

常见手法不是“Agent 自动执行了一段隐藏代码”这么简单,而是把恶意安装步骤伪装成正常前置条件,引导用户或 Agent 下载并运行外部程序。部分样本会窃取浏览器数据、钱包和密钥。

这类事件的核心教训是:SKILL.md 可读,不代表内容天然安全;其中引用的脚本、下载地址和安装命令也必须检查。

ClawHub 当前的安全信息

ClawHub 的审计页面会综合显示:

  • SkillSpector 检查;
  • VirusTotal 的文件信誉与恶意软件信号;
  • ClawScan 风险分析,其中会参考静态扫描、权限、文件和行为说明。

常见结果包括 PassReviewWarnMaliciousReview 表示需要进一步判断,不等于已确认恶意;Pass 也不是安全承诺。

平台扫描可能漏掉:

  • 新型或经过混淆的恶意脚本;
  • 安装后才从外部拉取的内容;
  • 看似合理、实际会泄露数据的自然语言指令;
  • 后续版本的恶意更新。

安装前五步检查

1. 看审计结果

确认当前版本的扫描状态。标记为 Malicious 的版本不要安装;ReviewWarn 必须看具体原因。

也可以在命令行核验 ClawHub 的信任信息:

openclaw skills verify @owner/skill-name
openclaw skills verify @owner/skill-name --card

2. 看发布者和版本记录

确认发布者身份、账号历史、更新说明和仓库活动。下载量和 Star 可以参考,但不能单独作为可信依据。

3. 读 SKILL.md 和附带文件

重点检查:

  • curlwgetbashevalbase64 -d 等执行或下载命令;
  • 不熟悉的域名和短链接;
  • 读取 ~/.ssh、浏览器配置、钱包、.env 等敏感目录的要求;
  • 与功能无关的高权限操作;
  • scripts/ 目录中的实际代码。

4. 核对权限是否匹配

一个天气查询 Skill 通常不需要读取 SSH 密钥;一个摘要 Skill 也不应要求修改 SOUL.mdMEMORY.md

5. 小范围测试

先在测试 Workspace 使用,不要直接接触真实客户数据、生产账号或高权限凭据。更新版本后重新检查变更。

一份可直接使用的检查表

检查项 通过标准
扫描状态 Malicious;已读懂 Review / Warn 原因
发布者 身份和历史合理,没有明显仿冒
文件内容 已检查 SKILL.md、脚本和外部下载
权限 与功能相符,遵循最小权限
凭据 不写进 Skill,不发送给不必要的外部服务
测试 先在低风险环境验证

第三章 常用能力怎么组合

先分清工具是否已经存在

OpenClaw 已提供或可通过插件提供多种工具。版本和配置不同,可用能力也会不同,因此不要照着固定“Top 10”榜单一次装完。

以资料调研为例,常见分工是:

能力 适合做什么 不适合做什么
web_search 不知道网址时搜索资料 登录后页面、复杂交互
web_fetch 已知 URL 时提取正文 执行 JavaScript、登录页面
Browser 打开动态网页、点击和填写表单 绕过验证码或访问控制
总结指令或 Skill 按固定维度压缩信息 替代来源核验和人工判断

web_search 的实际搜索提供方取决于配置,不能笼统写成“固定调用 DuckDuckGo 或 Tavily”。web_fetch 是轻量 HTTP 抓取,不执行 JavaScript。

调研任务示例

与其只说:

帮我调研一下 AI 创业方向。

不如把范围和输出要求说清楚:

请调研 2026 年 AI Coding、AI 教育和 AI 设计三个方向。

每个方向请整理:
1. 近 12 个月的代表产品;
2. 有可靠来源的融资或商业化信息;
3. 主要用户和常见使用场景;
4. 小团队可能的切入点;
5. 信息来源和发布日期。

遇到无法交叉验证的数据,请标记“待核实”,不要推测。
最后把结果写入飞书多维表格。

执行时可以按以下顺序:

  1. web_search 找到候选来源。
  2. web_fetch 读取普通网页;动态页面再使用 Browser。
  3. 按指定字段提取信息,并保留来源链接和日期。
  4. 对关键数字至少寻找两个独立来源。
  5. 经确认后再写入飞书表格。

结果检查

  • 来源是否真实可访问?
  • 发布日期是否满足时间范围?
  • 产品、融资和数字是否能在原文找到?
  • “事实”和“建议”是否分开?
  • 遇到付费墙、登录或验证码时,是否明确说明而不是猜测?

Agent 的价值在于减少重复操作,不代表结果可以免审。


第四章 编写 SKILL.md

基本结构

一个 Skill 至少是一个包含 SKILL.md 的目录:

skills/
└── crypto-monitor/
    ├── SKILL.md
    ├── scripts/       # 可选
    ├── references/    # 可选
    └── assets/        # 可选

Skill 的名称来自 Frontmatter 中的 name,不要求必须与文件夹同名。不过保持一致更便于维护。

SKILL.md 分为两部分:

  1. YAML Frontmatter:名称、描述、调用方式和依赖条件。
  2. Markdown Body:具体操作步骤、输出格式和异常处理。

最小示例

---
name: crypto-monitor
description: 获取 BTC、ETH 和 LTC 的价格及 24 小时涨跌幅;当用户查询行情或执行定期行情巡检时使用。
---

# 加密货币行情巡检

## 执行步骤

1. 从 CoinGecko 获取 BTC、ETH 和 LTC 的 USD、CNY 价格及 24 小时涨跌幅。
2. 检查返回数据是否完整。
3. 将涨跌幅绝对值与阈值比较。
4. 超过阈值时输出告警;否则按调用场景返回正常状态或 `NO_REPLY`

其中:

  • name:Skill 的唯一名称。
  • description:告诉 Agent 这个 Skill 能做什么、何时适用。

description 不需要堆满关键词,但要写清边界。太宽泛会误触发,太窄则可能找不到。

常用 Frontmatter 字段

字段 默认值 作用
name 必填 Skill 名称
description 必填 功能和适用场景
user-invocable true 是否允许用户通过斜杠命令调用
disable-model-invocation false 设为 true 后不进入 Agent 的可选 Skill 清单,只能由用户调用
metadata.openclaw 依赖、系统限制和主要环境变量等

涉及交易、删除或其他明显副作用的 Skill,可以考虑:

user-invocable: true
disable-model-invocation: true

这样可降低模型自行选择该 Skill 的机会,但真正的安全边界仍应放在权限和审批上。

声明依赖

建议采用官方文档中的对象格式:

---
name: crypto-monitor
description: 获取 BTC、ETH 和 LTC 行情,并按阈值生成巡检结果。
metadata:
  {
    "openclaw": {
      "requires": {
        "bins": ["curl", "jq"],
        "env": ["COINGECKO_API_KEY"]
      },
      "primaryEnv": "COINGECKO_API_KEY",
      "envVars": [
        {
          "name": "MONITOR_THRESHOLD_PERCENT",
          "required": false,
          "description": "告警阈值,默认 3"
        }
      ]
    }
  }
---

常用依赖字段:

字段 作用
requires.bins 所列命令必须都在 PATH
requires.anyBins 至少存在一个所列命令
requires.env 所列环境变量必须存在
requires.config 所列 OpenClaw 配置路径必须为真
os 限制系统,例如 ["darwin"]["linux"]["win32"]
primaryEnv skills.entries.<key>.apiKey 对应的主要凭据
envVars 描述环境变量,可把某些变量标为可选

requires.bins 只说明主机上能找到命令。如果 Agent 在沙箱中运行,沙箱内也必须安装相同命令。

Body 怎么写

给非专业同事使用时,正文至少写清四件事:

  1. 适用范围:什么任务该用,什么任务不该用。
  2. 执行步骤:按顺序写,避免“自行妥善处理”这类空话。
  3. 输出格式:用户最终会看到什么。
  4. 失败处理:哪些情况重试,哪些情况立即停止并报告。

示例:

## 数据检查

- 缺少任一币种的价格或涨跌幅时,报告缺失字段。
- 价格小于等于 0 时,不生成告警,标记为数据异常。
- 返回内容不是有效 JSON 时,保留状态码和前 200 个字符供排查。

## 输出

- 超过阈值:输出币种、价格、24 小时涨跌幅、阈值和查询时间。
- 未超过阈值:人工测试时输出“未触发告警”;Cron 任务中只返回 `NO_REPLY`

不要让 Skill 输出完整 API Key、Authorization 请求头或包含凭据的 URL。


第五章 环境变量和密钥

不要把密钥写进 SKILL.md

SKILL.md 可能进入 Git、被复制给同事或上传到 ClawHub。密钥应放在环境变量或 OpenClaw 支持的 SecretRef 中。

OpenClaw 会从进程环境、当前工作目录的 .env~/.openclaw/.env 和配置中的 env 等位置补充变量。已有值通常不会被后续来源覆盖,因此改了 .env 却未生效时,应先检查进程中是否已经存在同名变量。

课程环境的简单做法

nano ~/.openclaw/.env

写入:

COINGECKO_API_KEY=你的实际密钥
MONITOR_THRESHOLD_PERCENT=3

再限制文件权限:

chmod 600 ~/.openclaw/.env

修改后如果当前会话没有读取到新值,新建会话或重启相应服务。验证时只确认“变量存在”,不要打印完整内容。

Skill 级配置

~/.openclaw/openclaw.json 支持:

{
  "skills": {
    "entries": {
      "crypto-monitor": {
        "enabled": true,
        "apiKey": {
          "source": "env",
          "provider": "default",
          "id": "COINGECKO_API_KEY"
        },
        "env": {
          "MONITOR_THRESHOLD_PERCENT": "3"
        }
      }
    }
  }
}

说明:

  • apiKey 对应 metadata.openclaw.primaryEnv
  • envapiKey 只在主机 Agent 运行期间注入,不会自动进入沙箱。
  • 直接在 openclaw.json 写明文密钥并不比 .env 更安全;有 SecretRef 时优先引用,不要复制密钥。

第六章 异常处理

先区分两类错误

基础设施错误

例如模型服务短暂超时、限流或消息发送失败。OpenClaw 和底层 SDK 对部分请求有重试或模型故障转移机制,但不同组件的策略不同,不能概括为“所有任务都有三层自动重试”。

特别要注意:

  • Provider SDK 会处理部分 4084094295xx 响应。
  • 渠道配置中的 attemptsminDelayMsmaxDelayMsjitter 主要用于消息发送等渠道请求,不是任意业务 API 的通用重试器。
  • 模型故障转移不等于业务步骤会从头安全重跑。

业务错误

例如:

  • API 返回成功,但缺少价格字段;
  • 返回内容不是有效 JSON;
  • 数值不符合业务规则;
  • 重试可能造成重复发送或重复写入。

这类情况需要在 Skill 中明确处理。

重试要保守

推荐写法:

## 异常处理

1. 网络超时或 HTTP 5xx:等待 10 秒后重试 1 次。
2. HTTP 429:读取 `Retry-After`;没有该响应头时等待 60 秒,最多重试 1 次。
3. HTTP 401 或 403:不要重试,提示检查 API Key 和权限。
4. 返回数据缺字段:停止本次判断,报告缺失字段。
5. 任何失败都不得输出“巡检正常”。

创建日程、发消息、付款、删除文件等有副作用的操作,重试前必须确认上一次是否已经成功,避免重复执行。


第七章 Cron 与 Heartbeat

两者怎么选

维度 Heartbeat Cron
时间 周期性、允许一定偏差 支持固定间隔、Cron 表达式和单次时间
上下文 主会话上下文 可使用隔离、主会话或自定义会话
适用场景 收件箱、日历、通知等可批量检查 定时报表、提醒、独立后台任务
任务记录 不创建独立任务记录 每次运行会创建任务记录

Heartbeat 默认周期通常是 30 分钟,但可配置,不应写死为 1 小时。行情巡检需要单独记录和明确频率时,使用 Cron 更合适。

使用 OpenClaw Cron

不要直接把 openclaw run crypto-monitor 写进系统 crontab。OpenClaw 有自己的持久化调度器:

openclaw cron add "every 4h" \
  "使用 crypto-monitor Skill 巡检 BTC、ETH 和 LTC。超过阈值时输出告警;未超过时只返回 NO_REPLY。" \
  --name "crypto-check" \
  --agent main

也可以用五段 Cron 表达式:

openclaw cron add "0 */4 * * *" \
  "使用 crypto-monitor Skill 执行行情巡检;无告警时只返回 NO_REPLY。" \
  --name "crypto-check" \
  --agent main

查看和测试:

openclaw cron list
openclaw cron run <job-id> --wait
openclaw cron runs --id <job-id> --limit 20

隔离 Cron 任务默认会公告最终结果。如果最终回复只有 NO_REPLY,OpenClaw 会抑制消息发送。HEARTBEAT_OK 主要用于 Heartbeat,不应拿来当 Cron 的通用静默标记。


第八章 实战:加密货币行情巡检

本练习用于学习 Skill、环境变量和 Cron 的配合,不构成投资建议。

1. 确认 CoinGecko 配额

截至本文核验时,CoinGecko Demo 计划主要信息为:

项目 内容
月度调用额度 10,000 credits
速率限制 100 次 / 分钟
数据新鲜度 最快约 60 秒
信用卡 注册 Demo 计划不需要

套餐可能调整,实操前以 CoinGecko API Pricing 为准。页面宣传的 SLA 不应直接理解为免费 Demo 计划的服务承诺。

2. 配置环境变量

按第五章的方法配置:

COINGECKO_API_KEY=你的实际密钥
MONITOR_THRESHOLD_PERCENT=3

不要把真实 Key 发到群聊、截图或提交到 Git。

3. 创建 Skill

<workspace>/skills/crypto-monitor/SKILL.md 写入:

---
name: crypto-monitor
description: 获取 BTC、ETH 和 LTC 的 USD、CNY 价格及 24 小时涨跌幅;用于人工查询或定期行情巡检。
metadata:
  {
    "openclaw": {
      "requires": {
        "bins": ["curl", "jq"],
        "env": ["COINGECKO_API_KEY"]
      },
      "primaryEnv": "COINGECKO_API_KEY",
      "envVars": [
        {
          "name": "MONITOR_THRESHOLD_PERCENT",
          "required": false,
          "description": "告警阈值,默认 3"
        }
      ]
    }
  }
---

# 加密货币行情巡检

## 数据来源

调用 CoinGecko Demo API:

- Base URL:`https://api.coingecko.com/api/v3`
- 认证请求头:`x-cg-demo-api-key: $COINGECKO_API_KEY`
- 币种 ID:`bitcoin,ethereum,litecoin`
- 法币:`usd,cny`
- 包含字段:24 小时涨跌幅

## 执行步骤

1. 获取 BTC、ETH 和 LTC 的 USD、CNY 价格及 24 小时涨跌幅。
2.`jq` 解析 JSON,确认三个币种及所需字段都存在。
3. 读取 `MONITOR_THRESHOLD_PERCENT`;未设置时使用 3。
4. 比较涨跌幅绝对值和阈值。
5. 超过阈值时输出告警;否则人工调用输出“未触发告警”,Cron 调用只返回 `NO_REPLY`

## 异常处理

- 超时或 HTTP 5xx:等待 10 秒后重试 1 次。
- HTTP 429:遵循 `Retry-After`;没有时等待 60 秒,最多重试 1 次。
- HTTP 401 / 403:停止并提示检查 API Key。
- JSON 无效或字段缺失:停止判断并报告问题。
- 失败时不得输出 `NO_REPLY`,以免隐藏故障。

## 告警格式

📊 加密货币行情告警

- 币种:
- USD / CNY 价格:
- 24 小时涨跌幅:
- 告警阈值:
- 查询时间:

4. 手动测试

先明确调用 Skill:

/skill crypto-monitor

或使用自然语言:

请使用 crypto-monitor 查询 BTC、ETH 和 LTC 行情,并显示本次巡检是否超过阈值。

检查:

  • 三个币种和两种法币是否齐全;
  • 24 小时涨跌幅是否存在;
  • 查询时间和阈值是否显示;
  • 日志和回复中是否没有完整 API Key;
  • 故意使用错误 Key 时,是否明确报错而不是误报“正常”。

5. 接入 Cron

测试阶段先用较短间隔:

openclaw cron add "every 10m" \
  "使用 crypto-monitor Skill 巡检行情。超阈值时输出告警;未超阈值时只返回 NO_REPLY;发生错误时必须报告。" \
  --name "crypto-check-test" \
  --agent main

确认运行正常后,再调整为业务需要的频率。不要为了演示设置过高频率,以免浪费调用额度和 Token。

常见问题

表现 排查方向
401 / 403 Key 是否正确、是否读取到环境变量
429 查看 Retry-After、当前分钟速率和月度额度
缺少 litecoin 检查 ids 是否使用 CoinGecko 的小写 ID
jq 解析失败 保留状态码和响应片段,确认是否收到 HTML 错误页
Skill 没出现 检查 Frontmatter、依赖条件和目录;新建会话后再试
Cron 运行但无消息 无告警时 NO_REPLY 属正常;有错误时检查任务运行记录和投递目标

总结

完成本节后,应能回答以下问题:

  1. Skill、Tool 和 Plugin 分别负责什么?
  2. 为什么“装一个 Skill 就把全文永久注入 System Prompt”并不准确?
  3. 安装社区 Skill 前需要检查哪些内容?
  4. descriptionrequires 和 Markdown Body 各自解决什么问题?
  5. 密钥为什么不能写进 SKILL.md
  6. 什么任务适合 Cron,什么任务适合 Heartbeat?

课后练习

必做:完成一次安全评估

在 ClawHub 选择一个与工作相关的 Skill,记录:

  • 发布者和版本;
  • 扫描状态;
  • 需要的权限和外部服务;
  • SKILL.md 与脚本中的风险点;
  • 最终结论:安装、暂缓或拒绝。

选做:改写一个自己的 Skill

选择汇率监控、竞品更新或 GitHub Star 追踪等真实需求,至少包含:

  • 清晰的 namedescription
  • 必要的依赖声明;
  • 输出格式;
  • 可执行的异常处理;
  • 一次手动测试;
  • 如确有定时需求,再接入 Cron。

核验来源