---
title: Skills
description: Skills 的使用技巧
---

import { Aside, FileTree } from '@astrojs/starlight/components';
import { Code } from 'starlight-theme-nova/components'
import exampleSkill from '@/assets/example-skill.md?raw';

Skills 可以为大语言模型提供更多的模块化「技能」——包括但不限于工具用法、工作流程、最佳实践、指导原则等。
与 Prompt 相比，Skills 可以精炼、整合、持久化「技能」，并在需要时按需加载，无需每次都提供完整的指示。

ESP-Claw 支持使用 Skills 机制动态管理上下文，同时扩展 Agent 的能力。特别地，ESP-Claw 可以通过 Skills 调用硬件设备，实现硬件控制。

## 手动增删和修改 Skills

Skills 存放在文件系统中，默认路径为 `/fatfs/skills`。你可以通过 Web 配置页的文件系统管理功能增删 Skills。

<FileTree>
- fatfs
  - skills
    - cap_im_qq
      - **SKILL.md** QQ IM 能力用法的 Skill
    - cap_lua
      - **SKILL.md** Lua 脚本执行的 Skill
    - light_switch
      - **SKILL.md**
      - scripts
        - led_strip_switch.lua
    - builtin_lua_modules
      - **SKILL.md** 内置 Lua 模块索引
    - ...
</FileTree>

<Aside type="tip">
  各 `cap_*`、`lua_module_*` 与 `lua_driver_*` 组件自带的 Skill 文件位于组件源码的 `skills/` 目录下，构建时会被打包到 FATFS 镜像中。
</Aside>

### 元数据

ESP-Claw 从每个 Skill 的 `SKILL.md` JSON frontmatter 读取元数据。目录名、`name` 与构建后路径必须保持一致：`skills/<skill_id>/SKILL.md`。

<details>
<summary>`SKILL.md` frontmatter 格式</summary>
````md
---
{
  "name": "skill_id",
  "description": "Short capability description.",
  "metadata": {
    "cap_groups": ["cap_lua"],
    "manage_mode": "readonly"
  }
}
---

# Skill Title
````
</details>

其中 `name` 是模型可见的 Skill ID，`description` 是模型可见的摘要。

`metadata.manage_mode` 取值为 `readonly`、`web` 或 `runtime`。
Skills Lab 侧的项目通常使用 `web`；在设备上 `web` 在管理语义上与 `readonly` 等价。由运行时注册的 Skill 使用 `runtime`。

`metadata.cap_groups` 是可选字段，指定一个 Capability Group ID 列表。当该 Skill 被激活时，列表中的 Group 会自动对 LLM 可见（开放相应工具）；当该 Skill 被停用后，这些 Group 不再被纳入该 Skill 的可见集合。这一机制将「工具用法文档」与「工具本身」绑定在同一个 Skill 的生命周期内，避免大模型在不了解用法时就能访问工具。

<Aside type="tip">
  `metadata.cap_groups` 中填写的值对应 `claw_cap_group_info_t.id`，即各 Capability Group 注册时使用的 ID（如 `cap_lua`、`cap_im_qq` 等）。
</Aside>

### Skill 文件

`SKILL.md` 的正文格式类似普通的 Markdown 文件。在 Skill 文件中，你需要详细提供「技能」——工具用法、工作流程、最佳实践、指导原则等。例如：

<Code lang="md" title="weather.md" code={exampleSkill} />

### 撰写有效的 Skill 文档

Skill 的 `.md` 文件会在 LLM 激活后注入对话上下文，内容应面向 LLM 撰写，而非面向人类开发者。

**好的 Skill 文档应具备：**

| 要素 | 说明 |
|------|------|
| 场景描述 | 明确「何时用」，帮助 LLM 决定是否激活 |
| 调用规则 | 参数约束、顺序要求、频率限制 |
| JSON 示例 | 完整可复制的调用示例，而非自然语言描述 |
| 错误对照 | 常见错误信息与对应处理方式 |
| 与其他工具的关系 | 例如「需先调用 X 获取路径，再调用本工具」|

