🛠️ Agent Skills 开发指南
"我把一个 Skill 封装了99次,第100次才明白——最好的 Skill,是让用户忘记 Skill 的存在。"
什么是 Agent Skills?
Agent Skills 是 OpenClaw 的核心概念。你可以把它理解为 Agent 的"超能力插件"——每个 Skill 都是封装好的功能模块,让你的 AI 能执行特定任务。
就像钢铁侠的装甲可以换装不同武器,你的 Agent 也可以通过 Skills 获得网页抓取、文件处理、数据分析、消息推送等各种能力。
核心概念
Skill 的三层结构
my-skill/
├── skill.json # 技能元信息(名称、描述、依赖)
├── src/
│ └── index.js # 主逻辑实现
└── schemas/
├── input.json # 输入参数校验
└── output.json # 输出结构定义
创建你的第一个 Skill
Step 1: 初始化 Skill 项目
# 使用 CLI 创建 Skill 模板
openclaw skill create my-first-skill
# 或者手动创建目录结构
mkdir -p my-skill/src my-skill/schemas
cd my-skill
npm init -y
Step 2: 编写 skill.json
{
"name": "web-content-extractor",
"version": "1.0.0",
"description": "从网页提取结构化内容",
"author": "your-name",
"tags": ["web", "scraping", "content"],
"dependencies": {
"cheerio": "^1.0.0"
},
"entry": "src/index.js",
"config": {
"timeout": {
"type": "number",
"default": 30000,
"description": "请求超时时间(毫秒)"
}
}
}
Step 3: 实现核心逻辑
// src/index.js
const cheerio = require('cheerio');
module.exports = class WebExtractor {
constructor(config) {
this.timeout = config.timeout || 30000;
}
async execute({ url, selector }) {
try {
const response = await fetch(url, {
signal: AbortSignal.timeout(this.timeout)
});
const html = await response.text();
const $ = cheerio.load(html);
const content = $(selector).text().trim();
return {
success: true,
data: { content, url },
metadata: {
length: content.length,
timestamp: new Date().toISOString()
}
};
} catch (error) {
return {
success: false,
error: error.message,
code: 'EXTRACTION_FAILED'
};
}
}
};
Step 4: 定义输入输出 Schema
// schemas/input.json
{
"type": "object",
"required": ["url", "selector"],
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "目标网页 URL"
},
"selector": {
"type": "string",
"description": "CSS 选择器,用于定位内容"
}
}
}
// schemas/output.json
{
"type": "object",
"properties": {
"success": { "type": "boolean" },
"data": {
"type": "object",
"properties": {
"content": { "type": "string" },
"url": { "type": "string" }
}
},
"metadata": {
"type": "object",
"properties": {
"length": { "type": "number" },
"timestamp": { "type": "string" }
}
}
}
}
最佳实践
✅ Skill 设计原则
- 单一职责 - 一个 Skill 只做一件事,做好一件事
- 幂等性 - 相同输入产生相同输出,可重复执行
- 优雅降级 - 依赖服务失败时,给出友好提示而非崩溃
- 可观测性 - 记录执行日志,方便调试
错误处理规范
// ✅ 好的错误处理
return {
success: false,
error: `提取失败: ${error.message}`,
code: 'EXTRACTION_FAILED',
suggestion: '请检查 URL 是否可访问,选择器是否正确'
};
// ❌ 避免这样
throw error; // 直接抛出,调用方无法优雅处理
高级技巧
Skill 组合
// 在一个 Skill 中调用另一个 Skill
const { SkillRunner } = require('openclaw');
async execute(input) {
const runner = new SkillRunner();
// 先提取网页内容
const extraction = await runner.run('web-extractor', {
url: input.url,
selector: 'article'
});
// 再调用 AI 总结
const summary = await runner.run('ai-summarizer', {
text: extraction.data.content,
maxLength: 200
});
return summary;
}
缓存策略
const cache = new Map();
async execute(input) {
const cacheKey = JSON.stringify(input);
if (cache.has(cacheKey)) {
return { success: true, data: cache.get(cacheKey), cached: true };
}
const result = await this.process(input);
cache.set(cacheKey, result);
return result;
}
发布到 Skill 市场
# 打包 Skill
openclaw skill pack ./my-skill
# 发布到 ClawHub
openclaw skill publish ./my-skill --registry clawhub
# 验证发布
openclaw skill search my-skill