拆解 OpenClaw 的 Skills 机制:一个为 AI Agent 设计的"包管理器"

当大模型的上下文窗口成为稀缺资源,如何让 AI 在 50+ 个专业领域之间按需切换,同时不浪费一个 token?OpenClaw 的 Skills 系统给出了一个工程上极其优雅的答案。

一、背景:AI Agent 的"万能"困局

你一定遇到过这样的场景------

让 AI 帮你查天气,它不知道该调用哪个 API;让它帮你操作 1Password,它不知道 CLI 怎么用;让它帮你生成图片,它连 Python 脚本都要从头写一遍。

问题不在于模型不够聪明,而在于模型缺少特定领域的程序性知识(Procedural Knowledge)。这类知识------"具体用什么命令"、"参数怎么填"、"脚本长什么样"------不是通过预训练能完全覆盖的。

传统的解决方案是写一大段 System Prompt,把所有领域的知识塞进去。但这会导致:

  • 上下文窗口爆炸:50 个领域的详细指令能轻松吃掉 10 万+ tokens
  • 注意力稀释:模型在大段 prompt 中找到相关段落的能力会下降
  • 维护噩梦:增删改一个领域需要触碰整个 prompt

OpenClaw(一个开源的多渠道 AI 助手网关)提出了一种不同的思路:Skills 系统

二、Skills 不只是"文档"

一看到"Skill"这个词,你可能会想到 Custom Instructions 或者 Prompt Template------写一段文字告诉 AI 怎么做。

OpenClaw 的 Skill 远不止于此。它是一个完整的可分发能力包(Capability Package),包含:

python 复制代码
skill-name/
├── SKILL.md          # 必需:元数据声明 + 使用指令
├── scripts/          # 可选:可执行脚本(Python/Bash/Node)
├── bin/              # 可选:二进制包装器
├── references/       # 可选:按需加载的参考文档
└── assets/           # 可选:模板、图片等输出资源

让我们逐层拆解。

三、第一层:声明式元数据------"我是谁、我需要什么"

每个 Skill 的 SKILL.md 顶部有一个 YAML frontmatter 块。以本地 TTS(文字转语音)Skill 为例:

yaml 复制代码
---
name: sherpa-onnx-tts
description: Local text-to-speech via sherpa-onnx (offline, no cloud)
metadata:
  openclaw:
    emoji: "🗣️"
    os: ["darwin", "linux", "win32"]
    requires:
      env: ["SHERPA_ONNX_RUNTIME_DIR", "SHERPA_ONNX_MODEL_DIR"]
    install:
      - id: "download-runtime-macos"
        kind: "download"
        os: ["darwin"]
        url: "https://github.com/.../sherpa-onnx-v1.12.23-osx-universal2-shared.tar.bz2"
        archive: "tar.bz2"
        extract: true
        stripComponents: 1
        targetDir: "runtime"
      - id: "download-runtime-linux-x64"
        kind: "download"
        os: ["linux"]
        url: "https://github.com/.../sherpa-onnx-v1.12.23-linux-x64-shared.tar.bz2"
        ...
      - id: "download-model-lessac"
        kind: "download"
        url: "https://github.com/.../vits-piper-en_US-lessac-high.tar.bz2"
        targetDir: "models"
---

这段元数据声明了五件事:

字段 含义
os 支持哪些操作系统
requires.bins 需要哪些命令行工具
requires.env 需要哪些环境变量
requires.anyBins 多个工具中有一个即可
install 依赖缺失时如何自动安装

关键洞察:这些信息是给运行时引擎看的,不是给模型看的。 运行时在 Skill 被触发之前就用这些元数据做资格检查和依赖安装。

四、内置的自动安装系统

这是 Skills 机制最出乎意料的部分------它内建了 5 种安装器

看一下实际的安装命令构建逻辑(src/agents/skills-install.ts):

