← 返回教程列表

编写 OpenClaw 技能 —— 助手可以调用的可复用工具

如何编写、测试和发布 OpenClaw 技能:类型化工具调用、Shell 命令、HTTP API,以及 agent-skills 注册中心。

OpenClaw 中的技能(skill) 是助手可以调用的小型、类型化工具。技能是从"聊天玩具"走向"真正能做事的 Agent"的关键——它能拉取日历事件、提交 PR、发消息、执行脚本。本教程带你从零编写、测试、发布自己的技能。

技能长什么样

一个技能就是一个包含两个文件的文件夹:

my-skill/
├── skill.yaml        # 名称、说明、参数定义
└── handler.ts        # 被调用时执行的 TypeScript

sheet.yaml 是契约——LLM 通过它决定何时调用你的技能;handler.ts 是实现。

一个最小可用的技能

创建文件夹:

mkdir -p ~/.openclaw/skills/greet
cd ~/.openclaw/skills/greet

写 skill.yaml:

name: greet
description: |
  用指定语言向一个人打招呼。
  用于用户希望发送简短问候的场景
  (例如"用德语跟 Anna 打个招呼")。
parameters:
  type: object
  required: [name, language]
  properties:
    name:
      type: string
      description: 对方的名字
    language:
      type: string
      enum: [en, de, zh, ja]

写 handler.ts:

import type { SkillContext } from "openclaw/sdk";

const greetings: Record = {
  en: "Hello, {name}!",
  de: "Hallo, {name}!",
  zh: "{name},你好!",
  ja: "こんにちは、{name}さん!",
};

export default async function greet(
  input: { name: string; language: string },
  ctx: SkillContext
) {
  const template = greetings[input.language] ?? greetings.en;
  const message = template.replace("{name}", input.name);
  ctx.log.info(`greet → ${message}`);
  return { message };
}

重新加载 Gateway 以便它发现新技能:

openclaw skills reload greet

现在对助手发消息:

用德语跟 Anna 打个招呼

助手会调用你写的 greet 技能,回复 Hallo, Anna!。

调用 HTTP API

技能非常适合包装第三方 API。下面是一个查询天气的技能:

name: weather
description: |
  查询指定城市的当前天气。用于用户问
  "X 城市天气怎么样"之类的场景。
parameters:
  type: object
  required: [city]
  properties:
    city: { type: string }
export default async function weather(
  { city }: { city: string },
  ctx: SkillContext
) {
  const url = `https://wttr.in/${encodeURIComponent(city)}?format=j1`;
  const res = await fetch(url);
  if (!res.ok) {
    throw new Error(`weather: ${res.status} ${res.statusText}`);
  }
  const data = await res.json();
  const cur = data.current_condition[0];
  return {
    city,
    temperature_c: Number(cur.temp_C),
    feels_like_c: Number(cur.FeelsLikeC),
    description: cur.weatherDesc[0].value,
  };
}

Gateway 会自动重试瞬时错误、把类型化异常暴露给 LLM,并把返回值纳入回复上下文。

调用 Shell 命令

需要触碰本地文件系统或运行某个二进制的技能,可以使用沙箱化的 shell:

import { sh } from "openclaw/shell";

export default async function listDownloads(_: unknown, ctx: SkillContext) {
  const out = await sh("ls -lh ~/Downloads", { cwd: process.env.HOME });
  return { files: out.stdout };
}

shell 在文件系统沙箱中运行。默认能读取 ~/Documents、~/Downloads、~/Desktop、~/.openclaw。要访问其他路径,必须显式授权:

const out = await sh("git status", { cwd: "~/Code/myapp", allow: ["~/Code/myapp"] });

如果助手试图读取允许列表之外的路径,调用会以清晰的错误失败,而不是默默泄露数据。

与团队共享技能

OpenClaw 自带一个 agent-skills 仓库(github.com/openclaw/agent-skills),里面是经过整理的"标准技能"。如果你写的技能对其他人也有用,发布流程是:

openclaw skills publish greet

该命令会:

  1. 把文件夹打包成 tarball;
  2. 计算内容哈希;
  3. 推送到 ClawHub(社区技能注册中心 clawhub.ai);
  4. 返回一个可以在聊天里粘贴的永久 URL:
   https://clawhub.ai/skills/greet@1.0.2

安装别人的技能:

openclaw skills install https://clawhub.ai/skills/weather@1.4.0
技能以你的用户权限运行。安装前请阅读源码。ClawHub 上的每个技能都会标注来自 clawscanner.app 的 ClawScan 安全评分,安装前请先看一眼。

用 Lobster 组合技能

Lobster 是 OpenClaw 原生的工作流 shell,能把技能和 CLI 工具组合成类型化的、本地优先的流水线。下面是一个简单的 Lobster 配方,把多个技能串成一个"早间简报":

# ~/.openclaw/lobster/morning-briefing.yaml
name: morning-briefing
steps:
  - skill: weather
    args: { city: "Vienna" }
  - skill: calendar.today
  - skill: inbox.unread
    args: { limit: 5 }

按定时任务运行:

openclaw cron add \\
  --name "morning briefing" \\
  --at "0 7 * * *" \\
  --lobster ~/.openclaw/lobster/morning-briefing.yaml

每天早上 7 点,助手会拉取天气、日程、未读邮件,再发一条 Telegram 消息给你汇总。

测试技能

SDK 自带一个轻量测试框架:

import greet from "./handler";
import { test } from "openclaw/test";

test("greet 返回德语模板", async ({ run }) => {
  const out = await run(greet, { name: "Anna", language: "de" });
  expect(out.message).toBe("Hallo, Anna!");
});
openclaw skills test greet

下一步

OpenClaw 指南编辑部
独立维护的 OpenClaw 教程与生态解读。

发现问题或需要更正? 联系我们.