像写代码一样组合并版本化 Skill
教程 · 阅读时间 8 分钟
大多数 Skill 集合只是一堆彼此毫无关系的 Markdown 文件。如果 typescript-testing 和 rust-testing 都源自同一套基础测试理念,那么这套理念就在两个文件里各存了一份——而当它发生变化时,你得改两遍,或三遍,或者有多少 Skill 共享它就改多少遍。
Skilnu 更像是把 Skill 当作包来对待:它可以声明对另一项 Skill 的依赖、固定版本约束,并在该依赖发布新版本时自动获得更新后的内容。下面是具体用法。
1. 发布基础 Skill
先写共享的那部分——将被多项 Skill 共同依赖的内容。照常发布,并给它一个真正的语义化版本号:
name: testing-philosophy
description: Shared testing principles: what to test, what not to, naming conventions.
version: 1.0.0
2. 在组合 Skill 中声明依赖
当你发布基于它构建的 Skill 时,把基础 Skill 写在 Dependencies 下面,而不是把它的内容粘贴进去:
- type: skill
id: yourhandle/testing-philosophy
version_constraint: ">=1.0.0"
optional: false
Skilnu 会解析该依赖,确认你(或任何加载该组合 Skill 的人)有权访问它,并保持引用处于活动状态——组合 Skill 读取的始终是依赖在你的版本约束范围内的当前内容,而不是发布时留下的快照。
3. 更新基础 Skill
为 testing-philosophy 发布一个新版本——比如 1.1.0,新增一节关于不稳定测试的分类处理。任何以兼容约束依赖它的 Skill(>=1.0.0 匹配 1.1.0)都会在下次加载时获得该变更。你只改了一个文件,所有依赖方都自行更新了。
如果某项变更会破坏兼容性,请把它作为新的主版本发布,并把约束的决定权留给依赖 Skill 的维护者——这与语义化版本的包所遵循的惯例完全一致。
4. 下线旧版本而不破坏依赖方
当某个版本不再是你希望大家依赖的版本时,把它标记为弃用。仍固定在它上面的内容照常工作;约束较宽松的内容会在下次解析时自然迁移开。
5. 用 fork 取代复制
从别人的 Skill 出发,但需要分叉而不是实时依赖它?发布时使用 Derived from 和 Lineage mode: fork。Skilnu 会记录 fork 的来源以及你所做改动的摘要——即使两项 Skill 此后不再互相跟随更新,这层关系依然可追溯。
derived_from: origin-publisher/base-skill@1.4.2
lineage_mode: fork
lineage_changelog: Added stricter validation and examples
它在哪些场景最有价值
对于那些本质上是「同一项 Skill 重复 N 次」的情况,组合的收益来得最快——同一套测试或 lint 理念在不同语言下的变体、在共享故障手册之上的团队专属补充,或是被十几项更具体 Skill 共同依赖的内部风格指南。凡是在代码中你会去取用共享库的地方,在这里就取用依赖,而不是再来一次复制粘贴。