
1. 项目起因skill 为什么会散落在三台电脑上1.1 从提示词到技能包AI 工程的重心在转移老实说我一开始没觉得 skill 是个值得认真对待的东西。最早的 agent 用 skill无非就是把常用的提示词、工作流模板和脚本丢进一个目录让 AI 在开始干活之前先读一遍。那时候的 skill 更像是一个开场白帮你约束 AI 的语气、输出格式和思考路径核心是提示词工程那一套。但等我自己手头的 skill 超过十五个、电脑超过两台之后问题就开始变得非常现实。你会发现自己陷入一个尴尬的处境同一个技能Windows 上是旧版本macOS 上是改过的版本服务器上干脆没装。三台电脑各留一套残缺副本比没有更折磨人。更麻烦的是有些技能依赖特定的运行环境和工具链A 机器上跑得好好的B 机器上连依赖是什么都说不清。这种情况下技能本身已经不是一段文本而是一个具备完整状态、依赖关系、运行入口和验证方法的软件资产。你让我用一句话总结这个项目我会说把二十个 skill 当成一套可以自我安装、自我校验、自我修复的软件系统来治理让 AI 自己完成跨设备部署。这不是在写提示词这是在做一个非常轻量的智能体自主容错控制工程。核心思路来自社区里大家都在讨论的 LLM 智能体自主容错控制框架系统不能假设环境永远正确必须让 AI 在安装、执行、验证的闭环里实时发现问题、自己做判断、自己回滚。这也是我写这篇实录的原因。网上讲 skill 怎么写的内容很多讲怎么管理一堆 skill的内容很少。更没人告诉你当 skill 数量到了一定规模、机器到了一定数量真正卡住你的不是技能内容本身而是技能的分发、版本和故障恢复。这篇文章就是来补这个空白的。1.2 三台电脑各留一套残缺副本的教训我手头常驻三台设备用途完全不同。一台 Windows 桌面机主要处理文档、表格、批量数据处理偶尔写点报告一台 macOS 笔记本主力开发机跑 agent、跑代码生成、做 GIS 空间分析和日常自动化还有一台 Linux 服务器放在家里内网跑定时任务、数据抓取和需要长时间执行的后台批处理。这三台机器的操作系统不同、软件环境不同、网络条件也不同。早期我给每台机器分别手工配置 skill结果就是同一时间三个版本Windows 上的某个写报告技能还停留在上一个迭代macOS 上已经加了今年新要求的格式规范服务器上则干脆缺了好几个关键技能因为装的时候正好赶上一次大改我忘了同步。再加上有些技能需要调用外部的命令行工具比如 pandoc、ffmpeg、ogr2ogr 这些不同机器上装没装、版本够不够完全靠脑子记。真正让我下定决心重构的是一次线上事故。当时我在 macOS 上调好了一个生成短剧脚本的技能跑得很顺。第二天出差只有 Windows 笔记本在身边我顺手让 AI 写一个短剧脚本它直接给我报错——技能未安装。我一查这个技能在 macOS 上是通过一个软链接目录启用的Windows 上文件倒是拷过去了但目录结构不对依赖的批处理脚本也找不到。那个时候我意识到靠人肉同步 skill 已经完全不可行了。所以这个项目的目标特别明确同一套技能清单二十个 skill无论放到哪台电脑上都只需要执行一条指令AI 自己完成目录创建、文件拷贝、依赖检查、自检启用、失败回滚。我不再关心某台机器上缺什么我只需要维护好一个技能仓库和一个技能清单剩下的事全部交给 AI 的自主容错能力。2. 技能工程的顶层设计SKILL 也是软件资产2.1 技能的文件组织规范要让 AI 能自己安装技能首先得给技能定一套严格的目录规范和文件格式。我的做法是把每个技能做成一个独立目录放进技能仓库统一管理。一个标准技能的最小结构是四样东西skills/ └── write-report/ ├── SKILL.md ├── run.sh ├── check.sh └── assets/SKILL.md是这个技能的身份证和说明书头部用 YAML 格式写元信息正文用 Markdown 写执行规则。run.sh是实际执行的入口脚本AI 调用这个技能时读的就是它。check.sh是自检脚本用来判断这个技能在当前环境下是否处于可用状态。assets/放模板文件、配置文件、参考样例这些辅助资源。之所以把技能说明和运行入口分开我是踩过坑才想明白的。最开始我把所有内容都塞进SKILL.mdAI 读完后自己决定怎么做看起来灵活实际上每次执行结果都不稳定。后来改成SKILL.md只做主流程拆解和规则约束具体的确定性操作收敛到脚本里AI 只负责编排和参数填充不再临场发挥。这个改动让技能输出稳定了非常多。再看 SKILL.md 的元信息头这是给程序看的不是给人看的--- name: write-report version: 2.1.0 signature: skill-report-0193 platforms: [windows, darwin, linux] run: run.sh check: check.sh dependencies: [python3, pandoc] ---这里我特别解释一下signature字段。技能名可能会改但签名是一个唯一编号相当于技能的程序指纹。技能升级不影响签名只要功能定位没变签名就不变。skill 编码 0193、0247 就是这么来的——我给我的每个技能分配了一个固定编号哪怕以后重命名目录、改版本号AI 都能通过签名认出这个技能我见过。后来我把签名格式统一成skill-{category}-{number}写报告是 0193GIS 空间分析是 0247短剧脚本是 0248一眼就能看出归属。2.2 用 manifest 索引一切技能技能目录是物理存在但 AI 不能靠肉眼找技能它需要一个机器可读的总索引。我在仓库根目录放了一份inventory.json维护所有技能的元数据、版本、签名、所属分类、目标平台和安装状态。{ skill_inventory: [ { signature: skill-report-0193, name: write-report, version: 2.1.0, category: writing, platforms: [windows, darwin, linux], install_to: ~/.agent/skills/write-report, checksum: a3f29c... } ] }AI 在处理安装这个任务时不是直接遍历目录猜测要装什么而是先读inventory.json拿到这份标准化的清单再跟当前机器的实际状态做对比。这一步非常关键它把让 AI 自己装好从一句口号变成了一个可执行的项目管理流程读清单、查现状、算差异、执行安装、跑自检、更新状态。目录规范之外我还定了一条硬性约定技能的物理文件放在哪个位置不重要重要的是安装后必须注册到本机的状态文件里。每台机器上维护一个~/.agent/skill_state.json记录本机已安装技能的签名、版本、安装时间和自检结果。这样 AI 检查状态时就有一个明确的依据——清单里有、状态文件里也有、且自检通过才算这个技能可用。2.3 为什么把可用和启用拆开刚开始设计自动安装的时候我以为装完就算完事。后来发现不对某台机器上技能文件倒是复制过去了但依赖没装好AI 调用技能时照样报错。于是我把技能的目录拆成两层available/存放所有已安装但未经自检的技能文件enabled/只放通过自检的软链接。这个设计其实来源于一个特别朴实的管理学类比药品仓库里可以堆着一批新到的库存但只有通过质检、拿到批号的药品才会放进药房货架。available 相当于待检验库存enabled 才是真正能对外提供服务的货架。AI 安装技能的时候先把文件解压/复制到 available 目录然后运行check.sh通过之后在 enabled 目录创建软链接如果自检失败技能就留在 available 里等着排查但 AI 调用时不会加载它。这套先准入、后启用的机制给了自动安装一个安全边界AI 的任何错误操作最多污染 available 目录不会影响已经正常服务的技能。你在执行一条自主安装指令时最担心的是它搞崩你本来能用的东西有了这层隔离最坏情况也只是新增技能没装上存量技能一个都不会坏。3. 一句话自装自主安装与容错控制的核心逻辑3.1 自举流程的设计让 AI 自己装好本质上是把一套完整的部署流程封装成一个超级 skill我给它起名叫agent-bootstrap。这个技能不干别的只负责管理其他技能。它的执行入口是一个bootstrap.sh但真正起作用的是 AI 会按照 SKILL.md 里的流程动作走完四个阶段扫描、对账、安装、验证。第一阶段是扫描。AI 读取inventory.json技能清单和本机的skill_state.json状态文件同时实际查看 enabled 目录里的软链接拿到当前机器到底有哪些技能可用的真实情况。这一阶段不修改任何文件只做信息采集。第二阶段是对账。AI 逐项对比清单和现状得出三类结论缺失技能清单有、机器没有、版本过期签名一致但版本落后、冗余技能机器有、清单已删除。对账结果会写进一份临时差异报告AI 会输出这段内容让我确认。这一步我坚持必须要人看一眼因为自主再高也不该在用户没确认的情况下动文件。第三阶段是安装。对于缺失和过期的技能AI 按分类处理先把技能文件复制到available/再检查依赖声明缺什么装什么。依赖装不动的情况AI 不会硬来它会判断瓶颈在哪里给出两个选项需要本机管理员权限或者需要用户手动操作某项前置步骤。这种判断是执行 prompt 里明确规定的不是 AI 现场猜的。第四阶段是验证。每个安装完的技能都跑一遍check.sh通过则创建软链接到enabled/失败则保留在available/并记录失败原因。整个流程结束后AI 输出一张报告表列出新装、升级、回滚、失败四个分类方便最终确认。用户侧的操作其实就是一句话请按标准流程检查这台机器上的技能状态对照 inventory 清单补齐缺失技能完成自检后输出报告。这句话发出去之后AI 会自己按流程动作不需要我再干预。中途如果遇到必须人工介入的点它会主动停下来问我而不是蒙着继续跑。3.2 验证与回滚机制自主容错控制的重点不在能装而在装错了怎么办。我设计了两个安全阀一个是自检命令一个是回滚机制。自检命令就是每个技能自带的check.sh。写这个脚本的时候我给自己立了一个规矩check.sh 必须做三件事——检查入口文件是否存在、检查关键依赖是否可达、执行一次最小烟雾测试。拿 GIS 分析技能来举例它的 check.sh 先确认run.sh存在再用which ogr2ogr验证 GDAL 工具链已安装最后尝试跑一次极小的空间分析命令比如读取一个测试 GeoJSON 并输出要素数量。三步全过才算自检通过。如果自检失败AI 会进入回滚流程。回滚的粒度是单个技能不影响其他技能。具体做法是安装之前AI 先把该技能对应的 enabled 软链接指向的原目录做一个快照备注记录原版本号安装中如果自检失败AI 删除 available 里新拷贝的目录保留原可用目录不动。因为可用和启用是分离的所以回滚操作非常简单——把软链接重新指向原版本目录即可整个过程不需要重新拷贝文件几秒钟就完成。我一开始自己写回滚逻辑的时候想的很复杂什么版本快照、差异备份后来发现根本不需要。目录结构上做一点隔离回滚自然就变得很轻。这个思路后来也写进了我的 SKILL.md 设计模板里任何 skill 都必须提供 check 命令任何安装流程都必须假设 check 可能失败。3.3 跨设备同步的心得二十个 skill 散在三台机器上最重要的枢纽其实是一份统一的技能仓库。我的做法是把整个技能仓库放在内网服务器上用 Git 管理每台设备上只需要保证能访问这个仓库地址。为什么不用云盘同步文件夹我试过文件能同步但目录权限和软链接会被云盘搞得乱七八糟而且同步回来的文件经常带着冲突副本AI 去读的时候根本分不清哪个是准的。Git 仓库做源有几个天然优势。第一版本有记录每个技能什么时候改过、为什么改一目了然这就是技能的完整变更历史。第二分支可以玩策略稳定版放主干测试中的技能放单独分支AI 默认只从主干安装。第三Git 的 clone/pull 动作本身就是 AI 很容易执行的命令不需要额外的同步协议。跨设备同步的完整链路是这样的我更新技能内容后提交并推送内网 Git 仓库任意一台电脑上我发一条同步技能仓库并检查技能状态的指令AI 先执行 Git pull 拉取最新清单和技能文件然后自动走扫描、对账、安装、验证的流程。这样我只需要在一台电脑上改一个技能其他机器下次同步时就会自动跟上不会再有改了 A 忘了 B的情况。这里我多说一句为什么这个方案比直接 rsync 文件更值得做。rsync 只会机械地把文件从源头复制到目标它不知道目标机器的依赖缺了什么也不知道复制过去的技能是否能在当前环境运行。而 AI 自装流程做的是语义级同步——它不只是把文件放到位还会检查依赖、执行自检、判断启用、处理回滚。文件同步解决的是有没有的问题AI 自装解决的是能不能用的问题。4. 实操记录三台电脑的部署实录4.1 设备与技能清单先把实际部署的环境摆出来。三台机器的角色和技能分布如下设备系统技能数量主要用途特殊依赖桌面机Windows 118文档写作、报表生成、批量数据处理pandoc、Python 3.11主力笔记本macOS12日常开发、AI 编码、GIS 分析、短剧脚本Node.js、GDAL、ffmpeg内网服务器Ubuntu 22.049定时任务、数据抓取、后台批处理cron、curl、jq三台机器加起来一共装过 20 个不同的技能其中大约 7 个技能在多台设备上共用。比如说write-report这个写报告技能三台机器都要用因为我在任何一台电脑上都有可能临时要出报告。而像gis-spatial-analysis这种技能只在 macOS 主力机和 Linux 服务器上装Windows 桌面机用不到。技能清单的分类我分成五类写作类报告、短剧脚本、语言学习、开发类代码生成、代码审查、测试命令生成、数据处理类批量文件处理、数据清洗、GIS 分析、系统自动化类定时任务管理、设备文件扫描、以及提示词工程类去 AI 味写作、角色风格控制、打斗动作提示词。每类技能对运行环境和依赖的要求不同正好能检验自动安装流程的通用程度。4.2 在新增电脑上一句话装好的全过程我拿最近一次在新笔记本上部署来演示完整流程。那台笔记本是一台全新的 macOS干净系统只装了基础开发工具一个技能都没有。我要做的是直接在对话里发出指令请同步技能仓库到本机并按照 inventory 清单完成所有技能的安装与自检。AI 拿到这条指令后第一件事是确认仓库地址和访问凭据。仓库我放在了内网服务器的 Git 服务上AI 执行了git clone把技能仓库拉到了~/.agent/skills-src/。这一步用了一分多钟取决于仓库大小和网络速度主要是技能 assets 里有一些模板文件和样例数据比较大。然后 AI 读取inventory.json对照本机空的skill_state.json得出全部 20 个技能缺失的结论。它没有直接动手而是先把一份即将安装 20 个技能的清单打印出来并标出其中需要额外依赖的技能名称然后问我是否继续。这一步是我在 prompt 规则里强制要求的AI 不能在未确认的情况下大批量修改系统。确认后AI 开始逐个处理技能。每个技能的安装顺序是先看依赖。比如write-report需要 pandocAI 检测 Mac 上没装它会先执行brew install pandoc成功后再继续装技能本体。如果某个依赖装不上比如某个技能需要特定版本的 GDAL 而 Homebrew 默认源里没有AI 会跳过这个技能继续装后面的最后在报告里单独标出失败原因。这个跳过但不中断的容错逻辑很重要否则一个技能失败会拖垮整条安装链。全部处理完后AI 输出了一份安装报告我简化一下核心内容分类数量说明新装成功17含自检通过软链接已建暂存待处理2依赖未满足文件在 available 未启用失败1需要账号授权的外部服务看到这个结果我只花了大概十分钟处理那两个待处理项和那个授权问题其余 17 个技能一装就能用。如果按以前的手工方式新机器配置完全部技能至少得大半天而且中间很容易漏装少装。4.3 实际效果安装耗时、容错表现、人工介入点这套流程跑了大半年体感和一些具体数据都积累了不少。一次全量安装从开始到出报告总耗时通常控制在五到十分钟。其中 Git 拉取占了大头真正执行安装的耗时反而很短因为大部分技能就是复制文件和建软链接真正费时间的是依赖安装。容错表现给了我不少惊喜。有一次服务器上的技能批量升级其中一个技能新版本引用了系统里不存在的库。自检失败后AI 自动把那个技能保留在 available 目录enabled 软链接还是指向旧版本旧技能照常能用。等我在仓库里修复了依赖声明并推送新版本后再发一次同步指令AI 检测到版本落后重新走了安装和自检流程。整个过程几乎没感觉到中断。人工介入点主要集中在两类技能上。一类是需要账号授权的比如某些外部服务的 API 密钥或网盘授权这类技能的安装本身很简单但凭证不在技能包里需要我手动完成一次授权操作AI 会卡在那里等我。另一类是需要特定 GUI 环境的比如某个 Windows 上的自动化技能它依赖一个只有桌面登录后才能访问的本地工具AI 检测到当前会话没有 GUI 权限会明确提示需要使用图形界面环境执行。这些情况不是缺陷反而说明 AI 的容错判断是有效的——它知道自己能力的边界。5. 常见问题与避坑速查表5.1 高频问题与排查思路问题现象排查思路技能依赖装不上自检失败check.sh 报 command not found先看依赖声明是否完整再看包的源是否可用最后考虑版本兼容性自检通过但实际运行报错check.sh 只做了最小验证真实场景数据却触发问题扩大烟雾测试的取样规模增加真实数据的抽样用例同一技能不同系统行为差异Windows 上正常macOS 上路径分隔符或命令不同在 run.sh 里用条件分支判断系统类型或者针对平台拆 run 脚本跨机器版本不一致某台机器技能版本长期落后检查 Git 同步是否成功确认 state.json 里的版本号有没有正确落盘AI 把技能装到了错误位置enabled 目录里出现孤立软链接检查技能声明里的 install_to 路径确认不同系统的路径映射规则排查的时候最好反过来想绝大多数问题都出在技能声明不够严格而不是 AI 执行不给力。依赖写得模糊、路径写死、check 命令设计得过于简单这些才是根源。AI 只是在执行一份写得有漏洞的说明书你不能指望它自己把漏洞补上。5.2 几个让我少走弯路的设计心得第一个心得每个技能必须有一个可执行的验证命令。这可能是整个项目里最重要的一条规则。没有验证命令自动安装就是一个盲盒——装上之后到底能不能用只能靠运气。有了 check.shAI 才能做出装上了和能用了这两个层次的判断后者的价值比前者高得多。第二个心得技能名是写给人看的签名是写给程序看的。刚开始我给技能取名很随意结果改名之后 AI 的逻辑就乱了因为状态文件里记录的还是旧名字。后来强制引入 signature 签名机制改名不影响识别技能的身份和名字解耦。这个改动看起来很小但对稳定性的提升是质的。第三个心得权限和凭据绝不放进技能包。技能包主要分发给三台电脑如果里面包含 API 密钥或私有凭证只要仓库泄露一次所有机器的安全性都完蛋。我的做法是技能安装时只生成一个配置文件模板具体的密钥由用户手动填或者从本机独立的凭据文件里读取。AI 可以在需要时提示用户配置但绝不能通过 Git 分发敏感信息。第四个心得定期做一次技能体检。我给自己设了一个 cron 任务每周在 Linux 服务器上跑一次全量技能自检把每个技能的 check.sh 都执行一遍然后生成健康报告。服务器上的技能常在后台批处理场景中使用出了问题不会立刻被发现体检机制帮我提早抓到过好几次依赖静默失效的隐患。如果让我重新来一次我最先做的一定不是先写二十个 skill而是先把 inventory.json、目录规范和自检机制搭好。技能内容可以慢慢迭代但骨架和闭环要一步到位。工具会换模型会升级真正能积累下来的东西其实是这套让 AI 自己做决策、自己做检查、自己承担容错责任的工作流。