编写 Skill Bundle
技能包是一种插件类型,完全不包含任何 WebAssembly。它是一个 markdown 技能目录,通过插件机制进行打包和分发:相同的清单、相同的发现方式、相同的签名策略、相同的 zeroclaw plugin install。当你要添加的能力是说明、提示和工作流,而不是代码,并且你希望使用插件分发语义(签名、注册表安装、版本管理),而不是 skills 目录中的松散文件时,就使用它。
首先检查您的二进制文件。 技能包依赖插件机制,而安装程序提供的预构建发布二进制文件在构建时未启用
plugins-wasm特性:在标准二进制文件上,zeroclaw plugin ...是无法识别的子命令,且通过插件分发的技能无法加载。要使用本页面中的技能包,请使用插件执行后端从源码构建,例如cargo build --release --features plugins-wasm-cranelift。如果您只想在标准二进制文件上使用共享技能目录,请改用 Skills 中描述的原生技能包:zeroclaw skills bundle add <alias>可创建一个技能包,zeroclaw skills install <source> --bundle <alias>可将技能安装到其中,从而在不使用插件分发语义的情况下获得相同的技能。
本指南已根据 crates/zeroclaw-plugins/src/host.rs 中的校验路径(validate_skill_bundle、validate_skill_md_frontmatter)以及 crates/zeroclaw-runtime/src/skills/mod.rs 中的加载器进行检查。
关于技能本身是什么以及代理如何使用它们,请先阅读Skills。本页仅介绍 bundle 打包。
布局
仅技能插件会省略 wasm_path,并包含符合 agentskills.io 格式的 skills/ 目录:
my-toolkit/
manifest.toml # capabilities = skill only, no wasm_path
README.md # optional bundle-level overview
skills/
design-review/
SKILL.md
scripts/ # optional
references/ # optional
code-review/
SKILL.md
data-analysis/
SKILL.md
references/
验证:是什么发现机制强制执行
主机会在发现和安装时验证 bundle 的形状,并在首次失败时拒绝整个插件(host.rs 中的 validate_skill_bundle)。具体规则:
skills/必须存在且是一个目录。- 它必须至少包含一个子目录。空的
skills/是无效的清单,而不是一个空的 bundle。 - 每个子目录都必须包含一个
SKILL.md。 - 每个
SKILL.md必须以 YAML frontmatter 开头(第一行是---分隔符,并以关闭的---结束),且该 frontmatter 必须声明非空的name和description键。
frontmatter 检查有意在发现时运行:当技能缺少 name 或 description 时,bundle 会在插件加载时失败,而不是在代理首次在对话中调用该技能时才失败。
有效的技能头部:
---
name: design-review
description: Structured design review workflow for architecture proposals.
---
# Design Review
...instructions...
命名空间化
已加载的 bundle 技能会以插件限定的 ID 注册:plugin:<plugin-name>/<skill-name>,例如 plugin:my-toolkit/design-review(namespace_plugin_skill 在 skills/mod.rs 中)。每个技能还会接收一个 plugin:<plugin-name> 标签。这可以防止与用户编写的技能以及不同 bundle 之间发生冲突:两个 bundle 都可以提供 code-review 技能并共存。
命名空间与技能优先级相互作用:在代理的有效技能解析中,来自不同来源的同名技能会按优先级去重,失败者会被记录为被遮蔽。除非同一捆绑名称的另一个副本也在参与,否则 plugin 限定符会让你的 bundle 完全避开这场争夺。
脚本
一个技能可以携带一个 scripts/ 目录。是否加载带脚本的技能由操作者的 skills.allow_scripts 设置决定,插件技能加载器会原样传递该设置(skills/mod.rs 中的 discover_plugin_skills):带脚本的捆绑包技能与工作区技能完全受相同的审核并丢弃规则约束。不要仅仅因为捆绑包已安装就假定你的脚本会运行。
清单
manifest 是插件目录中名为 manifest.toml 的文件。其字段是 crates/zeroclaw-plugins/src/lib.rs 中 PluginManifest 的 serde 表面,这是唯一的事实来源:
| 字段 | 必填 | 含义 |
|---|---|---|
name | 是 | 唯一的规范包 slug,也是每个派生实例配置键中的包组件。它本身不是操作符配置键。使用 1–128 个小写 ASCII 字符;以 [a-z0-9] 开头和结尾,中间只能包含 [a-z0-9._-]。发现过程会拒绝无效或重复的名称。 |
version | 是 | 版本字符串,例如 0.1.0。 |
description | 不 | 由 zeroclaw plugin list 显示的人类可读描述。 |
author | 不 | 作者姓名或组织。 |
wasm_path | 用于 WASM 能力 | 组件文件名,相对于插件目录。除非唯一的 capability 是 skill,否则为必填。如果指定的文件不存在,发现过程会跳过该插件。 |
capabilities | 是,非空 | 插件类型:tool、channel、memory、observer、skill 中的任意一个(PluginCapability,序列化为 snake_case)。 |
permissions | 不 | 代码可能访问的主机服务:http_client、config_read、file_read、file_write、memory_read、memory_write(PluginPermission)。目前仅前两项会被强制执行;其余项虽会被接受,但不起作用。声明 config_read 需要 config_schema,目前只有工具/通道适配器会提供它。 |
config_schema | 恰好使用 config_read | 为此插件的私有配置起草 2020-12 JSON Schema;它会包含在规范清单字节中,因此在清单签名时也会受到保护。根必须是一个包含 properties 映射且 additionalProperties = false 的对象。每个顶层属性都必须具有一个明确的受支持类型,可直接指定,也可通过本地 JSON Pointer 指定:string、boolean、integer、number、array 或 object。工具和通道使用者可以直接在顶层字符串属性上设置 x-secret = true,以便将其从公共配置中移除,并通过带作用域的 secrets.get 主机导入来公开。工具会在 execute 期间通过 __config 接收公共配置,并可以读取机密。通道会在 configure 和操作调用期间通过 config.get 读取当前公共对象,并通过 secrets.get 读取机密;这两个导入在实例化和静态元数据发现期间均不可用。嵌套、值为 false 或非布尔值的机密标记,以及非字符串的机密属性都会被拒绝。没有 config_read 的 schema,或没有 schema 的 config_read,都会被拒绝。 |
signature | 不 | 对规范化清单字节进行的 Base64url Ed25519 签名。用于发布签名时设置。 |
publisher_key | 不 | 签名者的十六进制编码 Ed25519 公钥。 |
只声明代码实际使用的权限。未声明的权限是组件无法触达的宿主表面;不必要声明的权限则是你主动增加的攻击面,也是审查你的插件的人需要承担的审核负担。
操作方提供的值在 plugins.entries 中仍保持为字符串,并会在持久化时加密,以一个由宿主拥有的包、能力和绑定标识派生的版本化 zpi1_… 字符串作为键(安装过程会打印并初始化默认工具绑定的完整实例密钥):字符串按原样存储,布尔值和数字使用 JSON 标量文本,数组和对象使用 JSON 文本。在任何来宾代码运行之前,宿主会将这些字符串物化为包模式规定的类型,并针对工具和频道适配器验证完整对象。非机密工具属性构成 __config;频道通过 config.get 获取非机密对象。标记为 x-secret = true 的属性会从两个公共接口中省略,仅可在授权的服务帧中通过 secrets.get("property") 获取。频道在一次调用中的公共和机密读取共享同一个规范修订版本,调用结束时宿主会丢弃该物化视图。符合要求的频道插件 必须 在每个使用点都解析这两类值,并且不得在来宾的热状态中保留配置或凭据值;将明文返回给来宾意味着宿主无法针对恶意代码强制实施不保留策略。如果请求了 config_read 但未实际获授予,宿主会验证一个空对象;因此,包含必需属性的模式会拒绝启动,而不会在缺少必需配置的情况下启动。如果空对象有效,工具会省略空的 __config,而频道的配置/机密导入会返回 access-denied;在授权帧之外的调用、解析失败以及宿主调用预算耗尽会返回 unavailable。
对于一个技能包:capabilities 仅包含 skill,不包含 wasm_path,并且通常根本没有 permissions;该包是数据,而权限集用于控制 Markdown 从不调用的宿主函数。
混合能力插件(例如 tool + skill)是合法的:此时它必须为工具世界携带一个有效的 wasm_path,并且还要有一个有效的 skills/ bundle,而且两项校验都会运行。
安装并验证
这些命令需要一个编译了插件宿主的二进制文件。 安装程序附带的预构建发布二进制文件在构建时未启用
plugins-wasm特性,因此zeroclaw plugin ...在该版本中是无法识别的子命令,已安装的插件也永远不会被发现。请从源码构建并选择一个插件执行后端,例如cargo build --release --features plugins-wasm-cranelift。
每个插件都位于 plugins 目录的各自子目录中(默认 ~/.zeroclaw/plugins/,通过 plugins.plugins_dir 解析),其中包含清单以及与清单的 wasm_path 匹配的组件:
~/.zeroclaw/plugins/
└── my-plugin/
├── manifest.toml
└── my-plugin.wasm
从本地目录安装(这会在复制任何内容之前验证清单形状并运行签名策略):
zeroclaw plugin install ./my-plugin/
启用插件系统并确认发现:
zeroclaw config set plugins.enabled true
zeroclaw plugin list
zeroclaw plugin info my-plugin
zeroclaw plugin list 和 zeroclaw plugin info 可确认软件包已安装且可被发现,但发现并不等于激活。plugins.enabled = true 会开启插件主机;只有同时将 plugins.auto_discover = true 设为 true 时,自动发现的工具和技能功能才会在运行时加载,而该标志默认为 false(故障关闭):
zeroclaw config set plugins.auto_discover true
因此,仅设置 plugins.enabled = true 时,会启用你在 [channels.plugin.<alias>] 下声明的通道,而不会启用任何插件工具或技能:工具或技能包可能会出现在 zeroclaw plugin list 中,但在运行时不会产生任何作用。显式通道绑定由操作员命名,而不是自动发现,因此不需要 auto_discover;该标志仅控制自动发现的工具和技能。
zeroclaw plugin list 中缺失的插件在发现时已被跳过:请检查启动日志中的跳过警告(清单格式错误、缺少 wasm_path 文件,或签名策略拒绝)。
在发现之后,这些技能会在技能界面(技能列表、仪表板)中以 plugin:<your-bundle>/<skill> 的命名空间形式显示。请让代理使用其中一个,以确认端到端流程。
下一个
- 发布插件:技能包是最简单的发布形式,其签名流程与 WASM 插件完全相同。