技能开发指南
概述
技能(Skill)是 OpenClaw 的核心扩展机制。每个技能本质上是一个以 SKILL.md 为核心的目录,定义了 Agent 在特定场景下应该如何使用工具。本指南教你从零开发自己的技能。
Skill 的本质:知识注入
Skill 不会给 Agent 增加新工具。它做的事情只有一件:在特定场景下,把一段知识塞进 Agent 的 context。Agent 读到这段知识后,自己决定调用什么工具、怎么执行。
打个比方:你给新员工一本操作手册,手册本身不会帮他干活,但他看完就知道该怎么干了。
Skill vs AGENTS.md
两者都是给 Agent 注入信息,区别在加载时机:
| 维度 | AGENTS.md | Skill |
|---|---|---|
| 加载时机 | 每次 session 都加载 | 只在触发词匹配时加载 |
| 适合放什么 | 通用工作规范:文件命名规则、搜索策略、犯错怎么记录 | 特定业务知识:日报格式、代码审查流程、搜索工具用法 |
| Token 影响 | 每次都占 token | 只在需要时占 token |
AGENTS.md 管工作态度,Skill 管业务知识。把不常用的知识从 AGENTS.md 移到 Skill,启动成本直接降下来。
最小技能
一个技能只需要一个 SKILL.md 文件:
mkdir -p ~/.openclaw/workspace/skills/hello-world<!-- ~/.openclaw/workspace/skills/hello-world/SKILL.md -->
---
name: hello-world
description: 一个简单的问候技能
version: 1.0.0
---
# Hello World
当用户打招呼时,用热情友好的方式回复,并告诉他今天是星期几。保存后,Agent 会自动加载这个技能——无需重启。
SKILL.md 格式
YAML Frontmatter
文件顶部 --- 包裹的部分是元数据:
---
name: weather # 必填:技能名称(小写、连字符)
description: 查询全球天气预报 # 必填:触发条件(AI 据此判断何时使用)
version: 1.2.0 # 必填:语义化版本号
author: your-name # 可选:作者
requirements: # 可选:系统依赖
- curl
- jq
metadata:
openclaw:
requires:
env: # 所需环境变量
- WEATHER_API_KEY
bins: # 所需系统命令
- curl
---description 很关键
description 决定了 AI 何时调用这个技能。写得越具体,触发越精准。例如:
- ❌ "天气相关" — 太模糊
- ✅ "查询指定城市的实时天气和未来 7 天预报" — 精准
Markdown 指令
Frontmatter 之后的 Markdown 内容是给 AI 的「操作手册」:
# Weather Skill
## 使用场景
当用户询问天气、温度、是否需要带伞等问题时触发。
## 操作步骤
1. 从用户消息中提取城市名称
2. 使用 curl 调用天气 API:
```bash
curl -s "https://api.weatherapi.com/v1/forecast.json?key=$WEATHER_API_KEY&q={city}&days=3&lang=zh"- 解析返回的 JSON 数据
- 以友好的格式展示天气信息
输出格式
- 城市名称 + 当前温度
- 天气状况描述
- 未来 3 天概览
- 是否需要带伞/防晒的建议
注意事项
- 如果城市名称不明确,先确认
- API 返回错误时,告知用户稍后重试
## 目录结构
完整的技能目录结构:
```text
my-skill/
├── SKILL.md # 必须 — 技能定义文件
├── scripts/ # 可选 — 辅助脚本
│ ├── setup.sh # 安装依赖
│ └── query.js # API 调用脚本
├── templates/ # 可选 — 提示词模板
│ └── report.hbs
└── README.md # 可选 — 使用说明脚本引用
在 SKILL.md 中可以引用技能目录下的脚本,使用 {baseDir} 占位符:
执行以下命令查询天气:
```bash
node {baseDir}/scripts/query.js --city "{city}"
`{baseDir}` 会在运行时自动替换为技能的实际目录路径。
## 环境变量配置
敏感信息通过环境变量传递,**不要硬编码**:
```bash
# 方式一:全局环境变量
openclaw config set env.WEATHER_API_KEY "your-api-key"
# 方式二:技能级配置
# 在 openclaw.json 中{
"skills": {
"weather": {
"api_key": "your-api-key",
"default_city": "Beijing"
}
}
}开发流程
1. 创建技能
# 在工作区创建(最高优先级)
mkdir -p ~/.openclaw/workspace/skills/my-skill
# 或在用户级创建
mkdir -p ~/.openclaw/skills/my-skill2. 编写 SKILL.md
参考上面的格式示例。
3. 验证
# 检查技能格式
openclaw skills check
# 查看已加载的技能
openclaw skills list4. 测试
直接在对话中测试:
你:帮我查一下北京天气
Agent:[触发 weather 技能]
正在查询北京天气...
北京今天晴,25°C,空气质量良好...5. 调试
如果技能没有被触发:
- 检查
description是否足够描述触发场景 - 检查日志:
openclaw logs --follow - 确认技能在列表中:
openclaw skills list - 确认环境变量已配置
触发机制详解
软触发(模糊匹配)
Skill 的触发机制是语义相关性判断,不是字符串精确匹配:
- 扫描时机:Agent 启动时扫描
~/.openclaw/skills/和项目级.openclaw/skills/两个目录,读取每个SKILL.md的 YAMLdescription字段,提取触发词缓存在内存中。注意是启动时一次性扫描,运行期间新增或修改的 Skill 不会被感知——必须重启才能加载。 - 匹配方式:用户发消息 → Agent 拿消息和触发词做模糊匹配 → 匹配上了就把 SKILL.md 内容注入 context。
- 模糊匹配:不是你说了某个触发词就一定触发,也不必须一字不差。你触发词写的是「日报」,用户说「帮我写今天的工作总结」也可能触发,因为 Agent 判断语义相关。
触发词写法策略
核心词简短明确,同时多列几种同义表达,中英文都覆盖。不用担心写太多——宁可多触发让 Agent 自己判断要不要用,也别因为漏了触发词导致 Skill 从来不被加载。
description: >
Generate daily work reports by reading memory files and summarizing activities.
Use when (1) user asks for daily report, (2) user says "今天做了什么",
(3) user wants to review today's work.
Triggers: "daily report", "日报", "今天做了什么", "工作总结", "今日汇报".让 Agent 帮你写 SKILL.md
你不需要从零手写 SKILL.md。直接告诉 Agent 你要什么:
帮我创建一个 Skill,放在 ~/.openclaw/skills/daily-report/
功能:根据今天的 memory 文件生成日报
触发词:日报、工作总结、今天做了什么
日报格式:完成的工作、重要决策、遇到的问题、明天计划Agent 会帮你生成完整的 SKILL.md,包括 YAML front matter 和正文。你要做的只是检查一下触发词覆盖够不够、步骤描述准不准确,然后重启加载。
Skill 常见坑
坑 1:创建了 Skill 但 Agent 没反应
Skill 只在启动时加载。创建或修改后必须重启 OpenClaw,不重启就一直用的旧版本。
openclaw restart坑 2:触发词不生效
三个常见原因:
- 触发词写在了 Markdown 正文里而不是 YAML 的
description字段 — Agent 只扫描 description - 触发词太长太复杂 — 保持简短,两三个字最好,多列几种表达方式
- 用户消息太复杂,触发词被淹没 — 测试时用简单直接的消息
坑 3:YAML 格式写错
最常见的错误:description 是长文本但没用 > 折叠符。
# 错误 — 长文本换行会破坏 YAML 解析
description: Generate daily reports.
Triggers: "日报".
# 正确 — 用 > 折叠长文本
description: >
Generate daily reports.
Triggers: "日报".坑 4:以为 Skill 会自动执行命令
Skill 不是可执行的工具。它只给 Agent 提供知识。你在 SKILL.md 里写 agent-reach search ...,Agent 读到后会自己决定调用 exec 来跑这个命令。但如果 agent-reach 这个 CLI 没有安装,命令跑不了,Skill 也帮不上忙。
Skill 提供知识,工具提供能力。两者缺一不可。
坑 5:多个 Skill 触发词重叠
你有一个搜索 Skill 和一个数据分析 Skill,触发词都包含「查一下」。结果两个 SKILL.md 都注入 context,Agent 自己决定用哪个。
没有优先级机制。如果发现 Agent 经常选错,把触发词做得更具体:搜索 Skill 用「搜一下」,数据 Skill 用「查数据」。
实战案例:Tavily 搜索
以社区热门技能 tavily-search 为例:
---
name: tavily-search
description: 使用 Tavily API 进行 Agent 优化的网络搜索
version: 2.1.0
metadata:
openclaw:
requires:
env:
- TAVILY_API_KEY
bins:
- node
---
# Tavily Search
## 何时使用
当用户需要搜索网络信息、查找最新新闻、验证事实时使用。
## 搜索方式
执行以下脚本进行搜索:
```bash
node {baseDir}/scripts/search.js --query "{search_query}" --max-results 5结果处理
- 按相关性排序展示搜索结果
- 提供来源链接
- 综合多个结果给出简明答案
- 如结果不满意,可调整搜索关键词重试
## 性能注意事项
| 活跃技能数量 | 影响 | 建议 |
|-------------|------|------|
| 1-5 个 | 几乎无影响 | 正常使用 |
| 5-10 个 | 上下文略增 | 日常使用推荐上限 |
| 10-20 个 | 明显增加 Token 消耗 | 按需启用 |
| 20+ 个 | 严重影响性能 | 应避免 |
每次对话会在启动时「快照」当前活跃技能,采用懒加载——脚本仅在被触发时才执行。
## 安全提醒
::: danger 技能安全
2026 年 2 月的审计发现,约 12% 的 ClawHub 技能存在恶意行为或安全漏洞。开发和安装技能时请注意:
1. **先安装 `skill-vetter`** — 安全审查工具
2. **不要在脚本中硬编码密钥**
3. **审查第三方技能的 scripts/ 目录**
4. **优先使用高星标、高下载量的技能**
:::
## 技能类型详解
在 OpenClaw 生态中,技能(Skill)是可以被 Agent 调用的功能模块。类比理解:Agent = 大脑(思考和决策),Skill = 手(执行具体动作)。
技能分为三种类型:
| 类型 | 说明 | 示例 |
|------|------|------|
| **工具型(Tool)** | 封装外部 API 调用 | 天气查询、股票数据、地图导航 |
| **流程型(Workflow)** | 多步骤任务自动化 | 简历筛选、合同审查、SEO 分析 |
| **集成型(Integration)** | 连接第三方平台 | 飞书机器人、微信消息、Slack |
::: tip 如何选择技能类型
- **Tool 型**:适合单一功能、快速响应的场景。开发最简单,一个 API 调用即可。
- **Workflow 型**:适合需要多个步骤协作的复杂任务。通常包含多个脚本和模板。
- **Integration 型**:适合需要与外部系统双向交互的场景。需要处理认证、Webhook 等。
:::
## AgentSkills 目录结构规范
OpenClaw 技能遵循 AgentSkills 开放规范。一个技能本质上是一个**包含 `SKILL.md` 文件的目录**,`SKILL.md` 是唯一必需的文件:
```text
weather-query/
├── SKILL.md # 必需:技能定义(YAML frontmatter + 使用说明)
├── scripts/ # 可选:可执行脚本(Python/Bash/JS 等)
├── references/ # 可选:参考文档
├── assets/ # 可选:模板、资源文件
└── ... # 其他任意文件或目录关键要点:
SKILL.md是唯一必需文件,不需要index.js、skill.json等入口文件- 目录名必须与
SKILL.md中的name字段一致 name只允许小写字母、数字和连字符,不能以连字符开头或结尾,不能有连续连字符- 技能通过渐进式披露管理上下文:启动时只加载
name和description(约 100 tokens),激活时加载完整SKILL.md(建议 < 5000 tokens),按需加载scripts/、references/等文件
技能加载位置与优先级(从高到低):
- 工作区技能:
<workspace>/skills - 用户技能:
~/.openclaw/skills - 内置技能:随安装包发布
- 额外目录:通过
~/.openclaw/openclaw.json中skills.load.extraDirs配置
SKILL.md 定义规范详解
OpenClaw 使用兼容 AgentSkills 规范的 SKILL.md 文件来定义技能。文件使用 YAML frontmatter 声明元数据,正文部分是技能的使用说明。
YAML frontmatter 字段
必填字段:
| 字段 | 必需 | 说明 |
|---|---|---|
name | 是 | 1-64 字符,仅小写字母、数字、连字符,必须与目录名一致 |
description | 是 | 1-1024 字符,描述技能功能和使用场景,应包含便于匹配的关键词 |
可选字段:
| 字段 | 说明 |
|---|---|
license | 许可证名称或文件引用 |
compatibility | 1-500 字符,环境要求说明 |
metadata | 任意键值对(OpenClaw 内嵌解析器要求单行 JSON 对象) |
allowed-tools | 空格分隔的预授权工具列表(实验性) |
OpenClaw 扩展的可选 frontmatter 字段:
| 字段 | 说明 |
|---|---|
homepage | macOS Skills UI 中显示的 URL |
user-invocable | true / false(默认 true),是否作为用户斜杠命令暴露 |
disable-model-invocation | true / false(默认 false),为 true 时从模型提示中排除 |
command-dispatch | 设为 tool 时,斜杠命令直接调度到工具 |
command-tool | command-dispatch: tool 时要调用的工具名 |
metadata 字段详解
metadata:
{"openclaw": {"requires": {"bins": ["node"]}, "primaryEnv": "WEATHER_API_KEY"}}metadata在 OpenClaw 内嵌解析器中必须是单行 JSON 对象(不支持多行 YAML 展开)metadata.openclaw.requires用于门控加载:bins(PATH 中的二进制文件)、env(环境变量)、config(配置路径)primaryEnv关联skills.entries.<name>.apiKey的环境变量名- 说明正文中可用
{baseDir}引用技能目录路径 - 建议
SKILL.md正文控制在 500 行以内,详细参考材料放到references/目录
完整示例
# weather-query/SKILL.md
---
name: weather-query
description: 查询全球任意城市的实时天气、未来7天预报和历史天气数据。当用户询问天气、气温、降雨等信息时使用。
metadata:
{"openclaw": {"requires": {"env": ["WEATHER_API_KEY"]}, "primaryEnv": "WEATHER_API_KEY"}}
---
使用 `get_current_weather` 工具查询指定城市的当前天气。
支持中英文城市名,如"北京"或"Beijing"。
## 可用工具
- `get_current_weather`:获取当前天气
- `get_weather_forecast`:获取未来7天预报
## 环境要求
需要设置 `WEATHER_API_KEY` 环境变量。技能的全局配置
在 ~/.openclaw/openclaw.json 中配置技能:
{
"skills": {
"entries": {
"weather-query": {
"enabled": true,
"apiKey": "YOUR_WEATHER_API_KEY",
"env": {
"WEATHER_API_KEY": "YOUR_WEATHER_API_KEY"
}
}
},
"load": {
"extraDirs": ["~/my-custom-skills"],
"watch": true
}
}
}实战示例:SEO 分析器技能
以蓝皮书中的 SEO 分析工具为例,这是一个有商业价值的 Workflow 型技能。
市场调研
开发技能前先做市场调研(market_research):
- ClawHub 上 SEO 类技能:目前 23 个,月销量前 3 平均 ¥8,000/月
- 需求:每个内容运营都需要,一次写作前必查
- 定价空间:¥29-99/月(对比外部 SEO 工具 $50-200/月)
SKILL.md 定义
# seo-analyzer/SKILL.md
---
name: seo-analyzer
description: 全面分析网页SEO状况,提供优化建议,支持竞品对比分析
metadata:
{"openclaw": {"requires": {"bins": ["node"]}}}
---
网页SEO深度分析工具,支持以下功能:
- `analyze_page_seo`:分析指定URL的SEO得分和优化建议
- `compare_competitors`:与竞争对手URL进行SEO对比分析
- `keyword_density`:分析页面关键词密度和分布
- `check_technical_seo`:检查技术SEO项目(速度、移动端、结构化数据等)核心分析逻辑
// tools/seo-analyzer.js
async function analyzePageSEO({ url }) {
// 1. 获取页面HTML
const html = await fetchPage(url);
const $ = cheerio.load(html);
// 2. 基础SEO检查
const checks = {
title: analyzeTitleTag($),
metaDescription: analyzeMetaDescription($),
headings: analyzeHeadings($),
images: analyzeImages($),
internalLinks: analyzeInternalLinks($, url),
externalLinks: analyzeExternalLinks($),
pageSpeed: await checkPageSpeed(url),
mobileOptimization: await checkMobileOptimization(url),
structuredData: analyzeStructuredData($),
canonicalUrl: checkCanonical($, url),
};
// 3. 计算综合得分
const score = calculateSEOScore(checks);
// 4. 生成优化建议
const recommendations = generateRecommendations(checks);
return {
url,
overallScore: score,
grade: getGrade(score), // A/B/C/D/F
checks,
topRecommendations: recommendations.slice(0, 5),
allRecommendations: recommendations,
};
}项目结构
seo-analyzer/
├── SKILL.md # 技能定义文件
├── index.js # 入口文件(保持 execute 函数签名不变)
├── tools/ # 工具实现(每个工具一个文件)
│ └── seo-analyzer.js
├── tests/ # 测试文件(覆盖率需 > 80%)
│ └── main.test.js
└── docs/ # 文档付费技能开发
OpenClaw Skill SDK 内置了订阅验证,让你轻松实现收费逻辑。
SDK 接入
// index.js
const { SkillSDK } = require('@openclaw/skill-sdk');
const sdk = new SkillSDK({
skillId: 'seo-analyzer',
version: '2.0.0',
});
async function execute(toolName, params, context) {
// 验证用户订阅状态(SDK 自动处理)
await sdk.verifySubscription(context.userId, context.skillToken);
// 记录使用量
await sdk.recordUsage(context.userId, {
tool: toolName,
credits: getToolCost(toolName),
});
// 执行具体工具
return await handlers[toolName](params);
}
// 不同工具消耗不同积分
function getToolCost(toolName) {
const costs = {
analyze_page_seo: 1, // 1积分
compare_competitors: 3, // 3积分
keyword_density: 1, // 1积分
check_technical_seo: 2, // 2积分
};
return costs[toolName] || 1;
}定价配置
{
"price": {
"type": "freemium",
"freeCalls": 50, // 每月50次免费
"paidPrice": 29, // 付费版¥29/月
"paidFeatures": [ // 付费专属功能
"无限次分析",
"历史趋势对比",
"批量分析(最多100个URL)",
"PDF报告导出"
]
}
}测试技能
在发布之前,必须编写充分的测试。每个工具至少 3 个测试用例(正常/边界/错误)。
编写测试
// tests/main.test.js
const { execute } = require('../index');
describe('SEO Analyzer Tests', () => {
test('分析基本SEO元素', async () => {
const result = await execute('analyze_page_seo', {
url: 'https://example.com',
});
expect(result).toHaveProperty('overallScore');
expect(result.overallScore).toBeGreaterThanOrEqual(0);
expect(result.overallScore).toBeLessThanOrEqual(100);
expect(result).toHaveProperty('grade');
expect(result).toHaveProperty('topRecommendations');
});
test('处理无效URL', async () => {
await expect(
execute('analyze_page_seo', { url: 'not-a-valid-url' })
).rejects.toThrow('无效的URL格式');
});
test('处理无法访问的URL', async () => {
await expect(
execute('analyze_page_seo', { url: 'https://nonexistent-domain-xyz.com' })
).rejects.toThrow('无法访问目标URL');
});
});运行测试
npm test
# 输出示例
# ✓ 分析基本SEO元素 (1234ms)
# ✓ 处理无效URL (12ms)
# ✓ 处理无法访问的URL (3021ms)
#
# Tests: 3 passed, 3 total本地测试流程
除了单元测试,还需要进行端到端的本地测试:
# 检查技能格式
openclaw skills check
# 查看已加载的技能
openclaw skills list
# 在对话中测试
# 输入:"分析 https://yoursite.com 的SEO"发布到 ClawHub
ClawHub 市场介绍
ClawHub(hub.openclaw.ai)是 OpenClaw 官方技能市场:
- 全球开发者:12,000+
- 已发布技能:8,500+
- 月活用户:340 万
- 开发者平均月收入(前 10%):$2,000-15,000
发布流程
Step 1:注册开发者账户
# 登录 ClawHub
openclaw login
# 注册开发者(需要实名认证)
openclaw developer register \
--name "你的名字" \
--email "[email protected]" \
--country "CN"Step 2:完善技能文档
技能的 README.md 是用户决定是否购买的关键,必须包含:功能介绍、适用人群、功能列表、快速开始、示例输出、常见问题等。
Step 3:发布技能
# 构建发布包
openclaw skill build
# 运行发布前检查
openclaw skill validate
# 发布到 ClawHub(审核通常1-3个工作日)
openclaw skill publish
# 查看审核状态
openclaw skill statusStep 4:审核标准
ClawHub 技能审核检查项:
- [ ] 功能描述与实际一致
- [ ] 代码不含恶意逻辑
- [ ] API 密钥等敏感信息正确处理
- [ ] 错误处理完善
- [ ] 测试覆盖率 > 70%
- [ ] README 文档完整
- [ ] 定价合理(不欺骗性定价)
技能销售策略
策略 1:免费增值(Freemium)最有效
数据显示,提供免费体验的技能转化率比纯付费高 3-5 倍:
{
"price": {
"type": "freemium",
"freeCalls": 50,
"paidPrice": 29,
"paidFeatures": [
"无限次分析",
"历史趋势对比",
"批量分析(最多100个URL)",
"PDF报告导出"
]
}
}策略 2:积极响应用户反馈
- 在 ClawHub 设置 GitHub Issues 链接
- 承诺 24 小时内响应 bug 报告
- 每月至少一次版本更新
- 公开更新日志
策略 3:社区推广
- 在 Reddit r/openclaw 分享使用案例
- 录制 YouTube/B 站教学视频
- 在 Twitter/微博分享用户成功案例
- 在 OpenClaw 官方 Discord 频道活跃
策略 4:技能捆绑(Bundle)
把相关技能打包销售:
SEO工具套件(¥99/月,原价¥147/月):
- 网页SEO分析
- 关键词研究工具
- 竞品监控工具
- 外链分析工具收益预估模型
月收益 = 付费用户数 × 月价格 × (1 - ClawHub抽成30%)
保守估计(3个月后):
日活用户:500人
付费转化率:8%
付费用户:40人
月价格:¥49
月收益:40 × 49 × 0.7 = ¥1,372
中等估计(6个月后):
日活用户:2000人
付费转化率:10%
付费用户:200人
月价格:¥49
月收益:200 × 49 × 0.7 = ¥6,860
乐观估计(12个月后):
日活用户:10000人
付费转化率:12%
付费用户:1200人
月价格:¥49
月收益:1200 × 49 × 0.7 = ¥41,160技能开发最佳实践
编码规范
- 所有工具函数必须有 JSDoc 注释
- 错误处理:使用自定义错误类,包含用户友好的中文错误信息
- API 密钥:只从环境变量读取,绝不硬编码
- 异步:全部使用 async/await,不使用 callback
测试要求
- 每个工具至少 3 个测试用例(正常/边界/错误)
- 运行:
npm test - 测试通过后才能发布
发布流程
npm test(必须全绿)openclaw skill validateopenclaw skill publish
description 写作技巧
description 决定了 AI 何时调用这个技能,写得越具体,触发越精准:
- 不要写"天气相关" -- 太模糊
- 要写"查询指定城市的实时天气和未来 7 天预报" -- 精准
SKILL.md 正文建议
- 控制在 500 行以内
- 详细参考材料放到
references/目录 - 使用
{baseDir}引用技能目录路径 - 明确列出可用工具和使用场景
- 包含错误处理的说明
常见问题
- 如果 API 调用失败,返回中文错误信息给用户
- 参数验证在工具入口处进行
- 敏感信息通过环境变量传递,不要硬编码