
我在一个空目录里敲完 npx skills add /tmp/local-skill -a '*' -y,屏幕上跳出一行 Installing to all 79 agents。两秒后,find . -name local-demo 只回了我三条路径。
这不是 bug。它把一个很少被讲清楚的规则暴露出来了:npx skills 的“支持 79 个 Agent”说的是名字,不是目录。 真正落盘多少,取决于你选了谁、这些 Agent 的项目目录在不在、以及你用默认模式还是 --copy。
我花了半个下午,把单 Agent、双 Agent、全 Agent、删除、错误输入和路径穿越都跑了一遍。下面是我看到的。
空目录里的 79 个 Agent,最后只剩三条路径
先交代环境:macOS 22.2.0 / x64,Node v22.19.0,npm 10.9.3,skills@1.7.2(2026-10-09 发布)。仓库 HEAD 是 13e4063a1cf913f5606d57d42ab83a86f5001e04,MIT。
第一个让我愣住的不是 79,而是 54。
-a '*' 的全量安装结束后,终端先打印了:
universal: Amp, Antigravity, Antigravity CLI, Cline, Codex +18 more
symlink → AiderDesk, AstrBot, Autohand Code CLI, Augment, IBM Bob +51 more
终端末尾又补了一行:
symlinked: Claude Code, Eve
skipped: AiderDesk, AstrBot, Autohand Code CLI, Augment, IBM Bob +49 more
(project directory not found)
23 个 universal、2 个 symlinked、54 个 skipped,加起来正好 79。磁盘上实际只有:
.agents/skills/local-demo # 规范副本
.claude/skills/local-demo # 唯一一条 symlink
agent/skills/local-demo # Eve 的副本,真目录
find . -type l | wc -l 是 1。npx skills list 只认两个 Agent:Claude Code、Eve。

换句话说,屏幕上的“全装”是名单全选,不是目录全建。 这个设计本身不算坏——它避免了在你的项目根目录里凭空造出 54 个空文件夹——但如果你只看第一屏的 Installing to all 79 agents,很容易以为所有 Agent 都已经接上了。
为了确认“跳过”的触发条件,我在第二个空目录里先 mkdir .aider-desk,再跑同样的命令。
结果 summary 变成了:
symlinked: AiderDesk, Claude Code, Eve
skipped: AstrBot, Autohand Code CLI, Augment, IBM Bob, OpenClaw +48 more
磁盘上也多了一条 .aider-desk/skills/local-demo -> ../../.agents/skills/local-demo。
规则很直白:目标 Agent 的项目根目录不存在,CLI 就不替你创建,只在 summary 里记一笔 skipped。 你项目里已经有 .cursor/、.claude/、.aider-desk/,它才会往里面放 symlink。对多 Agent 混用的仓库,这算一种保守的礼貌;对第一次上手的人,第一屏的 79 很容易造成误判。
从手动拷贝到路由表:一份规范副本加一张 lockfile
在这之前,我的做法很土:git clone 一份 skill 仓库,再把 SKILL.md 拷到 .claude/skills/;如果同时用 Cursor,就再拷一份到它认的目录。两三个 Agent 还能忍,四个以上就开始出问题:
- 哪份是最新的?没有 lockfile,只能靠文件名和记忆。
- 改了一处,另外两份忘了同步,Agent 行为不一致。
- 想删干净,得记住每个 Agent 的路径。
- 想回滚,只能重新 clone。
npx skills 解决的不是“下载”这一步,git clone 本来就能下载。它解决的是落盘路由:同一份技能,按 Agent 的约定放到该放的位置,并记下来源和 hash。
双 Agent 安装时,磁盘结构终于变成了 README 里说的样子:
.agents/skills/web-design-guidelines/SKILL.md # 规范副本
.claude/skills/web-design-guidelines -> ../../.agents/skills/web-design-guidelines
Cursor 被归到 universal,直接读 .agents/skills/,不额外建目录。skills-lock.json 里记了四样东西:来源 vercel-labs/agent-skills、sourceType=github、skillPath=skills/web-design-guidelines/SKILL.md、computedHash=a6a44d...。
这份 lockfile 是它和“手动 cp”最本质的区别。你可以把它提交进仓库,让同事和 CI 知道这个技能到底从哪来、哪一版。skills update 会按它检查更新;我这轮跑的时候,输出是 ✓ All project skills are up to date。有更新时它会不会覆盖你本地改过的 SKILL.md,我没造一个上游新版本去试,这条没验到。
还有个细节:单 Agent 安装不会创建 .agents 规范目录。 我单独装 claude-code 时,summary 第一行写着 ./.agents/skills/web-design-guidelines,实际磁盘只有 .claude/skills/web-design-guidelines/SKILL.md,find 找不到 .agents。双 Agent 才触发 canonical + symlink。
这不是文档写错,而是它的策略:只有一个目标时,复制一份最省事;有多个目标时,才值得维护一份规范副本。README 把 symlink 标成“Recommended”,但没有说它在单 Agent 下不会发生。
单 Agent 是 copy,双 Agent 才 symlink
我把四种常见装法放在一起,差异比 README 的表格更直观:
| 装法 | 命令里的目标 | 磁盘结果 | 实测耗时 |
|---|---|---|---|
| 单 Agent | -a claude-code |
.claude/skills/... 一份真目录 |
46.65s(含首次克隆) |
| 双 Agent | -a claude-code -a cursor |
.agents 规范副本 + 1 条 symlink |
2.91s(本地源) |
| 全 Agent | -a '*' |
3 条路径、1 条 symlink、54 个 skipped | 2.99s(本地源) |
| 强制复制 | --copy + 双 Agent |
两份真目录,0 条 symlink | 2.15s(本地源) |
表后的判断:如果你只用一个 Agent,npx skills add 的默认行为和手动 cp 没有本质区别,唯一多出来的是 lockfile;真正省事的是两三个 Agent 混用。 如果你追求“一份文件、多处复用”,要确认目标数大于一,或者直接用 --copy 接受两份副本。
耗时也能说明一点问题:冷启动 npx skills --help 是 8.08s,--list 是 12.85s,单 Agent 首次网络安装是 46.65s;后面这 30 多秒主要花在 npx 缓存和整仓 clone 上。换成已经缓存的本地源后,双 Agent 2.91s、全 Agent 2.99s、--copy 2.15s。它自己的落盘逻辑很轻,慢的是“把仓库拿下来”这一步。
--copy 的代价也很直接:技能目录多大,就复制几份。这次的 web-design-guidelines 只有 4.0K,复制两份无所谓;如果是一个带脚本、模板和图片的大 skill,差别就会变成几十 MB。
还有一个体验上的小毛病:--list 和 add 在非 TTY 环境里仍会往输出里刷 spinner 的控制字符,重定向到日志后能看到一堆 Fetching skills…。如果你要在 CI 里解析结果,先做一次过滤,别直接 grep 原始输出。

