ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

让AI Agent自动管理多设备Skill:从扫描到验证的全流程实践

让AI Agent自动管理多设备Skill:从扫描到验证的全流程实践

1. 三台电脑、二十个 skill,我到底在折腾什么

先说清楚这个项目的来龙去脉。我手头有三台常用机器:一台主力台式机放在家里,一台轻薄本随身带着跑会议和外出,还有一台放在工作室专门跑长时间任务。三台机器上各自散落着一批 AI 工具链里的 skill——有的装在全局目录,有的塞在某个项目的隐藏文件夹里,有的干脆是当时随手 clone 下来改了两行就再也没管过。前前后后加起来,二十个出头。

这些 skill 覆盖的场景很杂:有做代码审查的、有帮我整理会议纪要的、有专门处理表格数据的、有做文档翻译的、还有几个是给特定项目定制的私有 skill。它们平时各干各的,我也习惯了"哪台机器上有什么就用什么"。直到有一次我在轻薄本上想调用一个明明在台式机上跑得很顺的 skill,结果发现这台机器上压根没装,那一刻我才意识到问题的严重性——我的工作流被机器割裂了。

这个项目要解决的核心问题就一句话:让 AI 自己把这二十个散落各处的 skill 装好、配好、对齐好。不是我去一台一台手动复制粘贴,而是我对着 AI 说一句话,它自己完成扫描、比对、安装、验证的全流程。关键词里的 AI、skill、Agent 三个词,正好对应了这个项目的三个层面:AI 是执行者,skill 是被管理的对象,Agent 是让这件事自动跑起来的机制。

适合谁看?如果你也在多台设备上维护 AI 工具链,如果你手里有一堆 skill 但从来没系统管理过,如果你想知道"让 AI 自己装东西"这件事到底靠不靠谱、边界在哪,那这篇就是写给你的。我会把整个思路、踩过的坑、以及最后跑通的方案完整摊开讲,不藏私。

2. 为什么"手动同步"这条路我走了三次都放弃了

2.1 第一次尝试:网盘同步整个配置目录

最开始我的想法很朴素——把 skill 目录整个丢进网盘,三台机器同步同一个文件夹,不就完事了?我试了大概两周,问题一个接一个冒出来。

首先是路径依赖。很多 skill 的配置文件里写死了绝对路径,比如某个脚本里引用了/Users/xxx/work/skills/foo/config.json,网盘同步到另一台机器后用户名不一样,路径直接失效。其次是版本冲突。三台机器如果同时改了同一个 skill,网盘会生成一堆"冲突副本",我根本分不清哪个是新的。最要命的是平台差异,台式机是 macOS,工作室那台是 Linux,有些 skill 依赖的二进制工具在两个平台上根本不是一回事,同步过去只会报错。

网盘方案的本质问题是:它同步的是"文件",但 skill 真正需要同步的是"可运行的状态"。这两者之间隔着一整套环境依赖,网盘看不见也管不了。

2.2 第二次尝试:写个 shell 脚本手动推拉

网盘失败后,我转向了脚本方案。思路是维护一个 git 仓库,里面放所有 skill 的源文件,然后写个sync.sh,在三台机器上分别执行拉取和安装。这个方案比网盘靠谱多了,至少版本是清晰的。

但我很快发现,脚本能同步文件,却同步不了"意图"。举个例子,某个 skill 在台式机上我配置成了"只读模式",因为那台机器主要用来做代码审查,不希望它自动改文件;但在轻薄本上我需要它"可写",因为外出时经常要快速改点东西。这种"同一 skill 在不同机器上行为不同"的需求,脚本很难优雅表达——你只能写一堆 if-else 判断主机名,越写越丑。

而且每次新增一个 skill,我都要手动更新脚本里的安装列表。时间一长,脚本和实际情况就开始脱节,我又回到了"不知道哪台机器上到底装了什么"的状态。

2.3 第三次尝试:干脆不管理,用到再说

第三次我彻底躺平了,心想反正 skill 也不是天天用,需要的时候再装呗。结果就是文章开头那一幕——真正需要的时候发现没有,临时装又来不及,工作流直接断掉。

这三次失败让我想明白一件事:skill 管理的难点从来不是"复制文件",而是"理解每台机器的状态并做出正确决策"。而这恰恰是 AI Agent 擅长的事情。文件同步是机械劳动,状态判断是认知劳动,前者脚本能干,后者只有 Agent 能干。这就是我决定让 AI 自己来装 skill 的根本原因。

3. 让 AI 自己装 skill,核心机制到底怎么设计的

3.1 把"装 skill"拆成四个可验证的阶段

我没有一上来就让 AI"把 skill 装好",这种模糊指令它根本执行不了。我把整个流程拆成了四个阶段,每个阶段都有明确的输入和输出:

阶段名称输入输出验证方式
1扫描本机文件系统已安装 skill 清单清单条目数 > 0
2比对本机清单 + 云端清单缺失/多余/版本不一致列表差异列表可读
3安装差异列表安装执行日志每个 skill 有成功/失败标记
4验证安装后的环境可运行性报告每个 skill 能跑通冒烟测试

这个拆法的关键在于每个阶段都能独立验证。如果 AI 在第三阶段装失败了,我能立刻定位是哪个 skill、什么原因,而不是面对一个"整体失败"的黑盒。

3.2 为什么用"清单文件"而不是"实时扫描"作为比对基准

这里有个设计决策值得展开讲。我一开始想让 AI 每次都实时扫描三台机器然后互相比对,但很快发现这不现实——三台机器不一定同时在线,而且实时扫描的开销很大。

后来我改成维护一份中心化的清单文件(manifest),里面记录每个 skill 的名称、版本、依赖、以及"哪些机器需要装"。每台机器本地也有一份实际状态文件。AI 的工作就是比对"清单期望"和"本地实际",然后补齐差异。

这个设计的好处是:清单文件是人类可读、可版本控制的。我随时能打开看一眼"哦,这个 skill 我标记了只在台式机和工作室装",而不需要去猜 AI 的判断逻辑。清单是意图的载体,本地状态是事实的载体,AI 负责让事实向意图靠拢。

3.3 Agent 在这里扮演的角色:不是执行器,是决策器

很多人对 Agent 的理解停留在"能自动执行命令的程序",但在这个项目里,Agent 真正的价值是决策。具体来说,它要做这几类判断:

  • 这个 skill 缺失,是因为从没装过,还是因为装过但被删了?
  • 这个 skill 版本不一致,应该升级本机还是降级云端?
  • 这个 skill 安装失败,是依赖缺失、权限问题,还是平台不兼容?
  • 装完之后冒烟测试没过,是 skill 本身的问题还是环境的问题?

这些判断没有标准答案,需要结合上下文。比如"版本不一致"这件事,如果本机版本更新,那可能是本机做了实验性修改,不该被云端覆盖;如果本机版本更旧,那大概率是忘了同步。Agent 需要读日志、看时间戳、甚至读 skill 的变更记录,才能做出合理决策。这正是它区别于普通脚本的地方。

4. 扫描阶段:怎么让 AI 准确找到散落各处的 skill

4.1 skill 的藏身之处比我想象的多

在动手写扫描逻辑之前,我先花了一个下午把三台机器上所有可能藏 skill 的地方梳理了一遍。结果发现,skill 的存放位置远比我想的分散:

  • 全局 skill 目录(比如~/.ai/skills/这类约定俗成的路径)
  • 各个项目的.skills/隐藏目录
  • 某些工具自带的插件目录
  • 我手动 clone 到~/Downloads/然后忘了移走的
  • 还有几个是装在容器里的,宿主机上根本看不到

如果只扫全局目录,会漏掉一大半。所以扫描逻辑必须是多路径、递归、带过滤的。我让 AI 扫描时带上三个参数:搜索根路径列表、目录名匹配规则(比如*skill*、*plugin*)、以及排除规则(比如node_modules、.git这些明显不是 skill 的目录)。

4.2 识别"这是不是一个 skill"的判断标准

光找到目录还不够,还得判断它是不是一个真正的 skill。我总结了几条判断标准,让 AI 按优先级依次检查:

  1. 有没有描述文件:大多数 skill 会有一个skill.json、manifest.yaml或README.md,里面写着这个 skill 叫什么、干什么用。
  2. 有没有入口脚本:一个能跑的 skill 通常有个明确的入口,比如main.py、index.js、run.sh。
  3. 有没有依赖声明:requirements.txt、package.json、Cargo.toml这类文件能说明它需要什么环境。
  4. 目录结构是否符合约定:比如是否有config/、tests/这类子目录。

满足前两条基本就能确认是 skill,后两条用于后续的安装和验证。这里有个坑:有些目录看起来像 skill 但其实是缓存或临时文件,比如某些工具生成的.skill-cache/。我的做法是让 AI 在识别时输出置信度,高置信度的直接纳入清单,低置信度的列出来让我人工确认,避免误判。

4.3 扫描结果怎么组织才方便后续比对

扫描出来的结果不能是一堆散乱的文件路径,得结构化。我让 AI 输出成这样的格式:

{ "machine": "desktop-mac", "scan_time": "2025-01-15T10:30:00", "skills": [ { "name": "code-reviewer", "path": "/Users/me/.ai/skills/code-reviewer", "version": "1.2.0", "confidence": "high", "entry": "main.py", "deps": ["python>=3.10", "git"] } ] }

这个结构里,name是比对的主键,version用于判断是否需要更新,confidence用于人工复核,deps用于安装前的环境检查。有了这个结构,后续的比对就是简单的集合运算,AI 处理起来非常轻松。

