一次整理手头文件的时候我突然发现一个有点尴尬的事实我这些年零零散散攒下的 20 个 AI skill不在同一个地方。办公笔记本上一套家里台式机上一套实验室的工作站上又有一半版本还不一样。每次换电脑干活都要先手动补一堆环境运气不好还得跟依赖搏斗半天。于是我做了一个很小的工程化改造写一个安装器把 20 个 skill 打包进 Git 仓库然后让 AI Agent 听懂一句话——“帮我把这些 skill 装到另外两台电脑上”剩下的事由 AI 自己完成。这篇文章就是这次落地的完整记录包括为什么这么设计、安装脚本怎么写、Agent 是怎么拆解指令的以及我踩过的那些坑。如果你手上也有多台设备、一堆自定义 AI skill 要管理这篇文章应该能帮你省下不少时间。1. 先聊清楚这 20 个 skill 到底是什么以及为什么散了三台电脑1.1 从“随手存一段提示词”到“正经技能包”很多人会把 AI skill 理解成一个提示词文件其实放到工程环境里它更像一个带入口的“技能包”。一个完整的 skill 通常包含几个部分一段用于触发能力的核心提示词一组可复用的脚本或工具函数一份描述“这个 skill 能干什么、需要什么参数”的说明文件以及它依赖的环境配置。我最初也是从提示词开始的。比如“会议纪要”这个 skill最早就是一个 prompt让 AI 把会议录音转写结果整理成结论、待办、风险。看起来能用但换个电脑、换个模型效果就飘忽不定。后来我把它拆成标准结构用 YAML 写清参数把处理脚本单独拿出来再配上依赖清单它才算真正变成一个可以安装、可以卸载、可以在多台机器上保持一致的 skill。这 20 个 skill 覆盖的场景很杂有写代码用的代码审查、日志分析、提交信息生成有写文档用的技术方案起草、周报生成还有一些偏工具型的 PDF 内容抽取、图片批量压缩、数据库慢查询分析。它们的共同点是都会被执行多次值得被当成一套“资产”来维护。1.2 散落在三台电脑的真实原因不是一开始就故意设计成多机的纯粹是自然长出来的。办公笔记本是日常工作主力最早一批 skill 在这里产生。家里台式机主要用于周末写点东西、跑跑私人项目我图方便复制过几个文件过去但复制之后很少再同步。实验室工作站是 GPU 机器很多需要在本地跑模型推理的 skill 会被放在那边数据也在那边文件路径跟另两台完全不一样。问题在对比版本时彻底爆发了。同一个代码审查 skill办公笔记本上是 v2.1家里台式机上还是 v1.3实验室里干脆是某个中间改动。三台机器各有自己的“正确版本”我根本记不清哪个是最新的。手动改完一台另外两台大概率就落后了。这种状态也让我意识到skill 本身不重要重要的是它的版本、依赖、入口路径都是可描述的。只要把可描述的信息固化下来多机同步就能从“手工复制”变成“工程问题”。1.3 一句话装好的目标不是炫技是省命我可以直接用脚本批量同步为什么还要做“一句话让 AI 自己装”因为真正的痛点不是“装一次”而是“每次都在不同上下文里装”。有时候我在 A 电脑上想用某个 skill发现没装有时候我改了 skill 想立刻同步到另外两台有时候新机器到手需要一次性恢复全部环境。这些操作如果都要手打命令、查文档、处理报错那这套系统就毫无意义。我的目标是对着 AI 说一句人话比如“把代码审查 skill 装到另外两台电脑上”AI 自己确定传输方式、检查依赖、执行安装、给出结果。它本质上是一个 AI Agent 驱动的自动部署系统只是部署的对象不是微服务而是那 20 个 skill。2. 系统设计给每个 skill 立规矩安装才可能自动化自动化最怕“约定不明”。如果每个 skill 文件和脚本的位置都不一样安装器将无从下手。所以在写任何安装逻辑之前我先给所有 skill 立了一套规矩。2.1 Skill Manifest名字、入口、参数、依赖全写进一个文件每个 skill 的根目录下必须有一个manifest.yaml这个文件就是整个 skill 的身份证。我参考了一些开源 Agent 插件的做法把安装时需要的信息全部集中到这一个文件里。下面是一个简化的示例name: code-review version: 2.1.0 description: 对 MR/PR 的 diff 进行代码审查输出问题、建议和风险等级 entry: skills/code-review/entry.py prompt: skills/code-review/prompt.md parameters: - name: diff_path required: true description: 待审查 diff 文件路径 - name: focus required: false default: bug, security, performance dependencies: - python 3.10 - openai 1.0 platforms: - linux - macos - windows postinstall: - python -m pip install -r requirements.txt这里有几个字段值得展开说明。entry字段表示 skill 的主执行入口我把所有逻辑都收敛到一个可执行文件里Agent 不需要猜测“到底该跑哪个脚本”。prompt字段指向提示词文件安装时会把提示词内容注册到本地的 skill 列表里。parameters让 Agent 知道调用这个 skill 时应该传哪些参数避免一句模糊的“帮我审查代码”就无从下手。postinstall是安装后的附加命令我最初的版本没有设计这个字段结果很多 skill 装完不能直接用因为依赖没装后来才补上。2.2 统一目录约定的价值三台机器同一个“家”只靠 manifest 还不够三台电脑上的 skill 目录必须一致。我在每台电脑上都统一用了~/skills这个根目录每个 skill 通过一个子目录存放目录名就是 skill 名。例如~/skills/code-review。这样的好处是安装路径的推导不需要硬编码只要知道 skill 名就能算出目标路径。统一的目录约定还有其他隐性好处。比如 Agent 检查“这个 skill 装没装”时只需要看目标目录是否存在、manifest.yaml是否存在、版本号是否满足。这比扫描一堆杂乱路径要省力得多。用户也可以直接打开~/skills看到一个清单完全透明。我在一台新机器上恢复环境时只需要说“从仓库把所有 skill 装回来”Agent 就会按 manifest 列表逐一下载、安装、注册。这个体验比起以前“右键–另存为”再到终端里手动pip install已经不是一个时代了。2.3 安装器只认 manifest不认“人情”整个系统里最核心的代码是一个叫skill_installer.py的脚本。它的逻辑很直接读 manifest校验版本和平台准备目标目录复制文件执行 postinstall写安装状态。写这个脚本时我坚持一条原则安装器只认 manifest不认任何目录特殊规则。某个 skill 的数据文件放在哪个子目录依赖装到什么环境只要 manifest 里写了安装器就照做manifest 没写的安装器一律不管。刚开始看起来有点死板但正是这种死板保证了可预测性。Agent 在调用安装器时实际上只做三件事确认目标机器、确认 skill 列表、调用脚本。真正的判断逻辑都在安装器内部。这样即使 Agent 理解错了什么最终执行层仍然是可控的不会把乱七八糟的文件写到系统目录里去。3. 从“一句话”到“真装好”自然语言指令在背后发生了什么用户感知是“一句话”但在工程上这句话要经过好几个环节才能变成可靠操作。这个部分最容易被人忽略也最值得详细拆。3.1 用 Agent 承接指令先别急着动手我目前接指令的 Agent 是一个基于函数调用的封装层。它本身并不直接复制文件也不去注册 skill而是维护了一份“可执行工具列表”。当用户说“把代码审查 skill 装到另外两台电脑上”时Agent 会先解析用户意图再映射到两个可用工具remote_install(skill_name, target)和list_remote_status(target)。为什么不让 Agent 直接执行 shell因为 shell 的自由度太大容易出安全问题。我只暴露几个语义明确的工具比如安装、卸载、列出状态、同步清单。Agent 在这个工具集里做选择既保留了自然语言的交互体验又把风险边界框住了。这一步还有一个小细节Agent 在动手前会输出“计划”比如“准备将 skill 安装到 work-laptop、lab-workstation确认请回复”。这是给用户的一个确认机会。前期我直接让 Agent 动手结果有一次把 skill 装错了电脑后来就加了确认环节。3.2 指令解析把“把镜像站那个翻译 skill 装到办公本”拆成结构化任务一个现实的指令往往带有模糊表达。例如“镜像站那个翻译 skill”指的不是仓库里的translate而是translate-mirror“办公本”要映射到主机名work-laptop。Agent 要做的一项工作是“消歧”。这个解析过程不是用正则硬匹配而是让 Agent 参考一份环境清单。环境清单里记录了每台设备的别名、主机名、当前系统、可达状态。Agent 看到“办公本”时会搜索别名列表找到work-laptop。如果一条指令里出现了无法匹配的实体Agent 会直接反问而不是瞎猜。拆出来的结构化任务类似这样{ action: install, skill: translate-mirror, targets: [work-laptop], sync_after_install: true }有了这个结构安装器就可以按部就班地执行了。自然语言到结构化任务的转换是整个链路里最容易被低估的一环但也是让“一句话”真正可靠的基石。3.3 下载与校验skill 包传输要可验证把文件传到目标机器之前要先确认三件事文件在仓库里存在、版本号正确、内容没有被改动过。我的做法是在每个 skill 目录下放一个sha256sums.txt里面记录每个文件的哈希值。传输完成后安装器不会立刻进入安装流程而是先做一次哈希比对。比对通过才认为文件确实到位比对失败直接终止并报告差异文件。这一步在局域网环境下看起来有点多余但实际上非常值得。因为我在传输过程中踩过文件被截断的坑尤其是通过不太稳定的无线网络传比较大的文件时缺几个字节就会导致 skill 运行结果诡异。现在的流程是Agent 从仓库拉取 skill 元数据和打包文件传输到目标机器的临时目录用sha256sum -c sha256sums.txt校验然后把文件移动到~/skills/skill_name。整个过程可以用一条命令验证也能让 AI 自动处理失败。3.4 自动安装循环探测—执行—校验—回滚安装不是“执行一次”就结束而是变成一个循环尤其是多机并行安装时任意一台失败都不能影响其他机器。我参考自动化运维的“幂等”理念把安装流程设计成四个阶段。探测检查目标目录是否存在、版本是否满足、依赖是否已经就位。如果目录存在且版本高于或等于待安装版本直接跳过。执行按 manifest 的 entry 和 postinstall 执行安装动作。校验运行一个轻量的自检命令比如导入对应模块、调用入口的--version参数确认 skill 可用。回滚如果校验失败恢复安装之前的目录快照删除新写入的文件保证系统不处于“半装半不装”的状态。回滚功能是后来补的。早期版本没有回滚有一次安装了新依赖导致另一个 skill 的依赖版本冲突现场很狼狈。现在每个 skill 安装前都会生成一份当前目录的tar.gz快照放在临时目录校验失败后可以立即还原。这个步骤让整个安装过程从“一气呵成”变成了“可靠可控”。4. 三台电脑之间到底怎么同步没有共享目录也能装得快多机自动安装另一个绕不开的问题是文件怎么过去。我试验过几种方式最终根据场景做了区分。4.1 文件传输局域网共享 / rsync / 打包下载我三台电脑都在同一个局域网里所以首选的方式是 rsync。它增量传输、保权限、断点续传而且天然跨平台。在使用 rsync 之前我试过普通 SCP但 skill 目录里文件很多每次哪怕改一个文件也要全量传一遍速度感人。后来改用 rsync 的-az --partial参数传输时间从几十秒降到了几秒。如果目标机器不在局域网就必须走中转。我把 skill 仓库放在 Git 服务上Agent 生成一个包含当前版本 tag 的下载链接目标机器通过git clone --depth 1 --branch vX.Y.Z拉取对应版本。这里没有用大文件中转网盘之类的东西因为 Git 本身能保证版本一致性和历史可追溯对 skill 这种文本加少量脚本的资产非常合适。4.2 状态同步一个 skill 装没装用状态文件说了算每台电脑上我都保留一个~/skills/.state.yaml文件记录当前已安装的 skill 和版本。它的作用就是“状态真相”。Agent 执行任何同步操作前先读这份文件再跟仓库里的manifest.yaml列表做对比得出差异然后只安装差异部分。状态文件长这样installed: code-review: 2.1.0 meeting-notes: 1.4.0 translate-mirror: 0.9.0 last_updated: 2025-06-17T22:10:0008:00有了状态文件重复执行同一句话也不会重复安装因为我之前提到安装器会先探测版本。更重要的是AI 可以基于这份状态文件回答用户问题“哪台机器缺哪些 skill”“哪些 skill 版本落后了”这种可查询能力比简单传输文件更有价值。4.3 离线与局域网备选方案如果遇到完全没有网络的场景我留了一条很土但有效的备选方案U 盘导出。Agent 可以把所有 skill 的当前版本打成一个大包导出一个skills-bundle.tar.gz到指定目录然后我手动复制到另一台电脑在那台电脑上运行skill_installer.py --bundle skills-bundle.tar.gz。这套方案看起来不够“自动”但它是最后一道兜底。工程系统不应该假设网络永远可用保留一条纯离线路径比让 Agent 卡死在“无法连接远程主机”上要舒服得多。我在一次出差途中实际用过这个备选方案虽然多了一步手动复制但到了现场之后依然是一句话完成剩余安装。5. 实测过程同一句话在不同电脑上的差别理论讲再多不如看一次实际操作。我拿“把代码审查 skill 装到另外两台电脑上”这句话做了一次完整实测记录一下真实表现。5.1 三台电脑环境差异三台电脑的系统环境差别明显办公笔记本是 macOS家里台式机是 Windows 11实验室工作站是 Ubuntu 22.04。这正好考验了 manifest 里的platforms字段是否靠谱。macOS 上 Python 是 Homebrew 装的Linux 工作站上 Python 是系统自带Windows 上用的是 Anaconda。三台机器都没法共用一套安装路径但好在每个 skill 本身都是跨平台的依赖冲突才是真正的点。代码审查 skill 依赖openai库和ripgrep这两者在三台机器上都有不同安装方式我只能在 manifest 里分别写好postinstall的条件判断。实际测试时Agent 的表现符合预期在 Windows 上执行powershell -Command安装ripgrep在 macOS 上执行brew install ripgrep在 Linux 上执行apt-get install ripgrep。这些命令都写在 manifest 的postinstall里由安装器选择当前平台对应的部分执行而不是让 Agent 临场发挥。5.2 一次典型的安装过程实录我简化了安装过程中的日志输出大致长这样[Agent] 正在解析指令... [Agent] 目标: work-laptop, lab-workstation [Agent] skill: code-review (source: repo2.1.0) [Installer] 校验 manifest: 通过 [Installer] 检查目标机器: work-laptop [Transfer] rsync -az --partial ./skills/code-review work-laptop:~/skills/ [Installer] 文件校验: sha256sums 全部通过 [Installer] 执行 postinstall(platformmacos): brew install ripgrep [Installer] 校验安装: entry --version 输出正常 [Installer] 写入状态: .state.yaml [Agent] work-laptop 安装完成 [Installer] 检查目标机器: lab-workstation ... [Agent] 全部完成2 台机器已更新0 台失败这不是打印出来给用户看的花架子每一步都是真实动作。Agent 在每台机器上安装完都会返回一个结构化结果我可以在最终答复里看到每台机器的安装时长、是否有跳过、是否有回滚。整个测试跑下来一次安装的平均耗时在 20 秒以内主要时间花在了 rsync 传输和依赖安装上。如果目标机器已经有对应依赖传输完就能直接注册体感几乎是瞬时的。5.3 幂等重复安装不会爆一个容易翻车的点是重复安装。如果我说“再把代码审查 skill 装一遍”系统应该察觉到已经装了同样版本然后直接跳过而不是再跑一遍安装流程也不会重新brew install ripgrep。这个逻辑我在安装器的探测阶段已经做了。现在实际测下来重复执行的安全性没问题安装器会输出“已是最新版本跳过”。但有一个边界情况我提醒过自己如果同一个 skill 存在两个不同版本比如本地是 v2.1.0仓库是 v2.1.1则不应简单跳过而应执行升级安装。升级流程跟全新安装类似但多了备份旧版本和迁移配置文件的步骤。目前我的 20 个 skill 里只有少数需要升级时保留配置所以这个流程还在逐步完善。6. 踩坑与排查技巧实录这部分是我最想写的因为很多问题是文档里根本不会写的只有真正跑过才会遇到。6.1 常见问题速查表我把这段时间最常遇到的问题整理成了表格方便你直接对照排查。症状可能原因解决办法安装后 skill 能注册但运行时缺依赖manifest 的 dependencies 和 postinstall 没写全在 manifest 里补全依赖并将pip install写入 postinstallWindows 上路径带中文/空格导致失败命令没有正确加引号统一使用Path对象拼接路径传给子进程时shlex.quote同网段 rsync 连接超时防火墙未开放 ssh 端口检查三台机器的 ssh 服务状态放行 22 端口Agent 把“办公本”理解成台式机环境清单里的别名不准确维护别名表并在 Agent 计划阶段确认目标机器名称安装中断状态文件被写了一半未使用临时文件 原子替换先写.state.yaml.tmp再os.replace原子替换某 skill 校验失败但不报具体文件缺少sha256sums.txt或文件被修改每次提交仓库前重新生成全部哈希6.2 三个让我改代码的教训第一个教训是不要过度相信语音/自然语言的“模糊能力”。有一次我对 Agent 说“把写日报的 skill 装到老电脑上”它居然把“老电脑”解析成了服务器差一点把开发机搞乱。后来我意识到与其让 Agent 猜不如让它在遇到不确定的值时直接问用户。现在 Agent 的执行优先级是“不确定就先问问不到再放弃”。第二个教训是 Windows 下的路径处理比 Linux 麻烦得多。同样一段 Python 代码在 Linux 上能正确拼接路径在 Windows 上可能因为反斜杠和引号翻车。我后期统一用了pathlib.Path并且禁止在 skill 代码里硬编码字符串路径所有路径都通过manifest.yaml或者环境变量传入。这个改动消除了一大批“能跑但不能迁移”的问题。第三个教训是安装校验不能只看文件存在。早期我在校验阶段只检查entry文件是否存在结果有些 skill 虽然文件在但依赖环境完全不对一运行就报错。后来我把校验分为静态校验和动态校验两层静态校验检查文件、版本、哈希动态校验调用入口执行一次自测。动态校验更可靠但会慢一点所以只对核心 skill 开启。6.3 安全红线自动安装不是免死金牌AI 自动安装听起来很爽但如果没有安全边界它就是一个巨大的风险点。我在设计这套系统时给自己划了几条必须遵守的红线。不在没有确认的情况下跨机器修改系统级配置。Agent 能操作的范围限制在~/skills、用户级 Python 环境、用户级服务任何需要 root/管理员权限的命令都会触发人工确认。不在安装过程中无差别执行第三方脚本。所有 skill 的postinstall命令只允许在白名单命令范围内比如pip install、brew install、apt-get install等而且命令内容必须与 manifest 一致。这个白名单机制是从一次“skill 试图安装任意包”的教训中加的。不对状态文件之外的系统文件做任何假设。Agent 可以创建和修改~/skills下的文件但不能主动去动其他目录即使它认为自己“有权限”。这个约束看起来有点反效率但换来的是高确定性。自动生成的安装日志会保存在~/skills/logs/下每天轮转。一旦哪里出了问题可以从日志回溯到底哪一步被跳过了、哪条命令执行失败、哪台机器成功。日志本身也被纳入状态同步的范畴这样能避免“本地有异常但远程完全不知情”的信息孤岛。回滚逻辑同样安全优先。它只删除安装过程中新增的文件和目录绝不会执行整目录的rm -rf操作。我甚至在回滚函数里强制禁止了绝对路径传入防止某些极端情况下把~/skills之外的内容清掉。树枝特别小也不允许滑过。7. 最后说点实际操作里的个人体会这次“二十个 skill 散在三台电脑一句话让 AI 自己装好”的工程改造给我最大的收获不是自动化本身而是把“不可控的散落资产”变成了“有版本、有依赖声明、有安装入口的标准化资产”。现在即使某个 skill 在电脑上出了问题我也可以用一句话让 AI 去排查、回滚、重新安装而不用 SSH 上去一个个看文件。实际操作中我发现最容易让整个系统失效的不是技术方案而是“懒”。如果新增了一个 skill 却没有及时把 manifest 和哈希文件补上后续自动化就会瞬间失去依据。于是我在仓库里加了一个 pre-commit hook每次 commit 前自动校验所有 skill 的 manifest 字段是否完整、哈希是否最新。这个钩子虽然简单但比任何口头规范都有效。如果你也想搭一套类似的系统我的建议是从小处起步。不要一上来就想管 20 个 skill先挑两个跨平台差异最大的 skill 练手把安装器、状态文件、Agent 工具调用跑通再逐步扩大范围。多机自动安装的复杂度并不在于复制文件而在于每一次安装后的验证和每一次失败后的恢复。先把这两块做好剩下的都只是时间问题。
阅读完成 · 觉得有帮助?