正在刊行长文 · Essay
2026-07-23所有内容
随机比特 · Random Bits

我把 Skill 搬到全局,却把代码留在项目里

2026-07-23AI Engineering / Systemsrbits.uk
我把 Skill 搬到全局,却把代码留在项目里

今天,我把一套已经在项目里运行的 Skill 搬进了全局目录。目的很简单:无论从哪个会话进入,Agent 都能发现同一个入口,不必先猜项目路径。这次迁移的原则也由此确定:发现入口全局化,运行态继续由项目保留。

迁移做到一半,问题随即出现。这个 Skill 并不只是一份说明文件。它后面还有 runner、配置、草稿、数据,以及记录进度的状态文件。若全部留在项目里,发现入口仍受目录限制;若全部搬到全局,公共入口又会吞进某个项目的运行现场。

两种省事方案都会留下后患

第一种方案是复制两份入口文件:全局一份,项目一份。这样几乎不用改旧脚本,却把同一套规则变成了两个来源。触发条件或发布边界只要漏改一处,两个入口就会分叉。

第二种方案是把整个 Skill 目录搬到全局。目录看起来更整齐,但 runner、配置、草稿、数据和状态也会进入公共目录。升级入口可能误碰运行态,其他项目也可能读到不属于自己的状态。

方案 规则来源 运行态位置 主要代价
双份入口 全局与项目各一份 项目 规则漂移、长期双写
整目录全局化 全局单份 全局 所有权混乱、状态串用
全局入口+项目运行态 全局单份 项目 需要根解析与兼容路径

Skill 的发现入口适合全局化,脚本、数据、配置和状态必须项目化。统一入口不等于统一运行态。

入口与运行态的所有权分层

最终结构分成三层。

第一层是全局发现层。我只留下一个很薄的入口,负责声明触发条件、给出决策树,并把任务路由回项目。它不保存草稿,不维护状态,也不直接拥有项目配置。

第二层是项目根解析层。解析脚本先看显式环境变量,再检查默认目录和当前 Git 根目录;候选目录只有同时具备状态文件、账号策略与可执行 runner,才会被接受。入口只负责提出“去哪里找”,项目用自身结构证明“我可以运行”。

仅有状态文件还不足以确认项目根,备份目录也可能残留同名文件。状态文件、账号策略和可执行 runner 必须同时存在,任一缺失就跳过;所有候选都失败时则明确报错,而不是返回一个看似合理的目录。

第三层是项目运行层。runner、drafts、data、config 和状态文件继续留在工作区。原来的 Skill 路径改成软链接,指向全局唯一入口,因此旧脚本仍能沿原路径读取,但规则不再维护第二份。

这个软链接只是兼容层,不是备份。真正的规则只有全局入口一份;项目路径只是稳定门牌,让旧 runner 和检查脚本继续工作,却不能单独修改规则。

全局发现层与项目运行层分离

这三层分别回答三个问题:能力如何被发现,项目如何被定位,任务如何执行并记录结果。目录划分的依据也从“看起来像 Skill”改为清晰的所有权。

迁移完成要验证四条链路

文件搬完不代表迁移完成。我随后检查了 Skill 结构、软链接指向和项目根解析,又验证 YAML、Shell 与 Node 语法,最后跑完 115 项测试。验收应确认发现、解析、执行和状态边界继续成立,不能停留在“文件已经存在”。

115 项测试还要确认旧路径调用未断、解析顺序确定、配置能够加载、产物仍写回项目,并且全局目录没有新增草稿、数据或状态。否则入口虽然变薄,运行态仍在外泄。

软链接也不是普遍答案。这次迁移发生在同一台 Linux 机器、固定目录布局的环境中;跨机器、容器镜像或 Windows 环境不应直接照搬。更稳妥的做法是通过环境变量配置项目根,或在安装阶段生成适合目标系统的入口映射。

下一次迁移前,先列出每个目录的所有者、允许写入的内容和状态落点,再移动文件。所有权与写入责任明确之后,入口换位置才不会牵动运行现场。

随机比特公众号二维码
公众号 · 随机比特
从 AI 工具热闹里拆工程真相

写边界、控制面、上下文、成本与安全。