给 agent 读的那份 SKILL.md:字段与正文结构

2026-08-10

在 CLI-Anything 里,SKILL.md 是整套 harness 唯一一份明确写给 agent 看的文档。<APP>.md 是给人看的项目分析与 SOP,README.md 是给人看的安装说明,TEST.md 是测试台账,只有 SKILL.md 会被塞进模型上下文,直接决定它认为这个命令行工具”有哪些命令、该怎么调”。

所以这一份文档写成什么样,比其它三份都更有后果。本文只拆 SKILL.md 这一件——四件套整体是怎么摆的、core/utils/ 怎么分工,我们另有专门的篇目在讲,这里不重复。

以下所有数字来自我们 2026-08-10 采集的本地 clone,对应仓库快照 39634a6(提交日期 2026-08-03)。

先看它在哪里、有几份

截至我们采集时,仓库里 agent-harness 目录共 69 个,而这些目录下的 SKILL.md70 份——比目录数多一份。原因是两处双份:openrefinefirefly-iii 各含 2 个 SKILL.md,而 sketch 一个都没有。

除此之外,仓库根还有一个独立的 skills/ 目录,里面的 SKILL.md 数量同样是 70 份——也就是说同一批技能说明在仓库里存了两处。要提醒一句:数量对齐不等于名字对得上,其中有若干份按 skill 名在另一处匹配不上,两处副本的同步与差异情况另有篇目在讲。本文只需要你记住一件事:你读到的 SKILL.md 可能有两个来源,路径不同

统计方式很直白,你可以自己复现:

find . -type d -name agent-harness | wc -l
find . -path '*/agent-harness/*' -name SKILL.md | wc -l
find . -path '*/agent-harness/*' -name SKILL.md | sed 's#/agent-harness/.*##' | sort | uniq -c
find skills -name SKILL.md | wc -l

frontmatter:规范只要求两个字段

SKILL.md 的模板文件在 cli-anything-plugin/templates/SKILL.md.template,共 123 行。它开头的 YAML frontmatter 只有两个键:

---
name: >-
  {{ skill_name }}
description: >-
  {{ skill_description }}
---

方法论文档 cli-anything-plugin/HARNESS.md 第 245-250 行给出的示例也是这两个字段,取值形如 name: "cli-anything-<software>"description: "Brief description of what the CLI does"。注意模板用的是 YAML 折叠标量写法 >-,值换行缩进写在下一行,而不是写在冒号后面——如果你要手写或改写一份,照着模板的写法来。

我们把 70 份 SKILL.md 的 frontmatter 键逐个抽出来做频次统计,结果是:name: 70、description: 70,其余都是零星出现——version: 9、requires: 4、install: 4、command: 3、categories: 3、tags: 2、contributor: 2、category: 2、author: 2,另有 metadataentrypointentry_pointdisplay_namecommandsbinary 各 1 次。

结论就一句:只有 namedescription 是全仓 100% 一致的,其它字段属于个别 harness 自行添加,不能指望它们存在。你写消费端的解析逻辑时,只能把这两个字段当作必然存在的输入。

复现命令是对每个文件取第一段 frontmatter 再抽键名:

awk '/^---$/{n++;next} n==1' <某份 SKILL.md> | grep -oE '^[a-zA-Z_-]+:'

正文:模板给了固定顺序,实际落地并不齐

模板正文的小节顺序是写死的:# {{ skill_name }} 标题 → intro → ## Installation(含 pip install cli-anything-<software> 与 Prerequisites)→ ## Usage(下面分 Basic Commands 与 REPL Mode)→ ## Command Groups(每组一个三级标题,配一张 | Command | Description | 两列表)→ ## Examples## State Management## Output Formats## For AI Agents## More Information## Version

数一下就知道:这是一个 H1 标题加九个 H2 小节。模板文件一共 123 行,各小节的起始行你可以自己 grep -n '^## ' cli-anything-plugin/templates/SKILL.md.template 复现,不必记具体行号。

但 70 份实际文件里的 H2 频次是另一回事:## Installation 50、## Command Groups 46、## Usage 31、## For AI Agents 30、## Version 29、## Examples 26、## Output Formats 25、## More Information 19、## State Management 16。

也就是说,覆盖率最高的 ## Installation 也只有 50/70,模板里排在后半段的几节掉得更多。这里只陈述差异:模板规定了九节,实际文件里没有一节是全覆盖的。以我们实读的仓库状态为准。

★ 这份文档是”正则抽出来的”,不是跑出来的

这是本篇最需要讲透的一处,因为它和大多数人的直觉相反。

看到一份列满命令与说明的 SKILL.md,很容易默认它是从 CLI 里导出来的——比如导入模块、反射遍历 Click 的命令树、把每个命令的 help 文本吐出来。不是。 生成器 cli-anything-plugin/skill_generator.py 走的是纯文本正则:它把 *_cli.py 读成字符串,用正则匹配 Click 装饰器与紧随其后的 def xxx(...),从中抽出命令组与命令(skill_generator.py:211,220-238,274-312);版本号也是正则,从 setup.py 文本里 version = "..." 的位置抠出来,抠不到就回落到字面量 1.0.0(同文件 :202)。

这个实现路径带来三处具体后果,都能在文件里直接看到:

其一,模板里的常量文案会被原样带进成品。 ## State Management 那一节模板写死了一句 “Undo/Redo: Up to 50 levels of history”(模板第 86 行)。blender 的 SKILL.md 原样保留了这句(blender/agent-harness/cli_anything/blender/skills/SKILL.md:237)。这句话不是从目标 harness 的代码里读出来的,它是模板常量。要知道某个 harness 真实的撤销上限,得回去看它自己的 core/session.py——blender 那份里确实有类常量 MAX_UNDO = 50blender/.../core/session.py:39),两处对得上;其余 harness 我们没有逐个核对,而全仓带 session.py 的目录只有 40 个。换句话说,一份 SKILL.md 里出现 “50 levels” 不构成”这个工具支持 50 级撤销”的证据。

