
如果你手里同时装着三五个 AI 编程工具你会发现一个特别拧巴的现象Cursor 里的规则、Claude Code 里的 skill、Cline 里的 rules明明想干同一件事却得各自维护一份。我最近把之前散落在各个终端里的技能文件全部收拢进了一个桌面程序名字就叫 Skills Manager——它做的只有一件事用一套技能定义统一管住 54 个 AI 编程工具的 Agent 技能让它真正成为一个跨平台桌面中枢。这个工具不解决“哪个大模型更强”的问题而是把“技能包”从目录里解放出来你不用再记每个工具读哪几个文件、用哪种格式也不用在换工具时把几十个规则重新翻译一遍。如果你也在用 Cursor、Claude Code 或 Cline并且维护的规则文件开始超过十个这篇文章值得你花十分钟读完后面我会把设计思路、适配层原理、实操流程和踩坑记录都摊开讲。1. 为什么 AI 编程工具的“技能”需要统一管理1.1 “技能孤岛”是怎么出现的过去两年里AI 编程工具的数量爆发得很快。闭源的有 Cursor、Windsurf、GitHub Copilot、JetBrains Assistant开源的有 Cline、Roo Code、Aider、Continue、OpenCode再加上各家 CLI 版本我数过一遍能稳定进入我工作流的已经超过四十个如果算上同一产品的 IDE 插件和终端变体54 是一个很保守的数字。问题就出在“各有各的规矩”上。Cursor 把你想要的约束放进.cursor/rules/下的.mdc文件YAML frontmatter 里写globs和alwaysApplyClaude Code 用.claude/skills/技能名/SKILL.md靠文件里的name和description决定什么时候被触发Cline 更简单直接在.clinerules/下堆 MarkdownWindsurf 在.windsurf/rules/Codex 则倾向于把项目级指令写进AGENTS.md个人级技能放~/.codex。同样是“让 Agent 在生成 SQL 前先做结构巡检”在这五个工具里要分别写成五种格式。第一次配置还好等你把技能攒到二十个、三十个每次换工具都像重新装修一套房子线要重拉插座要重排灯的位置还要适应新的开关逻辑。我把这种状态叫作“技能孤岛”——每一座岛上功能都有岛与岛之间却完全没有桥梁。1.2 被低估的隐含成本规则打架与上下文开销孤岛带来的第一个显性成本是重复劳动。同一个技能我在 Cursor 里维护一份、Claude Code 里维护一份、Cline 里维护一份改一个触发表达要动三个地方。后来我拿 Git 比对过三个目录发现同一技能竟然有三种微妙的差异有些是版本演进导致的有些是复制粘贴时手滑造成的这时候你根本不知道当前 Agent 执行的是哪版规则排查起来特别痛苦。第二个成本更隐蔽就是“规则打架”。不同工具会读取不同位置的规则如果项目里同时有.cursor/rules、.clinerules、还有一份AGENTS.md模型可能在同一轮对话里看到两套互相冲突的指令。比如一条规则说“所有 SQL 必须用参数化查询”另一条又说“为了调试方便可以直接拼接 table 名”LLM 并不会自动帮你仲裁它只会按照概率糊一个结果出来甚至可能在这两个要求之间反复横跳。还有一个非常容易被忽略的开销——上下文。很多工具会把匹配到的技能全文注入到系统提示里。假设单个技能的平均体积是 2000 token挂载五十个技能就是 100k token别说是普通模型就连大窗口模型也会被这种“全量注入”浪费掉大量能力。真正需要某条技能的往往只是这个需求里的几分钟但成本却从头到尾都在支付。这也是为什么我会坚持用“中央索引 按需加载”的方式来做技能管理后面会详细讲。2. Skills Manager 的整体设计一个模型两套协议三层结构2.1 统一技能模型skill.yaml SKILL.md scripts做这个项目前我先做了个小实验把所有工具的规则文件收敛归纳看它们到底在描述什么。最后发现不管格式怎么变都可以拆成三块第一块是“这个技能什么时候用”也就是元数据第二块是“怎么用、边界在哪”也就是指令正文第三块是“要执行什么动作”也就是脚本或工具调用。于是我把统一技能模型定义成三层。第一层是skill.yaml负责元数据名字、版本、触发关键词、适用工具、上下文权重都放这里。第二层是SKILL.md负责指令正文用自然语言描述触发场景、操作步骤、输入输出和边界限制。第三层是scripts/和assets/存放可执行脚本、模板文件、示例数据。这样设计的好处是职责清晰元数据可以被程序解析正文可以被 LLM 理解脚本可以被沙箱执行三者互不干扰。拿一个具体例子说明。我写了一个“SQLite 结构巡检”技能目录长这样skills/ sqlite-schema-review/ skill.yaml SKILL.md scripts/ review_schema.pyskill.yaml里面是这样写的name: sqlite-schema-review version: 1.2.0 description: 对 SQLite 数据库的 schema 进行巡检输出缺失索引、冗余索引和潜在性能问题。 author: fei license: MIT trigger: keywords: [sqlite, schema, 索引, 慢查询, 表结构, 数据库设计] tools: [cursor, claude-code, cline, windsurf, codex] context_weight: medium dependencies: - python3 - sqlite3注意context_weight这个字段它不是摆设。high意味着这个技能在绝大多数会话里都应该被注入比如“代码提交规范”low意味着只有触发关键词极其明确时才该加载“SQLite 巡检”在我这里就属于medium。这个字段的价值在第四章我会再细说。2.2 适配器层怎么兼容 54 工具有了统一模型接下来就是“翻译”。Skills Manager 给每个工具写一个适配器只做一件事把统一模型转成目标工具认识的格式。适配器分为三个翻译级别我按工具的标准化程度来分。L1 是格式翻译适用于那些本身就是“带 frontmatter 的 Markdown”的工具比如 Cursor 的.mdc、Windsurf 的 rule 文件只需要把skill.yaml的字段映射到对应 frontmatter把SKILL.md的正文放进去再加一个globs声明“这组文件适用哪些文件后缀”。L2 是结构适配适用于像 Claude Code 这样要求固定目录结构的工具适配器要在目标位置创建.claude/skills/name/SKILL.md还要把scripts/一并复制过去。L3 是行为映射适用于像 Continue、Aider 这种本身没有标准技能机制的适配器会把它转成 slash command或者把内容拼进项目约定的CONVENTIONS.md尾部同时加一行注释标明来源版本。下面是我整理过的一份适配矩阵可以让你直观感受这些工具的差异工具输出载体适配级别备注Cursor.cursor/rules/*.mdcL1需要globs和alwaysApplyWindsurf.windsurf/rules/*.mdL1规则比 Cursor 宽松Claude Code.claude/skills/*/SKILL.mdL2要求目录规范Cline.clinerules/L2多技能合并时注意顺序CodexAGENTS.md~/.codexL2项目级和个人级分开AiderCONVENTIONS.md追加L3无原生技能机制Continue~/.continue/config.yamlL3注册为 command虽然工具列表在继续增长但大多数新工具都能归到这三个级别里所以新增适配器的工作量往往只有半天这也是“54”这个数字能保持住的原因。2.3 桌面中枢技术选型与本地优先原则为什么不做成一个 Web 服务或者纯 CLI而要做成桌面中枢我有几个现实理由。第一技能文件就在本地目录里。Web 服务要去读你磁盘上的.cursor/rules和.claude/skills权限和流转链路会很别扭纯 CLI 能读但可视化差管理几十个技能时表格、对比、拖拽导入这些操作用终端做会很吃力。第二Agent 技能这个场景天然和 Git、文件系统、进程打交道桌面应用可以原生调用这些能力不需要为了安全把功能阉割掉。第三很多团队有隐私要求技能内容往往包含业务规则甚至部分代码本地优先能让所有数据不出机器只有你主动 push 到 Git 时才会上云这一点是 Web 服务很难承诺的。技术栈上我选了 Tauri 而不是 Electron。Tauri 包体积小、内存占用低启动速度快而且 Rust 侧可以直接操作 Git 仓库、监听文件变化、做全文索引这对一个“本地工具”来说体验差距非常大。Electron 生态更成熟但我项目里没有复杂的 Web 需求纯本地的前端界面用 Tauri 完全够用。Windows、macOS、Linux 三端我都跑过除了系统通知的 API 有些差异核心逻辑一套代码打通。跨平台真正的坑在文件系统。Windows 路径分隔符是反斜杠macOS 和 Linux 是正斜杠Git 在 Windows 上默认会把换行符转成 CRLF符号链接在三个平台上的行为也不一样。我的做法是项目内部统一用正斜杠对外交互时才转换提交 Git 时强制统一core.autocrlf策略所有依赖脚本的调用路径通过一个SKILLS_HOME环境变量解析不写死绝对路径。细节很多但每一条都能省掉后面几小时的排查时间。3. 实操把一套技能从零管起来3.1 初始化技能库先说怎么上手。装好应用后第一步是初始化一个技能仓库。我习惯把所有技能放在一个独立目录里比如~/skills然后执行skills-manager init ~/skills这个命令会生成一个 Git 仓库骨架并创建skills/、templates/、config.yaml三个目录。接着把你手上已经有的规则文件导入进来skills-manager scan ~/.cursor/rules ~/.claude/skills ~/.clinerulesscan会尽力识别这些文件属于哪个工具、哪个技能能匹配到统一模型的就直接转换匹配不到的就先原样放进来打一个“未适配”标记。实际跑完之后我建议你不要急着批量补齐先挑一个使用频率最高的技能手动把它整理成标准格式跑一遍验证流程再批量推广不然很容易在垃圾数据上叠垃圾数据。3.2 编写一个真实技能SQLite 结构巡检我以一个真实技能为例讲讲“怎么写才不是玩具”。这个技能要解决的实际问题是很多时候你让 AI 写 SQL、改表结构它洋洋洒洒给了一堆建议却根本没看过数据库长什么样。DB4S 这类跨平台 SQLite 图形工具确实很好用但它和 AI 编程工具之间是脱节的。让 Agent 直接用sqlite3命令做结构巡检再把结果整理成报告效率会高很多。SKILL.md的正文我是这样写的# SQLite Schema Review 当用户要求分析 SQLite 数据库的 schema、索引设计、慢查询或表结构时使用本技能。 ## 使用步骤 1. 通过对话或 .schema 信息确认数据库路径。 2. 执行 python3 scripts/review_schema.py db_path --output md。 3. 根据输出重点检查缺失索引、冗余索引、无主键表、隐式类型转换。 4. 输出一份 Markdown 报告按“严重 / 警告 / 建议”三档排列结论。 ## 边界 - 本技能只做读操作绝不执行 DELETE、DROP、UPDATE 等写语句。 - 数据库大于 1GB 时只抽样分析不要做全表扫描。 - 如果数据库路径由用户临时提供先确认该文件确实存在并且是 SQLite 格式。为什么强调“边界”因为 Agent 一旦拿到脚本权限偶尔会主动“帮忙”修改数据。明确写死“只读”这个限制比在系统提示词里反复强调“要谨慎”有用得多。这也是我在整理技能时发现的一个规律好的技能文档宁可限制多也不要让模型自由发挥。skill.yaml里我还会加一个test字段指向一个冒烟测试命令比如用临时数据库跑一遍脚本确保在导出到任何工具前就知道它是否能正常工作。这一步类似 CI 里的 smoke test在技能数量多的时候价值非常大。另外回应一个很多人问过的场景像跨平台音乐管理系统这类源码很多人拿到手后会困惑“AI 能帮我做什么”。其实它同样适合做成技能包——把曲库目录结构、支持的音频格式、数据库写回规则写进skill.yamlAgent 就能自动完成文件重命名、格式转换、元数据补全这一连串操作。凡是输入输出规则明确、又需要反复人工操作的流程都是技能的天然候选。3.3 跨工具下发从仓库到各家的规则目录技能整理好之后下发就很简单了。指定目标工具指定技能名Skills Manager 会调用对应适配器完成翻译并写到目标工具的规则目录skills-manager export --target cursor sqlite-schema-review skills-manager export --target claude-code sqlite-schema-review skills-manager export --target cline sqlite-schema-review以 Cursor 为例导出的.cursor/rules/sqlite-schema-review.mdc会是这样的--- description: SQLite 结构巡检用于分析 schema、索引和潜在性能问题 globs: [**/*.sqlite, **/*.db, **/schema.sql] alwaysApply: false ---正文部分就是SKILL.md的完整拷贝scripts/会被复制到技能仓库里的固定位置并在正文开头用相对路径引用。这里我有一个习惯导出工具文件时会同时导出一个.metadata.json记录这条规则对应的技能名称和版本这样以后改规则时我能通过反向索引定位到统一模型里的源头不会出现“改了仓库但没改工具副本”的遗忘。批量管理还有一个很实用的功能skills-manager status。它会列出所有已导出技能的位置、版本、与统一模型是否一致并在不一致时高亮提示。这解决了我前面说的“三份副本微妙的差异”问题——每次只要看到 status 里有漂移我就知道该重新导出一遍了。4. 踩坑实录技能冲突、上下文污染与跨平台兼容4.1 典型问题排查速查表这个项目做下来我整理的排障经验大概超过二十条这里挑最典型、最容易复发的几条。症状原因解决办法同一技能在 Claude Code 里正常在 Cursor 里完全不被触发Cursor 规则缺少 globs 或 alwaysApply 配置适配器自动补全 globs手动配置时永远检查这两项多个技能同时命中同一条 promptAgent 行为来回漂移触发关键词重叠优先级未定义在 skill.yaml 设置 priority并让 Agent 只读“决策索引”Windows 下脚本路径报错macOS 下正常路径分隔符与换行符不一致统一使用正斜杠并做运行时自动转义导出后技能版本还是旧的工具规则目录里的副本被直接编辑源头没同步使用反向索引文件和 status 命令定期比对上下文窗口很快被打满对话质量下降所有技能被无条件注入开启按上下文权重加载只注入索引团队里有人改了技能其他人不知道没有版本管理与评审机制技能仓库走 Git PR hooks 校验第一行和第二行是我最常遇到的。很多工具自带“规则优先级”的设计但用户在手工维护时几乎不会去设置最后被困扰一整周。适配器如果能自动生成合理的优先级比让用户自己去理解各家规则体系要可靠得多。4.2 让技能“瘦身”按上下文权重智能加载前面我提过“全量注入”的问题这里展开讲。假设你的技能库有 50 个有效技能每个SKILL.md平均 2000 token全量注入就是 100k token。大窗口模型 200k token 看着绰绰有余但模型在 100k token 的“噪音指令”里找当前任务真正需要的那一小段效果一定不如只用 10k token 核心上下文。我自己实测过把技能库从全量注入改成“索引 按需加载”之后多轮任务里模型跑偏的概率明显下降响应质量也稳定了不少。实现上分三步。第一导出的规则里只注入一份“技能索引”每行一个技能名和一句话说明大概几百个 token。第二当对话内容命中某个技能的trigger.keywords时SKILL.md的正文才会被放进上下文。如果工具侧无法做到动态加载就在技能正文开头写清楚“请先阅读本技能描述确认当前需求是否真正需要”用指令引导模型自行判断。第三context_weight: high的技能永远注入low的技能除非用户明确点名否则不进入上下文。这套策略我用了两个月效果明显连带着把很多“上下文太长”导致的幻觉问题也解决了。我在实际使用中发现一个很有意思的现象当技能正文可以按需加载时模型代码生成时的行为一致性反而提高了。原因很简单任何一个技能都带有自己的表达习惯和潜在偏见同时加载两个不同风格的低优先级技能模型会产生倾向性冲突只加载真正命中的一两个技能生成的代码风格会更稳定。这也解释了为什么有些团队明明在同一个项目里却经常出现“上午风格一套、下午风格一套”的现象——多半不是模型不稳定而是上下文里被塞进了太多互相没有协调过的技能。5. 进阶从个人效率到团队技能仓库5.1 用 Git 做技能版本管理与评审技能本质上也是代码只是它“运行”在模型推理里。既然是代码就该有版本管理、评审和回滚。我把技能仓库托管在一个 Git 远端每次修改走分支合并git checkout -b fix/sqlite-schema-review git add skills/sqlite-schema-review skills-manager validate sqlite-schema-review git commit -m fix: 增加大库抽样策略 git push origin fix/sqlite-schema-review然后在远端开 Pull Request。评审人 check 的不是语法而是三件事触发描述是否准确、边界说明是否清楚、脚本是否有破坏性行为。我会在仓库里放一个 lint 脚本自动检查 frontmatter 必填字段、脚本文件大小限制、是否有未适配的文件格式这些都能在 CI 里跑掉省下评审人的体力。更进阶一点我会给技能写行为测试。比如“sqlite-schema-review”技能准备一个 500 行的临时数据库跑一遍skills-manager test sqlite-schema-review验证输出是否包含“缺失索引”和“冗余索引”两个关键字。虽然 LLM 输出有随机性但技能文档只要写得足够结构化断言关键结论还是可行的。这套测试没法覆盖所有场景能兜住 80% 的低级问题就够了。5.2 团队共享场景下的安全与权限团队共享技能时最容易被忽略的是安全问题。技能里除了提示词往往还带着可执行脚本一个“无意中”写成rm -rf的脚本如果被分发到每个人手里后果不堪设想。我至少在三个地方加了防护第一脚本默认跑在沙箱里没有显式授权不能访问网络和特定目录第二技能文件带哈希签名Skills Manager 在导入时会校验“来源是否在可信列表里”第三所有技能文档里禁止出现“无条件执行”、“忽略确认”这类危险指令发现就阻止导入。还有一点和团队选型直接相关。经常有人问我“推荐选哪个大模型需要哪些技能包”。我的建议是把模型选择和技能包解耦。技能包应该尽量写成模型无关的描述的是目标和流程而不是“调用某个模型的某个参数”。但同一套技能在不同模型上的表现差别很大所以在skill.yaml里我留了一个model_hints字段写清楚哪种模型更适合比如“擅长长上下文推理的模型效果更佳”仅供选择参考不构成硬约束。这样团队换模型时技能库不用跟着推倒重来采购、运维的成本都会低很多。最后再分享一个小技巧。如果团队刚起步不要一上来就搞五十个技能先维护三到五个最高频的业务场景比如代码评审、SQL 巡检、日志分析、部署前检查。把它们整理成标准格式跑通导入、导出、测试的完整流程让团队尝到甜头之后再按需扩展。技能管理这件事最怕的不是工具不好用而是你自己先被管理成本吓退了。