typescript 复制代码
function buildInstallCommand(spec: SkillInstallSpec, prefs: SkillsInstallPreferences) {
  switch (spec.kind) {
    case "brew":
      return { argv: ["brew", "install", spec.formula] };
    case "node":
      return { argv: buildNodeInstallCommand(spec.package, prefs) };
    case "go":
      return { argv: ["go", "install", spec.module] };
    case "uv":
      return { argv: ["uv", "tool", "install", spec.package] };
    case "download":
      // 单独处理:下载 + 解压
      return { argv: null, error: "download install handled separately" };
  }
}

五种安装器覆盖了主流的包管理生态:

kind 用途 实际命令示例
brew macOS Homebrew brew install python
node npm/pnpm/yarn/bun 全局包 npm install -g <package>
go Go 模块 go install <module>
uv Python 工具 uv tool install <package>
download 下载归档文件并解压 从 GitHub Releases 下载 .tar.bz2

而且,node 安装器还会尊重用户的包管理器偏好:

typescript 复制代码
function buildNodeInstallCommand(packageName: string, prefs: SkillsInstallPreferences): string[] {
  switch (prefs.nodeManager) {
    case "pnpm": return ["pnpm", "add", "-g", "--ignore-scripts", packageName];
    case "yarn": return ["yarn", "global", "add", "--ignore-scripts", packageName];
    case "bun":  return ["bun", "add", "-g", "--ignore-scripts", packageName];
    default:     return ["npm", "install", "-g", "--ignore-scripts", packageName];
  }
}

注意 --ignore-scripts------默认禁用 npm 的 postinstall 脚本,这是一个安全考量。

download 安装器更有意思,它实现了完整的"下载 → 解压 → 安全校验"流程:

typescript 复制代码
// 下载文件到临时目录
const result = await downloadFile({ url, rootDir: safeRoot, relativePath, timeoutMs });

// 自动检测归档类型
const archiveType = resolveArchiveType(spec, filename);  // tar.gz / tar.bz2 / zip

// 解压到目标目录
await extractArchive({ archivePath, archiveType, targetDir, stripComponents, timeoutMs });

所有下载目标都被严格限制在 ~/.openclaw/tools/<skill-name>/ 下,有完整的路径遍历防护。

从用户视角看:你说"帮我用本地 TTS 朗读这段话",系统发现 sherpa-onnx-tts Skill 可用但依赖未安装,自动下载对应平台的运行时和语音模型,然后执行。整个过程对用户透明。

五、运行时资格检查------"这个 Skill 现在能不能用"

在 Skill 被注入到 AI 上下文之前,运行时会做一系列检查(src/agents/skills/config.ts):

typescript 复制代码
function shouldIncludeSkill(params) {
  const { entry, config, eligibility } = params;

  // 1. 用户手动禁用了?
  if (skillConfig?.enabled === false) return false;

  // 2. 不在 bundled allowlist 中?
  if (!isBundledSkillAllowed(entry, allowBundled)) return false;

  // 3. 运行时资格检查
  return evaluateRuntimeEligibility({
    os: entry.metadata?.os,                    // 操作系统匹配
    requires: entry.metadata?.requires,        // 依赖检查
    hasBin: hasBinary,                         // 本机二进制检查
    hasRemoteBin: eligibility?.remote?.hasBin,  // 远程设备二进制检查
    hasEnv: (envName) => Boolean(              // 环境变量检查
      process.env[envName] ||
      skillConfig?.env?.[envName] ||
      (skillConfig?.apiKey && entry.metadata?.primaryEnv === envName)
    ),
  });
}

这意味着:

  • Linux 上不会出现 macOS 专属的 Apple Notes Skill
  • 没有安装 tmux 的机器上不会出现 tmux Skill
  • 没有配置 OPENAI_API_KEY 的环境不会出现 OpenAI 图片生成 Skill
  • 连接了 iOS 设备时,才会出现需要 iOS 的 Skill

这种"按能力过滤"的设计,避免了 AI 去调用一个根本不可能成功的工具。

六、渐进式加载------上下文窗口的精细管理

