Skills
一个 Skill 就是一份 Markdown 文档,加上它所引用的文件。agent-bundle 从 src/ 约定中发现 Skill,把
每个 Skill 降级为每个所选宿主期望的写法,并把该目录中其余文件作为这个 Skill 的资源随行发布。
约定
每个 Skill 一个目录,里面放 SKILL.md:
这样就能随产物发布,无需任何声明。目录中除 SKILL.md 之外的所有内容,以及除渲染式 Skill 源文件
之外,那些是构建输入,都会成为该 Skill 的资源,并保留相对路径复制进产物。
文档
SKILL.md 以 YAML frontmatter 开头,其后是普通 Markdown:
frontmatter 是必需的。缺少 frontmatter 的文档报告 AB3001;YAML 无效则报告 AB3002。name 与
description 是每个宿主都会读取的字段,description 就是激活表面,因此请把它写成「在什么条件下应当
使用这个 Skill」,而不是写成标题。
指向同级文件的链接是 Skill 引用自身资源的方式。它们在输出文档中保持相对形式,因此在宿主安装的任何 产物中都能正确解析。
让指令保持聚焦
宿主会把每个 Skill 的 name 与 description 载入上下文供模型选择。描述过长或彼此重叠会被截断;
触发条件含糊会加载错误的 Skill。优先写简短能力加上明确的 何时使用,而不是宽泛领域:
避免,任何与数据库沾边都会触发:
更好,只有真正做迁移时才触发:
正文只保留有用的共通指引和真实的安全或授权约束。如果描述已经说明适用边界,就无需重复一个 “When to use” 小节。
把根目录 SKILL.md 当作路由器:把较长的特定模式操作流程放入 references/,并通过链接说明何时阅读
(渐进披露)。不要在入口加载所有参考文件,也不要为简短且自包含的 Skill 创建无用的资源目录。
assets/ 保存用于输出的文件,而不是必须始终加载到上下文中的指令。曾帮助较弱模型的过细步骤清单,
往往反而约束较强模型,保留不变量,删掉仪式。
正文应让代理保持用户请求的范围:计划或审查不能悄悄变成实施或发布。复用已有授权与当前有效的证据, 在确需批准前完成相关准备,最后交付所请求的结果及其验证或限制。除非真实工作契约要求,否则不要强制 进行广泛审计、重复检查或固定的报告仪式。发布就绪判定仍需当前候选版本的检查证据;计划任务可以明确 列出待完成的检查。
create-agent-bundle 的 minimal 模板遵循这一模式:它检查当前 Skill 目录,而不是假定脚手架最初的
能力始终不变。渲染式 Skill 也应遵循相同原则:审查输出的 Markdown,而不仅是组件源码。
显式选择 Skill
约定发现覆盖 src/skills/*/SKILL.{md,ts,tsx}。当你需要不同位置、只取子集,或需要一份字面清单时,
再声明 skills:
字面路径保持字面;glob 匹配 Skill 目录或 SKILL.md 文件。配置总是胜过约定。
宿主扩展
可移植的 Skill 元数据,name、description、license、compatibility、allowed-tools(Agent Skills
的拼写;驼峰式 allowedTools 只在 targets.claude 下被接受),以及一个
自由形式的 metadata 记录,每个 target 都能理解。宿主专属的键位于各自宿主之下,因此只会抵达该适配器:
Skill frontmatter 中的 targets 就是上述按宿主划分的对象,别无他用;写成列表(如 targets: ['claude'])是
AB3006。Skill 会输出到项目选择的每一个 target,不存在按 Skill 限制产物的机制。
Claude Code、Codex、Cursor 与 portable 共享 skills/<name>/SKILL.md;Amp 的副本位于
.amp/plugins/<plugin>/skills/<name>/SKILL.md。若某个宿主扩展让共享文档在一个选中宿主上的降级结果
与另一个宿主不同,例如在 claude + codex 的构建中写
targets: { claude: { effort: high } },就是致命的 AB4103 冲突。请让输出的文档对每个选中宿主
都完全一致,或者把这些宿主分开构建到不同的产物中(每次构建只写一个 targets 条目)。
Amp 注册与 Skill MCP
Amp 不会扫描目录插件中的 skills/。生成的 index.js 会为每个捆绑 Skill 恰好一次地等待
amp.registerSkill({ path: 'skills/<name>' })。Amp 把它列为 <plugin>:<skill>,因此不会与机器、项目、
Claude 兼容、内置、个人或工作区来源发现的裸 Skill 名竞争。
builtin-tools 会把同一个 Amp 插件注册的工具隐藏到 Skill 加载时。SKILL.md frontmatter 中的
mcpServers 优先于同级 mcp.json;作者提供的同级文件也会保留而不会被覆盖。规范
mcp.servers 以 Amp 为 target 时,仅在恰有一个捆绑 Skill 且两种原生来源都不存在时,才输出扁平服务器映射。
路径 token
各宿主的占位符语法并不相同,${CLAUDE_PLUGIN_ROOT} 并不是 Cursor 或可移植标准所使用的写法。请改为
编写规范 token,由构建期降级替换成宿主写法:
降级只替换语法;构建期不会解析任何运行时取值。宿主无法表达的 token 会被报告,而不是悄悄以字面文本 输出。
渲染式 Skill
当一份 Skill 文档是生成出来的而不是手写的,例如逐环境重复的同一张检查表,或从某个契约推导出的表格,
请在 src/skills/<name>/SKILL.tsx(或 .ts)放一个组件。它默认导出一个组件并导出一个
frontmatter 记录;构建会把渲染树编译成宿主消费的 SKILL.md 文档:
六个 Skill.* 成员会输出规范 token:Skill.Arguments、Skill.PluginData、Skill.PluginRoot、
Skill.ProjectRoot、Skill.SessionIdentity 与 Skill.SkillRoot。Skill.Resource 渲染的是
Markdown 链接([path](path)),不是 token。宿主语法在降级阶段应用,绝不在组件里应用。
渲染源可以导入项目代码,因此文档由插件所发布的同一批源码计算得出;它也可以导入
agent-bundle/meta:加载器提供的 { name, packageName, packageVersion, version } 与编译器烙印到
每个构建面上的完全相同,所以 Skill 能打印出它所描述的版本。它的 JSX 针对加载器自己的元素工厂编译,
而不是项目的 react/jsx-runtime,渲染器只遍历普通元素对象,不需要任何 React 内部实现,因此求值
不依赖进程如何解析 react(包括 route-unit 池的 react-server 条件),inspectWorkbenchSurface
可以从任意池检查带有渲染 Skill 的项目。
同目录下手写的 SKILL.md 总是胜出,手写文件胜过生成文件,被遮蔽的组件会报告信息级的 AB4735
提示。渲染模块加载失败报告 AB3003;未默认导出组件函数、或未导出 frontmatter 记录,则报告
AB3004。
defineSkill 可以在渲染式源码旁给 Skill 定义加上类型:
检查发布了什么
skill focus 会展示每个被发现的 Skill、它的 provenance(conventional 或 config)、它的资源,以及
逐 target 的降级判断。在开发者 Workbench 中,于 Application → Skills 下选中该 Skill。
输出文档是默认视图;源码/生成差异、frontmatter、资源与 eval 覆盖是检查器标签。
Skill Markdown 中的原始 HTML、JSX/MDX 与 Mermaid 在 Workbench 渲染器中是惰性的。这是刻意的隔离边界, 不是渲染缺失。
下一步
- 钩子:对生命周期事件作出反应。
- MCP 服务器与 MCP App:暴露工具、资源与提示词。