背景:skill 从玩具变成资产
用 Agent 的人大多经历过同一个过程:先是写一个 SKILL.md 试试水,跑通一个真实任务之后突然发现——这个东西是可以沉淀的。目录结构、校验脚本、参考文档、模板资源,攒齐了就是一个可复用的资产。我把自己这种「SKILL.md + references + scripts + assets」四件套结构的 skill 称为一条生产线:喂进去一批用户反馈,产出一份可复核的分析报告。
但资产一旦多起来,玩具式的管理就撑不住了。压垮我的是三个条件同时到来:
- skill 数量奔着 10 个以上去;
- 多台机器都要用,随时可能换电脑;
- 要分发给同事,而且同事往往只需要其中两三个,不是全家桶。
在这三个条件下,我此前「改完直接用、备份靠拷贝文件夹」的方式暴露出四类问题:改了安装副本但源文件没提交的副本分裂;改坏了想回退却发现没有任何历史可回;给同事分发靠微信传压缩包,版本对不上;想给某个 skill 改名,才发现没有任何地方记录过它的来龙去脉。
这篇文章记录我最终落定的方案。它不复杂,甚至可以说朴素,但它把「个人 AI 技能库」从一堆文件夹变成了一个可版本管理、可选择性分发、可快速回滚的小型软件资产库。
架构:双 monorepo,仓库边界即权限边界
第一个决定是仓库怎么分。我见过两种极端:一种是一个 skill 一个仓库,十个 skill 就是十个远程地址,日常 pull 都嫌烦;另一种是全部塞进一个大文件夹不上版本控制,回到原点。
我的答案是按受众切分两个私有 monorepo:
| 工作仓 | 个人仓 | |
|---|---|---|
| 示例名 | org/skills-work |
org/skills-personal |
| 前缀约定 | work-* |
my-* |
| 受众 | 同事(可加为仓库协作者,或走 Release 分发) | 仅自己 |
| 内容示例 | 痛点分析报告、PPT 生成 | 生活工具类 |
关键词是这句话:仓库的边界就是权限与分发的边界。工作仓可以放心加同事为协作者,因为里面本来就没有私人内容;个人仓永远只有自己,也不需要在注册表里做任何「对同事隐藏」的逻辑——物理隔离比逻辑隐藏干净得多。归仓判定只需一句话:会发给同事或涉及公司业务的进工作仓,纯自用的进个人仓。
两个仓内部结构完全同构:skills/ 放所有 skill,registry.json 是注册表,install.py 是安装器。模式是复制的,边界是隔离的。
注册表与安装器:选择性安装是刚需
registry.json 长这样:
{
"skills": [
{ "name": "report-insight", "desc": "用户反馈痛点分析", "version": "3.3", "tags": ["分析类"], "path": "skills/report-insight" },
{ "name": "deck-builder", "desc": "演示文稿生成", "version": "1.4", "tags": ["演示类"], "path": "skills/deck-builder" }
]
}
安装器是一个零依赖的 python3 单文件,核心能力四个:
| 命令 | 作用 |
|---|---|
install --select |
交互式勾选装哪几个,或 --tags 演示类 按标签批量 |
install <name> --tag <skill>/v1.2 |
安装指定历史版本 |
update |
拉取仓库最新状态并同步已安装的 skill |
rollback <name> <tag> |
把某个 skill 回滚到指定 tag |
安装模式分两种人:作者机用链接模式——skill 以符号链接装进 Agent 的技能目录,编辑即生效,永远不会出现「改了安装副本、仓库里还是旧的」的分裂;同事机用复制模式——把所选 skill 拷贝进技能目录,简单直接。没有仓库权限的同事走离线包:你发他一个打包目录,解压后运行同一个安装器,一样可以勾选。
「别人不一定全部安装」这个需求,就是靠注册表的标签字段加安装器的选择性解决的。
版本管理:tag 即版本,CHANGELOG 伴随提交
版本策略三条:
- tag 即版本,格式
<skill名>/vX.Y.Z(如report-insight/v3.3)——monorepo 里每个 skill 独立打 tag,互不干扰; - 语义化版本:主版本号给机制级变更(比如报告生成从手写脚本换成标准生成器),次版本号给样式与组件升级,修订号给规则沉淀和 bug 修复;
- CHANGELOG.md 每个 skill 一份,先于或伴随提交更新,每一条版本记录都写清「触发原因 + 新增/修复/变更」。
提交纪律只有一条,但很硬:每次改动 skill 之后必须提交,不允许攒。这条纪律的价值在一次真实运行里被验证过——我给校验器加了一条「子类计数不得超过分类总数」的规则,下一次跑数据时它立刻抓到一个真实的计数溢出;因为每次改动都有提交,这个修复本身也成了可追溯的历史记录。
回滚路径同样清晰:同事侧用安装器带 tag 重装;作者侧在仓库里 checkout 对应 tag 即可。你不需要记住「上周四改了什么」,CHANGELOG 和 tag 会替你记。
迁移:subtree 保历史,旧仓归档不删
存量迁移最怕丢历史。我的做法是用 git subtree 把已经独立成仓的 skill 并入 monorepo——完整提交历史跟着走;尚未纳入版本控制的其他 skill 直接复制进来作为初始提交。旧的独立仓库保留归档、不删除,作为历史存档。
迁移清单里还有两件容易漏的小事:一是作者机的安装模式切换到链接模式前,先拿一个 skill 实测 Agent 对符号链接目录的发现能力(不同工具行为可能不同,兜底方案是复制模式加提交前反向同步);二是迁移之后「在 skill 目录里提交」的习惯要相应调整为「在 monorepo 提交,但暂存时按 skill 路径划分」——效果完全一样,一次提交仍然只含一个 skill 的变更。
踩过的坑
有三个坑是真实踩过才写进方案的:
- 符号链接的发现性:不是所有 Agent 工具都会把技能目录下的符号链接当真目录处理,先实测再切换;
- 大资产问题:某些 skill 会内置体积可观的资源文件(模板库、运行时依赖),monorepo 会因此膨胀——量小可接受,量大了再评估拆仓或 LFS,不要一开始过度设计;
- 权限模型的二选一:给同事仓库协作者权限意味着他能看到工作仓全部 skill 源码;涉敏感内容时改走离线包分发,只给所选成品。内部协作一般前者够用。
写在最后
整套机制可以用四句话概括:仓库是权限边界,注册表是资产清单,安装器是分发通道,tag 是时间机器。它没有任何高深技术,全部由 git 基础能力加一个几百行的脚本构成,真正的门槛只有一个:把「每次改动必提交」当成纪律而不是习惯选项。
AI 时代的个人资产不只是对话和文档,还有这些被验证过、能稳定复现产出的 skill。它们值得被当成代码一样对待——因为它们的本质就是代码。
评论
0 条登录后参与讨论。本站评论仅对注册用户开放(需站长审核注册),用于展示你的身份。