万字干货 | 一篇讲透Skill:规范、跨平台、触发、调用、组合与串联

最近读《敏捷史话》时,书里提到了 Robert C. Martin。他是《敏捷软件开发宣言》的 17 位签署者之一,也是《代码整洁之道》的作者。
看到这里,我想到自己用 AI Coding 时反复遇到的一类问题:生成结果能够运行,却容易留下重复逻辑、多余封装和含混命名;该解释的地方没有注释,有些注释又只是在复述代码。局部看似完成,代码的可读性、修改成本和错误边界却没有得到稳定控制。
我最初只想借用《代码整洁之道》中的思想,做一个约束代码生成与审查的 Skill。真正动手后,问题很快超出了“把规则写进一个 Markdown 文件”:Skill 应该采用什么结构,哪些字段属于开放规范,同一个包怎样被不同平台发现和加载,description 怎样参与触发,工具权限由谁控制,这些都需要先弄清楚。
调研各个平台的 Skill 实现后,我又受到 Superpowers 的启发,继续研究多个 Skill 怎样组合、交接和串联。原本针对代码整洁的一项实践,逐渐展开成了一条完整链路。于是有了这篇文章:从一个 SKILL.md 目录开始,依次拆开规范、跨平台实现、触发、调用和自动串联背后的机制。
一、Skill 从一个目录开始
一个 Skill 包至少由一个目录和其中的 SKILL.md 组成:
example-skill/
└── SKILL.md
SKILL.md 的开头必须是 YAML frontmatter,正文随后写给 Agent 的工作说明。开放标准要求 name 与 description,其余标准字段是可选项。资源目录不是最低要求,但规范建议用相对路径组织 scripts/、references/ 和 assets/。[1]
一个可使用的 Skill 至少应声明适用范围与非目标、输入范围与禁止访问对象、判断和行动顺序、输出契约、授权点、停止条件以及命令或测试验证方法。这些声明属于正文契约,不会自动转化为宿主权限或确定性调度规则。
Skill 不等于以下对象:
| 对象 | 主要职责 | 与 Skill 的关系 |
|---|---|---|
| Skill | 按任务加载的方法、约束和资源 | 这里讨论的包格式 |
| 插件 | 分发多个能力、配置或工具 | 可以携带 Skill,但范围更大 |
| MCP | 连接实时数据、外部工具和受控动作 | 可被 Skill 调用,不是 Skill 本体 |
AGENTS.md |
项目或目录范围的持久规则 | 约束宿主工作环境,不是按任务加载的能力包 |
GEMINI.md |
Gemini 系列宿主的项目指令 | 宿主指令文件,不是开放 Skill 格式 |
把这些对象统称为“技能”会掩盖权限、发现和生命周期差异。
目录结构
最小布局
适合一次性方法、没有脚本和外部参考资料的 Skill:
example-skill/
└── SKILL.md
只要 SKILL.md 能独立说明触发条件、步骤、输出和停止条件,就不必为了形式增加空目录。
扩展布局
适合需要确定性检查、长篇参考资料或模板资产的 Skill:
example-skill/
├── SKILL.md
├── LICENSE.txt
├── scripts/
│ ├── prepare-input.py
│ └── validate-output.py
├── references/
│ ├── output-schema.md
│ └── domain-guidance.md
└── assets/
└── output-template.md
扩展布局的原则是按需加载。SKILL.md 先告诉 Agent 何时读取哪个资源,不要把所有参考资料复制进主体。目录名采用小写 ASCII kebab-case,例如 example-skill,这是跨文件系统、搜索工具和宿主解析器的稳妥建议,不是说标准必然拒绝 Unicode 名称。参考实现实际上接受 Unicode 字母数字名称,也接受小写 skill.md,但这些属于实现宽松行为,不应作为可移植包的依赖。[2]
文件职责
| 路径 | 必需性 | 职责 | 不应承担的职责 |
|---|---|---|---|
SKILL.md |
必需 | 名称、描述、工作流程、输入输出、边界 | 承诺宿主一定会授予权限 |
scripts/ |
可选 | 可重复的机械检查或数据转换 | 绕过用户授权执行高风险动作 |
references/ |
可选 | 长篇规范、术语、示例和背景材料 | 作为自动发现入口 |
assets/ |
可选 | 模板、样例、静态资源 | 存放凭据或隐含的运行时配置 |
LICENSE.txt |
工程建议 | 说明包的许可条件 | 代替 frontmatter 的 license 字段 |
agents/openai.yaml |
Codex 扩展 | Codex 的界面、默认提示或调用配置 | 伪装成开放标准字段 |
脚本应使用相对路径访问包内资源,避免假定当前工作目录。脚本需要的依赖、输入、输出和失败码应写在 SKILL.md 中。是否允许执行脚本,仍由宿主的工具、沙箱和授权策略决定。
Frontmatter 与元数据字段
标准字段
推荐的跨平台核心写法如下:
---
name: example-skill
description: Process a bounded task with the documented workflow and return a validated structured result.
license: MIT
compatibility: Requires a host that can read package resources and run the declared validation command.
metadata:
version: "0.1.0"
author: example
---
| 字段 | 标准地位 | 约束或用途 |
|---|---|---|
name |
必需 | Skill 名称。建议小写 ASCII kebab-case,并与目录名一致。 |
description |
必需 | 说明做什么和何时使用。应足够帮助宿主发现和路由。 |
license |
可选 | 包的许可说明,可以是标识符或文件名。 |
compatibility |
可选 | 环境要求,例如工具、网络或运行时约束。 |
metadata |
可选 | 宿主或发布方的额外键值。具体键不由开放标准统一解释。 |
allowed-tools |
实验性 | 某些实现尝试声明允许工具,不应作为跨平台安全边界。 |
标准没有规定 version、依赖、签名、注册表、锁文件或更新协议。若把版本放在 metadata.version,它只是包作者的可读信息,不能假设宿主会比较或阻止旧版本。
宿主扩展
| 宿主 | 可观察扩展 | 处理方式 |
|---|---|---|
| Claude | 产品级调用控制、工具和模型控制,以及不同产品表面的加载与共享能力 | 放在适配文档,不写入便携核心。Claude 的安全建议也要求审计整个目录。[3] |
| Codex | agents/openai.yaml 等 Codex 专属配置,项目或用户目录的发现与显式调用 |
作为可选适配层。固定提交中的官方 Skill Creator 文件和协议文档支持这些形状,不推出当前产品的额外承诺。[4] |
| Gemini CLI | activate_skill、激活前同意、允许路径、启用和禁用命令 |
这些是 Gemini CLI 行为,不是 SKILL.md 的标准字段。 [5] |
| Antigravity | Google 公告确认保留 Skill 开放规范方向,但不承诺立即与 Gemini CLI 一对一平等 | 目前不写解析器规则,等待独立文档或实测证据。 [6] |
| OpenCode | 支持核心字段,忽略未知顶层字段,并由原生 skill 工具按需加载 |
不能据此推断其他宿主也会忽略未知字段。 [7] |
| Hermes Agent | 兼容核心包结构,并增加 version、platforms、prerequisites、required_environment_variables 和 metadata.hermes |
这些字段属于 Hermes 扩展。便携核心仍只使用标准字段,平台、工具、环境变量和 Blueprint 配置进入 Hermes 适配层。[9] |
skills-ref是 Agent Skills 仓库提供的参考解析器和校验器,用于检查 Skill 包的基本结构是否符合规范。它会读取 SKILL.md,解析 YAML frontmatter,并检查必需字段、字段类型、名称规则和允许出现的顶层字段。如果出现未知顶层字段,它会直接报错。需要注意的是,它只能检查 Skill 的“文件外形”,不能判断正文是否有用,也不会验证引用资源是否存在、脚本是否能够执行,或模型是否会遵守其中的指令。
在字段处理上,skills-ref 使用固定允许列表,而 OpenCode 会忽略未知顶层字段。这是两种实现之间的直接差异。为了提高可移植性,Skill 顶层应只使用标准字段;额外信息放入 metadata,宿主专属配置则放入对应的适配文件。。
二、从安装到生命周期的一条运行链
Skill 从安装或注册到生命周期记录,经过十个连续阶段。下面用 example-skill 表示其中的具体包;表格中的“保证”只描述执行主体自身能够观察和控制的范围。
| 阶段 | 执行主体 | Skill 输入或对象 | 动作 | 可观察输出 | 能保证什么 | 不能保证什么 |
|---|---|---|---|---|---|---|
| 安装/注册 | 发布系统、插件或宿主配置 | example-skill/ 注册路径及提交 |
将包放入项目、用户或外部 Skill 路径 | 磁盘目录和注册配置 | 文件和路径可被读取 | 宿主一定扫描该路径 |
| 发现 | 宿主扫描器 | 注册路径、example-skill/SKILL.md |
查找包并解析文件入口 | 候选包 | 扫描范围内发现符合外形的包 | 同名优先级和模型采用结果 |
| 索引 | 宿主索引器 | frontmatter 中的 name: example-skill 和 description |
建立低成本候选清单 | example-skill 名称、描述索引 |
元数据可被列出 | description 变成确定性语义规则 |
| 环境过滤 | 宿主索引器 | compatibility、工具集、命令和环境变量 |
检查当前环境并显示或隐藏包 | 过滤后的可见性 | 宿主声明的过滤规则生效 | 过滤器理解用户任务或授予权限 |
| 激活 | 用户、宿主或模型 | example-skill 索引、用户任务、名称或显式参数 |
选择、请求同意或发起加载 | 激活请求、同意提示或工具调用 | 显式入口可被解析 | 模型每次都正确选择 |
| 主体加载 | 宿主 Skill 工具 | example-skill/SKILL.md |
读取 frontmatter 后的正文 | 方法说明进入上下文 | 指定主体被读取 | 正文被完整遵循或不会被压缩 |
| 资源加载 | 模型和宿主读取器 | example-skill/references/output-schema.md |
按正文要求用包内相对路径读取 schema | 输出字段和资源内容 | 指定资源可被加载 | 资源内容可信、存在或可执行 |
| 工具与授权执行 | 宿主权限层、工具注册器、操作系统 | report-only 意图、目标 diff、只读命令 | 拒绝写入或允许已授权的读取和检查 | 工具结果、拒绝结果或授权记录 | 宿主权限门禁能够限制动作 | Markdown 自行成为权限边界 |
| 输出与评估 | 模型、测试夹具、人工审查 | 结构化结果、命令输出、transcript、fixture | 生成结果并区分发现、选择、合规、权限和验证状态 | 结果、状态、未知项和评估记录 | 已覆盖夹具的行为可复现 | 一次通过证明所有会话都正确 |
| 版本与生命周期 | 仓库、发布系统、宿主 | tag、提交、.usage.json 或生命周期记录 |
固定版本、升级、归档或回滚 | 可追踪版本状态 | 仓库和宿主能记录其管理范围 | 开放规范自动锁定、更新或回滚 |
Hermes 的项目发现顺序是 <project-root>/.hermes/skills/、<project-root>/.agents/skills/、~/.hermes/skills/ 和配置外部目录,按 first-wins 处理同名包;项目包还需通过 hermes skills trust 建立信任。该发现、覆盖和信任行为属于 Hermes 固定提交 27562ad5f80e90f7d552f92dbd4af7f1f511c3c8 的宿主证据。[9] 同一提交记录了本地 Skill 的 active → stale → archived 生命周期和 .usage.json 活动记录;这不能扩展为开放规范的统一生命周期。[9]
三、触发与调用
Skill 的触发与调用按因果顺序分为四种机制:自动发现产生候选,环境过滤改变可见性,模型依据元数据作语义选择,用户或模型再通过显式入口加载主体和资源。下面继续使用 example-skill 表示被处理的具体包。
| 机制 | 执行主体 | 具体输入 | 宿主动作 | 输出 | 确定性 | 失败边界 |
|---|---|---|---|---|---|---|
| 自动发现 | 宿主扫描器 | 注册路径、example-skill/SKILL.md |
扫描目录并解析入口文件 | 候选 Skill | 扫描范围内较确定 | 路径未扫描、同名覆盖、信任未建立 |
| 环境过滤 | 宿主索引器 | metadata.hermes.requires_toolsets、requires_tools、fallback_for_toolsets、fallback_for_tools |
检查工具集和环境,显示或隐藏候选 | 过滤后的 example-skill 可见性 |
规则执行可确定 | 字段不识别、显式路径绕过;过滤不等于授权 |
| 模型介导选择 | 模型与宿主工具 | name: example-skill、description、用户任务和上下文 |
模型判断是否适用并决定是否加载 | Skill 调用决定 | 概率性 | 漏选、误选、重复;description 不是确定性语义触发器 |
| 显式调用/渐进加载 | 用户、模型和宿主接口 | Gemini activate_skill、OpenCode skill、Hermes /skill-name 或 skill_view(name);Codex 固定协议中的名称和路径证据 |
解析入口,读取主体,再按需读取资源 | SKILL.md 和需要时的 references/output-schema.md |
指定解析和读取通常确定 | 名称错误、宿主不支持、权限拒绝、压缩或资源缺失 |
以 example-skill 为例,它的 name 和 description 先进入索引;过滤字段决定它是否可见;用户或模型选择后,宿主读取主体;只有生成结构化结果时才读取 references/output-schema.md。Hermes 的渐进接口是 skills_list()、skill_view(name)、skill_view(name, file_path),分别对应低成本索引、完整主体和包内资源。[9]
Gemini CLI 的 activate_skill 和激活前同意、OpenCode 的原生 skill 工具属于宿主行为。[5][7] Hermes 支持 /skill-name 和 skill_view(name);固定提交还记录最多五个连续 Slash Skill。Codex 固定协议和 Skill Creator 样本支持名称及 SKILL.md 路径形状,但不足以断言所有当前产品行为。[4][9]
四、跨平台实现
| 检查维度 | Claude | Codex | Gemini CLI | OpenCode | Hermes | Antigravity |
|---|---|---|---|---|---|---|
| 核心包与证据状态 | 官方文档支持 Skill;具体调用和工具/模型控制随产品表面变化。[3] | 固定提交 186b449bc218ced20399bc950e23ca16cc3f9be3 的固定文件支持核心包和 agents/openai.yaml;仅由固定文件支持,不作当前产品保证。[4] |
官方文档支持 Skill;以下行为限于 Gemini CLI 文档。[5] | 官方文档支持核心字段和原生 Skill 工具。[7] | 固定提交 27562ad5f80e90f7d552f92dbd4af7f1f511c3c8 的文档和源码证据。[9] |
Google 公告只确认方向,独立解析器行为未确认。[6] |
| 发现/入口 | 产品表面决定,未据此指定通用路径;需以具体 Claude 表面验证入口。[3] | 项目/用户发现及显式协议形状有固定文件支持;当前产品行为未被这些文件确认。[4] | 分层发现;入口和允许路径由官方 CLI 文档定义。[5] | 文档列出多个发现位置;原生 skill 工具是入口。[7] |
<project-root>/.hermes/skills/、.agents/skills/、~/.hermes/skills/、外部目录,first-wins;项目入口需 hermes skills trust。[9] |
解析路径未确认。[6] |
| 显式调用 | 调用、工具和模型控制按产品表面变化,未外推统一命令。[3] | 固定协议包含 Skill 名称和 SKILL.md 路径形状;这是协议文件事实,不等于当前产品承诺。[4] |
activate_skill,激活前可请求同意。[5] |
原生 skill 工具。[7] |
/skill-name、skill_view(name);固定提交记录最多五个连续 Slash Skill。[9] |
未确认。[6] |
| 主体与资源加载 | 产品表面决定;需实测 example-skill/SKILL.md 和资源读取。[3] |
固定文件支持 Skill 文件路径;资源加载没有统一协议。[4] | 宿主行为由 CLI 文档定义,资源加载需实测。[5] | 原生 Skill 工具按需加载主体;资源读取需逐包验证。[7] | skills_list() → skill_view(name) → skill_view(name, file_path),可验证主体和 references/output-schema.md 按需读取。[9] |
未确认。[6] |
| 权限/同意边界 | 工具和模型控制随产品表面变化,不能从 Skill 文本推导权限。[3] | 由运行时决定;固定协议文件不提供跨产品权限保证。[4] | 激活前同意、启用/禁用和允许路径由 CLI 配置控制。[5] | 权限系统可询问;未知字段处理不等于权限授予。[7] | 项目 trust、profile、toolset、工具注册和运行时共同决定;allowed-tools 不能据此写成强制沙箱。[9] |
未确认。[6] |
| 可执行验证 | 具体产品表面和版本必须单独记录;矩阵不把格式支持当作行为证明。[3] | 标记为 repository-evidence-only;需实测当前版本。[4] | 可按官方入口、同意和允许路径做 CLI 夹具。[5] | 可按发现位置、skill 工具和权限规则做宿主夹具。[7] |
可按 trust、first-wins、三段加载、Slash 和生命周期记录做固定提交夹具。[9] | 只能记录未确认,不从 Gemini CLI 外推。[6] |
同一个 example-skill 包应在每个宿主分别记录最终解析路径和版本提交,执行该宿主支持的显式入口,确认 SKILL.md 与 references/output-schema.md 的读取结果,尝试未授权写入并记录拒绝或放行,再检查结果是否符合预定输出 schema。这样能把格式发现、入口调用、资源访问、权限边界和输出行为分开归因;未确认单元不能用其他宿主的通过结果填补。
五、Skill 怎样组合与串联
一项复杂任务通常无法由一份 Skill 完成。范围确认、实现约束、代码审查、有限修改和结果验证承担的是不同职责。把这些职责全部写进一份巨大的 SKILL.md,会让触发条件变得模糊,也会让每次调用都加载与当前阶段无关的规则。拆成多份 Skill 后,系统还需要解决两个问题:哪些 Skill 应同时生效,以及前一阶段结束后怎样进入下一阶段。
组合解决共同约束
组合是让多份 Skill 在同一阶段共同进入上下文。它们没有天然的先后顺序,也不自动传递阶段状态。例如,代码审查时可以同时加载 reviewing-code-quality 和对应的语言配置:前者规定审查范围、finding 结构和只读边界,后者补充 Python、TypeScript、Go 或 Rust 的具体检查方式。两份材料共同约束一次审查,但不会因为同时加载就产生“先审查、再修改、后验证”的流程。
同时加载还需要处理职责重叠。若一份 Skill 要求只读,另一份 Skill 允许修改;一份要求先报告,另一份要求立即修复,模型只能在自然语言中解释冲突。可组合的 Skill 因此需要明确自己的责任、默认副作用和优先级,避免两份 Skill 同时控制同一个动作。
| 组合方式 | 进入上下文的内容 | 适合解决的问题 | 不会自动获得的能力 |
|---|---|---|---|
| 同时加载 | 多份 SKILL.md |
共同约束同一阶段 | 阶段顺序和状态转移 |
| Skill 加语言配置 | 通用方法与语言细节 | 保留跨语言核心,同时应用项目惯例 | 自动选择正确工具和命令 |
| 名称清单或 Bundle | 一组 Skill 名称及可选补充说明 | 预先声明需要共同使用的能力 | 结构化交接、失败恢复和授权继承 |
| 宿主预加载 | 入口 Skill 或固定 Skill 集合 | 降低模型发现入口的成本 | 模型必然遵守每条规则 |
部分宿主允许在一条消息中列出多份 Skill,或通过 Bundle 加载一组 Skill。这证明宿主可以确定地完成“把哪些文件放进上下文”,不能证明模型会按预期协调这些文件。[9]
串联解决阶段交接
串联要求前一份 Skill 的结果影响下一份 Skill 的选择。以代码整洁流程为例,可以拆成下面几段:
code-craft-foundations
确认范围、基线、风险和授权
输出:scope、risk、authorization、next_stage
↓
writing-maintainable-code
在实现前固定接口、错误、日志、性能和测试约束
输出:实现契约
↓
reviewing-code-quality
读取实现或 diff,只报告有证据的 findings
输出:findings、unknowns、verification
↓ 人工选择 findings 并授权
simplifying-code-safely
只修改获批文件和 finding
输出:最小 diff、保留的语义假设
↓
verifying-code-changes
分别运行格式化、静态检查、类型或编译、测试和场景验证
输出:结果、未覆盖风险、最终状态
这条链不是因为文件名排成一列就成立。每次交接至少需要前一阶段的状态、输出、下一跳、授权和停止条件。缺少其中任何一项,后一份 Skill 都可能不知道该读取什么,也可能把“报告问题”误解成“已经允许修改”。
一个可检查的交接对象可以写成:
task_id: code-review-001
stage: review
status: complete
scope_checked:
- src/cache.ts
findings:
- CQ-2026-0001
authorization:
mode: report_only
next_stage: needs_human
unknowns:
- 真实依赖服务尚未验证
next_stage 只表达建议去向。authorization.mode: report_only 明确说明当前结果不能直接进入写入阶段。只有用户或宿主更新授权状态,后续修改 Skill 才具备合法输入。这样,串联传递的不是一句含糊的“继续”,而是一组能够被下一阶段检查的条件。
文本路由把下一跳写进 Skill
没有工作流引擎时,Skill 可以直接在正文中声明交接规则。完整的文本路由通常包含以下内容:
| 路由内容 | 作用 | 代码整洁流程中的例子 |
|---|---|---|
| 触发条件 | 确定当前 Skill 何时适用 | 收到限定范围的代码审查任务 |
| 入口动作 | 指定要加载的 Skill 或工具 | 加载 reviewing-code-quality |
| 输入契约 | 规定开始前必须具备的材料 | base revision、目标 diff、项目规则 |
| 输出契约 | 规定交接给下一阶段的内容 | findings、evidence、unknowns |
| 下一跳 | 指出可能进入的阶段 | 授权后进入 simplifying-code-safely |
| 停止条件 | 阻止流程在证据不足时继续 | 范围不清或工具失败时停止 |
| 否定路由 | 明确不能自动进入的路径 | 未授权时不得修改代码 |
| 用户优先级 | 处理默认流程与用户选择的冲突 | 用户拒绝修改时停在报告阶段 |
模型读取这些文字后,可以调用宿主的 Skill 工具加载下一份 SKILL.md。这一过程表现得像自动串联,实际包含了不同性质的动作:宿主注册目录和读取文件通常由程序执行;模型根据任务选择 Skill、理解下一跳并发起调用,仍然是概率性的语言行为。
Superpowers 展示了这种文本串联如何落地。宿主先注册 Skill 目录并注入一个短入口,模型再根据任务选择具体 Skill;brainstorming 的正文把 writing-plans 写成设计确认后的下一步,模型读到规则后再次调用 Skill 工具。这里可复用的是“入口、选择、加载、交接”的结构,而不是这些具体 Skill 名称。[10]
宿主注册 Skill 目录
↓
入口规则进入上下文
↓
模型依据任务选择当前 Skill
↓
宿主工具加载 SKILL.md
↓
当前 Skill 输出结果、停止条件和下一跳
↓
模型或用户决定是否加载下一份 Skill
这条链中,目录注册、入口注入和指定文件读取可以由宿主代码确认;任务匹配、文字规则遵循和下一跳选择不能获得同样的确定性。行为评测需要检查 transcript 中是否真的发生了 Skill 调用,不能仅凭正文出现“必须进入下一阶段”就判定串联成功。[10]
宿主编排提供更强的确定性
宿主还可以在会话开始时预加载入口 Skill、按名称清单同时加载多份 Skill,或在用户接受后建立定时任务。这些机制负责确定“何时把哪份 Skill 放入上下文”。例如,Bundle 表达一组待加载的 Skill;Blueprint 可以形成 SKILL.md → suggestion → user acceptance → cron job → Skill preload 的调度链。[9]
宿主调度仍不等于阶段工作流。真正的工作流引擎需要保存权威状态、校验当前阶段输出、判断转移条件,并把结构化结果作为下一节点输入。它可以强制“没有授权就不能进入修改阶段”,也可以在验证失败后返回指定节点。普通 Skill 的文字下一跳没有这种执行权。
| 串联方式 | 谁决定下一步 | 是否保存权威状态 | 是否能强制转移条件 |
|---|---|---|---|
| 文字 handoff | 模型根据 Skill 正文判断 | 通常依赖当前上下文 | 不能保证 |
| 用户确认后调用 | 用户决定 | 可由宿主记录 | 能形成明确授权点,但不等于完整状态机 |
| 宿主预加载或定时调度 | 宿主配置和调度器 | 保存配置与调度状态 | 能保证加载时机,不能保证模型遵循正文 |
| 工作流引擎 | 程序状态机 | 保存结构化状态 | 可以校验并强制节点转移 |
因此,Skill 的组合与串联处在三个层次:组合负责把相关方法同时放进上下文;文本交接负责表达下一阶段及其条件;宿主或工作流引擎负责把其中一部分关系变成可执行约束。所谓“自动串联”必须说明自动发生在哪一层,不能把文件加载、模型选择和状态调度合并成一个动作。
六、权限、失败与验证边界
权限与信任边界
example-skill 正文声明只读模式,只输出结构化结果,不修改目标文件。这个声明不是权限实现。宿主必须在工具注册、授权提示、沙箱和操作系统层实际拒绝未授权写入;allowed-tools 即使能被解析或扫描,也没有足够证据构成跨平台强制沙箱。[1][9]
项目 Skill 的 trust、外部目录优先级、脚本解释器和环境变量都由宿主和运行环境决定。prerequisites 或 required_environment_variables 可以描述依赖,不能自行授予读取凭据、联网或运行进程的权限。目录中的 Markdown、脚本、README、issue、注释和外部仓库内容都按不可信数据处理;提示注入和供应链内容不能改变 example-skill 的授权范围。[8]
运行时失败类别
- 发现失败:注册路径没有扫描到
example-skill,或同名包解析到意外路径。 - 过滤或选择失败:包进入索引却被环境字段隐藏,或模型看到
name、description后没有选择它。 - 重复 bootstrap:宿主在多个 agent step 注入同一入口,缺少 marker 导致上下文重复。Superpowers v6.3.0 的 OpenCode message transform 需要这类去重边界。[10]
- 压缩丢失:上下文压缩后丢失 report-only、已完成阶段或下一跳;Superpowers 本地 6.1.1 的压缩后补注入记录不能外推为开放规范保证。[10]
- 控制者/worker 泄漏:worker 重复执行入口流程,造成重复规划或错误角色边界。
- 资源或 shell 漂移:
references/output-schema.md不存在、相对路径错误、解释器或 shell 不同,导致正文声明的资源或脚本不可用。 - 权限拒绝:宿主正确拒绝未授权写入,不能被误报为 Skill 执行失败;若实际放行,则是权限边界失败。
- 虚假完成:报告声称已运行命令、读取资源或通过测试,但 transcript 和工具结果没有对应证据。
验证层次
结构层用 skills-ref 检查 SKILL.md、frontmatter 和允许字段;它不能证明 references/output-schema.md 存在,也不能证明模型遵守正文。[2] 宿主基础设施测试记录最终解析路径、版本、索引、显式调用、主体和资源读取、权限拒绝,以及 Hermes 固定提交 27562ad5f80e90f7d552f92dbd4af7f1f511c3c8 的 trust/生命周期行为。[9]
行为夹具必须分别标记发现失败、选择失败、body-compliance 失败、权限失败和验证失败。example-skill 夹具应检查只读模式是否生效、references/output-schema.md 是否解析、结果是否满足 schema,以及输出是否只建议下一阶段而不伪造后续结果。模型行为评估保存任务、Skill 调用、工具调用、结构化结果和失败原因,不能只保存最终文本。
baseline 与 with-Skill 使用同一模型、宿主、输入、权限和工具;前者不加载 example-skill,后者加载它。两组都保存 transcript、资源访问、写入尝试、命令结果、报告、diff 和耗时。对照结果只能说明固定夹具和版本中的观察,不构成所有会话的调度或语义等价证明。
七、规范、宿主和模型各自决定什么
开放格式保证的是一个可被识别的公共核心:目录中有 SKILL.md,文件有合法 frontmatter,name 和 description 表达包的名称与用途,资源可以用相对路径组织。它不保证发现目录、激活时机、工具权限、模型选择、版本锁定、更新回滚或定时调度。[1]
宿主可以保证自己实现的发现、索引、加载、同意、信任、工具和调度行为。Hermes 的三级读取、项目 trust、first-wins、Bundle、Blueprint 和生命周期存在于固定提交;OpenCode 的原生 skill 工具和未知顶层字段处理是另一种宿主行为。Claude、Codex、Gemini CLI 的公开文档支持各自产品能力,不能自动变成跨平台保证。Antigravity 的独立解析规则仍未确认。[4][5][6][7][9]
模型只是在上下文中根据自然语言、任务和工具结果进行概率性选择。它可能正确理解 description,也可能漏掉 Skill、重复调用、跳过授权说明或误读下一跳。Superpowers 的 bootstrap 和文字 handoff 能降低发现成本,却没有把 Markdown 变成程序化状态机。[10]
必须实测的内容包括:同名冲突、信任门槛、资源读取、脚本失败、权限拒绝、提示注入、压缩后规则是否仍在、显式调用是否绕过过滤、Bundle 是否按预期加载、Blueprint 是否等待用户接受、模型是否在正确阶段调用 Skill,以及输出是否通过项目已有验证。能证明的结论应写成“在固定宿主、版本、输入和测试范围内观察到”;不能证明的内容保留为未知,不用“通常”“应该”或产品名称填补空白。
参考文献
- Agent Skills Specification.
- Agent Skills, pinned
skills-refvalidator and parser. - Anthropic, Agent Skills and Claude Code Skills.
- OpenAI Codex, pinned Skill Creator sample and protocol v1.
- Gemini CLI, Skills.
- Google Developers Blog, transitioning Gemini CLI to Antigravity CLI.
- OpenCode, Skills.
- OWASP GenAI, Prompt Injection.
- Nous Research, Hermes Agent,固定提交
27562ad5f80e90f7d552f92dbd4af7f1f511c3c8 - Superpowers v6.3.0。
更多推荐




所有评论(0)