79 个名字、58 份配置:谁和谁共用一个目录
README 说支持 79 个 Agent;源码里 AgentType 也是 79 个值,但 src/agents.ts 的 agents 对象只有 58 个 key。原因不神秘:很多 Agent 共用同一个目录约定。
举一个具体的:cline、codex、dexto、fx、kimi-code-cli、loaf、pi、sarvam-code、warp、zed 这 10 个名字,共用 src/agents.ts 里的一条配置,落点都是 .agents/skills/。79 减掉这些合并项,才是 58。README 的 79 个 --agent 值我没有手点,是用脚本按表格第二列数出来的;AgentType 的 79 个值也单独数了一遍,两边对上了。

| 类型 | 例子 | 实际目录 | 本次数量 |
|---|---|---|---|
| universal | Amp、Codex、Cline、Zed | .agents/skills/ |
23 |
| symlink 到规范副本 | Claude Code | .claude/skills/ |
1 |
| 独立 copy | Eve | agent/skills/ |
1 |
| 跳过 | AiderDesk、AstrBot、Augment | 项目里没有对应根目录 | 54 |
表后的判断:79 是市场名单,58 是配置表,3 才是这次空目录里的物理结果。 三个数字都真实,但回答的是不同问题。你如果拿 79 去评估“装完占多少目录”,会高估;拿 3 去评估“支持多少 Agent”,会低估。
还有一处 summary 和磁盘对不上的地方:全量安装的 summary 把 Eve 写在 symlinked 里,但 agent/skills/local-demo 是个真目录,不是 symlink。find . -type l 只找到 Claude Code 那一条。Eve 可能需要独立副本,CLI 按自己的规则处理了;屏幕上的分类没跟上。
边界:缺 SKILL.md、路径穿越与大仓库超时
我挑了三个失败路径,看看它会不会说人话。
第一,本地目录里没有 SKILL.md:
No skills found
No valid skills found. Skills require a SKILL.md with name and description.
退出码 1。没有堆栈,也没有假装成功。
第二,我在 SKILL.md 的 name 里写了 ../../evil-name。安装完成后,磁盘上的目录是 .claude/skills/evil-name/,没有跳出 .claude/skills/。源码里的 sanitizeName() 会把非 [a-z0-9._] 的字符压成 -,再去掉首尾的点和横线。安全上这是对的;但 summary 仍然显示原始名 ../../evil-name,看起来有点吓人。
第三,删除。skills remove web-design-guidelines -y 退出 0,规范副本和 symlink 都清掉了,skills-lock.json 变成 {"version":1,"skills":{}},但 .agents/skills/ 和 .claude/skills/ 两个空目录还留着。无害,但别把它当成“没删干净”。
| 我做的操作 | 结果 | 我的判断 |
|---|---|---|
目录里没有 SKILL.md |
exit 1,提示 Skills require a SKILL.md with name and description |
错误信息说人话 |
name 写成 ../../evil-name |
落到 .claude/skills/evil-name/,没有逃出去 |
路径安全,屏幕显示吓人 |
remove 已装技能 |
lockfile 清空,空目录留下 | 内容干净,目录不回收 |
还有一个环境层面的小插曲:skills@1.7.2 的 package.json 要求 Node >=22.20.0,我这台机器是 v22.19.0。npx 打印了 EBADENGINE warning,命令仍然跑通。我没有 22.20+ 的环境,无法判断这是单纯的版本声明保守,还是某个 API 真的在 22.20 才出现。这条我没验到。
小边界之外,还有一条大的:npx skills add 的底层还是 git clone,仓库一大,问题就来了。
vercel-labs/skills#278(2026-02-04 开,截至 2026-10-17 仍是 open,13 条评论)里,有人装 vercel/turborepo 的 skill:仓库约 770MB、6,830 个文件,而目标 skills/turborepo/ 只有 38 个文件。CLI 用了 --depth 1,但那只省历史,不省 HEAD 的文件,60 秒后 clone 超时。社区给的 workaround 是:先手动 git clone --depth=1,再把本地路径传给 skills add。
这正好解释了我自己在第二次网络安装时遇到的 Failed to clone repository。它不一定是仓库的问题,也不一定是网络的问题,而是这条“先整仓 clone,再挑文件”的路径对大仓库天然不友好。