提示:扫描阶段一定要让 AI 输出原始路径,不要只输出 skill 名称。因为同名 skill 可能装在不同位置,路径是区分它们的关键信息。

5. 比对与安装:AI 做决策时最容易翻车的地方

5.1 版本比对不是简单的字符串比较

我一开始让 AI 用字符串比较来判断版本新旧,结果踩了个大坑。1.10.0和1.9.0按字符串比,1.10.0反而"小于"1.9.0,因为字符1小于9。这种错误在版本号里太常见了。

正确的做法是语义化版本比较:把版本号拆成主版本、次版本、修订号三段,逐段做数值比较。如果版本号里带预发布标识(比如1.2.0-beta.1),还要额外处理优先级。我让 AI 在比对时统一用语义化版本解析,遇到无法解析的版本号就标记为"需人工确认",而不是瞎猜。

还有一个更隐蔽的坑:有些 skill 的版本号是日期格式,比如20250115。这种和语义化版本混在一起比会出问题。我的处理方式是让 AI 先识别版本号格式,同格式的才互相比较,跨格式的一律标记为"格式不一致,需人工判断"。

5.2 安装顺序:依赖关系决定谁先谁后

二十个 skill 里,有几个是互相依赖的。比如 skill A 依赖 skill B 提供的某个工具函数,那 B 必须先装。如果 AI 按字母顺序装,很可能先装 A 然后失败。

我让 AI 在安装前先构建一张依赖图:每个 skill 是一个节点,依赖关系是边。然后做拓扑排序,得到安装顺序。如果依赖图里有环(A 依赖 B,B 又依赖 A),那就说明配置有问题,AI 应该报错而不是硬装。

构建依赖图的数据来源有两个:一是 skill 自己的依赖声明文件,二是我在清单文件里手动标注的依赖。两者合并后去重,得到最终的依赖关系。这里要注意,依赖声明里写的依赖不一定真的存在,AI 在构建图的时候要顺便检查每个依赖节点是否在清单里,不在的话要么补进清单,要么标记为"外部依赖"单独处理。

5.3 安装失败时的重试与降级策略

安装不可能一次全成功。我遇到过的情况包括:网络超时导致下载失败、依赖包版本冲突、权限不足无法写入目标目录、平台不兼容导致脚本报错。针对这些,我让 AI 按这样的策略处理:

  • 网络类失败:自动重试三次,每次间隔递增(1秒、3秒、9秒)。
  • 依赖冲突:尝试用隔离环境安装,不污染全局环境。
  • 权限问题:报告具体是哪个路径没权限,让我决定是改权限还是换路径。
  • 平台不兼容:直接跳过并标记,不浪费时间重试。

关键原则是:AI 可以自动重试,但不能自动"绕过"问题。比如权限不足,它不能自作主张用管理员权限硬写,那可能带来更大的麻烦。它应该停下来报告,把决策权交还给我。

6. 验证阶段:装完不等于能用

6.1 冒烟测试:每个 skill 至少跑一次最小用例

装完就完事?那是对自己不负责任。我给每个 skill 都定义了一个冒烟测试——一个最小的、能证明这个 skill 基本可用的用例。比如代码审查 skill 的冒烟测试是"给它一段有明显 bug 的代码,看它能不能指出问题";翻译 skill 的冒烟测试是"给它一句英文,看它能不能翻成中文"。

冒烟测试不需要覆盖所有功能,只需要证明"这个 skill 能启动、能接收输入、能产生输出"。如果连冒烟测试都过不了,那这个 skill 装了也是白装。

这里有个实操心得:冒烟测试的用例要写在清单文件里,而不是让 AI 临时生成。因为 AI 临时生成的测试用例质量不稳定,有时候会生成一个过于复杂的用例,导致误判。写在清单里,每个 skill 对应一个固定的最小用例,结果才可复现。

6.2 环境一致性检查:为什么"能跑"和"跑得对"是两回事

冒烟测试过了,只能说明 skill 能跑。但"跑得对"还需要检查环境一致性。我遇到过这样的情况:某个 skill 在台式机上跑出来的结果和在轻薄本上不一样,排查半天发现是两边的某个依赖库版本不同。

所以验证阶段还要做一件事:比对关键依赖的版本。我让 AI 在验证时输出每个 skill 的关键依赖及其版本,然后跨机器比对。如果发现不一致,标记出来让我决定是否统一。这个检查不阻断安装流程,但会生成一份"环境差异报告",供我后续排查问题用。

6.3 验证报告的呈现方式

验证完成后,AI 会生成一份报告。我不喜欢那种"全部成功"或"部分失败"的笼统结论,我要的是逐条明细。报告格式大概是这样:

skill: code-reviewer 安装: 成功 冒烟测试: 通过 依赖版本: python 3.11.2, git 2.39.0 环境一致性: 与台式机一致 skill:>
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进