一套让 7 个 AI Agent 共享同一份 Skills 的方案(Windows Junction 实战)
你的电脑上装了多个 AI Agent(Claude Code、Codex、Cursor、Qoder、Trae、WorkBuddy......),每个都从自己的约定目录加载 Skills。同一个 Skill 装了 N 份副本,改一处其余全不知道,时间一长必然漂移。本文给出一套经过实战验证的方案:一个 git 仓库做唯一实体层,其余所有 Agent 目录全部用 Junction 指入,改一处全端生效。
一、问题:Skills 副本漂移是必然的
各 AI Agent 都遵循 Agent Skills 规范(每个 Skill = 一个含 SKILL.md 的文件夹),但都只从自己固定的约定目录加载,且大多不支持自定义路径。我在自己的机器上做了一次全盘扫描,结果很典型:
- 全机约 29 个 Skill 散落在 6 个目录里;
- 5 个 Skill 存在多副本,其中 3 组副本的 SKILL.md 哈希已经不一致------同一个 Skill 在不同工具里是不同版本;
- 有一组 169 个文件的 Skill 存了两份完全相同的拷贝,纯冗余;
- 只有 1 个 Skill 是理想形态:实体只存一份,其他目录是链接。
副本漂移不是偶发,是结构性的:只要"每装一个工具复制一份"的模式不变,漂移只是时间问题。
二、各 Agent 的技能目录(官方文档核实)
动手前先核实了各工具的用户级技能目录(以官方文档为准,2026-10):
| Agent | 用户级技能目录 | 原生读 ~/.agents/skills/? |
|---|---|---|
| Codex | ~\.codex\skills\ |
✅ |
| Cursor | ~\.cursor\skills\ |
✅ |
| Claude Code | ~\.claude\skills\ |
❌(但官方明确支持 symlink 条目) |
| Qoder 国际版 | ~\.qoder\skills\ |
❌ |
| Qoder 国内版 | ~\.qoder-cn\skills\ |
❌ |
| Trae 国内版 | ~\.trae-cn\skills\ |
❌ |
| WorkBuddy | ~\.workbuddy\skills\ |
❌ |
两个容易踩的坑:
- 国内版目录名带
-cn后缀 (qoder-cn、trae-cn),照抄国际版文档会配错地方; - Codex 部分版本 Skills 是实验特性,需要在
~/.codex/config.toml加[features] skills = true。
三、方案演进:三条路线的取舍
| 路线 | 做法 | 结论 |
|---|---|---|
npx skills add <repo> -a ... |
官方 CLI 一键装到项目级 .agents/skills/ 并链入各 Agent |
项目级、每 Agent 一份副本(Windows 默认 copy),不是机器级共享 |
实体放 ~/.agents/skills/ 作枢纽 |
Codex/Cursor 原生读,其余 Agent Junction 指入 | 可行,但枢纽仍是一份"中间副本",与 git 版本化脱节 |
| 唯一实体层 = git 仓库(终态) | 一个资产仓库存全部 Skill 实体并 git 版本化,所有 Agent 目录一律 Junction 指入 | 单一真相源 + 免费获得版本化/回滚/审计 |
第三条路线胜出的关键:换新机器 = clone 仓库 + 跑一遍建链脚本;改坏了 = git checkout 回滚;第三方 Skill 的安全审计只需要审计一份。
四、终态架构