另外两条 open issue 也值得知道:#840(2026-04-01)说 Windows 上全局安装的技能 update 失败;#421(2026-02-25)说 Cursor 全局技能的默认目录不对。都不影响我这次 macOS 项目级安装,但如果你在 Windows 或全局模式下用,先看一眼。
谁该用,谁先别用
我会把它推荐给这三类人:
- 同时在 Claude Code、Cursor、Codex 之间切换,想让同一份 skill 只维护一次的人。
- 想把 skill 来源和版本写进仓库、让同事和 CI 对齐的人。lockfile 比“我本地有一个文件夹”可靠。
- 只想临时用一次某个 skill 的人。
npx skills use /tmp/local-skill --skill local-demo只往 stdout 打 271 字节的 prompt,不落盘,适合一次性任务。
我会劝这三类人先别急:
- 只用一个 Agent 的人。默认就是 copy,和你手动 cp 的区别只有 lockfile;如果你不在意版本记录,手动更直接。
- 大型 monorepo。先看 #278,能手动浅克隆再传本地路径,就别让 CLI 去啃整仓。
- 需要强审计的团队。CLI 的 summary 里确实有 Socket/Snyk 的风险标记,但它安装的是 markdown 指令,最终执行权限在 Agent 手里。安装完的提示写得很清楚:
Review skills before use; they run with full agent permissions.这句话比任何风险徽章都重要。
顺带说个我自己的翻车:第一次试 use,我写成了 npx skills use /tmp/local-skill@local-demo,CLI 直接回 Local path does not exist: /tmp/local-skill@local-demo。本地路径得配 --skill,写成 npx skills use /tmp/local-skill --skill local-demo 才通。README 的示例主要给 GitHub 源,本地路径这条语法没有现成例子。
如果你想今天就试,最小的一套命令大概是:
# 先看仓库里有哪些 skill
npx skills add vercel-labs/agent-skills --list
# 装到两个 Agent,默认走 symlink
npx skills add vercel-labs/agent-skills --skill web-design-guidelines \
-a claude-code -a cursor -y
# 只打印 prompt,不落盘
npx skills use vercel-labs/agent-skills --skill web-design-guidelines
本周另外两个仓库
ranxianglei/billion-context:给 coding agent 做上下文压缩的代理。我核了 npm 上的 billion-context@0.1.198:license 字段写 MIT,GitHub API 却识别成 NOASSERTION,LICENSE 文件不是标准文本;dist.unpackedSize 是 147,805,403 字节,约 141 MB,光 dist/agent/pi-native.js.map 就占 14.9 MB。README 说能省 5 倍 token、撑到 100K 窗口,这轮我没接真实 agent 和上游 API,压缩率没验。它自己承认 jcode 只能 cert-MITM、Gemini CLI 只能 launcher。想接之前,先看看那 141 MB 里有多少是 sourcemap。链接:https://github.com/ranxianglei/billion-context(截至 2026-10-17)
KittenML/KittenTTS:能在 CPU 上跑的本地 TTS。我核了 PyPI 上的 kittenml==0.9.4:wheel 只有 129,810 字节,Apache-2.0,要求 Python >=3.10,包本身很薄,权重另下。GitHub releases 最新 tag 还停在 0.8.1(2026-02-24),但仓库到 2026-10-16 仍在 push,release 页落后于 main。README 说 1.7B 参数 1-bit 模型、默认 947 MiB、47 个音色、20 种语言、CPU 实时;我没下权重,实时性没验。想不碰 GPU 跑 TTS 的人可以盯一下,先确认要用的音色在不在那 47 个里。链接:https://github.com/KittenML/KittenTTS(截至 2026-10-17)
我的判断:它是技能落盘的路由表
回到那个空目录。
Installing to all 79 agents 这句话没有撒谎,它只是回答了“名单上有谁”。真正决定你磁盘长什么样的,是另外三个变量:目标 Agent 的项目根目录在不在、你选了一个还是多个目标、你用默认还是 --copy。
npx skills 的价值不在“一条命令装 79 个”,而在把 79 个名字收敛成 58 份配置,再用 canonical + symlink + lockfile 把落盘这件事变成可重复的。 对多 Agent 用户,这个收敛值钱;对单 Agent 用户,它更像一个带版本记录的 cp。
下次你看到那行 Installing to all 79 agents,别急着关终端。先跑一句 find . -name SKILL.md。屏幕上是名单,磁盘上才是事实。
什么证据会让我改口?如果后续版本在单 Agent 下也建 .agents 规范目录,或者 -a '*' 开始替你创建缺失的项目根目录,我上面“3 条路径”的判断就作废;如果 #278 用 partial clone 或按需下载修掉大仓库超时,那条劝退也要撤回。这两个变化都比 star 数值得盯。
项目地址:https://github.com/vercel-labs/skills
参考:
- 仓库:https://github.com/vercel-labs/skills(抓取 2026-10-17)
- v1.7.2 release:https://github.com/vercel-labs/skills/releases/tag/v1.7.2(2026-10-09)
- issue #278:https://github.com/vercel-labs/skills/issues/278(2026-02-04)
- issue #840:https://github.com/vercel-labs/skills/issues/840(2026-04-01)
- issue #421:https://github.com/vercel-labs/skills/issues/421(2026-02-25)
- npm 包:https://www.npmjs.com/package/skills
FAQ · 常见问题
常见问题
npx skills 装完为什么磁盘上只有三条路径?
目标 Agent 的项目根目录不存在,CLI 就不替你创建,只在 summary 里记一笔 skipped。我在第二个空目录先 mkdir .aider-desk 再跑同一条命令,symlinked 就多出一个 AiderDesk,磁盘上多出一条指向规范副本的 symlink。23 个 universal 加 2 个 symlinked 加 54 个 skipped 正好 79。
只用一个 Agent 时它比手动拷贝强在哪?
只多一份 lockfile。单装 claude-code 时 summary 第一行写着 ./.agents/skills/...,实际磁盘只有 .claude/skills/ 下面一份真目录,find 找不到 .agents;双 Agent 才触发规范副本加 symlink。skills-lock.json 记下来源、sourceType、skillPath 和 computedHash,能提交进仓库让同事和 CI 对齐。
skills add 报 Failed to clone repository 是谁的问题?
多半是仓库太大。它底层还是 git clone,--depth 1 只省历史不省 HEAD 的文件:issue #278 里装 vercel/turborepo 的 skill,仓库约 770MB、6,830 个文件,目标 skills/turborepo/ 只有 38 个文件,60 秒后 clone 超时,社区给的 workaround 是先手动浅克隆再把本地路径传进去。同一批操作换成本地源,双 Agent 只要 2.91 秒。
End of article · 读完这一篇
- 实际用时
- —
- 章节覆盖
- —
- 约读字数
- —
微信支付
支付宝