其二,description 会被截断。 有 13 份 SKILL.md 的 frontmatter description 以字面量三个点结尾。以 blender 为例,它的 description 结尾是 “…following the same patterns as the GIMP CLI …”(blender/.../skills/SKILL.md:5)。这是生成阶段截断后直接落盘的结果,而 description 恰恰是 agent 判断”要不要用这个技能”时最先读到的那一行。

其三,模板里的固定条款也不是全覆盖。 ## For AI Agents 一节的模板正文是固定 5 条(模板第 107-113 行):始终加 --json、检查返回码(0 成功、非 0 失败)、失败时从 stderr 读错误信息、文件操作一律用绝对路径、导出后校验产物存在。这几条在实际文件里的覆盖数分别是:含 “Always use `—json` flag” 52 份、含 “Check return codes” 56 份、含 “Parse stderr” 50 份。都不是 70。

把这三条合起来看:SKILL.md 是一份由源码文本推导、并混入模板常量的静态说明。它描述的是”生成时源码长什么样”,不是”这条命令现在能不能跑通”。你用它给 agent 打底可以,但把它当成能力清单会踩坑。

落盘位置、分发与 REPL 里的指路

生成器会落两份:规范位置是仓库根的 skills/cli-anything-<software>/SKILL.md,另外写一份”兼容拷贝”到包内的 cli_anything/<software>/skills/SKILL.mdHARNESS.md:262-265)。

要让这份文件跟着 pip 包一起发出去,setup.py 里必须带上 package_data={"cli_anything.<software>": ["skills/*.md"]}HARNESS.md:287-291,blender 的实例在 blender/agent-harness/setup.py:63-65)。少了这一句,源码树里有 skill、装出来的包里没有。

运行期这边,共享的 repl_skin.py 在 REPL banner 里会显示 skill 路径,查找顺序是先找仓库根 skills/<skill-id>/SKILL.md,找不到再回退包内的 skills/SKILL.mdcli-anything-plugin/repl_skin.py:141-148),并给出形如 npx skills add HKUDS/CLI-Anything --skill <id> -g -y 的安装串(同文件 :61,134)。

## More Information 一节的模板则是固定三行指路:README.md、TEST.md、以及 “Methodology: See HARNESS.md in the cli-anything-plugin”(模板第 117-119 行)。这意味着 agent 顺着 SKILL.md 往下摸,第二跳会去找 README.mdTEST.md——而这两份文件分别有 5 个和 12 个 harness 是缺的。

你可以自己跑的核查动作

想验证上面任何一条,按这几步走,不需要装任何宿主软件:

  1. 数文件:find . -path '*/agent-harness/*' -name SKILL.md | wc -l,与 find . -type d -name agent-harness | wc -l 比对,差值就是双份与缺件的净结果。
  2. 看模板全貌:wc -l cli-anything-plugin/templates/SKILL.md.template 应为 123 行,直接通读一遍最快。
  3. 对比模板与成品:任取一份 SKILL.md,把它的 H2 列出来(grep -oE '^## .*'),与模板的九节顺序对照,看少了哪几节。
  4. 验证”常量文案”:grep -rl "Up to 50 levels of history" --include=SKILL.md .,把命中的 harness 逐个回去看它有没有 core/session.py
  5. 找截断:搜 frontmatter 里以三个点结尾的 description
  6. 读生成器:翻 cli-anything-plugin/skill_generator.py,第 211 行起是命令抽取段(正则主体在 220-238 与 274-312 行),第 202 行附近是版本抽取段,确认它走的是正则而非 import。

三条必须说清的边界

第一,有 SKILL.md 不等于这个能力可用。 注册表 registry.jsonclis 数组有 79 条,本地 harness 目录 69 个,SKILL.md 70 份——三个数互不相等,且 79 条里有 13 条在本仓找不到同名目录。文档齐不齐是一回事,harness 能不能真的驱动宿主软件是另一回事。仓库自己也留了余地:打包文件里 45 处标 Development Status :: 4 - Beta、2 处标 3 - Alpha没有任何一个标 Production/Stable

第二,## Installation 那一节会让 agent 去装东西、跑东西。 模板的 Installation 段包含 pip install cli-anything-<software> 与 Prerequisites,而 Prerequisites 指向的是宿主软件本身。这类 harness 的工作方式就是在你本机执行外部程序与脚本——是否使用请结合自身环境评估,尤其是当决定”装什么、跑什么”的是一个正在读 SKILL.md 的 agent 的时候。

第三,我们只精读了四个样本。 blender、audacity、adguardhome、browser 这四个 harness 我们逐层读了文件,其余 65 个只做了结构性统计与针对性 grep。上面所有”70 份里有 N 份”的数字都是文本统计的结果,我们没有运行过任何一个 harness,也没有在本机驱动过任何宿主软件。


本文依据 CLI-Anything 官方仓库(github.com/HKUDS/CLI-Anything)的 README、registry.jsondocs/ 与各 agent-harness/ 下的源码整理,核对日 2026-08-10,对应仓库快照 39634a6。 本文内容为仓库源码与文档口径,我们没有安装或运行过其中任何一个 harness, 也没有在本机驱动过任何一款宿主软件,因此不涉及实际操控效果的任何描述。 这类 harness 会在本机执行外部程序与脚本,是否使用请结合自身环境评估。 注册表与 harness 内容随上游更新而变动,请以仓库最新内容为准。

安全相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。