xml
D:\ai-assets\skills\ ← 唯一实体层(git 仓库)
│ <skill-name>\SKILL.md ...
│ MANIFEST.json ← 登记表:来源/收录日期/ignore 清单
│
├─→ ~\.agents\skills\<skill> (junction,Codex/Cursor 原生读)
├─→ ~\.claude\skills\<skill> (junction)
├─→ ~\.codex\skills\<skill> (junction)
├─→ ~\.cursor\skills\<skill> (junction)
├─→ ~\.trae-cn\skills\<skill> (junction)
├─→ ~\.qoder-cn\skills\<skill> (junction,产品内置 Skill 不收编)
└─→ ~\.workbuddy\skills\<skill> (junction)
终态验收标准很简单:每个 Agent 目录里的 junction 数 = 仓库 Skill 数,实体副本清零。
五、Windows Junction 实战要点(踩坑实录)
1. 用 Junction,不用 Symlink
cmd
mklink /J %USERPROFILE%\.claude\skills\<skill> D:\ai-assets\skills\<skill>
- Symlink(
mklink /D)需要管理员权限或开发者模式;Junction 不需要,且对应用完全透明; - Junction 支持跨本地盘(C: 用户目录 → D: 仓库没问题);
- 注意 Junction 存的是绝对路径:仓库目录一旦改名/移动,全机链路同时断。对策是路径固化 + 建链脚本可一键重建。
2. Node 建链会 EBUSY,需要降级路径
批量建链用 Node 脚本很顺手(fs.symlinkSync(target, path, 'junction')),但实测发现:在正在运行的工具所监视的目录里(如 ~/.agents),Node 的 symlinkSync 会稳定报 EBUSY,而系统原生 API 不受影响。
脚本里的降级写法:Node 建链失败时,调用 PowerShell 兜底:
powershell
New-Item -ItemType Junction -Path <链接路径> -Target <实体路径>
这个坑只影响"目录被进程占用"的场景,其余目录 Node 直建即可。
3. 其他 Windows 特有注意项
- clone 含 symlink 字段的仓库(如
AGENTS.md → CLAUDE.md)在 Windows 检出为普通文本,warning 可忽略; - 实体仓库不要放进 OneDrive 等云同步目录,同步工具会错误处理 junction;
- 执行清理/建链期间,注意正在运行的 Agent 可能并发操作自己的技能目录------先收编(复制进仓库 + 哈希校验)再删除实体,顺序不能反。
六、配套工具链:让方案"活得下去"
架构只是一半,另一半是防止半年后忘了规则。配了 4 个零依赖 Node 脚本:
| 脚本 | 作用 |
|---|---|
link-skills.mjs |
正向建链:仓库 skills/ × 各 Agent 目录 → 补缺失 junction。幂等可重复跑,含 EBUSY 降级 |
sync-from-agents.mjs |
反向收编 :扫描各 Agent 目录里的"黑户"(实体 Skill 但仓库没有,比如在某家商店里装的)。默认只报告,--archive 归档进仓库并原位替换为 junction |
sync-all.mjs |
总入口:建链 → 黑户扫描 → 漂移/悬空检查 → git 未提交提醒。日志落盘,退出码 0=干净/1=有警告 |
sync-all.cmd |
定时壳文件,给任务计划程序/任意调度器调用 |
常用命令:
bash
# 体检(只读,推荐每周跑一次)
node scripts\sync-all.mjs --report-only
# 新装 Skill 后全量建链
node scripts\link-skills.mjs
# 商店装了新 Skill 后收编
node scripts\sync-from-agents.mjs --archive

定时体检接入 Windows 任务计划程序:
cmd
schtasks /Create /TN "ai-assets skill sync" /SC WEEKLY /D MON /ST 09:00 ^
/TR "D:\ai-assets\scripts\sync-all.cmd"
一条纪律:脚本绝不碰 git
工具链只做"检查 + 提醒",绝不自动 commit/push。提交永远由人执行------AI 代理仓库执行 git 状态变更的事故概率,不值得用自动化去赌。
七、风险清单(值得抄走)
| 级别 | 风险 | 缓解 |
|---|---|---|
| P0 | 供应链爆炸半径 ×N:一个被投毒的 Skill 同时注入全部 Agent | 只挂审计过的来源;pin tag/commit 不盲目追 main;新 Skill 先单 Agent 验证再全量 |
| P0 | 坏更新无灰度:git pull 即全端生效 |
pull 前看 diff;git checkout <tag> 可回滚;先单端冒烟 |
| P1 | 上游改名/删除 → 悬空 junction | 定时体检自动检测,建链脚本幂等重建 |
| P1 | 同一 SKILL.md 在不同工具触发语义不同(Codex $name、Claude /name、其他按 description 自动触发) |
接受"内容共享、触发各异";description 写可移植 |
| P1 | Skill 数量多会吃上下文预算(Codex 约有 2% 上限) | 只挂真正在用的,不要 39 个全链 |
八、验证:证明加载的是同一份物理文件
最后一步别省------证明所有工具读到的确实是同一份文件,而不是 N 份巧合相同的副本:
- Junction 有效性 :
cmd /c dir "%USERPROFILE%\.claude\skills"应看到<JUNCTION>类型及指向仓库的目标路径;

- 逐 Agent 加载 :Claude Code 输
/看技能列表;Codex 用$skill-name;Cursor/Qoder 在聊天框/搜索;Trae 看技能面板; - 单一真相源实验(关键) :直接改仓库里的某个
SKILL.md,在 frontmatter 的 description 末尾加标记词SHARED-CHECK,重启各 Agent 确认都读到该标记 → 证明物理同源。验证完改回。
九、总结
- 唯一实体层 + Junction 解决"多 Agent 共享同一份 Skills",且自带 git 版本化;
- 两个 Windows 专属坑:Junction 而非 Symlink;Node 建链 EBUSY 需 PowerShell 降级;
- 方案要配"双向同步 + 定时体检"的工具链才活得下去:正向建链、反向收编黑户、每周体检;
- 纪律比自动化重要:脚本不碰 git,供应链风险用 pin 版本 + 单端冒烟来兜。
如果你的 Agent 数量 ≥ 3,这套方案的维护成本优势会立刻显现;只有 1-2 个工具的话,直接用各家商店装副本也够用。