
我电脑里躺着二十多个自己攒的 skill分别散在三台机器上办公机、家里台式、还有一台常跑的服务器。每次换台机器干活第一件事就是翻聊天记录找之前配过什么手动复制目录、装依赖、改配置一折腾就是半小时起步。后来我实在受不了花了两个晚上把整套流程收拾成了「一句话让 AI 自己装好」的样子。这篇就聊聊我怎么做这件事的。内容比较适合正在做 LLM agent 工程、经常琢磨 Codex / Claude Agent Skills / 豆包这类 AI 工具或者自己攒了一堆 prompt 和脚本却没有统一管理的朋友。看完你能拿到一套相对完整的方案skill 该怎么封装、多台机器怎么同步、AI 接到一句话指令后怎么自主完成安装和自检。1. 二十个 skill 散落三台电脑问题到底出在哪1.1 先讲清楚 skill 到底是个什么东西如果你最近在用 Codex、Claude、豆包这类带智能体的工具大概率已经接触过一个概念skill。不同平台叫法不一样有的叫技能有的叫插件有的叫 action但本质上是一回事——给 AI 准备的一个「可复用能力单元」。它不是单纯的一段提示词。我自己的理解是一个合格的 skill 应该包含四个层面第一是自然语言定义说明这个能力什么时候触发、怎么触发、输出什么格式第二是可执行脚本真正干活的部分比如数据清洗、文件批量处理、代码仓库扫描第三是资源文件像是模板、字典、参考示例、配置文件第四是元数据记录版本、作者、依赖、入口等信息。现在主流的 agent skill 格式也基本沿着这个思路走。Claude Agent Skills 就是一个文件夹配一个 SKILL.mdCodex 的习惯是把可执行指令和说明文件放一起Spring AI 2.0 里的 skill 更像是一个带描述和函数的服务单元。我自己的二十个 skill 里就有好几种形态有纯提示词的「写作风格控制」有带 Python 脚本的「日志分析」还有需要外部命令行的「视频片段抽取」。它们形态不统一但核心目标一致让 AI 在合适的场景下自动把合适的工具和流程调出来。1.2 多机分散的真正痛点不是「复制文件」这么简单表面上三台电脑的问题就是「文件没同步」。但我实际踩过的坑比这深得多。举个例子我有个「GIS 空间分析」skill里面依赖 GDAL 和一堆 Python 包。办公机上跑得好好回到家那台 Windows 上同一个 skill 因为 GDAL 版本差异直接报错。还有「写小说」那个 skill里面带一个角色设定模板我在服务器上改过一版本地却还是旧版——两边的 AI 行为直接不一致。逐个罗列的话痛点大概有五类版本漂移同一份 skill 在不同机器上被改得面目全非完全无法追溯谁改过什么。依赖缺失skill 里用的工具链、Python 包、外部命令在另一台机器上不存在AI 报错报得很随机。配置状态有的 skill 需要预先设置 API key、工作目录、环境变量这些状态不会跟着文件走。平台差异macOS、Windows、Linux 下路径、命令语义都不一样一份脚本经常不能直接跑。手工重复每台机器都要重新经历「下载 → 解压 → 放目录 → 装依赖 → 试跑 → 修问题」的循环。这些问题的根源在于我把 skill 当成了「文件」但实际上它是个「应用程序」是代码加环境加配置的组合体。只同步文件不解决环境只拷贝目录不维护元数据机器之间的行为就不可能一致。1.3 为什么最终选了「Git 仓库 统一安装脚本 AI 自主执行」最初我想偷懒把整个 skills 文件夹丢到云盘里自动同步。这个方案解决了一部分问题——文件确实能过去但依赖、权限、配置还是一团乱更别提几乎没法做版本回滚。后来又试过用私有 Git 仓库管理版本问题解决了可每台机器还是要手动 clone、手动建软链、手动装环境换汤不换药。最后定下来的方案是三段式所有 skill 收进一个 Git 仓库统一管理版本、分支、标签都走正常工程流程写一个幂等的安装脚本负责解析清单、核对依赖、放到正确位置、生成配置、做自检把这个安装脚本的使用方式做成一段清晰的任务说明让 AI agent 接到一句话后自动执行全流程。选这个方案的原因也很实际。第一skill 本质上是文本加脚本Git 是对文本最合适的版本工具没有之一。第二安装过程的绝大多数步骤是可以程序化的——读元数据、查环境、建链接、配变量这些不该靠人肉完成。第三AI 已经足够聪明到理解「先做检查再动手、遇到问题停下来报告」这种任务约束把安装交给 AI 比我手动敲命令反而更稳尤其是它能把报错信息直接解释给我听。2. 给 skill 定一个通用装载格式目录、说明、清单、脚本2.1 标准目录结构长什么样在我动手之前二十个 skill 的结构是「薛定谔的格式」有的就一个 Markdown 文件有的散着一堆.py和.sh有的还夹着临时文件和测试数据。第一件正事就是统一目录。我定的标准结构是这样的ai-skills/ ├── README.md # 仓库总说明AI 装好之后第一份读的文件 ├── install.py # 统一安装脚本 ├── install_report.json # 最近一次安装报告用完可以删 ├── skills/ │ ├── code-review/ │ │ ├── SKILL.md │ │ ├── manifest.yaml │ │ ├── scripts/ │ │ │ └── review.py │ │ └── requirements.txt │ ├── log-analyzer/ │ │ ├── SKILL.md │ │ ├── manifest.yaml │ │ └── scripts/ │ └── ...为什么这么定核心是让机器可扫描AI 可理解。安装脚本只需要遍历skills/*/manifest.yaml就能拿到全仓库的 skill 清单AI 只需要读README.md就能知道这个仓库怎么安装、怎么维护。目录是分层的一层是「仓库元信息」一层是「安装逻辑」一层是「真正的技能包」。后面加新 skill 时只需要新建一个文件夹、写上 manifest 和 SKILL.md其余什么都不用改。有人可能问为什么不用云盘那种扁平文件夹因为当 skill 数量超过十个以后靠「人眼扫目录」已经不可靠了。统一目录结构意味着安装、测试、统计、备份全部可以自动化。哪怕以后我直接从 20 个涨到 200 个这套结构也不用推倒重来。2.2 SKILL.md 怎么写才能让 AI 真正用起来SKILL.md 是整个 skill 的「说明书」既给 AI 看也给未来的自己看。我的体会是写这份文件最重要的原则是把触发条件和产出格式写到死不给 AI 太多自由发挥的空间。一份我实际在用的 SKILL.md 骨架是这样# 日志分析器 ## 触发场景 当用户提供一个日志文件路径并要求「分析」「排查」「统计」时激活。 ## 输入约定 - 输入单个日志文件路径可选时间范围参数 - 输出Markdown 报告包含错误分布 TOP10、时间线、可疑点 ## 执行步骤 1. 读取日志文件识别格式Nginx / Java / 自定义 2. 调用 scripts/analyze.py 进行统计 3. 将原始统计结果转成报告 4. 如遇解码问题提示用户确认文件编码 ## 失败处理 - 文件不存在直接返回错误不尝试猜测路径 - 文件过大200MB建议用户提供采样行数写完之后我拿给 AI 试过几次效果明显比那种「帮我看一下日志」的模糊 prompt 稳定得多。关键点在于场景要窄、步骤要明确、失败要有预案。AI 最怕的不是指令复杂而是指令模糊时它会自己脑补流程而脑补出来的流程往往不是你想要的。SKILL.md 的使命就是掐掉脑补的空间。还有一个细节SKILL.md 的开头两句话很重要。Agent 读取 skill 时通常会先扫前几行来判断这个技能能不能处理当前任务所以开头就把「触发场景」和「输入输出」讲清楚比藏在文档中段强得多。2.3 manifest.yaml 里藏着工程化的关键目录结构可以靠约定但安装脚本需要一个「硬规范」——这个角色由 manifest.yaml 来承担。我定义的字段不多但每个都有明确用处name: log-analyzer version: 2.1.0 description: 对常见日志文件做统计分析输出 Markdown 报告 author: self entry: scripts/analyze.py language: python deps: - python3 - pip requirements: requirements.txt env: LOG_DIR: ~/logs tags: - server - work platforms: - darwin - linux checksum: sha256:...各字段的意图解释一下name和version用于识别和对比安装时可以判断「这台机器上的版本是否落后于仓库」deps和requirements是依赖声明脚本靠它去做前置检查env声明这个 skill 需要哪些环境变量没有就顺手创建tags用于按场景过滤安装比如server标签的只在服务器装platforms表示兼容的系统避免在 Windows 上硬装 Linux 专属工具checksum是安全校验用的防止仓库被篡改后脚本盲跑。entry这个字段要特别强调一下。它标记了 AI 真正要执行的入口文件。没有它agent 常常面对一个 skill 文件夹无所适从是先读 SKILL.md 还是先跑 scripts现在直接看 manifest 就知道入口在哪。这套结构其实是从软件工程的「package.json 入口文件」思路搬过来的对我的场景来说完全够用。3. 一句话让 AI 自己装好从仓库到本机的执行链路3.1 安装脚本的核心设计幂等、可验证、可回滚手动装 skill 最怕什么最怕装到一半出问题留了一堆半成品。所以安装脚本的底线是三个幂等、可验证、可回滚。幂等的意思是不管跑一次还是跑十次最终状态都一致。我第一次写的脚本就很 naive每次运行都往.ai_skills里复制文件结果跑了两次就出现重复目录。后来改成「先扫描目标目录已有同名 skill 就对比版本仓库新则更新本地新或有未提交修改则跳过并报告」。这样重复执行不会破坏已有状态。install.py的关键逻辑大概是这样的#!/usr/bin/env python3 import json import shutil import subprocess import sys from pathlib import Path REPO_ROOT Path(__file__).parent SKILLS_DIR REPO_ROOT / skills TARGET_DIR Path.home() / .ai_skills def collect_skills(): skills [] for manifest_path in SKILLS_DIR.glob(*/manifest.yaml): content json.loads(manifest_path.read_text(encodingutf-8)) skills.append({ path: manifest_path.parent, manifest: content, }) return skills def check_dependencies(manifest): missing [] for dep in manifest.get(deps, []): if shutil.which(dep) is None: missing.append(dep) return missing def install_skill(skill_path, manifest, target_dir): skill_name manifest[name] dest target_dir / skill_name # 已安装且版本相同则跳过 version_file dest / .version if version_file.exists() and version_file.read_text().strip() manifest[version]: return skipped # 用软链而不是复制后续更新仓库后重新执行即可 if dest.exists() or dest.is_symlink(): dest.unlink() dest.symlink_to(skill_path, target_is_directoryTrue) version_file.write_text(manifest[version], encodingutf-8) return installed为什么要用symlink而不是copy这里有个很实际的考虑软链指向仓库本体下次git pull更新之后AI 读到的天然就是新版本不需要再执行安装。代价是仓库不能随便删但对我的场景来说完全 OK。真正要隔离版本时再切到 tag 或分支就行。至于安装报告的生成脚本会把每一步的结果写进install_report.json包括哪些装好了、哪些跳过了、哪些因为缺依赖被标记为pending。这份报告就是第 3.3 节里 AI 向用户汇报的依据它让「AI 说装好了」这件事变得可查。3.2 让 AI 理解安装任务的 prompt 该怎么写脚本写好了但要实现「一句话让 AI 自己装好」关键还在于给 AI 的任务说明足够清楚。我实际用的触发指令是这样的请执行 ai-skills 仓库的安装任务。仓库已经克隆到本地 /tmp/ai-skills-install。 要求 1. 先读 README.md 和 install.py理解安装流程。 2. 运行 python3 install.py --install-only暂不执行任何外部安装命令。 3. 读取 install_report.json如果存在 missing 依赖先检查系统里是否有替代方案。 4. 如果关键依赖缺失不要猜测路径将缺失项列成清单报告给我。 5. 安装完成后抽查其中 3 个 skill 的 SKILL.md确认内容完整。 6. 最终用三句话以内的摘要汇报装了多少、跳过多少、哪些需要我人工介入。这个 prompt 的要点有两处一是让 AI 先读文档再动手很多 agent 失败是因为上来就跑脚本不了解整体流程二是明确禁止猜测。AI 最大的毛病是遇到错误硬着头皮自圆其说比如 Python 包装不上它就自动去改 pip 源路径不对就自动换一个——这种「自作聪明」在安装场景下非常危险。所以我每一步规约都写得比较死。实际用下来优秀一点的 agent我主要用 Codex 和 Claude基本能按我的要求完成全流程。它们会自己调pip install -r requirements.txt会处理权限问题遇到不确定的还会反问我。这就是「一句话」背后的真实成本——表面是一句话实则是脚本加 prompt 加错误处理三件套在兜底。3.3 三台电脑上的实测效果我找了个周末依次在三台机器上执行了同样的操作。先说结果办公机 macOS 上20 个 skill 装上 18 个2 个因为缺少特定环境的 API Key 被我主动跳过家里 Windows 上全部 20 个装完其中一个路径转换的问题被 AI 自己发现后修正服务器 Linux 上装上 17 个3 个需要 GPU 环境的标成 pending等后续配置。以服务器为例AI 运行完的汇报大致是这样已从仓库收集 20 个技能。 安装成功17 个已链接至 ~/.ai_skills 跳过3 个video-analyzer / stt-local / ocr-batch 需要 GPU 工具链 缺失依赖cuda-toolkit、ffmpeg部分已存在 建议先安装 ffmpeg 后再重跑一次这个结果比我手动折腾的时候干净太多了。以前我在服务器上配环境至少要开三个终端一个看文档、一个敲命令、一个搜报错。现在 AI 把整个过程收敛成了一次对话它自己拉代码、解析 manifest、检查依赖、建立软链、生成报告我只负责最后的确认和补环境。当然中间也出过一些小插曲。Windows 那台机器上路径分隔符的处理就出过问题——AI 写了一段 PowerShell 脚本去读 manifest结果Path(skills/log-analyzer)这种 POSIX 风格在 Windows 上解析出岔子。好在 AI 读到报错后自己意识到是路径问题改用Path(str).resolve()解决了。这个细节也提醒我跨平台脚本必须从第一天就考虑路径差异不能等踩坑再补。4. 多机同步与版本管理的工程细节4.1 用 Git 分支和标签把「稳定版」和「试验版」分开仓库里二十个 skill不可能每个都稳定。有的我写了一晚上就丢进去有的已经迭代到大版本。如果不区分稳定和试验AI 在装的时候就会把半成品也装进去。我目前的做法是主分支main只放稳定版本所有 skill 必须是能跑、能通过自检的试验性的改动放在experiments/xxx分支验证通过后再合入main。发布时会给某几个 skill 打 tag比如log-analyzer2.1.0。这样做的价值不在平时而在某台机器出了问题需要回滚时——我只需要执行git checkout log-analyzer2.0.0再重跑安装脚本AI 读取 SKILL.md 时就能回到旧版本。这比「我记得这个功能以前能用但我不知道改了啥」要强太多。Git 的 commit message 我也立了规矩每次改动必须写清「哪个 skill 改了什么 为什么」。比如log-analyzer: 增加按时间范围过滤日志的选项解决超大日志分析过慢问题。AI 在排查跨机器差异时第一件事就是看 commit 历史message 写得好它定位问题能快一个量级。4.2 处理 skill 之间的依赖关系虚拟环境和版本约束skill 之间的依赖冲突是个迟早要面对的问题。我有两个 skill一个做日志分析需要pandas2.0另一个做文本分类需要pandas1.5如果都装进同一个 Python 环境必然互相炸。我的解法是分两层。全局层面manifest.yaml里只声明「系统级依赖」比如ffmpeg、node这种二进制命令每个 skill 专属的 Python 依赖统一要求跑在自己的虚拟环境里。SKILL.md 里会写明「使用scripts/venv/bin/python执行激活命令为source scripts/venv/bin/activate」。安装脚本在requirements.txt存在时自动为 skill 创建独立虚拟环境并安装依赖。这个设计牺牲了一点磁盘空间和一个「统一的全局环境」但换来的是确定性每个 skill 的运行环境与其他 skill 无关更新某个 skill 的依赖不会连带弄坏其他技能。20 个 skill 各带虚拟环境加起来可能多占几 GB——但我宁可多花磁盘也不愿意花两天去排查依赖冲突。4.3 安全校验不能什么脚本都敢让 AI 跑既然安装的本质是把外部代码放到本机执行安全就必须放在非常靠前的位置。我的策略有三道第一道仓库源可信。所有 skill 只从我自己控制的 Git 仓库拉取不接受任何外部动态 URL。如果哪天想引用一个网上现成的 skill我会把它下载到本地、review 一遍、再放进自己仓库。热词列表里那些「从某个网盘地址安装 skill」的用法我实操中不会采用——好歹你得看一眼里面的脚本干什么再决定要不要执行。第二道manifest 里的 checksum 校验。Git 本身能防止仓库历史被篡改但依赖项比如 pip 包有被中间人替换的风险。安装脚本在 pull 下新代码后会先校验checksum字段与文件内容一致不一致就拒绝安装。第三道AI 在执行前展示将要运行的命令。我在 prompt 里规定安装脚本里的每条外部命令AI 必须先输出到对话里再执行。比如pip install pandas2.0、ln -s ...都要先给用户看到。这样万一出现什么诡异命令我还有人工拦截的机会。这三道防线叠加起来已经足够覆盖我的个人使用场景。如果是在团队里批量分发我还会加上更严格的白名单机制但单机场景下做到这层就够了。5. 常见问题排查与避坑清单5.1 AI 报告安装成功但 skill 根本没生效这个问题我遇到过不止一次。症状是AI 信誓旦旦说「已安装 20 个」但实际调用某个 skill 时agent 完全没反应。根因基本都在「加载路径」上——skill 被链接到了~/.ai_skills但 agent 配置里读取的路径是~/.claude/skills两边根本没有交集。排查思路也简单先看install_report.json里的目标路径再对比 agent 配置里声明的技能目录。现在我的安装脚本会把目标路径写进报告如果发现和 agent 配置不一致就把软链补到正确位置。还有一个隐藏坑agent 的缓存。有些 agent 在启动时扫描一次技能目录之后就不再读了安装完必须重启会话或清缓存才能生效。遇到这个问题别急着怀疑脚本先重启一次试试。5.2 同一个 skill 在不同 agent 上行为不一致同一个 skill 在 Codex 里跑得很好换到豆包或 Claude 里就成了「听不懂人话」这个现象很常见。原因主要在于各家 agent 对 SKILL.md 的解析深度不同有的会很严格地按步骤执行有的则只把文档当作参考。我见过最典型的情况一个 skill 的 SKILL.md 写「第 2 步调用 scripts/analyze.py」Codex 会老老实实执行而另一个平台直接跳过脚本去猜答案。这个问题没有一劳永逸的解法我的对策是SKILL.md 里把「必须执行脚本」这句话用显式标记写出来比如用「严禁跳过脚本必须运行python3 scripts/validate.py后才有资格输出结论」这种强约束。同时在 manifest 里加一个agent_hint字段写清楚推荐运行的平台。多平台维护确实成本高但有了统一格式之后至少不至于每个 skill 都要单独处理一遍。5.3 这台机器不想装某些 skill怎么按场景过滤有时候不是所有 skill 都适合某台机器。比如我的办公机上不需要跑 GPU 视频分析家用电脑不装数据库相关的技能。如果每次都手动改install.py来选择那又回到了手工维护的老路。我用tags解决了这个问题tags: - work # 办公场景 - server # 服务器场景 - gpu-heavy # 需要 GPU 资源安装时加一个--tags work,server参数脚本就会只挑 manifest 里包含这些标签的 skill。AI 接到指令时也理解这个机制——它只要把用户说的「这台机器不要 GPU 相关的」翻译成--tags work就行。这个设计本质上就是给 skill 增加了一个「元数据维度」让选择策略从「人肉判断」变成了「规则匹配」。5.4 常见问题速查表症状可能原因处理方式AI 说装好了但技能不可用加载路径不一致 / agent 缓存核对 install_report 中的目标路径重启 agent 会话同一个 skill 行为不一致平台对 SKILL.md 解析深度不同在文档中用强约束词或加 agent_hint 指定推荐平台依赖冲突导致装不上全局环境被多版本污染改用 skill 级虚拟环境按 requirements.txt 独立安装安装后 A 机器正常 B 机器报错平台差异 / 缺系统级依赖检查 manifest.platforms 字段按平台补充依赖脚本没跑完就报成功AI 跳步或忽略错误在任务 prompt 中要求 AI 每步输出错误必须上报库中文件被篡改仓库被外部改动执行 checksum 校验或重新 clone 可信源这张表是我这阵子踩坑后总结出来的最强实用部分。遇到类似问题时先按表格对号入座大部分都能在几分钟内定位到原因解决不了再去找 AI 一起看日志。6. 写在最后的经验与建议我个人的体会是这件事最值得投入的部分不是写安装脚本本身而是把 skill 的「可安装性」当作一等公民来设计。当初如果我只把精力花在「写更好的 prompt」上问题只会越攒越多反而是先定目录、定 manifest、定安装流程之后后面每写一个新 skill都是在复制一套成熟流水线成本肉眼可见地降下来了。还有个小建议尽量让 AI 把安装脚本的运行过程和结果报告结合起来而不是只让它报「装好了」三个字。可验证的结果比口头汇报可靠一万倍。这套方案目前已经稳定跑了一个多月。接下来我准备给它加一个「自动发现更新」的能力——agent 隔一段时间去仓库看一次版本如果有新版本就提醒我确认后自动执行git pull加安装脚本。把这个也做成一个 skill 以后整个 skill 管理系统就算是闭环了。