Skills 部署与自建
从“会安装”到“能判断、能编写、能维护”
先说结论
- Skill 是一份给 Agent 阅读的操作说明,可以附带脚本和参考资料;它本身不会凭空增加系统权限或工具。
- OpenClaw 不会把所有
SKILL.md全文永久塞进上下文。它先提供一份精简的 Skill 清单,相关任务出现时再按需读取正文。 - 社区 Skill 应按第三方代码对待。平台扫描只能降低风险,不能代替人工检查。
- 自建 Skill 先写清适用场景、操作步骤、输出格式和失败处理,不必一开始就追求复杂。
- 定时任务应使用 OpenClaw 自带的 Cron;Heartbeat 更适合时间不必精确、可以合并执行的日常检查。
第一章 Skill 是什么
Skill、工具和插件不要混为一谈
这三个概念解决的问题不同:
| 概念 | 主要作用 | 示例 |
|---|---|---|
| Skill | 告诉 Agent 何时做、怎么做 | “收到行情巡检任务时,调用接口、检查阈值并按固定格式输出” |
| Tool | 提供真正可执行的能力 | 搜索网页、读取文件、调用浏览器 |
| Plugin | 向 OpenClaw 扩展工具或集成能力 | 浏览器、消息渠道等插件 |
Skill 可以指导 Agent 使用已有工具,但不能只靠一段 Markdown 创造一个系统里不存在的工具。
OpenClaw 如何加载 Skill
加载过程可以分成三步:
- 发现:OpenClaw 扫描 Skill 目录,读取
name、description和依赖条件。 - 列出:符合条件的 Skill 以精简清单出现在 Agent 的上下文中,内容包括名称、描述和文件位置。
- 按需读取:当任务与某个 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
安装前先回答三个问题:
- 现有工具是否已经能完成任务?
- 是否需要一套可复用的操作流程?
- 这个 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 风险分析,其中会参考静态扫描、权限、文件和行为说明。
常见结果包括 Pass、Review、Warn 和 Malicious。Review 表示需要进一步判断,不等于已确认恶意;Pass 也不是安全承诺。
平台扫描可能漏掉:
- 新型或经过混淆的恶意脚本;
- 安装后才从外部拉取的内容;
- 看似合理、实际会泄露数据的自然语言指令;
- 后续版本的恶意更新。
安装前五步检查
1. 看审计结果
确认当前版本的扫描状态。标记为 Malicious 的版本不要安装;Review 或 Warn 必须看具体原因。
也可以在命令行核验 ClawHub 的信任信息:
openclaw skills verify @owner/skill-name
openclaw skills verify @owner/skill-name --card
2. 看发布者和版本记录
确认发布者身份、账号历史、更新说明和仓库活动。下载量和 Star 可以参考,但不能单独作为可信依据。
3. 读 SKILL.md 和附带文件
重点检查:
curl、wget、bash、eval、base64 -d等执行或下载命令;- 不熟悉的域名和短链接;
- 读取
~/.ssh、浏览器配置、钱包、.env等敏感目录的要求; - 与功能无关的高权限操作;
scripts/目录中的实际代码。
4. 核对权限是否匹配
一个天气查询 Skill 通常不需要读取 SSH 密钥;一个摘要 Skill 也不应要求修改 SOUL.md 或 MEMORY.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. 信息来源和发布日期。
遇到无法交叉验证的数据,请标记“待核实”,不要推测。
最后把结果写入飞书多维表格。
执行时可以按以下顺序:
- 用
web_search找到候选来源。 - 用
web_fetch读取普通网页;动态页面再使用 Browser。 - 按指定字段提取信息,并保留来源链接和日期。
- 对关键数字至少寻找两个独立来源。
- 经确认后再写入飞书表格。
结果检查
- 来源是否真实可访问?
- 发布日期是否满足时间范围?
- 产品、融资和数字是否能在原文找到?
- “事实”和“建议”是否分开?
- 遇到付费墙、登录或验证码时,是否明确说明而不是猜测?
Agent 的价值在于减少重复操作,不代表结果可以免审。
第四章 编写 SKILL.md
基本结构
一个 Skill 至少是一个包含 SKILL.md 的目录:
skills/
└── crypto-monitor/
├── SKILL.md
├── scripts/ # 可选
├── references/ # 可选
└── assets/ # 可选
Skill 的名称来自 Frontmatter 中的 name,不要求必须与文件夹同名。不过保持一致更便于维护。
SKILL.md 分为两部分:
- YAML Frontmatter:名称、描述、调用方式和依赖条件。
- 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 怎么写
给非专业同事使用时,正文至少写清四件事:
- 适用范围:什么任务该用,什么任务不该用。
- 执行步骤:按顺序写,避免“自行妥善处理”这类空话。
- 输出格式:用户最终会看到什么。
- 失败处理:哪些情况重试,哪些情况立即停止并报告。
示例:
## 数据检查
- 缺少任一币种的价格或涨跌幅时,报告缺失字段。
- 价格小于等于 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。env和apiKey只在主机 Agent 运行期间注入,不会自动进入沙箱。- 直接在
openclaw.json写明文密钥并不比.env更安全;有 SecretRef 时优先引用,不要复制密钥。
第六章 异常处理
先区分两类错误
基础设施错误
例如模型服务短暂超时、限流或消息发送失败。OpenClaw 和底层 SDK 对部分请求有重试或模型故障转移机制,但不同组件的策略不同,不能概括为“所有任务都有三层自动重试”。
特别要注意:
- Provider SDK 会处理部分
408、409、429和5xx响应。 - 渠道配置中的
attempts、minDelayMs、maxDelayMs、jitter主要用于消息发送等渠道请求,不是任意业务 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 属正常;有错误时检查任务运行记录和投递目标 |
总结
完成本节后,应能回答以下问题:
- Skill、Tool 和 Plugin 分别负责什么?
- 为什么“装一个 Skill 就把全文永久注入 System Prompt”并不准确?
- 安装社区 Skill 前需要检查哪些内容?
description、requires和 Markdown Body 各自解决什么问题?- 密钥为什么不能写进
SKILL.md? - 什么任务适合 Cron,什么任务适合 Heartbeat?
课后练习
必做:完成一次安全评估
在 ClawHub 选择一个与工作相关的 Skill,记录:
- 发布者和版本;
- 扫描状态;
- 需要的权限和外部服务;
SKILL.md与脚本中的风险点;- 最终结论:安装、暂缓或拒绝。
选做:改写一个自己的 Skill
选择汇率监控、竞品更新或 GitHub Star 追踪等真实需求,至少包含:
- 清晰的
name和description; - 必要的依赖声明;
- 输出格式;
- 可执行的异常处理;
- 一次手动测试;
- 如确有定时需求,再接入 Cron。