☰
第16课:OpenClaw|开发你的第一个自定义Skill,从 ISkill 到 TypeScript 落地
2026/10/2 20:11:50 网站建设 项目流程

1. 为什么你的 OpenClaw 需要一个自定义 Skill

OpenClaw 自定义 Skill 是什么?简单说,它是让 OpenClaw 从“通用助手”变成“你的专属数字员工”的那把钥匙。官方 Skills 能帮你整理文件、操控浏览器、发邮件,但当你需要对接公司内部 CRM、拉取行业报表、同步个人理财数据时,官方技能就力不从心了。自定义 Skill 就是为解决这类个性化场景而生的——它本质上是一个遵循固定规范的 TypeScript/JavaScript 模块,接收 OpenClaw 内核传来的标准化指令,执行具体操作,返回标准化结果。

它适合谁?只要你懂基础 JavaScript 或 TypeScript,就能在一小时内开发出第一个可运行的 Skill。OpenClaw v2026.4.20+ 版本以来,技能开发体系已经高度规范化,既有零代码的声明式 Skill(仅需 SKILL.md),也有原生代码 Skill(TypeScript/JavaScript),你可以根据需求和能力水平选择路径。

我试过从零手写一个 Skill,踩过的第一个坑就是目录放错位置——Skill 必须放在~/.openclaw/workspace/skills/或~/.openclaw/skills/下,否则openclaw skills list根本找不到。第二个坑是 SKILL.md 的 frontmatter 格式,---分隔符必须首尾对齐,name和description是必需字段,少一个技能就不会被加载。

这节课的完整链路是:环境准备 → 项目结构 → TypeScript 模板 → ISkill 接口详解 → 参数校验 → 本地测试调试 → 实战货币汇率转换技能。读完你就能独立开发、测试、调试 OpenClaw 自定义技能。开发环境极度轻量:Node.js 18+(推荐 22+)、任意代码编辑器、一个已部署运行的 OpenClaw 实例,就够了。

在动手之前,先理解 Skill 的定位:它不参与意图解析(用户说的话由内核转成结构化指令),不管理权限(文件访问、网络请求的权限由内核统一校验),专注单一能力(一个 Skill 只做一件事)。这种隔离设计保证了即使技能包含错误逻辑,也不会直接损坏主系统。

2. TaoToken 统一 Key 配置:让 Skill 调用大模型不再到处找 Key

开发自定义 Skill 时,一个绕不开的问题是大模型调用。你的 Skill 可能需要调用 LLM 做意图补全、结果润色或复杂推理,这时候就需要一个统一的 API Key 管理方案。TaoToken 提供的就是这样一个入口——通过一个 Key 访问多种主流模型,省去在多个平台之间切换的麻烦。

TaoToken 是什么?它是一个大模型 API 聚合服务,官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 。你可以把它理解为一个统一的模型网关:申请一个 Key,就能在代码里调用不同厂商的模型,不用为每个模型单独注册账号、单独管理密钥。对于 Skill 开发来说,这意味着你的manifest.json里只需要声明一个环境变量,而不是五六个。

适合谁?如果你正在开发需要 LLM 能力的 OpenClaw Skill,或者你的 Skill 需要根据任务类型切换不同模型(比如简单分类用轻量模型、复杂推理用旗舰模型),TaoToken 的统一 Key 方案能显著降低配置复杂度。

接入方式很简单。首先在 TaoToken 控制台创建一个 API Key,然后把它配置到环境变量里。OpenClaw Skill 的manifest.json中通过env字段声明所需的环境变量,内核会在加载技能时自动注入。具体来说,你的 Skill 目录下需要一个manifest.json:

{ "name": "my-llm-skill", "version": "1.0.0", "permissions": ["network:read"], "env": { "TAOTOKEN_API_KEY": { "description": "TaoToken API Key,用于调用大模型", "required": true } } }

然后在 Skill 的 TypeScript 代码中,通过context.env读取这个 Key:

const apiKey = context.env.TAOTOKEN_API_KEY; if (!apiKey) { throw new Error("缺少 TAOTOKEN_API_KEY,请在 OpenClaw 配置中设置"); }

Base URL 统一使用https://taotoken.net/api,模型 ID 根据你的需求选择。比如调用对话模型时,请求体里指定model字段即可。这样你的 Skill 就具备了 LLM 能力,而 Key 的管理完全交给 OpenClaw 的环境变量机制,代码里不出现硬编码密钥。

需要提醒的是,manifest.json中的permissions要遵循最小化原则。如果你的 Skill 只需要调用 LLM API,声明network:read就够了,不要申请fs:write等无关权限。权限申请过多不仅过重,还会在 ClawHub 发布时触发安全扫描告警。

如果你还没有 TaoToken 账号,可以先到官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 了解一下。API Key 的创建入口在控制台的 API Keys 页面,创建后记得复制保存,页面关闭后就不再显示完整 Key 了。

3. 可复制配置:ISkill 接口实现与项目结构

这一节给出完整的可复制配置。先看标准项目结构,一个原生代码 Skill 的目录长这样:

my-custom-skill/ ├── SKILL.md # 技能元数据和 AI 调用说明(永远必需) ├── manifest.json # 权限声明和配置定义(v2026.4+ 推荐) ├── package.json # Node.js 依赖配置 ├── tsconfig.json # TypeScript 严格模式配置 ├── index.ts # 核心逻辑入口 ├── src/ │ ├── tools.ts # 工具定义 │ └── types.ts # 类型定义 ├── tests/ │ └── unit.test.ts # 单元测试 └── README.md # 用户文档

对于最简单的声明式 Skill,唯一必需文件只有SKILL.md。你可以从纯描述式技能开始,随着需求增长逐渐添加代码逻辑。

接下来是 ISkill 接口的实现模板。OpenClaw 的 Skill 核心是导出一个符合SkillDefinition接口的对象:

import { SkillDefinition } from '@openclaw/skills-core'; const mySkill: SkillDefinition = { id: "my-custom-skill", name: "我的自定义技能", description: "一句话描述技能功能", version: "1.0.0", parameters: { type: "object", properties: { query: { type: "string", description: "用户查询内容" }, limit: { type: "number", default: 10 } }, required: ["query"] }, execute: async (args, context) => { const { query, limit } = args; context.logger.info("技能执行开始", { query, limit }); try { const result = await doSomething(query, limit); return { success: true, data: result }; } catch (error) { context.logger.error("技能执行失败", { error: error.message }); return { success: false, error: error.message }; } }, init: async (context) => { context.logger.info("技能已加载"); }, cleanup: async (context) => { context.logger.info("技能已卸载"); } }; export default mySkill;

SkillDefinition的核心组件包括:id(唯一标识)、name(显示名称)、description(触发描述,直接影响 AI 能否正确匹配用户意图)、parameters(输入参数 schema)、execute(核心执行函数),以及可选的init和cleanup生命周期钩子。

参数校验推荐使用 ArkType,它比传统 JSON Schema 更简洁,且完全兼容 TypeScript 类型推断:

import { type } from '@arktype/arktype'; const inputSchema = type({ from: 'string', to: 'string', amount: 'number' });

在manifest.json中声明权限和环境变量时,注意路径和字段名要与 OpenClaw 规范一致。permissions数组支持network:read、fs:read、fs:write等值,按需声明。env字段用于声明技能运行所需的环境变量,OpenClaw 内核会在加载时检查并注入。

如果你使用脚手架工具openclaw-skill-boilerplate,一条命令就能生成包含上述所有文件的完整项目:

npx openclaw-skill-boilerplate my-awesome-skill cd my-awesome-skill npm install npm run build

脚手架会自动生成格式正确的 SKILL.md、TypeScript 严格模式配置、工具定义模式,以及 ClawHub 发布就绪的项目结构。原本需要 30 多分钟的初始化工作,压缩到 30 秒内完成。

