
我手头同时维护着好几个Agent环境——主力是Claude CodeClaude Code之外又装了Codex做对照测试偶尔还要开着VSCode里的AI插件跑点小任务。刚开始那会儿我的心态很简单谁好用用谁。结果用了两周就发现一个问题每个Agent都要单独配一套SkillsClaude Code收一份技能Codex再收一份技能同样一个代码审查技能我在两个环境里维护了两份改了一处忘了另一处行为开始漂移版本对不上最后干脆靠复制粘贴硬撑。这肯定不是长久之计。Skills这套东西本质上是给Agent的岗位说明书工具箱它跟具体哪个Agent跑没有强绑定关系。只要格式统一、路径管理得当完全可以做到一套技能库多个Agent共享。这篇文章就把我踩过坑之后搭出来的统一管理方案完整拆开从目录设计、SKILL.md格式规范、符号链接打通到Claude Code、Codex两边的实际配置一条一条讲清楚。不管你是刚接触Skills的新手还是已经维护了一堆技能的老手这套方案都值得参考。1. 先搞清楚Skills在Agent里到底是以什么形态存在的1.1 每个Agent都在重复造轮子这本身就是问题先说现状。Claude Code按官方规范从~/.claude/skills/和个人项目里的.claude/skills/目录加载技能每个技能是一个子目录里面放一个带YAML头部的SKILL.md文件再加上若干辅助脚本和参考文档。Codex虽然历史包袱重一些但社区里主流的扩展方式也统一到了类似形态——在~/.codex/skills/或项目的.codex/skills/下放SKILL.md。VSCode类插件比如Cline、Roo Code对SKILL.md的兼容性也越来越好。但问题就在这同一个技能你得按每个Agent的目录约定各自放一份。今天优化了Claude Code里前端开发技能的一段prompt明天忘了同步到Codex后天跑出来的结果就是两套行为。更麻烦的是脚本类技能一旦涉及本地可执行文件两份拷贝各自独立改bug要改两遍漏一处就是坑。这种重复维护的成本短时间内还能忍技能一多直接失控。1.2 SKILL.md的本质是纯文本协议不绑定任何Agent解决重复维护问题之前得把Skills的底细摸清楚。我拆解过Claude Code官方那批技能包包括superpowers那套社区方案结论很明确SKILL.md本质上一个Markdown文本通过YAML frontmatter声明元信息通过正文一步步告诉Agent面对这个场景你该怎么做。这意味着Skills跟特定Agent是解耦的。Agent只是负责读这份说明书、按说明书执行的角色。只要你的SKILL.md写得足够通用不掺入如果你是Claude这类限定语不依赖某个Agent独有API它天然就能被多个Agent读取。脚本附件就更简单了Python脚本、Shell脚本只要是标准解释器能跑的任何Agent调用起来都没有障碍。理解这一点整个统一管理方案的地基就稳了——我们不是要做技术转换而是要做目录收敛和路径打通。让所有Agent都指向同一个物理位置的同一份Skills自然就消除了重复维护。1.3 统一管理到底能带来什么心里要有数我在团队内部推这套方案的时候有人问就直接把目录结构理一下真有那么大价值吗我列了三个实际收益第一行为一致性。所有Agent从同一份技能库读数你用Claude Code审查代码是什么样的规范切到Codex跑同样技能拿到的规则完全一致。这个对团队协作特别重要因为Agent跑出来的东西最终是要合并进同一个代码库的。第二维护成本骤降。技能更新只改一处git提交所有环境同步生效。不用再记着哪个Agent的哪份技能过期了这种脑内清单。第三可审计、可回滚。整套技能库纳入git版本管理每一行改动都有记录。出问题了一行命令回到上一个稳定版本这在多Agent场景下是刚需。2. 目录设计一套技能库多个Agent怎么共享落地2.1 顶层目录应该怎么规划我最终落地的目录方案是这样的用一个独立仓库承载所有技能skills-repo/ ├── skills/ # 所有技能包按领域分子目录 │ ├── code-review/ # 代码审查技能 │ │ ├── SKILL.md │ │ ├── rules/ │ │ │ ├── security.md │ │ │ └── performance.md │ │ └── scripts/ │ │ └── review_helper.py │ ├── frontend-dev/ # 前端开发技能 │ │ ├── SKILL.md │ │ └── templates/ │ └── math-model/ # 数学建模类技能 │ ├── SKILL.md │ └── references/ ├── README.md # 技能库使用文档 └── scripts/ ├── install.sh # 一键安装创建符号链接 └── update.sh # 一键更新拉取重链这里有几个设计要点我解释一下。skills/是技能的物理存放位置每个技能独占一个目录目录名就是技能名里面必须有一个SKILL.md辅助文件和脚本按rules/、scripts/、templates/这样的约定放。子目录分类是为了方便维护不是为了给Agent读的Agent读取的还是每个技能目录下的SKILL.md。真正把多Agent共享落地的是scripts/install.sh这个脚本。它在每个Agent的配置目录里创建符号链接指向skills-repo/skills/下对应的技能目录。这样Agent读到的还是它自己约定位置的文件但实际内容是仓库里唯一的物理拷贝。2.2 技能包目录的命名与内部结构约定技能目录命名我有几条强制约定都是实践中踩过坑换来的全部小写用连字符分隔比如code-review、frontend-dev。名字要能直观看出来这个技能是干什么的不要用utils、misc这种模糊命名。每个技能目录里只放跟这个技能相关的东西宁可多拆几个技能也不要搞出一个几百MB的全家桶目录。内部结构上我推荐至少区分SKILL.md和辅助资源。SKILL.md是入口文件负责定义什么时候用这个技能、核心步骤是什么。辅助资源包括规则清单、模板、脚本通过相对路径被SKILL.md引用。这样做的好处是需要大批量调整某个细节时你只需要改规则文件不需要动SKILL.md的主干描述。2.3 一套可复制的SKILL.md标准模板所有技能的SKILL.md我统一用下面这个模板格式固定了后续维护和批量生成都省事--- name: skill-name description: 什么时候用这个技能以及触发关键词。描述要具体写清楚适用场景。 --- # 技能名称 ## 适用场景 这个技能在哪些任务中使用什么情况下不应该使用。 ## 执行流程 1. 第一步做什么为什么做。 2. 第二步做什么具体标准是什么。 3. 最后一步产出什么结果。 ## 检查清单 - [ ] 输入参数是否齐全 - [ ] 输出是否满足验收标准 ## 参考资源 引用规则文件见 rules/ 目录。 调用辅助脚本python3 scripts/review_helper.py -h关键在YAML里的description字段。这是我反复强调的一点Claude Code官方文档明确说明技能被加载的依据是Agent判断用户请求与技能描述的匹配度。描述写得太泛写处理代码问题Agent根本不知道什么时候该用描述写得太窄写只在处理React组件性能优化时使用那换个框架场景就失灵。我自己的经验是description里要包含三块信息技能解决的场景、核心关键词、明确的触发条件。我后面第4章会展开讲条件触发机制。3. 实操从零搭建一套可用的统一Skills库3.1 初始化统一的技能仓库第一步当然是把技能仓库建起来。我建议从一开始就用git管理哪怕你目前只有自己一个人用。操作按这个来mkdir skills-repo cd skills-repo git init mkdir -p skills/code-review skills/frontend-dev # 把已有技能包复制进来每个技能包保留自己的SKILL.md和附属文件 git add . git commit -m 初始化技能仓库仓库建好之后我习惯建两个分支main是稳定分支只有验证过没问题的技能才合并进去dev是开发分支新技能或者修改都在这里验证。这个习惯帮我避免了好几次技能更新后把Agent环境搞挂的尴尬。如果你觉得分支流程太重至少做到提交前人工验证一遍技能在当前Agent里能正常跑。3.2 用符号链接打通多Agent环境这是整个方案里最核心的一步。原理不复杂Agent只会从它自己的约定目录读技能那我们就在这些目录里放符号链接指向仓库里的真实技能目录。# 假设仓库在 ~/workspace/skills-repo # 为Claude Code创建个人级技能链接 ln -s ~/workspace/skills-repo/skills/code-review ~/.claude/skills/code-review ln -s ~/workspace/skills-repo/skills/frontend-dev ~/.claude/skills/frontend-dev # 为Codex创建链接 ln -s ~/workspace/skills-repo/skills/code-review ~/.codex/skills/code-review ln -s ~/workspace/skills-repo/skills/frontend-dev ~/.codex/skills/frontend-dev手工敲链接不是不行但技能多了之后就很难维护。我写了一个install脚本支持一键初始化所有Agent环境#!/usr/bin/env bash # scripts/install.sh set -euo pipefail REPO_DIR$(cd $(dirname ${BASH_SOURCE[0]})/.. pwd) SKILLS_DIR$REPO_DIR/skills link_skills() { local target_root$1 mkdir -p $target_root for skill_dir in $SKILLS_DIR/*/; do [ -d $skill_dir ] || continue local skill_name skill_name$(basename $skill_dir) ln -sfn $skill_dir $target_root/$skill_name echo linked $skill_name - $target_root/$skill_name done } # 当AGENTS环境变量存在时只安装指定Agent否则全部安装 if [ -n ${AGENTS:-} ]; then for agent in $AGENTS; do case $agent in claude) link_skills $HOME/.claude/skills ;; codex) link_skills $HOME/.codex/skills ;; esac done else link_skills $HOME/.claude/skills link_skills $HOME/.codex/skills fi脚本里用ln -sfn而不是ln -s这个细节很多人会忽略。-f强制覆盖已存在的链接-n避免链接指向的目录被误当成目录层级来处理。加了这个参数之后脚本可以安全重复执行不会遇到文件已存在的报错。3.3 在Claude Code中配置技能路径Claude Code读取技能有两个层级用户级和个人级、项目级。用户级路径是~/.claude/skills/所有项目通用项目级路径是项目目录下.claude/skills/只对当前项目生效。刚才的install脚本默认配置的就是用户级路径。有些场景下你不想全局安装所有技能而是希望某个项目只暴露一部分技能那可以在项目里这样做cd /path/to/your/project mkdir -p .claude/skills ln -s ~/workspace/skills-repo/skills/code-review .claude/skills/code-review项目启动的时候Claude Code会优先读取项目目录下的.claude/skills如果里面有同名技能会覆盖用户级路径下的同名技能。这个优先级规则在做项目定制时非常有用——团队级的通用规则放用户级项目专属规范放项目级互不干扰。我个人的经验是能放项目级就放项目级不要把项目专属规则混进用户级技能库不然换个项目很容易串规则。3.4 在Codex中配置技能路径Codex这边我用的是类似方案。它同样支持从个人目录~/.codex/skills/加载技能也支持项目目录.codex/skills/。社区里对Codex技能格式的讨论比较多不同版本对SKILL.md的解析细节略有差异但基本约定是一致的目录内要有SKILL.md描述和触发条件写在YAML frontmatter里正文部分是给Agent的执行指引。配置方式跟Claude Code完全对称mkdir -p ~/.codex/skills ln -s ~/workspace/skills-repo/skills/code-review ~/.codex/skills/code-review如果你某个Codex项目只需要某几个技能同样在项目目录下建.codex/skills再链接。我这里特别提醒一句Codex对技能描述里关键词的敏感度可能跟Claude Code不完全一样。同一个技能在Claude Code里描述中的触发词能生效换到Codex里Agent不一定激活它。所以在写技能描述时我习惯把可能的触发场景用同义词场景描述的方式写全而不仅仅是堆几个关键词。第四章我会举实例。3.5 版本管理与更新流程技能库纳入git之后更新流程就标准化了。我自己日常的节奏是这样的修改某个技能后先在单个Agent里实测确认效果没问题git提交并推送到远端需要同步到其他环境时在各个环境里执行git pull因为符号链接指向的是仓库里的物理文件拉到新版本后所有Agent自动就生效了。我把这个流程固化成了一个update脚本#!/usr/bin/env bash # scripts/update.sh set -euo pipefail REPO_DIR$(cd $(dirname ${BASH_SOURCE[0]})/.. pwd) cd $REPO_DIR git pull --ff-only echo 技能库已更新到: $(git rev-parse --short HEAD) # 如果技能目录有增减需要重新执行链接 $REPO_DIR/scripts/install.sh这里有个不大不小但很容易踩的坑如果你在技能库里新增了一个技能目录符号链接不会自己冒出来必须重新执行install脚本。所以我update脚本里固定串了一次install防止这种仓库更新了但Agent读不到新技能的情况。4. 条件触发与协同编写让技能真正被Agent想起来4.1 description关键词设计的实战经验很多刚开始写Skills的人技术流程写得头头是道但实际用的时候Agent就是不理你——明明场景匹配技能却不加载。十有八九是description没写好。我以自己维护的代码审查技能为例早期版本是这样写的--- name: code-review description: 进行代码审查。 ---这个description的问题在于太抽象。Agent在真实对话里几乎不会用进行代码审查这种指令来找你真实的用户会说什么会说帮我看看这个PR有没有问题会说这段代码有没有安全隐患会说这个函数性能是不是有坑。这些表达都不会命中代码审查这个抽象描述。我改成这样之后激活率明显提升--- name: code-review description: 当用户要求检查代码质量、审查Pull Request、查找代码中的安全漏洞、性能问题、设计缺陷或者要求看看这段代码review一下帮我检查代码时使用。适用于前端、后端等各类编程语言的代码审查场景。 ---注意几个细节第一覆盖用户可能的口语化表达把看看这段代码这种日常说法也写进去第二覆盖专业术语的表达安全漏洞性能问题设计缺陷分别指向不同类型的审查能力第三明确适用范围适用于各类编程语言是防止Agent因为不确定而放弃加载。4.2 多技能协同与流程化任务设计单个技能解决单点问题但真实场景往往是一个复杂流程。比如用户说帮我给这个项目加一套前端开发规范这里面其实包含了代码风格定义、目录结构规范、组件设计原则等多个子任务。我的做法是在一个技能的内部通过步骤编排把流程串起来。拿 frontend-dev 技能举例它的SKILL.md正文字段是这样设计的## 执行流程 1. 先读取 templates/project-structure.md确认项目目录组织方案。 2. 再读取 templates/coding-style.md生成代码风格规范。 3. 最后读取 templates/component-principles.md输出组件设计原则。 4. 将三个文档合并按项目实际情况调整后输出最终规范。这样Agent被触发后会按步骤一步步读取对应的模板文件而不是一次性把所有内容塞进上下文。这里有性能上的考虑SKILL.md本身如果写得过长Agent在还没确定要不要加载这个技能时就要处理大量文本既浪费token又降低加载意愿。把大段细节拆到引用文件里SKILL.md只保留流程骨架是更优的做法。4.3 脚本技能里的通用参数约定带脚本的技能我强烈建议你在SKILL.md里把脚本的调用方式、参数含义、退出码约定写清楚。Agent是根据你文档里写的命令去执行脚本的文档写得含糊Agent就可能猜着调用猜错了就是一堆报错。以我的review_helper.py为例我会在SKILL.md里写上这几段内容## 参考资源 调用辅助脚本python3 scripts/review_helper.py -p 文件路径 [-f 格式] 参数说明 - -p 必填要审查的文件路径。 - -f 可选输出格式支持 plain、json默认 plain。 退出码 - 0 正常完成。 - 1 文件不存在或无法解析。 - 2 输入参数不合法。这种信息Agent读了就能直接执行不需要猜。写清楚退出码的约定还可以让Agent在脚本报错时快速定位问题原因——我在实践里发现Agent看到非零退出码后如果不知道含义往往会反复重试同一个错误命令白白浪费时间和token。有了退出码说明它可以直接判断哦这是文件不存在的问题然后采取相应的处理。5. 常见问题与时序坑实操中踩过的雷5.1 技能不生效多半是这些原因实践了这么久我把常见问题整理成一张速查表遇到症状直接对号入座症状可能原因解决方法Agent完全不提技能名像没装一样description写得太抽象触发不了按4.1的方法重写description加口语化触发词技能能识别但执行的还是通用流程SKILL.md正文步骤不明确Agent把它当成参考正文里写出带验收标准的强制步骤技能脚本报文件不存在脚本里用了相对路径工作目录不对脚本里用SKILL.md所在目录推导绝对路径新增技能后Agent读不到符号链接没创建重跑install脚本确认新目录已链接两个技能目录里的文件互相引用出错SKILL.md用了错误的相对路径统一约定所有引用基于技能目录本身改了技能但Agent行为没变Agent有缓存还在用旧版本检查Agent是否支持技能缓存刷新必要时重启5.2 符号链接与缓存交互的隐藏问题这里有两个值得单独展开的坑。第一个坑symlink在部分文件同步工具下会被展开成真实文件副本。如果你用的是某些云同步类的目录同步工具它可能会把符号链接实体化——变成一个真实的目录拷贝你的统一管理瞬间失效因为各个Agent又开始各自维护一份独立文件了。我实际遇到过解决方案是对Agent的配置目录做排除不要让同步工具碰~/.claude/skills和~/.codex/skills。另外Windows环境下如果你用mklink创建符号链接记得以管理员权限运行终端否则会因为权限问题失败。第二个坑Agent对技能列表的缓存刷新机制不同。Claude Code和Codex在会话启动时读取技能列表如果某个技能在会话中途被修改了正在进行的会话可能继续使用旧内容但新开会话会看到新版本。这个表现是正常的不算bug。但如果你在调试技能改完发现没生效先检查是不是会话没重开别急着怀疑链路有问题。5.3 技能仓库的可移植性与团队协作最后分享一个协作层面的经验技能仓库建好之后不要只躺在你本地。推到远程仓库让团队成员clone下来跑install脚本每个人就都有了一套完全相同的技能。如果团队里有人只用Claude Code有人只用Codex还有人两个都用install脚本的AGENTS参数就能派上用场AGENTSclaude ./scripts/install.sh # 只安装Claude Code环境 AGENTScodex ./scripts/install.sh # 只安装Codex环境这里我建议你写一个简洁的README放仓库根目录写明这个库是什么、目录结构怎么组织的、怎么安装、怎么新增一个技能。因为技能库的使用者不一定是当初搭建它的人哪怕是你自己三个月后回来看也需要一份地图。README不用写长五个章节够用用途说明、目录结构、安装方法、新增技能步骤、维护约定。我用模板化的方式维护这份文档每次调整目录结构或者新增约定时同步更新避免它过期失效。6. 这套方案的边界与后续扩展方向6.1 什么情况下这套方案可能撑不住任何方案都有边界。我实测下来单机多Agent共享这套方案非常顺。但如果你要管理的机器数量上去了比如三五台开发机都要同步技能靠人肉执行git pull就不太够用了。这时候可以用git hook或者定时任务让每台机器开机时自动拉取技能库更新。更重度的做法是用配置管理工具推送技能文件但那个对普通开发者来说有点杀鸡用牛刀了。另外一个边界是技能里的脚本如果有平台相关性。比如Windows路径和macOS路径差异、Linux上才能执行的命令这种平台绑定逻辑放在共享技能里会导致部分Agent环境的用户跑不通。我的处理方案是技能里区分通用步骤和平台适配步骤平台相关命令单独用platform:前缀标注或者拆成独立脚本让Agent根据当前操作系统选择执行哪一段。6.2 后续可以怎么扩展这套统一管理库其实还可以继续长出更多能力。比如在技能库基础上加一个技能审计流程定期扫一遍所有SKILL.md检查description质量、脚本引用路径是否有效、依赖是否过期。我自己写过一个简单的检查脚本遍历所有技能目录校验三个东西SKILL.md存在且YAML头部可解析、description长度超过50个字符、引用的脚本文件都真实存在。这三条规则治好了我一大半技能失效问题。另一个值得尝试的方向是用CI跑技能验证。技能库更新后自动触发一个测试任务用模拟的Agent环境加载所有技能验证每个技能至少能完成一个冒烟测试任务。这个做起来成本不低但对维护大型技能库的团队来说很值得。7. 最后分享一点实操心得从最开始每个Agent各自维护一套技能到后来统一成一个技能仓库用符号链接打通这个转变对我最直接的改变不是省了多少时间而是不再担心改技能导致环境不一致了。以前改一个技能要惦记着两个Agent环境同步现在完全不用想这件事因为所有环境读的都是同一套文件。如果你现在正在为多个Agent环境维护多份技能我建议你按这个顺序动手先建技能仓库把所有技能物理收敛到一起再写install脚本用符号链接打通各Agent路径最后把description质量提上来让技能在需要的时候能真正被Agent想起来。这三步走完你的技能管理就从一摊乱账变成了一个仓库、一个入口、多端生效。我目前还在这个方案上持续迭代比如尝试引入自动化的技能运行trace记录每个技能实际上被调用了多少次、用在哪些场景回来反哺description的优化。这条路远没走到尽头但对现有的统一管理架构我已经比较满意了。技能这个东西重点是让Agent真正用起来而一套干净的管理方案是用起来的前提。