这是整套设计最精巧的部分。Skills 使用三层渐进式加载(Progressive Disclosure)来管理上下文开销:

yaml 复制代码
                    ┌─────────────────────────────────────────┐
                    │  Level 1: 元数据(始终在上下文中)       │
                    │  name + description ≈ 100 tokens/skill  │
                    │  50 个 Skill ≈ 5000 tokens             │
                    └──────────────┬──────────────────────────┘
                                   │
                          AI 判断:"这个 Skill 和当前任务相关"
                                   │
                    ┌──────────────▼──────────────────────────┐
                    │  Level 2: SKILL.md 正文(触发后加载)    │
                    │  具体命令、参数、工作流 < 5000 words     │
                    └──────────────┬──────────────────────────┘
                                   │
                        AI 判断:"需要更多细节" / "需要执行脚本"
                                   │
                    ┌──────────────▼──────────────────────────┐
                    │  Level 3: 附属资源(按需加载/执行)      │
                    │  scripts/ → 直接执行,不占上下文        │
                    │  references/ → 读取到上下文             │
                    │  bin/ → 直接调用,不占上下文            │
                    └─────────────────────────────────────────┘

具体的限制参数:

typescript 复制代码
const DEFAULT_MAX_SKILLS_IN_PROMPT = 150;        // 最多 150 个 Skill 的元数据
const DEFAULT_MAX_SKILLS_PROMPT_CHARS = 30_000;   // 元数据总字符上限 30K
const DEFAULT_MAX_SKILL_FILE_BYTES = 256_000;     // 单个 SKILL.md 最大 256KB

为什么这很重要?

假设你有 50 个 Skill。传统做法是把所有 50 个 Skill 的完整文档塞进 System Prompt,可能需要 10 万+ tokens。

而在 OpenClaw 的方案中:

  • Level 1 只需要约 5000 tokens(50 × 100)
  • Level 2 只在用户明确触发某个领域时加载
  • Level 3 中的脚本甚至不需要进入上下文窗口 ------AI 只需要知道"运行 {baseDir}/scripts/gen.py"就行

节省的 token 可以用来处理更长的对话历史、更丰富的工具输出。

七、Skill 的丰富形态------不只一种"能力"

从 OpenClaw 内置的 50+ 个 Skill 来看,它们呈现出非常不同的形态:

形态 1:纯知识注入型

weather Skill 为例------目录下只有一个 SKILL.md,教 AI 如何用 curl 调用 wttr.in

yaml 复制代码
---
name: weather
description: "Get current weather and forecasts via wttr.in or Open-Meteo."
metadata: { "openclaw": { "requires": { "bins": ["curl"] } } }
---
markdown 复制代码
## Commands

### Current Weather
curl "wttr.in/London?format=3"

### Forecasts
curl "wttr.in/London?format=v2"

AI 天然知道 curl,但不知道 wttr.in 的 API 格式。Skill 补全了这块知识。

形态 2:脚本捆绑型

openai-image-gen Skill 自带了一个完整的 Python 脚本(scripts/gen.py,约 11KB),并声明了自动安装:

yaml 复制代码
metadata:
  openclaw:
    requires: { "bins": ["python3"], "env": ["OPENAI_API_KEY"] }
    install:
      - id: "python-brew"
        kind: "brew"
        formula: "python"
        bins: ["python3"]

AI 不需要从头写图片生成代码------直接调用打包好的脚本:

bash 复制代码
python3 {baseDir}/scripts/gen.py --prompt "a lobster astronaut" --count 4

脚本还自带测试(test_gen.py),是经过验证的确定性实现。

形态 3:二进制 + 运行时下载型

sherpa-onnx-tts Skill 自带了一个 Node.js 包装脚本(bin/sherpa-onnx-tts),并声明了跨平台的运行时下载------macOS、Linux、Windows 各一份,外加语音模型文件。

这不是简单的"教 AI 用工具",而是在用户不知情的情况下完成了一个完整的软件安装流程