4. 验证请求:从命令行到 AI 交互的完整测试

配置写完了,怎么确认 Skill 真的能跑通?OpenClaw 提供了从命令行基础调用到 Gateway 会话模拟的多级测试工具链。下面按反馈速度从快到慢排列,你可以根据调试阶段选择。

第一层是命令行直接测试,最快反馈。在技能源码仓库根目录下运行:

openclaw skills run my-skill --params '{"query":"test","limit":5}'

这条命令不依赖 Gateway 会话,直接调用技能的execute函数,适合验证核心逻辑。如果返回{ success: true, data: ... },说明技能逻辑本身没问题。

第二层是 AI 指令交互触发,端到端测试。在聊天工具或 WebUI 中发送自然语言消息,观察 Agent 是否能正确识别并调用你的技能:

帮我用 currency-convert 技能把 100 美元转成人民币

如果技能已被正确加载并注册到 user-invocable 列表,AI 会自动将自然语言请求解析为技能调用。这一步验证的是 SKILL.md 中description字段的触发描述是否足够明确。

第三层是开发者模式热重载,节省调试时间。启动时附加环境变量开启 DEV 模式:

OPENCLAW_DEV_MODE=true npm run start

修改任何已注册技能文件并保存后,控制台会输出[HOTRELOAD] skill-name reloaded,技能逻辑立即生效,无需反复重启 Gateway。

第四层是调试日志输出。使用context.logger输出结构化日志,而不是随意的console.log:

context.logger.info("技能执行开始", { from, to, amount }); try { const result = await doSomething(); context.logger.debug("API 响应", { status: result.status }); return { success: true, data: result }; } catch (error) { context.logger.error("技能执行失败", { error: error.message }); return { success: false, error: error.message }; }

查看日志:

openclaw logs --follow | grep "my-skill"

第五层是异常路径与边界条件测试。必须覆盖的场景包括:参数缺失(不传 amount 时返回明确错误)、参数类型错误(传字符串而非数字)、网络超时(按指数退避重试)、API 凭证失效(捕获 401/403 并提示更新 Key)、限流触发(队列等待或返回限流错误)、数据格式异常(解析失败时优雅降级)。

常用 CLI 调试命令速查:

openclaw skills list # 列出所有已安装技能 openclaw skills info my-skill # 查看指定技能详细信息 openclaw skill validate my-skill # 校验技能语法和格式 openclaw skills reload # 强制重载技能 openclaw skills run my-skill --params '{"from":"USD","to":"CNY","amount":100}'

成功结果预期是这样的 JSON 结构:

{ "success": true, "data": { "original": 100, "converted": 720.50, "rate": 7.2050, "from": "USD", "to": "CNY", "timestamp": "2026-05-05T12:34:56.789Z" }, "summary": "100 USD = 720.50 CNY (汇率: 7.2050)" }

如果openclaw skills list输出中包含你的技能且状态为enabled,说明技能已被正确识别。如果状态是error或技能根本不出现,进入下一节的排障环节。

5. 本篇常见错排查:401、local proxy failed 与 reading choices

开发自定义 Skill 时,报错信息往往不够直观。这一节对照真实报错,给出排查路径。

401 Unauthorized:这是最常见的错误,通常出现在 Skill 调用 LLM API 或外部服务时。排查顺序:先确认manifest.json中声明的环境变量是否已在 OpenClaw 配置中设置;再检查 Key 是否过期或被撤销;最后确认请求头中的Authorization格式是否正确(通常是Bearer <key>)。如果使用 TaoToken,Base URL 应为https://taotoken.net/api,不要多加路径后缀。

local proxy failed:这个报错通常与网络请求有关。OpenClaw 的 Skill 运行在隔离沙箱中,网络请求通过内核代理转发。如果代理配置缺失或目标地址不可达,就会报这个错。排查时先确认manifest.json中是否声明了network:read权限;再检查目标 API 地址是否可达(可以在宿主机上用curl测试);最后确认 OpenClaw 的网络代理配置是否正确。

