有次同事凑过来看我的配置目录,一堆 SKILL.md,一堆 .py,他问:「这不都是自动化吗,有啥区别?」
我说有区别,区别大到放错位置会出事故。
我自己就撞了两次。
先说结论
- Skill 不是「更聪明的脚本」。 它一行代码都不执行,是一份写给模型看的操作规程。
- CLI 保证「每次都一样」,Skill 保证「每次都对」。 这两句话答的不是同一个问题,所以也不是二选一。
- Skill 只拥有三件事——什么时候开工、走哪条分支、什么时候必须停下来问人。CLI 拥有剩下所有会动手的事,算、锁、写、重试、回滚。
这一篇只切一刀,叫执行权,谁动手。
机制层:Skill 根本不执行任何东西
CLI 是确定性函数。 输入进去,输出出来,附带一个退出码。它可以写单元测试,可以幂等,可以重试,可以在失败时回滚。退出码非 0 就是失败——这个「就是」里没有商量余地。同样输入,今天跑和明天跑,结果必须一样。
Skill 是一份按需加载的自然语言说明书。 一个文件夹,里面一个 SKILL.md,开头几行元信息写清楚「我叫什么、什么时候用我」,下面正文是步骤、边界、例外。它自己不动手。模型读完它,再去按 CLI 的按钮。
这里有个大多数人不知道的机制,叫渐进披露(progressive disclosure)。平时进上下文的只有那一行 description,几十个字;只有当模型判断「这活跟它有关」,才把整篇正文读进来。
我本地一个 Skill 正文 149 行,常驻成本是 1 行。
打个比方。CLI 是家电,Skill 是贴在墙上的操作规程。 家电按钮按下去就转,规程自己不会动,但它决定人怎么按、什么时候别按。
所以判对错的地方也不一样。脚本的对错在编译器和退出码里,Skill 的对错在读它的那个东西有没有读懂。前者是工程问题,后者是写作问题。
失败了也不一样。CLI 失败可以原样重试;Skill 失败是模型没按规程走,同样的说明书,下次可能走出另一条路。
我撞了两次号
我给每个 bug、每个需求发一个号,从 001 往下排,记在一份大家共用的清单里。规矩就一句话,写在说明书上,谁都能看懂——看表尾最大的那个号,加一,就是你的。
一句话的规矩,还能错到哪去?
能。
像医院大厅两个人同时看屏幕,都看见当前是 291,都去取了 292。清单上就出现两个 292。
我这边更热闹——同时干活的不只是我。我开着好几个 AI 窗口,群里还蹲着一个机器人,大家抢同一份清单。你看完最大号、还没写回去的那几分钟里,另一个窗口也在取,两边拿到的就是同一个。
今年七月撞过一次,这个月又撞一次,第二次撞在第 292 号。
关键在于,没有谁把规矩看错。 两边读到的都是当时真实的最大号,每一步都对,合起来是错的。说明书再写细、再加十条警告、再全大写加粗,都救不回来——规程管得了「怎么做」,管不了「两个人同时做」。
修法是写成一个脚本。它不靠谁先想起来,靠谁先把这个号交上去。清单存在 git 里,你改完往上推,如果别人已经先改过同一份文件,你这次会被拒。被拒就说明这号没了——脚本自己拉最新清单、重算一个号、再推,最多试八次。成功的那一刻,号已经写进远端那份清单,谁也抢不走。
能让 git 抢锁的事,别让模型投票。
判据就这一句
只要「两个人同时做会出错」,这一截就必须是脚本。
模型有判断力,判断力解决不了抢跑。
注意是「这一截」,不是「整件事」。外面可以有一份 Skill,告诉模型什么时候该去占号;但占号动作本身,不能写在说明书里。
同一类的还有两样,一起记着:算日期(模型不知道今天几号,让它算常偏一天)、管凭证。这三样活儿,例外再多也不能交出去。
收尾
以前我以为把这些钉死成代码叫保守。现在我知道这叫分工——你不会让一个再聪明的人去当保险丝。
会用 AI 的人和把 AI 用出事故的人,差别往往不在提示词写得多花哨,而在知道哪一格不能交出去。
这一刀切的是执行权。还有反过来的一刀——有些活写成脚本同样是灾难,那是判断权的事,下一篇讲。
浙公网安备 33010602011771号