形态 4:参考文档型

1password Skill 有一个 references/ 目录,包含 get-started.mdcli-examples.mdSKILL.md 本体保持精简,只在 AI 判断需要深入了解时才加载 references。

这种设计特别适合复杂 API------SKILL.md 放"概述 + 常用命令",references 放"完整 API 文档"。

形态 5:编排型(Meta Skill)

coding-agent Skill 教 AI 如何 spawn 和管理其他 AI Agent

markdown 复制代码
## The Pattern: workdir + background + pty

# 启动 Codex agent 在后台
bash pty:true workdir:~/project background:true command:"codex exec --full-auto 'Build a snake game'"

# 监控进度
process action:log sessionId:XXX

# 发送输入
process action:submit sessionId:XXX data:"yes"

这不再是"让 AI 用工具",而是让 AI 管理其他 AI

形态 6:自举型(Self-bootstrapping)

skill-creator Skill 教 AI 如何创建新的 Skill 。它自带了 init_skill.pypackage_skill.pyquick_validate.py 三个脚本,覆盖了 Skill 的创建、打包、验证全流程。

这意味着系统可以自我扩展------AI 可以根据用户需求创建新的 Skill,打包后分发。

八、安全机制------不信任任何输入

社区贡献的 Skill 可能包含恶意代码。OpenClaw 在多个层面做了防护。

安装时安全扫描

src/security/skill-scanner.ts 在 Skill 安装时扫描所有 JS/TS 文件,检测危险代码模式:

typescript 复制代码
type SkillScanFinding = {
  ruleId: string;
  severity: "info" | "warn" | "critical";
  file: string;
  line: number;
  message: string;
  evidence: string;
};

发现 critical 级别的问题会生成警告,用户可以选择是否继续。

输入净化

所有 frontmatter 中的安装参数都经过严格校验:

typescript 复制代码
// Brew formula 校验------防止命令注入
const BREW_FORMULA_PATTERN = /^[A-Za-z0-9][A-Za-z0-9@+._/-]*$/;

// npm 包名校验
function normalizeSafeNpmSpec(raw) {
  if (!spec || spec.startsWith("-")) return undefined;  // 防止 flag 注入
  if (validateRegistryNpmSpec(spec) !== null) return undefined;
  return spec;
}

// 下载 URL 校验------只允许 http/https
function normalizeSafeDownloadUrl(raw) {
  const parsed = new URL(value);
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return undefined;
  return parsed.toString();
}

路径安全

下载目标目录有严格的边界检查,防止路径遍历攻击:

typescript 复制代码
function resolveDownloadTargetDir(entry, spec) {
  const safeRoot = resolveSkillToolsRootDir(entry);  // ~/.openclaw/tools/<skill>/
  const resolved = path.resolve(safeRoot, raw);

  if (!isWithinDir(safeRoot, resolved)) {
    throw new Error(
      `Refusing to install outside the skill tools directory. ` +
      `targetDir="${raw}" resolves to "${resolved}". Allowed root: "${safeRoot}".`
    );
  }
  return resolved;
}

打包时也会拒绝包含 symlink 的 Skill,防止符号链接逃逸。

九、分发机制------ClawHub 生态

OpenClaw 有一个配套的 Skill 市场------ClawHubclawhub.com),类似 npm 之于 Node.js。

clawhub Skill(对,它自己也是一个 Skill)提供了完整的生命周期管理:

bash 复制代码
clawhub search "postgres backups"     # 搜索
clawhub install my-skill              # 安装
clawhub update --all                  # 批量更新
clawhub publish ./my-skill            # 发布

Skill 的打包产物是一个 .skill 文件(本质是 zip),包含验证过的目录结构。

十、与同类方案的对比