reading choices:这个报错出现在解析 LLM 响应时。OpenAI 兼容接口的响应结构中,choices数组包含模型输出。如果代码直接读取response.choices[0].message.content但响应格式不符合预期(比如返回了错误对象),就会报Cannot read properties of undefined (reading 'choices')。排查时先打印完整响应体,确认choices字段是否存在;再检查 API 返回的error字段,很多时候是上游返回了错误但代码没有先判断。

OAuth token expired:如果 Skill 集成了需要 OAuth 认证的第三方服务,token 过期后会报这个错。排查时检查 token 刷新逻辑是否实现,以及刷新失败时的降级策略。

技能不加载:openclaw skills list找不到你的技能。可能原因:SKILL.md 的 YAML frontmatter 格式错误(---分隔符未首尾对齐,或缺少name/description字段);技能目录未放在~/.openclaw/workspace/skills/或~/.openclaw/skills/中;manifest.json的 JSON 格式有语法错误。

技能无法触发:技能已加载但 AI 不调用。检查 SKILL.md 的description字段是否足够明确地关联了用户意图。描述太泛(如“处理数据”)会导致匹配失败,应该写成“当用户询问货币汇率、货币转换时使用”。

工具调用失败:缺少必需的 API Key 或环境变量。检查manifest.json中的env字段是否已在环境中配置,或技能配置中是否添加了env字段。

编译错误:TypeScript 版本或配置问题。确认tsconfig.json的target设置为ES2022及以上,module为NodeNext。

热重载不生效:DEV 模式未开启。启动时添加OPENCLAW_DEV_MODE=true环境变量。

如果技能无法加载或频繁崩溃,善用这条快速诊断命令链:

openclaw doctor # 诊断 OpenClaw 整体健康 openclaw skills check my-skill # 仅校验某个技能的 SKILL.md 格式 openclaw skills info my-skill # 显示技能的元数据和触发条件

这三条命令能在一个会话里扫清 90% 的配置问题。另外,发布到 ClawHub 前务必运行clawhub publish之前的安全扫描,确保没有硬编码密钥和 Token 泄露。

6. 从第一个 Skill 到 Coding Plan:持续迭代的路径

跑通第一个自定义 Skill 之后,你可能会想:接下来怎么走?我的建议是先把这个 Skill 打磨到生产级,再考虑扩展。

打磨的方向包括:参数校验是否覆盖了所有边界条件;错误处理是否返回了有意义的错误信息;日志是否记录了关键执行节点但避开了敏感信息;缓存策略是否合理(比如汇率数据缓存 1 小时,避免频繁调用 API);是否有单元测试覆盖异常路径。

当你需要开发更复杂的 Skill,比如涉及多步推理、代码生成或 Agent 编排时,可以考虑使用 Coding Plan。它适合长期编码和 Agent 场景,提供更稳定的模型调用配额和更低的延迟。具体来说,如果你的 Skill 需要频繁调用 LLM 做代码分析、生成或重构,Coding Plan 的性价比会比按量付费更高。

对于需要验证模型效果的场景,可以先用模型对话功能测试不同模型在你任务上的表现,确定最优模型后再写入 Skill 配置。模型对话入口在 TaoToken 控制台,支持多模型对比。

接入文档在 https://taotoken.net/api 页面有详细的接口说明和示例代码。API Keys 管理在控制台的 API Keys 页面,建议为不同的 Skill 创建独立的 Key,便于追踪调用量和排查问题。

最后分享一个实用技巧:在 Skill 的execute函数入口处记录开始时间,在返回前记录结束时间,把耗时写入日志。这样当用户反馈“技能响应慢”时,你能快速定位是网络请求慢、模型推理慢还是本地计算慢。这个习惯在调试复杂 Skill 时特别有用。

如果你在开发过程中遇到本文未覆盖的报错,可以先运行openclaw doctor和openclaw skills check,大部分配置问题都能被这两个命令捕获。剩下的逻辑问题,就靠context.logger输出的结构化日志来定位了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询