9.3 编写自己的技能
上一节你学会了安装别人的 Skill。但有些东西,只有你自己知道怎么做。
想象一下这个场景:
你的公司有一套内部数据 API,每次查询都要翻文档、拼参数、记格式。
你想:如果 OpenClaw 能直接查询就好了。
于是你花 10 分钟写了一个 Skill。
现在你只需要说:“查一下上个月的销售额”,OpenClaw 自动调用 API、解析数据、生成报告。
同事问你怎么做到的,你说:“就写了个 Skill,很简单。”
这就是自定义 Skill 的价值——把你的专属知识注入 OpenClaw,让它成为真正属于你的 AI 助手。
这一节,我们用 20 分钟,学会编写自己的 Skill。
准备工作
开始前,确认你有:
- OpenClaw 已安装并运行
- 一个文本编辑器
- 约 20 分钟时间
- 一个想要自动化的场景(比如查询公司 API、执行特定流程等)
第一步:理解 Skill 的本质
Skill 不是代码,是一份给 AI 的使用说明书。
每个 Skill 是一个文件夹,里面至少包含一个 SKILL.md 文件。这个文件用简单的格式告诉 AI:
- 这个技能是做什么的
- 什么时候该用它
- 怎么用
核心原则:写给 AI 看,不是给人看。
第二步:创建你的第一个 Skill
我们来创建一个“服务器状态查询”的 Skill。
2.1 创建目录
mkdir -p ~/.openclaw/workspace/skills/server-status2.2 创建 SKILL.md
cat > ~/.openclaw/workspace/skills/server-status/SKILL.md << 'EOF'
---
name: server-status
description: >-
查询服务器系统状态。当用户提到"服务器状态"、"系统资源"、"磁盘空间"、"内存使用"、"CPU负载"时使用。
---
# 服务器状态查询
查询当前系统的 CPU、内存和磁盘使用情况。
## 执行步骤
1. 运行 `df -h` 检查磁盘使用
2. 运行 `free -h` 检查内存使用
3. 运行 `uptime` 检查系统负载
4. 以清晰的格式汇总结果
## 输出格式【服务器状态报告】 磁盘:/ 分区已用 45GB/100GB (45%) 内存:已用 4GB/16GB (25%) 负载:0.52, 0.58, 0.61 (1/5/15 分钟)
## 错误处理
如果某个命令执行失败,跳过该项并继续执行其他检查。
## 示例触发
- "查看服务器状态"
- "检查磁盘空间"
- "系统资源使用情况"
- "服务器健康吗"
EOF2.3 刷新 Skills
在 OpenClaw 对话中输入:
刷新 skills或者重启 Gateway。
2.4 测试
查看服务器状态如果一切正常,OpenClaw 会执行命令并返回格式化的系统状态报告。
试一试:创建一个销售查询 Skill
现在我们来创建一个更完整的 Skill——“销售数据查询”。
第一步:创建目录结构
mkdir -p ~/.openclaw/workspace/skills/sales-query/{scripts,references}第二步:创建查询脚本
cat > ~/.openclaw/workspace/skills/sales-query/scripts/query.py << 'EOF'
#!/usr/bin/env python3
import sys
import json
from datetime import datetime
def query_sales(month=None):
"""模拟查询销售数据"""
if month is None:
month = datetime.now().strftime("%Y%m")
# 这里替换为实际的 API 调用
# 示例数据
data = {
"month": month,
"total": 128500,
"growth": 15.2,
"top_products": ["产品A", "产品B", "产品C"]
}
return data
if __name__ == "__main__":
month = sys.argv[1] if len(sys.argv) > 1 else None
result = query_sales(month)
print(json.dumps(result, ensure_ascii=False))
EOF
chmod +x ~/.openclaw/workspace/skills/sales-query/scripts/query.py第三步:创建 SKILL.md
cat > ~/.openclaw/workspace/skills/sales-query/SKILL.md << 'EOF'
---
name: sales-query
description: >-
查询公司销售数据。当用户提到"销售额"、"销售数据"、"查询销售"、"业绩"、"月度报表"时使用。
metadata:
{"openclaw": {"emoji": "📊"}}
---
# 销售数据查询
查询公司内部销售系统数据。
## 执行步骤
1. 解析用户请求中的时间范围(默认当月)
2. 执行查询脚本:`python {baseDir}/scripts/query.py <month>`
3. 格式化输出结果
## 输出格式【销售数据 - 2024年3月】 总销售额:¥128,500 环比增长:+15.2% Top3 产品:产品A、产品B、产品C
## 注意事项
- 月份格式为 YYYYMM(如 202403)
- 如查询失败,返回友好的错误提示
- 不要猜测或编造数据
## 示例触发
- "查一下上个月销售额"
- "2月的业绩怎么样"
- "最近三个月的销售数据"
EOF第四步:测试
重启会话后测试:
你:查一下上个月的销售额 OpenClaw:【销售数据 - 2025年2月】 总销售额:¥128,500 环比增长:+15.2% Top3 产品:产品A、产品B、产品C
理解三级资源结构
一个完整的 Skill 可以包含三种资源目录:
your-skill/
├── SKILL.md # 必需。给 AI 的指令
├── scripts/ # 可执行代码(执行而不读取)
├── references/ # 参考文档(需要时读取)
└── assets/ # 输出文件(用于输出)| 目录 | 目的 | AI 如何使用 | 何时用 |
|---|---|---|---|
| scripts/ | 确定性执行 | 直接执行,不读取内容 | 每次都一样的代码、精确格式约束 |
| references/ | 按需查阅 | 需要时读取到上下文 | API 文档、数据库 schema |
| assets/ | 直接输出 | 复制/修改后输出 | 模板、图片、样板代码 |
关键点:
scripts/中的代码执行时不会加载到上下文,零 token 成本references/中的文档只有 AI 需要时才会读取- 用
{baseDir}引用 Skill 目录的路径
理解三级加载架构
Skill 的信息有不同的“温度”:
L1:元数据(始终热)
位置:SKILL.md frontmatter
---
name: sales-query
description: >-
查询公司销售数据。当用户提到"销售额"、"销售数据"、"查询销售"时使用。
---关键规则:将所有“何时使用”信息放在 description 中。AI 决定是否使用这个 Skill 时,只看 description。
L2:SKILL.md 正文(触发时加载)
目的:告诉 AI 如何完成工作
内容指南:
- 程序性知识(分步指令)
- AI 不知道的领域细节
- 如何使用捆绑资源
- 错误处理模式
L3:捆绑资源(按需加载)
仅在 AI 明确需要时加载(scripts/、references/、assets/)。
核心原则
1. 写给 AI 看,不是给人看
❌ 不要写:
- README.md、CHANGELOG.md(AI 不需要)
- 背景故事、版本历史
- 模糊的指令(“要专业”、“保持友好”)
✅ 要写:
- 具体可执行的指令
- “不要做”的清单
- 明确的触发条件
2. “不做什么”比“做什么”更精确
## 避免以下模式
- 以反问句开头
- 每个名词使用超过 2 个形容词
- 以通用号召性用语结束段落3. 使用祈使语气
读取前检查文件是否存在。
返回包含 "status" 和 "data" 字段的 JSON。门控配置
通过 metadata 设置 Skill 的加载条件:
---
name: gemini-image
description: 通过 Gemini API 生成图片
metadata:
{
"openclaw": {
"requires": {
"bins": ["python3"],
"env": ["GEMINI_API_KEY"]
},
"primaryEnv": "GEMINI_API_KEY"
}
}
---| 规则 | 说明 |
|---|---|
requires.bins | 需要的可执行文件必须在 PATH 中 |
requires.env | 需要的环境变量必须存在 |
requires.config | 需要的配置项必须为真值 |
os | 限制操作系统(darwin/linux/win32) |
故障排查
Skill 没有被加载
检查清单:
- [ ] SKILL.md 文件是否存在于正确位置
- [ ] frontmatter 格式是否正确(YAML 语法)
- [ ] name 字段是否存在且符合规范(小写、连字符)
- [ ] description 字段是否存在
- [ ] 是否有门控条件未满足
AI 不触发 Skill
检查清单:
- [ ] description 是否包含足够的触发关键词
- [ ] 触发词是否与用户表达方式匹配
- [ ] 尝试在对话中明确提到 Skill 名称
脚本执行失败
检查清单:
- [ ] 脚本是否有执行权限:
chmod +x script.py - [ ] 脚本路径是否正确使用了
{baseDir} - [ ] 依赖是否已安装
- [ ] 在终端手动测试脚本是否能正常运行
这一节,你做了什么
| 做了什么 | 核心要点 |
|---|---|
| 理解 Skill 本质 | 给 AI 的使用说明书,不是代码 |
| 创建第一个 Skill | server-status:服务器状态查询 |
| 创建完整 Skill | sales-query:带脚本和元数据 |
| 理解三级资源 | scripts/执行、references/查阅、assets/输出 |
| 理解三级加载 | L1元数据、L2正文、L3捆绑资源 |
| 核心原则 | 写给AI看、用祈使语气、“不做什么”更精确 |
下一节
当你创建了多个 Skill,可能会遇到同名冲突的问题。
下一节,我们来了解 Skills 的加载优先级和最佳实践。