高级 Skills 技巧:OS 过滤、依赖门控、command-dispatch 与 Token 控制
第20章:高级 Skills 技巧——OS 过滤、依赖门控、command-dispatch 与 Token 控制
本章概览
本章是《OpenClaw 完全指南》Skills 部分的最终章。前几章建立了 Skills 的基础知识框架,本章深入那些让 Skills 真正专业化的高级特性:精准的 OS 过滤、多维度的依赖门控、command-dispatch 的内部机制、隐藏 Skill 的适用场景,以及如何将多项技术组合使用,在保持功能完整的同时将 Token 成本压到最低。
20.1 OS 过滤:让 Skill 只在正确的平台出现
问题背景
许多 Skill 依赖平台特定的工具或行为:
- macOS 特有:
brew、pbcopy、open、caffeinate - Linux 特有:
apt、systemctl、xclip - Windows 特有:
winget、clip.exe、PowerShell
如果一个依赖 brew 的 Skill 在 Linux 上显示为"可用",用户触发后会立即报错,体验极差。OS 过滤解决了这个问题。
配置方式
metadata:
openclaw:
os: darwin # 仅 macOS
metadata:
openclaw:
os: linux # 仅 Linux(含 WSL)
metadata:
openclaw:
os: win32 # 仅 Windows(含 Windows 11)
不设置 os 字段 = 全平台可用
OS 过滤的内部机制
OpenClaw 在启动时检测当前运行平台(通过 process.platform),并在加载 Skill 时:
加载 Skill 元数据 → 读取 os 字段
├─ os 字段不存在 → 加载(全平台)
├─ os 与当前平台匹配 → 加载
└─ os 与当前平台不匹配 → 跳过(不注入任何内容)
关键点: 不匹配的 Skill 完全不出现在模型 context 中,节省 token 的同时也避免了误触发。
实战示例:macOS 剪贴板 Skill
---
name: clipboard-mac
description: |
在 macOS 上管理剪贴板内容:复制文本到剪贴板、
从剪贴板读取内容、追加内容到剪贴板。
metadata:
openclaw:
emoji: "📋"
os: darwin
requires:
bins:
- pbcopy
- pbpaste
---
# macOS 剪贴板操作
## 写入剪贴板
```bash
# 将文本复制到剪贴板
echo "Hello, World" | pbcopy
# 将文件内容复制到剪贴板
cat file.txt | pbcopy
# 将命令输出复制到剪贴板
ls -la | pbcopy
读取剪贴板
# 查看剪贴板内容
pbpaste
# 将剪贴板内容写入文件
pbpaste > output.txt
---
## 20.2 requires 四维度的差异与选择
### 维度一:requires.bins(硬性二进制依赖)
**语义:** PATH 中必须**全部**存在这些可执行文件。
```yaml
requires:
bins:
- git
- gh
- jq
使用场景: Skill 的功能无法降级,没有替代方案。
实际检测:
OpenClaw 执行等价于 `which git && which gh && which jq`
如果任何一个失败 → Skill 不加载
维度二:requires.anyBins(软性多选一依赖)
语义: 至少有一个存在即可。
requires:
anyBins:
- yarn
- npm
- pnpm
- bun
使用场景: 多种工具都能完成任务,Skill 内部会检测用哪个。
Skill 内部的工具检测模式:
## 确定包管理器
按优先级检测:
1. `which bun` → 使用 bun
2. `which yarn` → 使用 yarn
3. `which pnpm` → 使用 pnpm
4. `which npm` → 使用 npm(总是存在于 Node.js 环境)
找到第一个可用的即停止检测。
维度三:requires.env(环境变量门控)
语义: 所有列出的环境变量必须存在且非空。
requires:
env:
- GITHUB_TOKEN
- SLACK_WEBHOOK_URL
典型配置场景:
| 环境变量 | 用途 |
|---|---|
GITHUB_TOKEN |
GitHub API 访问 |
OPENAI_API_KEY |
OpenAI API 访问 |
ANTHROPIC_API_KEY |
Anthropic API 访问 |
SLACK_WEBHOOK_URL |
Slack 消息推送 |
DATABASE_URL |
数据库连接 |
注意: requires.env 只检查变量是否存在,不验证值是否有效(错误的 API Key 要到调用时才暴露)。
维度四:requires.config(功能开关门控)
语义: openclaw.json 中的指定路径必须存在且为真值。
requires:
config:
- features.experimental.acp
- tools.browser.enabled
openclaw.json 对应配置:
{
"features": {
"experimental": {
"acp": true
}
},
"tools": {
"browser": {
"enabled": true
}
}
}
适用场景: 实验性功能开关、企业版特性、用户选择加入(opt-in)的高风险功能。
四维度组合使用
requires:
bins:
- docker
- kubectl
anyBins:
- helm
- kustomize
env:
- KUBECONFIG
- DOCKER_REGISTRY_TOKEN
config:
- features.k8s.enabled
当所有条件同时满足时,Skill 才会加载。任何一个维度不满足,Skill 整体跳过。
20.3 install 自动安装脚本的四种类型
当 requires.bins 中的工具缺失时,OpenClaw 可以根据 install 配置尝试自动安装。
类型一:brew(macOS Homebrew)
install:
- type: brew
pkg: ffmpeg
- type: brew
pkg: imagemagick
tap: homebrew/cask # 可选:指定 tap
适用: macOS 用户,需要 Homebrew 已安装。
执行等价命令:
brew install ffmpeg
brew install imagemagick
类型二:node(npm/npx 包)
install:
- type: node
pkg: "@anthropic-ai/claude-cli"
global: true # 安装为全局包
- type: node
pkg: "tsx"
global: true
执行等价命令:
npm install -g @anthropic-ai/claude-cli
npm install -g tsx
类型三:go(Go 二进制工具)
install:
- type: go
pkg: github.com/cli/cli/v2@latest
执行等价命令:
go install github.com/cli/cli/v2@latest
前提: 需要 Go 已安装(不会自动安装 Go 本身)。
类型四:uv(Python 工具)
install:
- type: uv
pkg: ruff
- type: uv
pkg: mypy
执行等价命令:
uv tool install ruff
uv tool install mypy
注意: uv 是现代 Python 工具管理器,比 pip install 更快、更安全。
类型五:download(直接下载二进制)
install:
- type: download
url: https://releases.example.com/tool-v2.0-darwin-arm64.tar.gz
dest: ~/.local/bin/
extract: true # 是否解压
chmod: "0755" # 设置执行权限
binary: tool # 解压后的二进制文件名
适用: 没有包管理器支持的闭源工具,或需要特定版本。
自动安装的完整流程
用户触发包含 requires.bins: [ffmpeg] 的 Skill
↓
OpenClaw 检测:which ffmpeg → 不存在
↓
读取 install 配置,找到 type: brew, pkg: ffmpeg
↓
提示用户:
"ffmpeg 未安装。是否自动安装?(y/n)"
↓
用户确认 → 执行 brew install ffmpeg
↓
安装完成 → 继续加载并执行 Skill
20.4 command-dispatch 的内部机制
零推理调用路径
普通 Skill 调用流程:
用户输入 → [模型 token 消耗] → 模型决策 → 工具调用 → 结果
command-dispatch 调用流程:
用户输入 → OpenClaw 路由层 → 工具调用 → 结果
(完全绕过模型,0 token 消耗)
路由层的工作原理
当 OpenClaw 接收到 /browser https://example.com 时:
1. 解析斜杠命令名称:browser
2. 查找名为 browser 的 Skill
3. 检查 Skill 是否设置了 command-dispatch: tool
4. 是 → 读取 command-tool: "browser_action"
5. 读取 command-arg-mode: raw
6. 将 "https://example.com" 作为原始字符串传递给 browser_action 工具
7. 直接返回工具结果
(整个过程不调用语言模型)
command-dispatch 的实际 Token 节省
场景: 用户每天平均使用 /browser 命令 20 次
| 调用方式 | 每次 Token 消耗 | 每日 Token 消耗 | 月度成本估算 |
|---|---|---|---|
| 普通 Skill | ~1,200 tokens | 24,000 tokens | ~$0.72 |
| command-dispatch | 0 tokens | 0 tokens | $0.00 |
以 GPT-4 级别 $0.03/1K tokens 计算
command-arg-mode 的两种模式
raw 模式:
用户输入:/search --limit 10 python async best practices
工具接收:python async best practices --limit 10
(参数原样传递,不做解析)
parsed 模式(默认):
用户输入:/search --limit 10 python async best practices
工具接收:{query: "python async best practices", limit: 10}
(参数被解析为结构化格式)
20.5 disable-model-invocation 的适用场景
什么时候该隐藏 Skill?
disable-model-invocation: true 将 Skill 完全从模型 context 中移除。以下场景适合使用:
场景一:内部工具,不应暴露给用户
---
name: internal-diagnostics
description: 内部诊断工具(不对外)
disable-model-invocation: true
user-invocable: true # 只有特定用户知道命令名才能调用
---
场景二:减少 context 消耗的高频命令工具
---
name: clipboard
description: 剪贴板快速操作
disable-model-invocation: true
user-invocable: true
command-dispatch: tool
command-tool: "clipboard_action"
---
这个 Skill 永远不会被模型自动触发,也不占用 context,但用户可以通过 /clipboard 命令直接使用。
场景三:防止意外触发的高风险操作
---
name: production-deploy
description: 部署到生产环境(危险操作)
disable-model-invocation: true
user-invocable: true
---
只有用户显式输入 /production-deploy 才能触发,模型永远不会在对话中自动决定"该部署了"。
disable-model-invocation vs requires.config 的选择
| 需求 | 推荐方案 |
|---|---|
| 永久隐藏 Skill | disable-model-invocation: true |
| 条件性隐藏(可开关) | requires.config: [feature.x.enabled] |
| 仅对特定环境隐藏 | os: darwin(OS 过滤) |
20.6 always: true 的风险与适用场景
always: true 是一个特殊字段,设置后 Skill 会跳过所有 gate(包括 requires 检查),始终可用。
配置方式
---
name: core-guidelines
description: 核心行为准则,始终激活
metadata:
openclaw:
always: true
---
# 核心准则
每次对话都遵循以下原则:
- 回答前先确认理解用户意图
- 给出代码时同时提供测试方案
- 不确定时主动说明不确定
真正的适用场景(极少数)
- 全局行为准则:想要在所有对话中都生效的规范
- 上下文注入:需要始终告知模型某些环境信息
- 紧急规避:临时覆盖某个行为(调试期间)
always: true 的风险
| 风险 | 说明 |
|---|---|
| 始终消耗 context | 即使当前任务与此 Skill 完全无关 |
| 无法被 requires 门控 | 即使依赖工具不存在也会加载 |
| 可能与其他 Skill 冲突 | 始终激活的指导可能与专业 Skill 的指导矛盾 |
| 难以调试 | 忘记有 always Skill 存在时,行为异常难以排查 |
建议: 绝大多数情况下不要使用 always: true。如果确实需要,控制 Skill 体积在 200 tokens 以内。
20.7 Token 成本控制:懒加载 + command-dispatch 组合策略
策略架构图
高频命令性操作
↓
command-dispatch + disable-model-invocation
→ 0 token 消耗
低频、需要推理的操作
↓
懒加载(仅注入元数据)
→ ~50 token 元数据,激活时才加载完整内容
深度参考资料
↓
references/ 目录 + {baseDir} 引用
→ 仅在明确需要时加载
实战:为一个团队工具包优化 Token 消耗
场景: 团队使用 15 个 Skills,每天对话 50 轮,每轮平均触发 2 个 Skills。
优化前(全量加载):
每轮对话:15 Skills × 1500 tokens = 22,500 tokens(Skills 部分)
每日:50 × 22,500 = 1,125,000 tokens
月度成本:~$33.75
优化后(懒加载 + command-dispatch):
每轮对话:
- 元数据:15 × 50 tokens = 750 tokens
- 激活的 Skills:2 × 1500 tokens = 3,000 tokens
- command-dispatch Skills(5个):0 tokens
总计:3,750 tokens(Skills 部分)
每日:50 × 3,750 = 187,500 tokens
月度成本:~$5.63
节省:83%
按操作类型分配技术
| 操作类型 | 推荐技术 | Token 消耗 |
|---|---|---|
| 立即响应命令(< 0.5s) | command-dispatch | 0 |
| 模型需要判断的任务 | 懒加载 | 50(元数据)+ 按需 |
| 深度文档查阅 | references/ 目录 | 仅按需 |
| 全局行为准则(谨慎) | always: true | 全量(每轮) |
20.8 多 Skills 协作模式:skill-creator 元 Skill
元 Skill 的概念
元 Skill(meta-skill)是一种特殊的 Skill:它的目的是创建其他 Skills。这是 OpenClaw Skills 系统中最高级的使用模式。
完整 skill-creator SKILL.md 示例
---
name: skill-creator
description: |
当用户想要创建新的 OpenClaw Skill、将重复性工作流打包为 Skill、
或者询问如何编写 SKILL.md 时使用。
引导用户通过问答过程生成完整的 Skill 文件。
user-invocable: true
metadata:
openclaw:
emoji: "🏗️"
primaryEnv: shell
---
# Skill Creator — Skill 创作向导
## 第一步:收集信息
向用户提问以下问题(每次一个,等待回答):
1. **这个 Skill 要做什么?** (一句话描述核心功能)
2. **用户在什么情况下需要它?** (触发场景,用于 description)
3. **它依赖哪些外部工具?** (用于 requires.bins)
4. **它需要哪些环境变量?** (用于 requires.env)
5. **它应该在哪些操作系统上运行?** (darwin/linux/win32/全部)
6. **用户可以通过斜杠命令调用吗?** (user-invocable)
7. **有简单的命令行形式吗?** (是否需要 command-dispatch)
## 第二步:选择合适的模式
根据收集的信息,按以下逻辑选择模式:
有明确的单一工具调用? ├─ 是 → command-dispatch 型 └─ 否 → 有复杂工作流? ├─ 是 → 信息型或 TDD 专业型 └─ 否 → 依赖外部工具? ├─ 是 → 工具集成型 └─ 否 → 工具型(最简洁)
## 第三步:生成 SKILL.md
根据收集的信息,生成完整的 SKILL.md 文件。
**生成规则:**
- description 控制在 50-150 字符
- requires 只声明确认存在的依赖
- 正文按"操作步骤"组织,不要写成散文
- 如果正文超过 1000 tokens,将详细内容移到 references/
## 第四步:验证与安装
生成后,提供以下验证步骤:
```bash
# 1. 查看生成的文件
cat ~/.openclaw/skills/<skill-name>/SKILL.md
# 2. 验证 SKILL.md 格式
openclaw skill validate ~/.openclaw/skills/<skill-name>/
# 3. 测试触发
# 在新对话中输入 Skill 的触发场景,检查是否被正确激活
常见 Skill 模板
如需具体模板,参见:
- 工具型:{baseDir}/references/template-tool.md
- 信息型:{baseDir}/references/template-info.md
- command-dispatch 型:{baseDir}/references/template-dispatch.md
---
## 20.9 高级组合案例:生产级 Skill 设计
### 案例:企业级 Kubernetes 部署 Skill
这个案例展示了如何将本章所有高级技术组合使用:
```yaml
---
name: k8s-deploy
description: |
当团队需要将服务部署到 Kubernetes 集群时使用:
创建/更新 Deployment、Service、ConfigMap,
执行滚动更新,回滚失败部署,查看 Pod 状态和日志。
仅适用于已配置 kubectl 访问权限的环境。
user-invocable: true
disable-model-invocation: false
metadata:
openclaw:
emoji: "☸️"
os: linux
requires:
bins:
- kubectl
- helm
anyBins:
- kustomize
- helmfile
env:
- KUBECONFIG
- K8S_NAMESPACE
config:
- features.k8s.enabled
- features.k8s.production_access
primaryEnv: shell
homepage: https://kubernetes.io/docs/
install:
- type: brew
pkg: kubernetes-cli
- type: go
pkg: helm.sh/helm/v3@latest
---
# Kubernetes 部署 Skill
## 安全前提(每次操作前必读)
**生产环境操作三原则:**
1. 先在 staging 验证,再推到 production
2. 滚动更新,绝不直接 delete+recreate
3. 保留回滚点(--record 已废弃,改用 revision history)
## 部署新版本
```bash
# 更新镜像版本(推荐方式,保留历史)
kubectl set image deployment/<name> \
<container>=<image>:<tag> \
-n ${K8S_NAMESPACE}
# 查看滚动更新进度
kubectl rollout status deployment/<name> -n ${K8S_NAMESPACE}
查看状态
# 查看所有 Pod
kubectl get pods -n ${K8S_NAMESPACE} -o wide
# 查看特定 Pod 日志(最近 100 行)
kubectl logs <pod-name> -n ${K8S_NAMESPACE} --tail=100 -f
# 查看 Pod 事件(排查 CrashLoopBackOff)
kubectl describe pod <pod-name> -n ${K8S_NAMESPACE}
回滚
# 查看 Deployment 历史
kubectl rollout history deployment/<name> -n ${K8S_NAMESPACE}
# 回滚到上一版本
kubectl rollout undo deployment/<name> -n ${K8S_NAMESPACE}
# 回滚到指定版本
kubectl rollout undo deployment/<name> \
--to-revision=3 \
-n ${K8S_NAMESPACE}
Helm 部署
详细的 Helm values 配置说明见:{baseDir}/references/helm-values-guide.md Chart 模板最佳实践见:{baseDir}/references/helm-chart-patterns.md
**这个 Skill 使用了哪些高级技术:**
- ✅ `os: linux`:OS 过滤(K8s 通常在 Linux 环境)
- ✅ `requires.bins`:硬性依赖 kubectl + helm
- ✅ `requires.anyBins`:软性依赖 kustomize 或 helmfile
- ✅ `requires.env`:门控 KUBECONFIG(无此变量不应加载)
- ✅ `requires.config`:双重门控(features.k8s.enabled + production_access)
- ✅ `{baseDir}/references/`:深度文档懒加载
- ✅ `install`:提供自动安装路径
---
## 20.10 本章小结与最佳实践速查
### 技术选择快速决策表
| 需求 | 技术 | 字段 |
|------|------|------|
| 仅在 macOS 可用 | OS 过滤 | `os: darwin` |
| 需要全部工具存在 | 硬性依赖 | `requires.bins` |
| 需要任一工具存在 | 软性依赖 | `requires.anyBins` |
| 需要 API Key | 环境变量门控 | `requires.env` |
| 需要功能开关 | 配置门控 | `requires.config` |
| 命令直达工具 | 零推理调用 | `command-dispatch: tool` |
| 完全隐藏 Skill | 从模型隐藏 | `disable-model-invocation: true` |
| 全局始终激活(慎用)| 跳过所有门控 | `always: true` |
| 减少 context | 深度文档延迟加载 | `references/ + {baseDir}` |
### 高级 Skill 设计的核心原则
1. **精确门控胜过宽松允许**:`requires` 配置得越精确,Skill 越可靠
2. **command-dispatch 优先**:凡是可以确定行为的命令,都应该 command-dispatch
3. **references/ 是 context 的缓冲区**:详细内容永远放 references/,正文只留操作核心
4. **always: true 是核武器**:只在真正需要全局影响时使用
5. **OS 过滤保护用户体验**:平台特定工具必须配置 OS 过滤
**恭喜!** 你已经完成了《OpenClaw 完全指南》Skills 部分的全部学习。从第16章的 ACP 协议到第20章的高级技巧,你现在具备了设计和实现企业级 Skills 生态系统的完整知识体系。
下一部分将介绍 OpenClaw 的安全模型与部署策略——如何在团队和企业环境中安全地运行 OpenClaw。