返回实战列表
进阶 22 分钟阅读

构建自定义 Skills

学习如何把高频能力从提示词中抽离出来,整理成更容易维护、测试和复用的自定义 skill。

C
ClawList Team
· 发布于 2025-03-05 · 更新于 2026-03-24

什么时候你应该开始做自定义 Skill?

如果你发现某类能力在多个任务中不断重复出现,就说明它已经不该继续藏在 prompt 里了。

典型信号包括:

  • 你反复复制同一段操作说明
  • 某个外部 API 每次都要重新解释入参和返回值
  • 同一个任务流程经常出现,但输出质量不稳定
  • 你希望把某种能力交给多个 Agent 复用

这时,把它整理成 skill 的收益通常会比继续堆 prompt 更高。

这篇文章要解决什么问题?

很多团队知道“要做 skill”,但不知道应该怎么拆:

  • 什么算一个 skill?
  • skill 和 tool 有什么区别?
  • skill 应该写到什么粒度?
  • 什么时候应该拆成多个 skill?

本文的目标不是给你一个“官方固定模板”,而是给你一套更稳的判断方法,让你能把 skill 做得可维护、可测试、可复用。

前置准备

开始前,建议你已经具备:

  • 一个可运行的单 Agent 项目
  • 对 prompts / tools / memory 的基本理解
  • 至少一个真实任务场景,而不是空想的 demo
  • 一个明确的外部能力来源(本地脚本、HTTP API、数据库、检索系统等)

如果这些基础还没准备好,建议先读 OpenClaw 快速入门指南

Skill、Tool、Workflow 到底怎么区分?

这是最容易混淆的地方。

Tool:最小可调用能力

Tool 更像一个可执行动作,例如:

  • 读取文件
  • 调用天气 API
  • 创建 issue
  • 查询数据库

它关注的是“做一件事”。

Skill:围绕某类任务的可复用能力封装

Skill 不只是工具清单,它还包含:

  • 什么时候使用
  • 输入输出应该长什么样
  • 任务中的决策约定
  • 对多个 tool 的组合方式

它关注的是“在某类任务里,怎样稳定地把事情做成”。

Workflow:多个 skill / tool / agent 的组织方式

Workflow 是更高层的编排,例如:

  • 先检索资料
  • 再写草稿
  • 再审核与修订

它关注的是“整体流程如何协作”。

一个更稳妥的 skill 设计流程

第一步:先用真实任务倒推

不要先问“我要写什么 skill”,先问:

  • 用户最常见的任务是什么?
  • 哪个步骤最容易出错?
  • 哪个能力最值得复用?

例如你在做一个代码助手时,可能真正值得抽出来的不是“coding-skill”,而是:

  • PR review
  • changelog 生成
  • 测试失败诊断
  • 文档差异总结

第二步:定义 skill 的边界

一个 skill 太大,会变成迷你框架;太小,又只是散落的工具函数。

更实用的判断方式是:

  • 一个 skill 应该围绕一个相对稳定的任务目标
  • 使用时机要清楚
  • 输入输出预期要清楚
  • 即使内部有多个 tool,外部也应被理解为一类能力

第三步:明确“何时触发”

高质量 skill 的关键不是“它能做什么”,而是“Agent 什么时候该想到它”。

所以你至少要写清:

  • 典型触发词
  • 适用任务
  • 不适用场景
  • 必要输入

一个示意性的 skill 目录

下面这个目录只是一个示意结构,用来说明常见组织方式,不代表 OpenClaw 官方要求必须如此。

my-skill/
├── SKILL.md
├── tools.ts
├── prompts.ts
├── examples/
└── tests/

你可以按你的项目技术栈调整,但建议至少保留这几类信息:

  • skill 说明文档
  • 工具入口
  • 示例输入输出
  • 验证或测试手段

如何写一份更有用的 SKILL.md?

一份有用的 SKILL.md 不该只是“这个 skill 用于……”一句空话,而应该回答:

  • 这个 skill 解决什么问题
  • 什么时候调用
  • 需要哪些输入
  • 会产生什么结果
  • 失败时如何处理

下面是一个更合理的示意 frontmatter:

---
name: weather-skill
description: Retrieve weather context for location-based tasks
---

## When to use

Use this skill when the task depends on current weather conditions.

## Required input

- city name
- optional temperature unit

## Expected output

- current condition
- temperature
- humidity
- wind summary

一个天气 skill 的设计示例

下面的代码是示意实现,目的是说明 skill 的典型职责分层,而不是承诺某个 OpenClaw SDK 中存在完全一致的 defineSkill 接口。

export default {
  name: 'weather-skill',
  description: 'Retrieve weather context for a city',
  whenToUse: [
    'The user asks about current weather',
    'The task depends on temperature or rain conditions',
  ],
  tools: ['get_weather'],
};

对应的工具层则应负责:

  • 参数校验
  • 调用外部 API
  • 统一输出格式
  • 清晰暴露错误

Skill 设计时最容易犯的 4 个错误

1. 用 skill 包装所有东西

不是所有功能都值得变成 skill。一次性逻辑、低复用逻辑、纯粹的项目内私有脚本,不一定要提升到 skill 层。

2. skill 描述不写“不要在什么情况下用”

没有边界的 skill 会让 Agent 乱触发。高质量 skill 应该写清楚不适用场景。

3. 只有 happy path,没有失败策略

如果 skill 调用 API 失败、限流、返回空结果,Agent 应该怎么降级?这通常比“成功时怎么返回”更重要。

4. 没有验证方式

如果你写完 skill 后无法判断它有没有变好,那它很难长期维护。

建议的最小验证清单

每个新增 skill 至少回答这些问题:

  • [ ] 触发条件是否明确?
  • [ ] 输入输出是否结构化?
  • [ ] 外部依赖失败时是否有降级策略?
  • [ ] 文档是否能让另一个开发者接手?
  • [ ] 是否有最小测试或示例?

什么时候拆分 skill?

如果你开始遇到这些信号,可以考虑拆分:

  • 一个 skill 同时覆盖了两个完全不同的任务目标
  • 文档越来越长,但触发条件越来越模糊
  • Agent 经常调用错分支能力
  • 一个小改动就影响很多不相关场景

通常来说,“按任务目标拆分”比“按技术实现拆分”更稳定。

下一步读什么?