以下是一份完整的 Capability Skill 文档模板：

``````markdown
# My Feature

一句话说明这个 Skill 的用途，让 LLM 知道什么场景下应该激活它。

## 使用规则

- 调用 `my_action` 时，`param` 字段不得为空
- 若操作失败，先检查 `param` 是否合法，再重试一次
- 不要连续调用超过 3 次，每次调用间隔至少 500 ms

## 典型调用示例

执行基础动作：
```json
{"param": "hello"}
```

带可选参数：
```json
{"param": "hello", "mode": "fast"}
```

## 错误处理

- `Error: param is required`：未传 param，补充后重试
- `Error: invalid state`：设备未就绪，告知用户稍后再试
``````

#### Lua 模块 Skill 的写法

`lua_module_*` / `lua_driver_*` 的 Skill 面向「LLM 编写 Lua 代码」的场景，与 `cap_*` Skill 的 JSON 调用示例不同，应提供精确的 API 参考：

**lua_module Skill 文档应包含：**

| 要素 | 说明 |
|------|------|
| 简要说明 | 控制什么硬件、连接到哪个引脚/接口 |
| 初始化说明 | `require` 是否有副作用、是否需要额外 init 步骤 |
| 完整 API 参考 | 每个函数的参数类型、返回值、Lua 示例 |
| 使用规则 | 调用限制、与其他模块的依赖关系（如「需先 `board_manager` 初始化」）|
| 错误行为 | 哪些情况会 raise Lua error |

``````markdown
# myled

Controls a single LED connected to GPIO 2.

## Setup

No explicit init required. The module configures GPIO 2 on first `require`.

## API

### `myled.set(on)`

Turns the LED on or off.

- `on`: boolean

```lua
local myled = require("myled")
myled.set(true)   -- on
myled.set(false)  -- off
```

### `myled.get()` → boolean

Returns the current LED state.

## Rules

- The module only controls GPIO 2; there is no parameter to change the pin.
- Do not call `myled.set` more than once per 50 ms.
``````

以 `lua_module_display` 的 Skill 为例，它详细列出了每个绘图函数的参数签名、可选 table 字段、返回值，以及「文本只支持 ASCII」等关键约束，这些信息都是 LLM 编写代码时不可或缺的。

### 一个 Skill 还是多个 Skill？

尽量保持使用一个 Skill 描述清楚，除非 Capability 功能复杂、存在多个独立使用场景，可以拆分为多个 Skill。

## 由 Agent 增删和修改 Skills

Skills 通常是某段重复工作或指导的精炼，因此通常可以在要求 Agent 完成某一项任务后，由 Agent 完成 Skills 的总结和迭代。

```sh
ask "帮我搜索一下今天东京的天气"
ask "把之前查询某地天气的技能总结一下"
```

## Skills 如何工作

通过上下文可以为模型提供 Tools、提出要求或额外规范。
但每次对话均需提供每个工具的完整用法、提供每条约束或技能的完整文档，不可避免地会导致上下文过长，影响模型表现、增加 Token 消耗。

Skills 是一种渐进式向大模型披露能力的机制。在初始状态下，大语言模型只会「看到」Skills 清单与每个 Skill 的摘要。
当模型认为某个 Skill 是当前工作所需的，模型会主动激活该 Skill，获取该 Skill 的完整文档。

若 Skill 配置了 `metadata.cap_groups`，激活时系统还会同步开放对应的 Capability Group，使 LLM 能立即调用相关工具，无需额外手动启用。任务完成后，模型可调用 `deactivate_skill` 停用 Skill，相关 Group 也随之退出该 Skill 的可见集，保持上下文精简。

<Aside type="tip">
  查阅 [Claude 文档](https://platform.claude.com/docs@lang/agents-and-tools/agent-skills/overview#how-skills-work)以了解 Skill 的更多细节。
</Aside>
