Skills 实测手册

Ponytail 实测:让 AI 别过度设计

同一个 Node CLI、同一个加 --csv 的任务,基线净增 20 行代码,Ponytail 净增 10 行。给出可复现的对照表、full 与 ultra 两档实测,以及它在帮助文本和触发条件上留下的坑。

实测 2026-10-19 DietrichGebert/ponytail · 167,323 stars ( 2026-10-19 ) 许可 MIT 环境 Windows 11 + Node 24.15.0 + npm 11.12.1 + git 2.54.0
三问结论 装前必读

解决什么

把「够用就行」写成可执行的取舍顺序,同一个小任务里净增代码约为基线的一半。

不适合谁

需求还没想清楚、需要先澄清的场景;它默认直接做最小可用版本,方向错了才发现。

坑在哪

它不会自己触发:不显式点名或用 /ponytail,agent 不会自动变懒;省掉 --help 这类没人要求但用户需要的部分是真实成本。

装法(实测用过的命令)

            npx skills add DietrichGebert/ponytail
          

这是单次对照,不是统计结论:执行者是同一个模型,每个任务只跑一遍。下面每个数字都有对应的命令和时间戳,记在实验记录里;哪些是测到的、哪些是判断,我在正文里分开写。

它到底做了什么

DietrichGebert/ponytail(167,323 stars,MIT,官网 ponytail.dev,最近 push 2026-10-18,2026-10-19 取数)装完是 6 个 skill:主 skill ponytail,加上 ponytail-review、ponytail-audit、ponytail-debt、ponytail-gain、ponytail-help。后面五个都是围绕主 skill 的查询工具,真正改变写代码行为的只有主 skill 一个。安装落盘在项目里的 .agents/skills/(真身)和 .claude/skills/(给 Claude Code 的副本),和 Superpowers 用的是同一个安装器。

主 SKILL.md 给的是一套取舍顺序,不是口号。它要求「取第一个完全够用的方案」,顺序是:这功能要不要存在 → 代码库里有没有现成的 → 标准库或平台有没有 → 已装的依赖有没有 → 能不能一行 → 否则再写最小实现。同时它明确列了不能砍的东西:信任边界的校验、防数据丢失的错误处理、安全、无障碍。新逻辑必须配一条小测试(分支、循环、解析、跟钱或安全相关的改动都算),取巧的地方要留一行 shortcut: <限制>, <什么时候升级> 的注释。强度分三档:lite 只做被要求的事并把更小的方案说出来,full 是默认,ultra 还要在动手前反驳需求本身。

还有一个容易被忽略的硬约束:回复结尾要用一两行说明「你跳过了什么、有什么风险」。这条约束直接决定了下面「问题」里说的那个坑。

实测:同一个小任务,装与不装

任务与起始代码和 Superpowers 那篇完全相同:44 行的 cli.js(add <a> <b> 与 --help)、22 行的测试、npm test 原有 2 个用例全绿。要求加 --csv(输出 2,3,5、位置无关、不传时行为不变)并补测试,不引入依赖。

指标基线(不装)Ponytail fullPonytail ultra
墙钟耗时26 秒(15:56:55→15:57:21)23 秒(16:00:03→16:00:26)19 秒(16:00:34→16:00:53)
工具调用7 次6 次6 次
改动文件2 个2 个2 个
代码净增+23 / -3(净 +20)+12 / -2(净 +10)+12 / -2(净 +10)
测试用例3 个3 个3 个
--help 是否更新是否否
npm test全绿全绿全绿
安装耗时—12.9 秒(15:59:38→15:59:50)—

口径:耗时是墙钟时间,从第一条命令到最后一条命令,含模型思考;工具调用按读一次、写一次、执行一条命令各计一次;行数来自 git diff --numstat。基线那 7 次里有 2 次是工具策略强制的「改文件前先读」,装后 6 次里也有同样的 2 次,两边抵消;基线多出的那 1 次是开工前查仓库状态。所以真实结论是:ponytail 没有省下调用次数,它省的是行数。

差在哪,两处,都在 diff 里:

  1. 没动 --help。 基线我给帮助文本加了一行 --csv,ponytail 版没加。
  2. 输出分支从 4 行 if 压成一行三元:console.log(csv ? `${a},${b},${add(a, b)}` : add(a, b));

净增从 20 行降到 10 行,几乎全部来自这两处。测试也一样:基线写 3 个 test(),ponytail 写成 1 个 test() 里 2 个断言,位置无关的覆盖没丢。