维度 OpenClaw Skills Custom GPTs / Prompts MCP Tools LangChain Tools
知识注入 ✅ 三层渐进式 ✅ 全量加载 ❌ 无 ❌ 无
可执行脚本 ✅ 内置 ✅ 需编码
依赖声明 ✅ 声明式
自动安装 ✅ 5 种安装器
平台感知 ✅ OS/bin/env
上下文优化 ✅ 按需加载 ❌ 全量 ✅ schema 级
安全扫描 ✅ 内置 N/A
社区分发 ✅ ClawHub ✅ GPT Store

OpenClaw Skills 的独特之处在于它将知识注入、工具集成、依赖管理、安全检查统一在一个声明式的框架内,而不是把这些问题留给开发者逐一解决。

十一、设计哲学与启示

从 OpenClaw Skills 系统中,可以提炼出几个值得借鉴的设计原则:

原则 1:上下文窗口是稀缺资源,要按需分配

不要把所有信息一股脑塞给模型。用元数据做路由,让模型自己决定需要什么深度的信息。这是一种信息的"懒加载"

原则 2:AI 不只需要知识,还需要工具

纯文本的 Prompt 只能教 AI "知道"------但 scripts/ 和 bin/ 让 AI 能"做到"。一个经过测试的确定性脚本,比让 AI 每次从头生成代码要可靠得多。

原则 3:声明式优于命令式

不是"请安装 Python",而是 requires.bins: ["python3"] + install: [{ kind: "brew", formula: "python" }]。运行时引擎负责"怎么做",Skill 只负责"需要什么"。

原则 4:安全不是事后补丁

从输入校验(brew formula 正则)、路径约束(isWithinDir)、到代码扫描(skill-scanner),安全考量嵌入在了每一层设计中。

原则 5:系统要能自我扩展

skill-creator Skill 赋予了 AI 创建新 Skill 的能力,ClawHub 提供了分发渠道。这种**自举(bootstrapping)**能力让生态可以有机增长。

十二、总结

OpenClaw 的 Skills 系统本质上是一个 为 AI Agent 设计的声明式包管理器

  • 它用 YAML frontmatter 声明能力和依赖
  • 用三层渐进式加载精细管理上下文开销
  • 用五种安装器自动解决运行时依赖
  • 用脚本和二进制提供确定性的执行能力
  • 用安全扫描和路径约束防御供应链攻击
  • 用 ClawHub 实现社区级的能力分发

在 AI Agent 框架百花齐放的今天,大多数项目都在解决"如何调用工具"的问题。OpenClaw 更进一步------它同时解决了**"怎么知道该用什么工具"、"怎么安装工具"、"怎么在有限上下文中管理几十个工具的知识"**这三个同等重要的问题。

这或许预示了 AI Agent 基础设施的一个方向:不只是工具编排,而是完整的能力生命周期管理。


本文基于 OpenClaw 项目(github.com/openclaw/op... 源码分析。 项目 MIT 协议开源,欢迎阅读源码深入了解。

相关推荐
kymjs张涛2 小时前
OpenClaw 学习小组:初识
android·linux·人工智能
warm3snow2 小时前
AI 重塑产品管理工具:从 Jira 到智能体项目经理的终极演进
人工智能·ai·excel·项目管理·飞书·产品经理·jira·协同·tapd
吴佳浩2 小时前
OpenClaw macOS 完整安装与本地模型配置教程(实战版)
人工智能·macos·agent
吴佳浩3 小时前
OpenClaw 2026.3.2 — 2026.3.8 权限变更与安全加固
人工智能·openai·agent
左右用AI3 小时前
将openclaw接入飞书:10分钟,让你的AI员工直接操作你的文档和表格!
人工智能
shuaicoding4 小时前
OpenClaw 完全指南:让你的 AI 助手真正『长』在浏览器里
人工智能
刀法如飞4 小时前
AI时代,程序员都应该是算法思想工程师
人工智能·设计模式·程序员
理想小青年4 小时前
OpenClaw网络搜索Tavily Search Skill 安装教程
人工智能
yangpow25 小时前
深度解析 OpenClaw:一个自托管 AI Agent 网关的架构设计与安全机制
人工智能