本文将带你系统掌握 OpenClaw 技能的开发流程,从基础概念到生产部署,涵盖结构设计、工具调用、错误处理、测试验证等核心主题。无论你是刚入门的新手还是希望提升技能的开发者,这篇指南都将为你提供实战性的指导。
1.1 什么是 OpenClaw 技能
OpenClaw 技能(Skills)是扩展 OpenClaw 能力边界的核心机制,它们是预配置的指令包,能够赋予 AI 代理特定领域的专业能力。 简单来说,技能就像是为 AI 装备的工具箱,让它能够处理各种专业任务——从文档处理到天气查询,从代码编写到浏览器自动化。
每个技能本质上是一个自包含的指令单元,由 SKILL.md 文件定义,包含元数据(YAML Frontmatter)和使用说明(Markdown Body)两部分。技能可以打包分发,用户只需简单安装即可让 OpenClaw 获得新的能力。
技能的设计理念源于"专业的事交给专业的人"这一原则。就像人类在面对不同任务时会调用不同的专业知识一样,AI 代理在面对特定场景时也应该激活相应的技能。这种机制不仅提高了任务处理的准确性,还大大减少了每次都重新输入相关知识的 token 消耗。
1.2 技能的作用与应用场景
技能的核心价值在于场景化能力封装。它将特定领域的知识、工具和**实践打包在一起,使 AI 代理能够在正确的时间调用正确的功能。
技能的主要应用场景非常广泛,涵盖了生活和工作的方方面面:
文档处理领域 - 专业的 Word 文档创建、编辑和修订 - PDF 文档的转换、分割、合并 - 电子表格的数据处理和分析
网络交互领域 - 网页自动化操作和数据抓取 - API 接口的调用和集成 - 浏览器行为的精确控制
编码开发领域 - 代码审查和重构建议 - 自动化测试生成 - 项目构建和部署流程
数据分析领域 - 结构化数据的处理和转换 - 报告生成和可视化 - 日志分析和监控
通信通知领域 - 邮件发送和接收管理 - 即时通讯消息发送 - 语音合成和播报
平台集成领域 - 飞书文档、云盘、知识库操作 - 企业微信文档和智能表格 - GitHub 仓库和 Issue 管理
以 weather 技能为例,它封装了从 wttr.in 或 Open-Meteo 获取天气数据的能力,并明确了使用边界(适合实时天气查询,不适合历史数据),让 AI 能够准确判断何时使用该技能。这种清晰的边界定义是技能设计的关键。
1.3 技能与普通脚本的区别
许多开发者可能会问:技能和普通的脚本有什么区别?为什么需要额外的技能层?樂 这个问题值得深入探讨。
技能的独特之处在于它的触发机制和渐进式披露设计。技能描述(description)会被系统用于判断何时应该激活该技能,就像大脑的神经通路一样——当用户提到特定场景时,相应的技能会自动被加载。
例如,当用户说"帮我查一下北京明天天气怎么样"时,系统会自动激活 weather 技能,因为 description 中包含了"Use when: user asks about weather"这样的触发条件描述。这种智能触发机制是普通脚本无法实现的。
1.4 技能开发的价值
开发自定义技能的价值体现在多个层面,每一个层面都能为开发者和用户带来实际的收益:
知识沉淀与传承 - 将团队的专业知识封装为可复用的技能 - 避免重复造轮子,减少重复工作 - 新成员可以快速上手团队的工具和工作方式 - 知识不会因为人员流动而丢失
⚡ 效率显著提升 - 特定领域的任务可以更快、更准确地完成 - 减少了每次都需要重新解释任务背景的时间 - 自动化的错误处理减少了人工干预的需要 - 标准化的工作流程提高了一致性
生态建设与社区共享 - 通过 ClawHub 与社区共享技能 - 利用社区贡献的技能快速扩展能力 - 参与开源生态,推动技术进步 - 建立个人或团队的技术影响力
定制自由的实现 - 不受限于官方提供的功能 - 按需打造专属能力 - 灵活适配特殊业务场景 - 快速响应变化的需求
无论你是希望自动化日常工作流程,还是为团队构建内部工具,或者是想要在社区中分享你的专业技能,技能开发都是释放 OpenClaw 全部潜力的必经之路。
2.1 标准目录结构详解
OpenClaw 技能采用标准化的目录结构,确保一致性和可发现性。一个完整的技能目录结构如下:
skill-name/ ├── SKILL.md (必需) │ ├── YAML frontmatter 元数据 (必需) │ │ ├── name: 技能名称 │ │ └── description: 触发机制描述 │ └── Markdown 指令内容 (必需) └── Bundled Resources (可选) ├── scripts/ - 可执行代码 ├── references/ - 文档资料 └── assets/ - 输出资源
理解这个目录结构是技能开发的基础。每一部分都有其特定的作用和**实践。
SKILL.md(必需文件)
这是技能的核心文件,每个技能必须包含。它包含两部分:
YAML Frontmatter - 包含 name 和 description 字段 - 描述技能的元信息和触发机制 - 这部分内容会始终加载到上下文中(~100 词)
Markdown Body - 技能的详细使用说明和指引 - 功能描述、使用场景、触发条件 - 技能触发时会完整加载(<5000 词)
scripts/ 目录(可执行代码)
存放可执行的脚本文件,如 Python、Bash、JavaScript 等。适用于以下场景:
- 需要确定性可靠性的任务(如 PDF 旋转)
- 重复使用的复杂逻辑
- 需要高性能或确定性的数据处理
- 需要调用外部系统或 API 的封装
示例场景:
scripts/ ├── rotate_pdf.py # PDF 页面旋转 ├── process_csv.py # CSV 数据处理 ├── fetch_api.py # API 数据获取 └── generate_report.py # 报告生成
使用 scripts 的优势在于它不需要加载到上下文中即可执行,这意味着可以显著节省 token 消耗。脚本直接在系统层面执行,只将结果返回给 AI 上下文。
references/ 目录(文档资料)
存放参考文档和资料,会按需加载到上下文中。适用于:
- API 规范文档
- 领域知识文档
- 配置说明文档
- 详细的操作手册
- 历史变更记录
**实践:如果参考文件较大(超过 10,000 词),建议在 SKILL.md 中包含 grep 搜索模式,帮助快速定位关键信息:
参考文档 详细 API 规范请参阅 [references/api_docs.md](references/api_docs.md) 如需搜索特定端点,请在参考文件中使用 grep 搜索 "endpoint" 或 "POST"
⚠️ 重要:信息应该存在于 SKILL.md 或 references 文件中,不要两者都存,避免重复和不一致。重复存放会导致维护困难和潜在的版本不一致问题。
assets/ 目录(输出资源)
存放不用于加载到上下文中、而是用于最终输出的文件,例如:
- 品牌资源(Logo、图片、图标)
- 模板文件(PPT、Word 文档模板)
- 前端样板代码(React 组件、HTML 模板)
- 样式文件(CSS、主题配置)
示例结构:
assets/
├── logo.png # 品牌 Logo
├── report-template.pptx # PPT 模板
├── frontend-template/ # 前端项目模板
│ ├── package.json
│ ├── src/
│ │ ├── App.jsx
│ │ └── index.css
│ └── README.md
└── email-templates/ # 邮件模板
├── welcome.html
└── notification.txt
2.2 文件组织**实践
良好的文件组织是技能可维护性的基础。以下是一些经过验证的**实践:
1. 保持 SKILL.md 精简 - 这是技能的门面,应该简洁明了 - 避免将所有细节都塞进去 - 详细文档放在 references/
2. 合理拆分大文件 - 当 SKILL.md 接近 500 行时,考虑将内容拆分 - 将详细说明移至 references/ 目录 - 主文件只保留快速参考和核心信息
3. 脚本命名清晰规范 - 使用描述性的名称:rotate_pdf.py 比 script1.py 更易理解 - 保持命名风格一致:全小写 + 下划线或全小写 + 连字符 - 添加适当的文件注释说明功能
4. 文档保持更新 - 过时的文档比没有文档更危险 - 在修改功能时同步更新文档 - 使用版本号追踪变更历史
5. 资源分类清晰 - 将不同类型的资源放入对应目录 - 避免根目录文件过多 - 使用子目录组织复杂资源
2.3 不应包含的文件类型
以下文件类型不应该出现在技能目录中,它们会造成混乱和冗余:
- ❌ README.md — 应该整合到 SKILL.md 中
- ❌ INSTALLATION_GUIDE.md — 应该整合到 SKILL.md 中
- ❌ QUICK_REFERENCE.md — 应该整合到 SKILL.md 中
- ❌ CHANGELOG.md — 可以放在 assets/ 子目录中
- ❌ requirements.txt — 如果有依赖,在 SKILL.md 中说明
- ❌ .gitignore — 版本控制应该在项目层面管理
- ❌ 符号链接 — 打包时会失败
技能应该只包含直接支持其功能的必要文件。遵循"最小化原则":只包含实现功能所必需的内容。
2.4 渐进式披露设计原则
OpenClaw 采用三级加载系统来管理上下文效率,这是一个关键的设计理念。理解这个机制能帮助你更高效地设计技能。
这个设计的核心理念是按需加载:只有当技能被激活时,才会加载其完整内容。这种机制有以下几个关键优势:
1. Token 效率优化 - AI 上下文不会因为加载所有技能而膨胀 - 只在需要时加载详细信息 - scripts 目录中的脚本甚至不需要读入上下文就可以执行
2. 响应速度提升 - 技能列表查询更快 - 触发判断更高效 - 整体响应时间缩短
3. 维护性增强 - 大文件可以独立更新 - 不影响主技能的加载速度 - 便于团队协作和版本管理
实践建议:
- 保持 SKILL.md body 精简,控制在 500 行以内
- 当内容接近 5,000 行时,将详细文档移至 references/ 目录
- 将可执行逻辑放在 scripts/ 中而不是直接在 SKILL.md 中描述
- 使用 references/ 时,在 SKILL.md 中提供搜索模式帮助定位
3.1 YAML Frontmatter 规范
YAML Frontmatter 是技能的"身份证",包含两个必需字段和完整的元信息。
--- name: skill-name description: 技能的触发机制描述 ---
name 字段
技能名称应该遵循严格的规范:
- 字符限制:保持在 64 字符以内
- 字符类型:仅使用小写字母、数字和连字符
- 命名风格:优先使用简短的动词开头短语
- 命名空间:按工具或领域命名空间化以提高清晰度
✅ 正确示例: - weather — 简短明了 - coding-agent — 领域 + 功能 - feishu-doc — 平台 + 功能 - gh-address-comments — 工具 + 动作 + 目标
❌ 错误示例: - My Skill — 包含大写和空格 - WeatherQuery — 驼峰命名不符合规范 - skill-name-with-spaces — 包含空格 - a-very-long-skill-name-that-exceeds-the-character-limit-and-is-hard-to-read — 过长
description 字段(触发机制)
这是技能最重要的字段之一,它帮助 AI 理解何时应该使用该技能。一个优秀的 description 应该包含四个要素:
1. 功能描述:技能能做什么 简明扼要地说明技能的核心能力。
2. 使用场景:具体的应用场景 列出技能最常见的用途。
3. 触发条件:什么情况下应该激活 明确指出用户说出什么内容时会触发技能。
4. 边界说明(可选但推荐:什么情况下不应该使用 明确技能的局限性,避免误用。
示例(来自 feishu-doc 技能):
description: > Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.
更详细的多场景示例:
description: > Comprehensive document creation, editing, and analysis with support for tracked changes. Use when Codex needs to work with professional documents (.docx files) for: (1) Creating new documents from scratch or templates, (2) Modifying or editing existing content, (3) Reading and analyzing document structure, (4) Formatting and styling content. NOT suitable for: converting between document formats, working with password-protected files, or handling very large documents (>100MB).
3.2 Markdown Body 编写技巧
Markdown Body 是技能的详细使用说明书。一个结构良好的 Body 应该包含以下部分:
功能描述
清晰阐述技能的功能范围和能力边界。使用"适合/不适合"的对比格式能帮助用户和 AI 准确理解:
功能 - 读取和解析 JSON/CSV 数据文件 - 执行数据转换和清洗操作 - 生成结构化报告和可视化图表 - 支持批量处理多个文件 适用场景 ✅ 适合: - 数据导入前的格式验证和转换 - 批量数据处理任务 - 生成数据分析报告 - 定期数据备份和导出 ❌ 不适合: - 实时数据流处理 - 复杂的机器学习模型训练 - 需要数据库实时连接的操作 - 处理加密或受保护的文件
使用场景
列出具体的使用示例,帮助用户理解何时应该使用该技能:
使用场景 - 用户想要查询特定城市的天气情况 - 需要获取未来几天的天气预报 - 旅行前需要了解目的地的气候 - 用户需要穿衣指数或出行建议
触发条件
明确什么关键词或场景会触发技能:
触发条件 技能会在以下情况下被激活: 直接触发(提到这些关键词): - 天气、温度、气候、气温 - 预报、降雨概率、风速 - 具体城市或地区名称 间接触发(这些请求隐含需要天气信息): - "明天出门需要带伞吗?" - "周末去杭州玩,天气怎么样?" - "最近气温如何,适不适合跑步?"
使用限制
明确说明技能的边界和限制:
限制 - 不提供历史天气数据(只能查询当前和预报) - 不提供严重天气警报或应急通知 - 不提供专业气象分析或专家解读 - 无需 API 密钥,但有请求频率限制 - 部分地区可能没有详细数据
3.3 描述撰写**实践
以下是编写高质量技能描述的黄金法则,这些法则来自于大量成功技能的经验总结:
1. 具体胜于笼统 - 避免泛泛而谈,要具体说明功能 - 使用精确的术语而非模糊的描述 - 明确技能的具体能力范围
❌ 笼统示例:description: "A skill for handling documents." ✅ 具体示例:description: "Document creation and editing. Use when user wants to create, edit, or analyze Word documents (.docx files)."
2. 场景驱动 - 用具体场景说明触发条件 - 列出常见的用户请求形式 - 帮助 AI 准确识别激活时机
3. 边界清晰 - 明确"不适合"的情况同样重要 - 列出常见的误用场景 - 避免用户得到不符合预期的结果
4. 保持简洁 - description 不需要包含所有细节 - 详细信息放在 Body 部分 - 控制在 100-300 词之间
5. 示例丰富 - 提供真实的使用示例 - 展示典型的用户请求形式 - 帮助理解触发条件的实际应用
3.4 示例分析
让我们分析一个优秀的 SKILL.md 结构(参考 weather 技能):
--- name: weather description: Get current weather and forecasts via wttr.in or Open-Meteo. Use when: user asks about weather, temperature, or forecasts for any location. NOT for: historical weather data, severe weather alerts, or detailed meteorological analysis. No API key needed. --- # Weather Skill 功能 获取指定位置的当前天气和未来几天的天气预报,包括温度、湿度、降雨概率、风速等信息。 使用场景 - 查询某地当前温度和天气状况 - 获取未来 3-7 天的天气预报 - 了解降雨概率、风速、空气质量等详细信息 - 旅行前了解目的地的气候条件 触发条件 激活关键词: - 天气、温度、气候、气温 - 预报、降雨概率、空气质量 - 具体城市名称(隐式触发) 典型用户请求: - "北京今天天气怎么样?" - "上海后天有雨吗?" - "周末去杭州玩,适不适合穿裙子?" 限制说明 - ❌ 不提供历史天气数据 - ❌ 不提供严重天气警报 - ❌ 不提供专业气象分析 - ✅ 无需 API 密钥 - ✅ 支持全球大部分城市 输出格式 技能返回结构化的天气信息,包括: - 当前温度和体感温度 - 天气状况(晴/阴/雨等) - 湿度和风速 - 未来几天的预报 使用示例 示例 1 Q: 北京今天天气怎么样? A: [调用天气技能,返回北京当前天气数据] 示例 2 Q: 周末去深圳,需要带伞吗? A: [调用天气技能查询深圳周末预报,提示是否可能下雨]
这个结构清晰、边界明确、示例丰富,是一个非常好的参考模板。每个部分都有明确的目的,逻辑清晰,易于理解和维护。
4.1 核心工具概览
OpenClaw 为技能提供了丰富的工具集,涵盖文件操作、命令执行、网络通信、消息发送等场景。熟练掌握这些工具是技能开发的核心能力。
read 读取文件内容 查看代码、配置文件、分析日志
write 写入/创建文件 生成报告、创建文件、保存结果
edit 精确编辑文件 代码修改、配置更新、文本替换
exec 执行 shell 命令 运行脚本、系统操作、编译构建
process 管理后台进程 长时间任务、交互式 CLI、编码代理
browser 控制网页浏览器 自动化网页操作、网页游戏、动态内容
web_fetch 获取网页内容 抓取数据、提取信息、API 调用
message 发送消息 通知用户、群组消息、频道操作
tts 文本转语音 语音播报、有声内容、辅助功能
canvas 控制画布展示 图形展示、UI 呈现、图像处理
feishu_* 飞书平台操作 文档、云盘、知识库、智能表格
wecom_* 企业微信操作 文档、智能表格、消息发送
sessions_yield 结束当前回合 子任务完成后交还控制权给主代理
4.2 工具调用**实践
每个工具都有其特定的调用方式和注意事项,掌握这些细节能让你的技能更加健壮和高效。
Read 工具
Read 工具用于读取文件内容,支持文本文件和图片格式。
# 基本读取 read(path="/path/to/file.txt") # 读取大文件的特定部分(分块读取) read(path="/path/to/large_file.txt", offset=100, limit=50) # 读取图片文件 read(path="/path/to/image.png")
重要特性: - 支持文本文件(txt、md、py、js 等) - 支持图片文件(jpg、png、gif、webp) - 文本文件输出会截断至 2000 行或 50KB(以先达到者为准) - 处理大文件时,使用 offset/limit 参数分块读取 - 不需要完整文件时,指定精确的读取范围以节省资源
⚠️ 注意事项: - offset 是从第 1 行开始的 - limit 是最大行数,不是结束行 - 对于超大文件,可能需要多次调用
Write 工具
Write 工具用于创建或覆盖文件内容。
# 创建新文件 write(path="/output/report.txt", content="# 报告内容 这是报告正文...") # 自动创建父目录(如果不存在) write(path="/new/directory/file.txt", content="内容") # 写入二进制内容(如图片) write(path="/output/image.png", content="
")
重要特性: - 会自动创建父目录 - 会覆盖已存在的同名文件 - 适合生成报告、导出数据、创建文件等场景 - 支持大文件的写入
使用技巧: - 先检查文件是否存在(用 read) - 需要追加内容时,可以先 read 再 write - 大文件写入建议分批处理
Edit 工具
Edit 工具用于精确编辑文件内容,是"外科手术式"的修改工具。
# 精确替换 edit( path="/path/to/file.py", oldText="def old_function(): pass", newText="def new_function(): return True" ) # 替换配置值 edit( path="/path/to/config.json", oldText='"max_retries": 3', newText='"max_retries": 5' )
⚠️ 关键注意事项: - oldText 必须完全匹配目标文本,包括所有空白字符(空格、制表符、换行符) - 建议先使用 read 工具查看原文,确保精确匹配后再编辑 - 适合代码修改、配置调整等场景 - 不适合大段文本的替换(用 write 更合适) - 如果匹配失败,会返回错误
**实践: - 先读取文件查看实际内容 - 复制要修改的确切文本 - 使用最小的匹配范围 - 编辑后再次读取验证修改结果
Exec 工具
Exec 工具用于执行 shell 命令,是技能与系统交互的主要方式。
# 基本执行 exec(command="python3 script.py", timeout=30) # 后台执行(适合长时间任务) exec(command="python3 long_task.py", background=True) # PTY 模式(需要终端的交互式命令) exec(command="python3 -m pip install package", pty=True) # 指定工作目录和环境变量 exec( command="npm install", workdir="/project/directory", env={"NODE_ENV": "production"}, timeout=120 ) # 提升权限执行 exec(command="apt-get update", elevated=True)
参数说明:
command string 要执行的命令
workdir string 工作目录(默认当前目录)
env object 环境变量(dict 格式)
timeout number 超时时间(秒)
background boolean 是否后台执行
pty boolean 是否使用 PTY 模式
elevated boolean 是否使用提升权限
PTY 模式使用场景: - 运行需要终端交互的 CLI 工具(如 pip、npm 安装过程) - 调用编码代理(Codex、Pi、OpenCode)需要 PTY - 任何需要 TTY 的命令 - Claude Code 不需要 PTY 模式
后台执行: - 适合长时间运行的任务 - 可以通过 process 工具管理 - 可以随时获取输出或发送输入
process 工具
process 工具用于管理后台执行的进程。
# 查看运行中的进程列表 process(action="list") # 向进程发送输入 process(action="write", sessionId="session-123", data="输入内容 ") # 提交表单(模拟回车) process(action="submit", sessionId="session-123") # 获取进程输出 process(action="poll", sessionId="session-123", timeout=5000) # 终止进程 process(action="kill", sessionId="session-123")
web_fetch 工具
web_fetch 工具用于获取网页内容并进行提取。
# 获取网页内容(Markdown 格式) web_fetch( url="https://example.com/article", extractMode="markdown", maxChars=10000 ) # 获取纯文本内容 web_fetch( url="https://api.example.com/data", extractMode="text" )
message 工具
message 工具用于发送消息到各种平台。
# 发送消息到频道 message( action="send", target="#general", message="任务已完成!" ) # 发送私聊消息 message( action="send", target="@username", message="您的报告已生成" ) # 回复消息 message( action="send", target="#channel", replyTo="message-id", message="这是回复" )
4.3 工具组合使用示例
实际开发中,工具往往需要组合使用,形成完整的工作流程。以下是一个典型的数据处理流程:
# 场景:读取配置文件,处理数据,生成报告,发送通知 # 1. 读取配置文件 config_content = read(path="/workspace/config.json") print(f"已读取配置文件: {len(config_content)} 字符") # 2. 解析并处理数据(调用处理脚本) process_result = exec( command="python3 process.py --config /workspace/config.json", workdir="/workspace", timeout=60 ) print(f"处理完成,返回码: {process_result.return_code}") # 3. 读取处理结果 if process_result.return_code == 0: result_data = read(path="/workspace/output/result.json") # 4. 生成报告 report_content = exec( command="python3 generate_report.py --data /workspace/output/result.json" ) # 5. 保存报告 write( path="/workspace/reports/daily_report.md", content=report_content.stdout ) # 6. 发送通知 message( action="send", target="#data-team", message=f"✅ 每日报告已生成! 文件位置: /workspace/reports/daily_report.md 处理数据量: {len(result_data)} 条记录" ) else: # 处理失败,发送错误通知 message( action="send", target="#data-team", message=f"❌ 数据处理失败! 错误信息: {process_result.stderr}" )
这个例子展示了从读取配置、执行处理、写入结果到发送通知的完整流程。工具之间的配合需要有逻辑顺序,并做好错误处理。
5.1 常见错误类型
在技能开发过程中,你会遇到各种错误。了解这些错误类型是构建健壮技能的第一步。
文件操作错误
文件操作是最常见的错误来源之一:
- ENOENT:文件或目录不存在 Error: ENOENT: no such file or directory, open '/path/to/file.txt'
- EACCES:权限不足 Error: EACCES: permission denied, open '/protected/file.txt'
- EISDIR:试图对目录执行文件操作 Error: EISDIR: illegal operation on a directory, read at '/path/to/dir'
- ENOTDIR:路径组件不是目录 Error: ENOTDIR: not a directory component in '/file/is/not/dir/file.txt'
处理策略:
try: content = read(path="/path/to/file.txt") except Exception as e: if "ENOENT" in str(e): # 文件不存在,根据业务逻辑决定是创建还是报错 write(path="/path/to/file.txt", content="") content = "" elif "EACCES" in str(e): raise Exception("权限不足,请检查文件访问权限") else: raise
工具调用失败
工具调用可能因为多种原因失败:
- 网络请求超时:API 或远程服务响应过慢
- API 速率限制:请求频率超过限制(429 错误)
- 参数验证失败:传入的参数不符合要求
- 资源不可用:依赖的外部资源不存在
# 网络请求超时处理 try: result = web_fetch(url=api_endpoint, timeout=10) except Exception as e: if "timeout" in str(e).lower(): # 超时重试 result = web_fetch(url=api_endpoint, timeout=30) else: raise
API 限制与超时
使用外部 API 时常见的限制:
- 速率限制:单位时间内请求次数超限
- 并发限制:同时进行的请求数超限
- 配额限制:月度或年度使用配额用尽
- 认证问题:API 密钥过期或无效
5.2 错误处理模式
良好的错误处理能让技能更加可靠和用户友好。以下是经过验证的错误处理模式:
优雅降级策略
某些工具在特定情况下会优雅降级而不是抛出错误。例如,memory_get 在文件不存在时返回空字符串而非报错:
# 优雅降级示例 result = read(path="/workspace/today-log.txt") # 如果文件不存在,返回 { text: "", path: "/workspace/today-log.txt" } # 代理可以处理"尚未记录"的情况并继续工作 # 业务逻辑中的优雅降级 if result.text: # 文件存在,处理内容 data = parse_json(result.text) else: # 文件不存在,使用默认值 data = {"records": [], "created_at": "首次创建"}
优雅降级的原则: - 尽可能提供合理的默认值 - 让调用方能够区分"空"和"错误" - 记录降级行为以便调试
重试机制
对于临时性失败(如网络超时、服务暂时不可用),实现重试机制:
import time def retry_with_backoff(func, max_retries=3, initial_delay=1): """指数退避重试装饰器""" for attempt in range(max_retries): try: return func() except Exception as e: if attempt == max_retries - 1: raise # 最后一次尝试,抛出异常 delay = initial_delay * (2 attempt) # 指数退避 print(f"尝试 {attempt + 1} 失败,{delay}秒后重试: {e}") time.sleep(delay) # 使用示例 result = retry_with_backoff( lambda: web_fetch(url=api_endpoint), max_retries=3, initial_delay=2 )
重试策略要点: - 设置最大重试次数,避免无限循环 - 使用指数退避,避免频繁请求 - 区分可重试错误和不可重试错误 - 记录重试日志便于调试
兜底方案
当主要方案失败时,提供备选路径。这是 API 集成技能的关键:
# 兜底策略示例(来自 otaku-wiki 技能) def search_anime(keyword): """搜索动漫,支持多种兜底策略""" # 策略1:精确搜索 try: result = api_search(keyword, top=1) if result: return result except Exception as e: print(f"精确搜索失败: {e}") # 策略2:扩大搜索范围 try: result = api_search(keyword, top=5) if result: return result except Exception as e: print(f"扩大搜索失败: {e}") # 策略3:返回友好提示 return { "error": "NOT_FOUND", "message": f"未找到与 '{keyword}' 相关的内容", "suggestions": [ "尝试使用更通用的关键词", "检查拼写是否正确", "提供原始日文名称可能有助于搜索" ] }
关键原则: - 永远不要编造信息 - 当无法获取可靠数据时,明确告知用户 - 提供可行的替代方案或建议 - 记录失败原因以便后续改进
5.3 调试技巧
有效的调试技巧能帮助你快速定位和解决问题。
日志记录
在执行关键步骤时添加日志,帮助追踪问题:
# 技能中的日志模式 def process_data(input_file): print(f" 开始处理文件: {input_file}") # 读取文件 content = read(path=input_file) print(f"✅ 已读取文件,长度: {len(content.text)} 字符") # 处理数据 result = process(content) print(f" 处理完成,结果数量: {len(result)}") # 写入结果 output_file = input_file.replace('.csv', '_processed.csv') write(path=output_file, content=result) print(f" 已保存结果到: {output_file}") return output_file
日志级别建议: - DEBUG:详细的调试信息 - INFO:正常的流程信息 - WARNING:警告信息,但不影响执行 - ERROR:错误信息,需要关注
状态检查
在执行前后检查系统状态:
# 执行前检查依赖 def check_dependencies(): required_commands = ['python3', 'ffmpeg', 'curl'] missing = [] for cmd in required_commands: result = exec(command=f"which {cmd}") if result.return_code != 0: missing.append(cmd) if missing: raise Exception(f"缺少必需依赖: {', '.join(missing)}") return True # 执行后验证结果 def validate_result(result): if not result: raise Exception("处理结果为空") if isinstance(result, dict) and 'error' in result: raise Exception(f"处理返回错误: {result['error']}") return True
沙盒模式测试
使用沙盒环境进行安全测试,防止意外的 destructive 操作影响主机系统。
# gateway.yaml 开发环境配置 sandbox: mode: "non-main" # 仅沙盒非主会话 workspace: "rw" # 开发阶段需要读写权限 # gateway.yaml 生产环境配置 sandbox: mode: "all" # 所有会话都在沙盒中运行 workspace: "ro" # 生产环境建议只读
沙盒模式选项详解:
"off" 无沙盒(不推荐开发中使用,生产环境有特殊需求时)
"non-main" 仅沙盒非主会话(默认,适合开发)
"all" 所有会话都在沙盒中运行(适合测试)
工作空间访问控制:
"none" 工具看到 ~/.openclaw/sandboxes 下的沙盒工作空间
"ro" 只读方式挂载代理工作空间到 /agent(禁用 write/edit)
"rw" 读写方式挂载代理工作空间到 /workspace
6.1 本地测试方法
技能开发完成后,需要进行充分的测试确保功能正常。本地测试是开发流程中不可或缺的环节。
单元测试
针对 scripts/ 目录中的脚本进行单元测试:
# 运行 Python 脚本的单元测试 cd scripts/ python3 -m pytest test_*.py -v # 或使用标准 unittest python3 -m unittest discover -s tests -v # 运行特定测试文件 python3 -m pytest test_process.py -v --tb=short
单元测试**实践: - 为每个函数编写测试用例 - 测试正常流程和边界情况 - 使用 mock 模拟外部依赖 - 保持测试的独立性和可重复性
集成测试
测试技能与 OpenClaw 的集成:
# 在本地安装技能进行测试 openclaw skills install ./my-skill # 列出已安装的技能 openclaw skills list # 测试触发 # 向 OpenClaw 发送触发该技能的消息,观察响应 # 例如:发送 "北京天气怎么样"
集成测试要点: - 测试技能的触发机制是否正常 - 测试工具调用是否正确执行 - 测试错误处理是否有效 - 测试输出格式是否符合预期
手动测试场景
创建测试清单,逐项手动验证:
- ✅ 技能安装成功
- ✅ 技能在预期场景下被触发
- ✅ 技能在非预期场景下不被触发
- ✅ 基本功能正常工作
- ✅ 错误场景正确处理
- ✅ 输出格式符合规范
- ✅ 性能在可接受范围内
6.2 沙盒环境配置
沙盒环境是测试技能的安全空间。OpenClaw 提供了灵活的沙盒配置选项。
# 开发环境推荐配置 (gateway.yaml) sandbox: mode: "non-main" workspace: "rw" # 测试环境配置 sandbox: mode: "all" workspace: "ro" # 生产环境配置 sandbox: mode: "all" workspace: "ro" allowedPaths: - /workspace/projects - /tmp/reports deniedPaths: - /etc - ~/.ssh
不同环境的配置建议:
6.3 功能验证清单
完成技能开发后,使用以下清单进行验证:
6.4 性能优化建议
以下是技能性能优化的关键策略:
1. 减少 token 消耗 - 将详细文档放在 references/ 而非 SKILL.md - SKILL.md 保持精简 - 使用脚本执行复杂逻辑而不是在上下文中处理
2. 优化脚本执行 - 使用脚本而非在上下文中执行复杂逻辑 - 脚本直接返回结果,不返回中间过程 - 避免在脚本中打印大量调试信息
3. 缓存频繁访问的数据
# 简单的内存缓存示例 cache = {} def get_weather(city): if city in cache and time.time() - cache[city]['time'] < 3600: return cache[city]['data'] # 实际获取数据 data = fetch_weather(city) cache[city] = {'data': data, 'time': time.time()} return data
4. 按需加载 - 只加载当前任务需要的 references/ 文件 - 使用 grep 搜索模式而非加载整个文件 - 大文件使用 offset/limit 分块读取
5. 并行处理 - 对于独立的子任务,可以使用后台执行并行处理 - 使用 process 工具管理多个并发任务
7.1 技能打包流程
当技能开发完成并通过测试后,下一步是打包成可分发的格式。OpenClaw 提供了自动化的打包工具。
使用 package_skill.py
# 基本打包 scripts/package_skill.py # 指定输出目录 scripts/package_skill.py ./dist # 打包并显示详细信息 scripts/package_skill.py -v
打包过程详解
打包脚本会自动执行以下步骤:
1. 验证技能(自动检查): - YAML frontmatter 格式检查 - 必需字段(name, description)验证 - 技能命名规范检查 - 目录结构验证 - 描述完整性和质量评估 - 文件组织和资源引用检查
2. 创建 .skill 文件: - 验证通过后,创建 zip 格式的 .skill 文件 - 包含所有文件并保持正确的目录结构 - 自动生成文件清单
⚠️ 安全限制: - 如果技能目录中存在任何符号链接,打包会失败 - 不允许包含可执行权限的特殊文件 - 文件大小有一定限制
验证检查项
打包前的自检清单:
# 1. 检查 SKILL.md 格式 python3 -c "import yaml; yaml.safe_load(open('SKILL.md'))" # 2. 检查目录结构 ls -la # 确保没有 README.md、符号链接等不应包含的文件 # 3. 测试脚本可执行性 python3 scripts/*.py --help # 4. 检查文件命名 # 确保所有文件名符合规范
7.2 技能安装方式
技能有多种安装方式,满足不同的使用场景:
本地安装
# 从本地目录安装 openclaw skills install ./my-skill # 安装到指定位置 openclaw skills install ./my-skill --path ~/.openclaw/skills # 强制覆盖已存在的技能 openclaw skills install ./my-skill --force
安装位置:~/.openclaw/skills//SKILL.md
工作空间安装
在项目工作空间中创建 skills 目录:
my-project/ ├── README.md ├── src/ └── skills/ ├── skill-a/ │ └── SKILL.md └── skill-b/ └── SKILL.md
优先级规则:
工作空间 skills/ > 本地安装 ~/.openclaw/skills/ > bundled 技能 > extraDirs 配置
这意味着如果同一个技能在多个位置存在,会优先使用工作空间中的版本。
从 ClawHub 安装
# 搜索技能 openclaw skills search "weather" openclaw skills search "document" # 安装技能 openclaw skills install weather openclaw skills install feishu-doc # 查看技能详情 openclaw skills info weather # 更新所有技能 openclaw skills update --all # 更新特定技能 openclaw skills update weather
卸载技能
# 卸载技能 openclaw skills uninstall weather # 卸载并删除本地数据 openclaw skills uninstall weather --purge
7.3 版本管理与更新
技能版本管理建议遵循语义化版本号:
skill-name/ ├── SKILL.md ├── scripts/ ├── references/ └── assets/ └── CHANGELOG.md
语义化版本号规范: - 主版本号 (1.0.0):不兼容的 API 变更 - 次版本号 (1.1.0):向后兼容的新功能 - 补丁版本号 (1.1.1):向后兼容的问题修复
更新技能时: 1. 修改 SKILL.md 中的版本信息(可选) 2. 更新 CHANGELOG.md 3. 重新打包 .skill 文件 4. 更新 ClawHub 上的版本(如适用) 5. 通知用户更新
更新流程:
# 本地更新 openclaw skills update weather # 或重新安装 openclaw skills uninstall weather openclaw skills install ./updated-weather
7.4 技能命名规范
遵循统一的命名规范能让技能更容易被发现和使用:
feishu-doc 不能使用大写字母 仅数字
pdf-tools 可以在名称中使用数字 仅连字符
code-review 使用连字符分隔单词 保持简短
pdf-tools 避免过长的名称 动词开头
send-notification 描述动作而非状态 工具命名空间化
gh-address-comments 工具名 + 动作 + 目标 文件夹与技能名一致 技能
weather → 目录
weather/ 避免不一致
✅ 正确示例: - weather — 简单明了 - coding-agent — 领域 + 功能 - feishu-doc — 平台 + 功能 - gh-create-issue — 工具 + 动作 + 目标
❌ 错误示例: - MySkill — 包含大写字母 - skill with spaces — 包含空格 - very_long_skill_name_that_is_hard_to_read — 过长的名称
8.1 简单技能示例:天气查询
让我们从简单的技能开始,分析 weather 技能的结构和设计思路:
# SKILL.md (简化版) --- name: weather description: Get current weather and forecasts via wttr.in or Open-Meteo. Use when: user asks about weather, temperature, or forecasts for any location. NOT for: historical weather data, severe weather alerts, or detailed meteorological analysis. No API key needed. --- # Weather Skill 功能 - 获取全球城市的当前天气 - 查询未来几天的天气预报 - 无需 API 密钥,直接使用公共 API 使用场景 - "北京今天天气怎么样?" - "上海明天有雨吗?" - "周末去杭州玩,适不适合穿裙子?" - "东京的温度是多少?" 限制说明 - ❌ 不提供历史天气数据 - ❌ 不提供严重天气警报 - ❌ 不提供专业气象分析 - ✅ 支持全球大部分城市 - ✅ 无需 API 密钥 技术实现 技能直接调用以下公共 API: - wttr.in — 简洁的天气 API - Open-Meteo — 无需密钥的天气预报 API 返回格式化的天气信息卡片。
设计特点分析: - 触发条件清晰:明确列出关键词(天气、温度、预报) - 边界明确:清晰说明不适合的场景 - 无外部依赖:不需要 API 密钥,降低使用门槛 - 实现简单:直接调用公共 API,适合学习参考
8.2 复杂技能示例:编码代理
coding-agent 技能展示了复杂技能的设计模式:
--- name: coding-agent description: Delegate coding tasks to Codex, Claude Code, or Pi agents via background process. Use when: (1) building/creating new features or apps, (2) reviewing PRs (spawn in temp dir), (3) refactoring large codebases, (4) iterative coding that needs file exploration. NOT for: simple one-liner fixes, reading code (with read tool), thread-bound ACP harness requests, or any work in ~/clawd workspace. Claude Code: use --print --permission-mode bypassPermissions (no PTY). Codex/Pi/OpenCode: pty:true required. --- # Coding Agent Skill 功能 - 委托编码任务给 AI 代理(Codex、Claude Code、Pi) - 支持完整的项目构建和代码生成 - 后台进程管理,支持长时间运行 - PR 审查和代码重构 支持的代理 | 代理 | PTY 模式 | 适用场景 | |------|----------|----------| | Claude Code | ❌ 不需要 | 快速代码生成、简单修复 | | Codex | ✅ 需要 | 复杂项目、完整应用 | | Pi | ✅ 需要 | 探索性编码、迭代开发 | | OpenCode | ✅ 需要 | 新项目初始化 | 使用示例 创建新功能 用户:帮我创建一个 React 待办事项应用 技能:启动 Codex 代理,创建完整项目 代码审查 用户:审查这个 PR 的代码 技能:克隆代码,运行审查工具,返回建议 关键实现细节 1. PTY 管理:根据代理类型选择是否使用 PTY 2. 进程控制:使用 process 工具管理后台会话 3. 工作目录:在临时目录进行操作,避免污染主工作空间 4. 输出捕获:实时捕获代理输出并展示给用户
设计特点分析: - 多代理支持:支持多种编码代理,各有优缺点 - 详细的触发条件:明确列出适合和不适合的场景 - 表格化信息:清晰展示代理对比信息 - 边界说明:明确指出不在哪些场景使用
8.3 外部 API 集成示例:AniList
otaku-wiki 技能展示了如何优雅地集成外部 API:
--- name: otaku-wiki description: 番剧/角色百科问答:用 AniList API 快速查番、查角色、查声优与作品关联(无需数据库) --- # Otaku Wiki Skill 功能 - 通过 AniList API 查询动漫信息 - 查询角色资料和声优信息 - 查找作品与人物的关联 - 支持中文和日文名称搜索 API 集成 使用 AniList GraphQL API: - 无需 API 密钥 - 速率限制友好 - 数据格式统一 错误处理策略 技能实现了完善的失败处理: # 失败与兜底 - AniList 搜索不到:把 top 提到 5,再试 - 仍失败就提示用户换关键词/提供原文名/给 MAL 链接 - 不要编造信息;所有硬数据必须来自脚本 JSON 输出格式 技能返回结构化数据: { "id": 1, "title": { "romaji": "Cowboy Bebop", "english": "Cowboy Bebop", "native": "カウボーイビバップ" }, "format": "TV", "episodes": 26, "score": 8.75, "genres": ["Action", "Sci-Fi"] } 使用示例 查询动漫 Q: 查找《进击的巨人》 A: 返回动漫基本信息、评分、类型等 查询角色 Q: 利威尔兵长是谁? A: 返回角色信息、出场作品、声优
设计特点分析: - 清晰的错误处理:具体的兜底策略 - 数据来源明确:所有数据必须来自 API,不编造 - 结构化输出:返回格式化的 JSON 数据 - 多语言支持:支持中文和日文搜索
8.4 案例对比分析
从案例中学到的关键洞察:
1. 简单技能侧重边界清晰 - 明确说明能做什么和不能做什么 - 减少用户期望与实际结果的差距
2. 复杂技能需要详细流程说明 - 多步骤操作需要清晰的指引 - 使用表格和列表组织信息
3. API 集成必须有完善的兜底策略 - 网络请求可能失败 - 用户输入可能无法匹配 - 永远不要编造数据
9.1 技能开发关键要点回顾
本文涵盖了 OpenClaw 技能开发的完整流程。让我们回顾一下关键要点:
结构设计 - 遵循标准目录结构:SKILL.md 为核心,scripts/references/assets 按需使用 - 保持 SKILL.md 精简,渐进式披露设计 - 避免包含不应有的文件(README、CHANGELOG 等)
✍️ 描述编写 - description 是技能的灵魂,要具体、场景化、边界清晰 - 包含功能描述、使用场景、触发条件和边界说明 - 遵循命名规范(小写字母、数字、连字符)
工具使用 - 掌握 read/write/edit/exec/process 等核心工具的特性 - 注意各工具的注意事项(如 Edit 的精确匹配、Exec 的 PTY 模式) - 学会组合使用工具构建完整工作流程
⚠️ 错误处理 - 优雅降级:提供合理的默认值 - 重试机制:指数退避处理临时失败 - 兜底策略:永远不编造信息
離 测试验证 - 本地测试 + 沙盒环境 + 完整检查清单 - 开发环境使用 non-main 模式,生产环境使用 all 模式
打包部署 - 使用 package_skill.py 打包 - 遵循命名规范和目录结构 - 多种安装方式满足不同场景
9.2 常见问题解答
Q: 技能一定要包含 scripts/ 目录吗? A: 不一定。scripts/ 是可选的,只有当需要确定性执行或复杂逻辑时才需要。简单的技能可以只靠 SKILL.md 中的描述来完成。
Q: description 应该多长? A: 建议在 100-300 词之间,包含功能、场景和触发条件即可。详细信息放在 Body 部分。
Q: 如何处理外部 API 失败? A: 实现重试机制 + 兜底策略。参考 otaku-wiki 技能的策略:搜索失败时扩大范围,仍失败则提示用户换关键词。永远不要编造信息。
Q: 技能可以依赖外部 Python 包吗? A: 可以,但需要在文档中说明依赖。调用 exec 工具时,系统已经预装了一些常用包,如有特殊需求可以在描述中说明安装方法。
Q: 技能开发需要多长时间? A: 简单技能(天气查询类)可能只需要 1-2 小时。复杂技能(集成外部 API、需要脚本处理)可能需要数天。取决于功能复杂度和测试深度。
9.3 进一步学习资源
官方文档 - 主文档:https://docs.openclaw.ai - 技能概览:https://docs.openclaw.ai/skills/overview - 技能结构:https://docs.openclaw.ai/skills/structure - **实践:https://docs.openclaw.ai/skills/best-practices
GitHub - 主仓库:https://github.com/openclaw/openclaw - Issues:https://github.com/openclaw/openclaw/issues - PRs:https://github.com/openclaw/openclaw/pulls - Changelog:https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md
技能市场 - ClawHub:https://clawhub.com(浏览、搜索和安装技能)
社区支持 - GitHub Issues(报告问题和请求功能) - 社区论坛(参与讨论和分享经验)
9.4 技能生态展望
OpenClaw 技能生态正在快速发展。随着更多开发者的参与,我们可以期待:
更丰富的技能市场 - 涵盖各领域的专业技能将不断涌现 - 社区贡献的技能质量将持续提升 - 技能发现和推荐将更加智能化
️ 更完善的开发工具 - 可视化的技能构建器 - 一键测试和部署工具 - 技能性能分析和优化建议
烙 更智能的触发机制 - 基于语义理解的技能推荐 - 上下文感知的技能建议 - 跨技能的工作流编排
更活跃的社区 - 更多开发者参与贡献 - 技能开发**实践的沉淀 - 新手友好的入门教程和模板
现在,你已经掌握了技能开发的全流程。 开始构建你的第一个技能吧!
无论是从简单的天气查询开始,还是挑战复杂的 API 集成,动手实践是最好的学习方式。也许你的技能会成为 ClawHub 上最受欢迎的技能之一,为整个社区带来价值。
常用命令
# 初始化技能 scripts/init_skill.py
--path
scripts/init_skill.py my-skill --path ./skills --resources scripts,references # 打包技能 scripts/package_skill.py
[output-dir] # 安装技能 openclaw skills install
openclaw skills install ./my-skill # 搜索技能 openclaw skills search
# 更新技能 openclaw skills update --all # 卸载技能 openclaw skills uninstall
目录结构速查
skill/ ├── SKILL.md # 必需:技能定义 ├── scripts/ # 可选:可执行脚本 ├── references/ # 可选:参考文档 └── assets/ # 可选:输出资源
YAML Frontmatter 模板
--- name: your-skill-name description: > 技能功能描述。使用场景:... 触发条件:... 不适合:... ---
工具对比速查
性能优化进阶
除了第六章提到的性能优化建议,这里补充一些进阶技巧:
1. 批量操作优化 当需要处理多个文件或执行多个操作时,优先使用批量方式:
# 不推荐:逐个处理 for file in files: process_single(file) # 推荐:批量处理 process_all(files) # 在脚本中实现批量逻辑
2. 增量处理策略 对于大数据集,采用增量处理方式避免内存溢出:
# 分块读取大文件 chunk_size = 10000 for offset in range(0, total_lines, chunk_size): chunk = read(path=file, offset=offset, limit=chunk_size) process_chunk(chunk)
3. 并行执行 使用后台执行实现任务的并行处理:
# 同时启动多个独立任务 exec(command="python3 task1.py", background=True) exec(command="python3 task2.py", background=True) exec(command="python3 task3.py", background=True) # 等待所有任务完成 # 使用 process 工具监控各任务状态
安全**实践
1. 敏感信息处理 - 避免在代码中硬编码敏感信息 - 使用环境变量或配置文件 - 清理日志中的敏感数据
2. 输入验证 - 验证用户输入的格式和范围 - 防止注入攻击 - 限制文件操作的范围
3. 沙盒限制 - 生产环境使用只读工作空间 - 限制可访问的路径 - 监控异常行为
可维护性建议
1. 代码组织 - 保持脚本函数单一职责 - 使用有意义的函数和变量命名 - 添加适当的注释说明
2. 配置外置 - 将可配置项提取到配置文件中 - 便于不修改代码的情况下调整行为
3. 版本控制 - 使用 Git 管理技能代码 - 编写有意义的提交信息 - 使用分支管理功能开发
用户体验优化
1. 清晰的输出 - 使用结构化格式输出结果 - 添加适当的 emoji 和格式化 - 提供可操作的建议
2. 进度反馈 - 长时间运行的任务提供进度反馈 - 使用日志输出中间状态
3. 错误提示 - 提供友好的错误信息 - 指导用户如何解决问题
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/248338.html