还有一个流程差异不在 diff 里:ponytail 不要求先写失败测试,所以这次我是先改实现、再补测试,一次跑绿,没有看到红灯。测试通过只说明代码符合我写的断言;它没有像 Superpowers 那次一样,先证明这条测试能抓住错误。对这么小的改动,差别不大;但如果你在意「测试是不是真的在测东西」,这一点值得记住。

ultra 档和 full 档的 diff 逐字节相同,都是 +12/-2。ultra 唯一的差别是动手前多了一句判断:这个需求其实可以完全不写代码,echo "2,3,$(node cli.js add 2 3)" 一行就够。它没有转化成任何代码差异。分档在这类小任务上不产生区分度——这是我测到的,不是看文档推断的;但我只测了这一个任务,不能反推其它任务。

好的地方

  1. 砍的位置很准。 省掉的不是测试、不是错误处理,而是「没人要求、但看起来该顺手做」的 --help 文案。这种改动最容易被当成好习惯,实际上很少改变任何人的决定。
  2. 「一条小测试」的粒度是可执行的。 它没说「写好测试」,而是「新逻辑配一条小测试或 assert 自检,trivial 改动不用」。照做之后,测试从 3 个函数变成 1 个函数 2 个断言,覆盖没少,噪音少了。
  3. 结尾必须报「跳过了什么」。 我因此明确写下:--help 没更新,用户查帮助看不到 --csv。这条约束把「省了东西」变成「省了东西并且说了」,比静默省略好一个档次。

问题

  1. 它不会自己触发。 装完这个 skill 之后,我这个会话里没有出现任何行为变化,直到我手动打开 SKILL.md 按它写。真实使用要靠触发词(ponytail、be lazy、yagni、simplest solution)或 /ponytail 显式点名;只对 agent 说「加个 --csv」,它不会自动切到懒模式。装和用之间隔着一个「你得记得说」。本机其实早就有一份副本(~/.agents/skills/ponytail,创建于 2026-09-05),也没能改变这一点。更准确地说,那份旧副本在会话的 skill 列表里是列出来的(listed),只是正文没有读入(not loaded)。这同样是污染项:基线里的模型已经看过「它会让人少写代码」这类主张,只是没加载正文——对照的干净程度因此打了折扣,不是零。

  2. 分层强度在小任务上没有区分度。 full 和 ultra 的 diff 逐字节相同(+12/-2)。官方把三档并列,读者容易以为 ultra 更省;这次实测里 ultra 只是多了一句反驳,代码一动没动。要么它在中等以上任务才有差别,要么这个分档更多是话术——我不知道是哪种,只能说这个任务上没差别。

  3. 省文档是真实成本,兜底只有一句风险提示。「没人要求就不做」在 CLI 这类靠 --help 自我说明的工具上会留下洞:用户装完不知道有这个参数。这不是理论风险,这次就发生了——同一个任务,基线版的 --help 里有 --csv,ponytail 版没有,用户查帮助会以为功能不存在。SKILL 用结尾一行风险提示兜底,但那行提示是给我(执行者)看的,不是给用户看的;团队里没人会负责把它转成文档。

  4. 和 Superpowers 的默认行为正面冲突。 Superpowers 要求先 brainstorm、写设计、写计划再动代码;ponytail 要求先问「这功能要不要存在」,最短 diff 赢。两个都装,同一句「加个 --csv」会得到相反的第一反应。这一条是我从两份 SKILL.md 的原文对照得出的判断,不是实测。

什么任务不值得用它

  1. 需求还没想清楚的任务。 ponytail 的默认动作是「取最小可用版本直接做」,它不负责帮你确认「到底要什么」;方向错了,省下的 10 行会变成重写的成本。
  2. 要给别人用的库或 CLI 的参数面。 YAGNI 会砍掉「暂时没人用」的扩展点;帮助文本、错误信息、退出码这些「没人要求、但用户会碰到」的东西也在它的裁剪范围里,这次就是活例子。
  3. 团队已有硬性规范的项目(比如规定帮助文本必须同步、每个新参数必须有文档和测试)。ponytail 的默认优先级和这类规范冲突,装上去之后每次都要额外解释一遍为什么不按它做。

结论

看场景。 需求已经清楚、你只要最短实现的日常小改动,值得装:这次净增代码从 20 行降到 10 行,测试覆盖没变。需求没澄清、或者项目有文档与帮助文本的硬规范,别装,它会省掉你正好需要的东西。单次对照,别把 20→10 当成稳定比例。

相关页面