AI 配置统一管理:skill 只存一份,软链分发到所有 agent

入门进行中

这篇解决什么问题

Claude Code、Codex、Cursor、opencode……同时用两个以上 AI 编程工具的人,几乎都遇到过同一件事:同一个 skill、同一份提示词,在每个工具的配置目录里各存一份。改一个提示词要改四遍,总有一份忘了改、和其他几份对不上。工具越加越多,这事越来越烦。

这篇教你换一种管法:skill 和配置只存一份,放在统一源目录里,用软链分发给所有 agent——改一处,全同步。看完你能拿走:

  • 一套可以直接照敲的命令:建源目录、收拢、逐 skill 建软链、验证
  • 一段丢给 agent 就能自动完成迁移的 prompt
  • 一段让 agent 给你做可视化管理面板的 prompt
  • 三个实际踩过的坑和绕法:缓存进 git、整目录软链、绝对路径死链

全文以 macOS / Linux 为准。Windows 用户建议在 WSL 里照做,行为和 Linux 一致。

前置条件

  • macOS 或 Linux,会打开终端敲命令
  • 本机装了至少两个 AI 编程工具(下文以 Claude Code 和 Codex 为例,Cursor、opencode 同理)
  • 已经有几个自己在用的 skill 或全局提示词文件

原理:软链不是复制,是指针

ln -s 建出来的软链(symbolic link,符号链接)不是把文件复制一份。它本身是个很小的指针文件,里面只存一句话:去那个地方找。

所以在 Claude 的 skill 目录里放一条指向源目录里某个 skill 的软链之后,Claude 打开这个 skill,实际读到的就是源里的那份。你在源里改一个字,Claude 这边立刻就是改过的——它们本来就是同一份文件。

源里存一份,每个 agent 那边一条链。以后改提示词只动源这一处,所有 agent 一起生效。

动手:建源目录,逐 skill 分发

先立一条规矩:一个 skill 一条链。各工具自己的 skills 目录保持是普通目录,里面放的是一条条指向源的软链——不把整个 skills 目录做成一条软链,为什么见后面避坑第二条。

动手前先退出正在运行的 Claude Code / Codex 会话,别在工具正拿着目录的时候搬它的配置。

建统一源目录

以后所有 skill 只在这一个地方存:

bash
mkdir -p ~/.ai/skills

把现有 skill 收拢进去

mv 不用 cp。收拢的目的就是让机器上只剩一份,复制会留下第二份,后面照样改岔:

bash
mv ~/.claude/skills/* ~/.ai/skills/

多个工具都有存量 skill 的话逐个搬。碰到同名但内容不同的,先 diff 看差异,留下你要的那版再搬。

逐 skill 建软链

原目录搬空后留着不动,往里面建链。一条链长这样:

bash
ln -s ~/.ai/skills/commit-message ~/.claude/skills/commit-message

skill 多的话用循环一次建完(目录刚搬空,不会撞名):

bash
for s in ~/.ai/skills/*; do
  ln -s "$s" ~/.claude/skills/
done

建链前确认 ~/.claude/skills 里的同名旧目录已经搬走。同名目录还在的话,ln -s 会把链建到它里面去,变成 commit-message/commit-message,工具读到的还是旧文件。

验证:看箭头

bash
ls -l ~/.claude/skills

每个 skill 一行、每行一个箭头,指向源里对应的目录,这就是成了:

text
lrwxr-xr-x  1 jiumu  staff  38  7  9 10:32 code-review -> /Users/jiumu/.ai/skills/code-review
lrwxr-xr-x  1 jiumu  staff  41  7  9 10:32 commit-message -> /Users/jiumu/.ai/skills/commit-message

链给其他 agent,做同步实验

Codex 同理(它的 skill 目录一般在 ~/.codex/skills,以你机器上的实际位置为准):

bash
mkdir -p ~/.codex/skills
# Codex 里有存量 skill 就先收拢,没有就跳过这行
mv ~/.codex/skills/* ~/.ai/skills/
for s in ~/.ai/skills/*; do
  ln -s "$s" ~/.codex/skills/
done

Cursor、opencode 的配置位置随版本变化,不用一个个查——交给下一节的迁移 prompt 自动探测。

链好之后做一个最能说明问题的实验:在源目录里改一个 skill 的内容并保存,再分别去 Claude Code 和 Codex 里调用它。两边拿到的都是改过的版本——没有复制、没有重配,它们读的是同一份文件。

让 agent 替你干:迁移 prompt

软链一条条敲,工具多了也累。把这套规则写成 prompt 丢给 Claude Code 或 Codex,让它自己探测各工具的配置位置、自己收拢、自己建链:

text
我要把多个 AI 编程工具(Claude Code、Codex、Cursor、opencode 等)的 skill 和配置统一管理:
只在一个源目录存一份,用软链分发给所有工具。请你帮我完成迁移:

1. 建统一源目录 ~/.ai/skills/(已存在就跳过)
2. 探测我机器上各工具的 skill / 配置位置:
   - Claude Code:~/.claude/skills/、~/.claude/CLAUDE.md
   - Codex:~/.codex/ 下的 skill 目录与 AGENTS.md
   - Cursor / opencode:按它们的实际安装位置自己找
3. 把现有 skill 去重后收拢进源目录(用 mv 不用 cp;同名但内容不同的列出来问我怎么取舍)
4. 在各工具的 skill 目录里逐个建软链——一个 skill 一条链,不把整个目录做成软链;
   优先相对路径,避免换机器断链
5. 每一步先列出执行计划等我确认,执行后用 ls -l 验证每条软链的指向
6. 绝不碰各工具目录里的聊天记录、缓存、日志——只动 skill 和配置文件

完成后输出一张清单:源目录里有哪些 skill、每个工具分别链了什么。

这段 prompt 有两处设计别删:让 agent 每步先列计划再执行,防它自作主张动你的文件;明确禁止碰聊天记录、缓存、日志。

增删改全在一个地方

统一源建好之后,日常管理就很干净:

  • 改提示词:只改源里那一份,所有 agent 一起生效
  • 不想用某个 skill 了:去源目录把它删掉,所有 agent 立刻都加载不到;各 agent 侧残留的软链用死链检测顺手清掉
  • 只想给某个 agent 解绑:删掉它那条软链就行,源里的 skill 还留着,其他 agent 不受影响

删软链时命令末尾不要带斜杠:rm ~/.claude/skills/commit-message 只删链本身;写成 rm -rf ~/.claude/skills/commit-message/(带了斜杠)会顺着链把源目录里的真文件删掉。拿不准就用 unlink:它一次只删一个文件名,绝不递归、不跟链。

要改一条已有链的指向(比如源目录搬了家),也别对着旧链直接 ln -sf:旧链指向目录时,新链会被建进目标目录里面。加 -n(不解引用)原地替换,macOS / Linux 都认这个写法:

bash
ln -sfn ~/.ai/skills/commit-message ~/.claude/skills/commit-message

想再直观一点,让 agent 给你做个本地管理面板:行是 skill,列是 agent,格子亮暗表示链没链,点格子就建链、删链,还带死链检测。prompt 直接用这段:

text
给我做一个本地网页面板,管理「统一源目录 + 软链分发」的 skill 体系:

1. 读取源目录 ~/.ai/skills/ 的所有 skill,以及各 AI 工具的 skill 目录
   (Claude Code ~/.claude/skills、Codex、Cursor、opencode——路径写成文件顶部的配置项,方便我改)
2. 渲染一张矩阵:行 = skill,列 = agent;格子亮 = 该 agent 已软链这个 skill,暗 = 未链
3. 点格子 = 实时建 / 删那条软链(后端真执行 ln -s / rm,操作完刷新状态)
4. 每行尾部一个删除按钮:删源目录里这个 skill(先弹确认),所有 agent 侧的软链一并清理
5. 死链检测:软链目标不存在的标红

技术要求:单文件 Node.js server(只用 node:http + node:fs,不装任何依赖)+ 内嵌 HTML 页面,
跑在 localhost。先在一个 demo 沙盒目录里验证增删逻辑,确认无误后我再把配置指向真实路径。

全局配置也这么管:AGENTS.md

不止 skill,全局行为规则同样适用。Codex、Cursor、opencode 都认 AGENTS.md——agent 的项目说明书和行为规则。把规则写在源目录的一份 AGENTS.md 里,同样软链到各工具的配置位置;Claude Code 只认自己的 CLAUDE.md,让 CLAUDE.md 也指过去就行(这是单个文件的链,和逐 skill 建链是同一个道理):

bash
# 一份规则做源(已有 ~/.codex/AGENTS.md 就先收拢进来)
mv ~/.codex/AGENTS.md ~/.ai/AGENTS.md
ln -s ~/.ai/AGENTS.md ~/.codex/AGENTS.md

# Claude 只认 CLAUDE.md,让它指向同一份
# (已有 ~/.claude/CLAUDE.md 的,先把内容合并进 ~/.ai/AGENTS.md 再删掉原文件)
ln -s ~/.ai/AGENTS.md ~/.claude/CLAUDE.md

项目仓库里同理:仓库根放一份 AGENTS.md,再用相对路径链一个 CLAUDE.md 出来,链接跟着仓库走,谁 clone 都不断:

bash
cd 你的项目根目录
ln -s AGENTS.md CLAUDE.md

Claude Code 也支持不用软链的写法:CLAUDE.md 里只放一行 @AGENTS.md(全局就在 ~/.claude/CLAUDE.md 里写 @~/.ai/AGENTS.md)。这是它官方的 import 语法,效果相同;团队里有人用 Windows 时,这招比软链省事。

这样全局规则和项目规则,你都只维护一份。

三个踩过的坑

坑一:别把 agent 的整个目录放进 git 仓库。 Claude、Codex 会往自己目录里写聊天记录、缓存、日志。整个目录进仓库,这些东西全被同步上去,还可能把敏感信息带出去。仓库里只放 skill 和配置这些你自己写的文件,缓存日志用 .gitignore 挡掉。

坑二:别把整个 skills 目录做成一条软链。 看起来省事,一条链全搞定,但工具不认账:Codex 不跟进指向目录的整链,Claude Code 的 issue 区也躺着一排「skills 目录是软链就加载不出」的报告。而且整目录只有一条链,没法按 agent 单独增删某个 skill,出了问题也不好排查。真目录加一个 skill 一条链最稳;上一节的管理面板矩阵,也是按这个模型做的。

坑三:软链尽量用相对路径。 绝对路径把完整路径写死了,换台机器、换个用户名,链就断。更麻烦的是死链不报错——agent 只是安静地加载不到 skill,你还以为它在生效。

相对路径的写法(目标路径相对的是软链所在的位置,不是你当前所在目录):

bash
# ~/.claude/skills/commit-message -> ../../.ai/skills/commit-message
cd ~/.claude/skills
ln -s ../../.ai/skills/commit-message .

单机自用,绝对路径没什么问题;配置要进 dotfiles 仓库、跨机器复用,就用相对路径。已经建好的链可以随时排查死链:

bash
# 找出目标已不存在的死链
find ~/.claude/skills -type l ! -exec test -e {} \; -print

进阶:用 GNU Stow 批量管理

链多了以后,把配置整理成一个 dotfiles 仓库,按工具分文件夹,用 GNU Stow 一句上链:

text
~/dotfiles/
├── claude/
│   └── .claude/
│       ├── CLAUDE.md
│       └── skills/
│           └── commit-message/
└── codex/
    └── .codex/
        └── AGENTS.md
bash
brew install stow        # Linux 用包管理器装:apt install stow
cd ~/dotfiles
stow --no-folding claude codex

--no-folding 一定要带:Stow 默认会把能折叠的目录「折叠」成一条整目录软链——正是坑二要避免的。带上之后 Stow 逐文件、逐个子目录建链,工具往自己目录里写的缓存日志会落成普通文件,不会混进你的仓库。

常见问题

软链会被工具更新弄坏吗? 会有这种事:Claude Code 就有过自动更新把 ~/.claude/skills/ 里的软链清掉的报告(真目录反而留着);重装或首次初始化也可能重建配置目录、把链顶掉。更新后 skill 突然不见,先 ls -l 看链还在不在,没了就重跑一遍迁移 prompt,很快恢复。

多台机器怎么同步? 把源目录(~/.ai 或整个 dotfiles 仓库)放进 git,新机器 clone 下来再建一遍链——手动、迁移 prompt、stow 都行。注意只进配置和 skill,别把缓存带进仓库。别拿 iCloud、Dropbox 这类网盘同步源目录:iCloud 的「优化 Mac 存储」会把不常用文件驱逐成云端占位符,agent 直接读会读不到;Dropbox 干脆不同步软链。

在 Docker / devcontainer 里跑 agent,链还有效吗? 只挂载 ~/.claude 进容器的话无效:链的目标 ~/.ai/... 在容器里不存在,全成死链——相对路径也救不了,目标在挂载子树之外。两个办法:把 ~/.ai 也挂载到容器里的相同路径;或者容器里不用软链,初始化脚本直接把源目录复制进去(Claude Code 官方 devcontainer 模板就是 named volume 加初始化脚本的做法)。

删了源里的 skill,各 agent 那边会怎样? 各 agent 侧会留下死链,agent 安静地加载不到、不报错。用上文的 find 命令或管理面板的死链检测清理。

Windows 能用吗? 建议在 WSL 里照做,行为和 Linux 一致。原生 Windows 的 mklink 概念相同,但各工具在 Windows 上的配置位置差异较大,本篇不展开。

AI 配置统一管理:skill 只存一份,软链分发到所有 agent | 资讯狗 | Zixungou