description 决定它会不会被触发:CLI-Anything 里 70 份 SKILL.md 的写法规律
在 CLI-Anything 的 skills/ 下这 70 份 SKILL.md 里,只有 name 与 description 两个字段是 70/70 全量出现的(生成指南 cli-anything-plugin/guides/skill-generation.md:17-24 也只规定了这两个字段)。这两个字段里,name 是身份,description 是这份文件唯一对外的自我说明——一个 agent 要不要把整份 skill 读进来,能拿到的信息基本就这一段。
所以我们把这 70 份文件的 frontmatter 全部解析了一遍,专门看 description 写成了什么样。快照是 39634a6(2026-08-03 提交),采集时间 2026-08-10。注意这个覆盖率是我们对本仓文件的统计结果,不是 skill 这套格式的通用规范——我们没有核实 CLI-Anything 之外的项目怎么约定必填字段。
先说清边界:我们没有核实任何 agent 运行时到底怎么消费这个字段——那不在这个仓库里。本文只统计仓库自己把它写成了什么样,以及仓库内部两套写法之间的差别。
一、五个数字先摆出来
统计口径是逐个文件取 --- 块、用 Python 的 yaml.safe_load 解析后再量长度,不是按原始行数量:
| 维度 | 数值 |
|---|---|
skills/ 下 SKILL.md 总数 | 70 |
description 覆盖率 | 70/70(100%) |
用 YAML 折叠标量(description: > 或 >-) | 40/70 |
| 解析后长度:最短 / 中位 / 最长 | 23 / 143 / 898 字符 |
| ≥200 字符 / <100 字符 | 22 个 / 14 个 |
最短的那条是 skills/cli-anything-zotero/SKILL.md,内容整整齐齐就一句 CLI harness for Zotero.,23 个字符。最长的是 skills/cli-anything-iterm2/SKILL.md,898 字符。同一个字段,两端差近 40 倍。
折叠标量那 40 份值得单独提一句:> 与 >- 会把后面缩进的多行折成一行,所以按行数或按肉眼看到的段落长度去估这个字段是不准的,必须解析后再量。这也是我们没有用 grep 数长度的原因。
二、开头三词:39/70 是同一种自我介绍
把每条 description 的前三个词拿出来做频次统计,分布相当集中:
Command-line interface for—— 31 次CLI harness for—— 5 次Agent-native CLI for—— 3 次- 其余为一次性写法
也就是 70 份里有 39 份以「我是某软件的命令行接口」开场。这是一种自我介绍式的写法:它说明这份 skill 是什么,不说明什么时候该用它。
其中 31 次的那种开头,来源是可以追到具体代码的。cli-anything-plugin/skill_generator.py 第 136-141 行的逻辑是:取 harness 里 cli_anything/<software>/README.md 的首段(skill_generator.py:107-115 负责抽取),截前 100 个字符,超出就补三个点,再拼成 Command-line interface for <显示名> - <README 首段摘要>。仓库里符合这个形状的有 23/70,其中 13/70 是以 ... 结尾的——那就是首段超过 100 字符被截断的痕迹。
这一段是可以自己复现的:挑一份以 ... 结尾的 SKILL.md,回到对应 harness 的 cli_anything/<software>/README.md 看首段,把前 100 字符对一遍。
三、反直觉的那处:写成触发条件的只有 2/70
标题说 description 决定它会不会被触发。但这份仓库里,真的按「触发条件」去写的只有 2/70:包含 use when / use this when / when the user 的文件一共 2 份;包含 trigger 这个词的是 0/70。
对照组就在同一个仓库里。三份不属于任何 harness 的 skill——codex-skill/SKILL.md:3、hermes-skill/SKILL.md:3、reasonix-skill/SKILL.md:3——全部以 Use when the user wants ... 开头。同一棵目录树下,两种写法并存,分布截然不同。
这个反差落到读者身上是很具体的一件事:如果你按「这份 skill 是什么」去读 skills/ 下的文件,39/70 那种开头是够用的;如果你想知道「什么时候该让 agent 去读它」,那 70 份里有 68 份没有正面回答这个问题,得往正文里翻——正文的小节分布是另一篇的题目,这里不展开。
harness 那侧的两个例外也值得点名:
skills/cli-anything-macrocli/SKILL.md:3写的是Use when the agent wants to define, list, inspect, or execute GUI macros via the MacroCLI CLI.skills/cli-anything-iterm2/SKILL.md:3,就是那条 898 字符的最长记录,里面有一句Read this skill instead of answering from general knowledge whenever the user wants to DO something with iTerm2——它不但写了触发条件,还直接对 agent 的行为下了指令。
顺带一个细节:这条最长的 description 在 skills/ 下存在两份。skills/cli-anything-iterm2/ 与 skills/cli-anything-iterm2-ctl/ 都是 100 行,diff 只在第 2 行的 name 上有差异,正文完全相同。成因是运行时别名与同步脚本对不齐:cli-anything-plugin/repl_skin.py:130-132 里有 software_aliases = {"iterm2_ctl": "iterm2"},banner 展示的 id 是 cli-anything-iterm2,而同步脚本按包名生成的是 cli-anything-iterm2-ctl。两处不一致,说完就停。
四、description 里放不放约束,是各写各的
另外两组关键词的分布,能看出这个字段被赋予了多少责任:
- 含
stateful字样的:15/70 - 在整个
skills/目录里 grepbeta|experimental|WIP|coming soon|TODO|not yet implemented|placeholder,只命中 4 处
那 4 处很能说明问题:
| 位置 | 落在哪 | 原文要点 |
|---|---|---|
skills/cli-anything-notebooklm/SKILL.md:3 | description | Experimental NotebookLM harness for ... |
skills/cli-anything-notebooklm/SKILL.md:8 | 正文 | Experimental NotebookLM harness for CLI-Anything. |
skills/cli-anything-notebooklm/SKILL.md:69 | 正文 | Treat this harness as experimental and unofficial. |
skills/cli-anything-zotero/SKILL.md:29 | 正文 | Experimental SQLite write commands are local-only, user-library-only, and should be treated as non-stable power-user operations. |
70 份里,把「实验性」写进 description 的只有 notebooklm 一家。zotero 那条关于 SQLite 写操作不稳定的提醒在正文第 29 行,而它的 description 只有 23 个字符——那句话进不去,也确实没进去。只看 description 选 skill 的读者,看不到这类限定。
五、想改 description,别改 skills/ 下那份
这一点是本篇最容易踩的实务坑,而且只有一个动作要记:改源,别改镜像。repo-root 的 skills/ 是镜像。同步脚本 .github/scripts/sync_root_skills.py 从各 harness 里的 packaged 副本刷新它,写入前只把 frontmatter 里首个 name:(含其后缩进续行)整体改写成 name: "<skill_id>"(:26-55),description 是原样搬运的。也就是说,你在镜像里改出来的 description,源文件那边一个字都没变。
判定动作:动手之前先确认你打开的这份是不是同步脚本产出的。把 sync_root_skills.py:60-61 那两条 glob 拿到本地跑一遍——*/agent-harness/cli_anything/*/skills/SKILL.md 与 */agent-harness/cli_anything/*/SKILL.md——命中的那些就是源,改 description 要回到源文件上改。skills/ 下只有 cli-anything-iterm2 与 cli-hub-meta-skill 这 2 个目录不由同步产生,它们才是「镜像即源」。
改完怎么验:直接改镜像的话,校验脚本 .github/scripts/validate_root_skills.py 会把这份文件判成 clobber——镜像里有源里没有的行。这套生成、同步、校验的链路具体怎么跑,两份副本又差在哪,我们另有专门的篇目讲,这里不展开。
什么情况说明不是这个原因:如果你改的是 firefly-iii/agent-harness/skills/ 或 openrefine/agent-harness/skills/ 下那两份,它们不在上面两条 glob 的范围内,本来就不受这套 CI 校验管——firefly-iii 那份 281 行、version: "1.0.0",而 skills/cli-anything-firefly-iii/SKILL.md 是 709 行、version: "2.0.0"。
六、几条必须说清楚的前提
注册表里有条目,不等于这个 harness 你装上就能用。 registry.json 的 79 条里,skill_md 字段填 skills/ 相对路径的 56 条、http URL 11 条、deep packaged 路径 7 条、null 5 条;sketch 这个 harness 目录下压根没有任何 SKILL.md(find sketch -iname '*skill*' 无输出),而 CONTRIBUTING.md:18 与 .github/PULL_REQUEST_TEMPLATE.md:25-26 都把 canonical + packaged 两份 SKILL.md 写成了规则。缺件清单我们另有一篇专门讲,这里只是提醒:description 写得再周到,也不代表对应的 harness 是齐的。
这类 harness 会在你本机执行外部程序与脚本,并且需要你自行安装宿主软件。 description 里那句 Command-line interface for X,落地就是驱动本机上真实存在的一个应用。是否引入请结合自身环境评估。
该怎么写自己的 description,仓库没有给通用规则。 生成指南 cli-anything-plugin/guides/skill-generation.md:17-24 只规定了 frontmatter 只含 name 与 description,模板 cli-anything-plugin/templates/SKILL.md.template:1-6 也只写这两个字段——对措辞、长度、要不要写触发条件,我们没有在仓库里读到规则性要求。写成哪一派取决于你的 agent 怎么用它。
七、可以自己跑一遍的核查清单
- 数文件:
find skills -maxdepth 1 -mindepth 1 -type d | wc -l应得 70,find skills -name 'SKILL.md' | wc -l同样是 70。 - 量长度:用 Python +
yaml.safe_load逐个解析 frontmatter 再取len(description),别用grep按行估——40/70 是折叠标量。 - 找生成痕迹:筛出 description 以
...结尾的(应有 13 份),回到对应 harness 的cli_anything/<software>/README.md比对首段前 100 字符,再对照skill_generator.py:136-141。 - 看两派写法的对照:把
skills/cli-anything-macrocli/SKILL.md:3与codex-skill/SKILL.md:3并排读一遍,再随手挑一份Command-line interface for开头的对比。 - 验副本:
diff skills/cli-anything-iterm2/SKILL.md skills/cli-anything-iterm2-ctl/SKILL.md,输出应只有name那一行。
以上为按仓库中的文件路径与参数语义组合的核查步骤,未经实测,以官方文档与脚本的实际输出为准。
本文依据 CLI-Anything 官方仓库(github.com/HKUDS/CLI-Anything)的 README、registry.json、
docs/ 与各 agent-harness/ 下的源码整理,核对日 2026-08-10,对应仓库快照 39634a6。
本文内容为仓库源码与文档口径,我们没有安装或运行过其中任何一个 harness,
也没有在本机驱动过任何一款宿主软件,因此不涉及实际操控效果的任何描述。
这类 harness 会在本机执行外部程序与脚本,是否使用请结合自身环境评估。
注册表与 harness 内容随上游更新而变动,请以仓库最新内容为准。
安全相关做法请结合自身环境评估,本文不构成安全方案建议。