跳到正文

Ponytail

一套装进编码 agent 的规则与 skill 包:写代码之前,agent 先停在七级阶梯上第一个成立的那级——不必存在、代码库里已有、标准库能做、平台原生能力能做、已装的依赖能解决、一行能写完——另外六个命令分别用来调档位、审 diff、审整仓库、把欠下的妥协收进台账、打印实测记分板、列出全部命令。

Screenshot of Ponytail
编辑截图, 30 Sep 2026Ponytail ↗

这是什么

一套装进编码 agent 的规则,用来改掉 agent 动手之前写下的东西:它先停在七级阶梯上第一个成立的那级——这东西不必存在、代码库里已经有了、标准库能做、平台原生能力能做、已装的依赖能解决、一行能写完——都否,才写刚好能跑的最小实现。它以六个 skill 的形式发布,也给有插件系统的宿主提供插件,档位按会话设为 lite、full、ultra 或 off(默认 full),并同样注入每个 subagent。安装通常是一两条命令:Claude Code 里先 /plugin marketplace add DietrichGebert/ponytail 再 /plugin install ponytail@ponytail;Codex 里是 codex plugin marketplace add DietrichGebert/ponytail 与 codex plugin add ponytail@ponytail;Gemini CLI 用 gemini extensions install https://github.com/DietrichGebert/ponytail;Pi 用 pi install git:github.com/DietrichGebert/ponytail;Cursor 用 node ponytail/scripts/cursor-hooks.js install;OpenClaw 用 clawhub install ponytail;OpenCode 只要在 opencode.json 里加一行。没有插件系统的宿主改为复制一份规则文件。默认档位可以用 PONYTAIL_DEFAULT_MODE 环境变量或 ~/.config/ponytail/config.json 固定下来。

谁做的仓库的 224 次提交里 114 次挂在他的 GitHub 账号下,另有 8 次用的是他另一台机器上的邮箱;其余来自约六十位贡献者,其中一位以 Emeriko 之名提交了 23 次。

它是怎么搭起来的

组成 · 6

一份规则文档,按每个宿主读得懂的格式各抄一遍,再加一层很薄的钩子来决定什么时候把它注入。这里没有服务,也不调用任何模型:规则是文本,注入是按宿主写的生命周期钩子,状态是用户主目录下的一个小文件。这个形状解释了树里几乎所有的东西——同一份规则以八份文件入库,六个 skill 写一次再为 OpenClaw 生成第二版,每个宿主一份钩子清单,每个适配器一个测试文件,还有几个只负责让副本保持一致、让版本号互相对齐的脚本。它也解释了这东西会在哪里坏掉:宿主换了插件 API——比如 OpenCode 2——时,没有服务器可以改,只能在每个适配器上各修一遍。

AGENTS.md 与各宿主的规则副本
一套规则,八份入库副本:.agents/rules/ponytail.md、.clinerules/ponytail.md、.cursor/rules/ponytail.mdc(2,620 字节)、.github/copilot-instructions.md、.kiro/steering/ponytail.md(2,560)、.qoder/rules/ponytail.md、.windsurf/rules/ponytail.md 与 AGENTS.md(2,593 字节),多数为 2,495 字节;scripts/check-rule-copies.js(2,981 字节)负责在改动后核对它们是否还一致。
skills/ 与 .openclaw/skills/
六个 skill,各一份 SKILL.md:ponytail 6,637 字节,help 2,796,review 2,383,gain 1,973,debt 1,703,audit 1,652;另有一份为 OpenClaw 生成的副本(它的 ponytail 只有 5,957 字节),由 scripts/build-openclaw-skills.js(2,873 字节)产出,过期时测试会失败。
hooks/
十二个文件、34 KB:ponytail-activate.js 4,601、ponytail-config.js 5,881、ponytail-instructions.js 5,487、ponytail-mode-tracker.js 6,194、ponytail-runtime.js 5,682、ponytail-subagent.js 2,683,两个 statusline 脚本(.sh 696、.ps1 885),以及四份按宿主写的钩子清单。
.opencode/、commands/ 与 pi-extension/
同样六个命令写了两遍:六个 .opencode/command/*.md(510 到 1,141 字节)与六个 commands/*.toml(515 到 1,152 字节)。.opencode/plugins/ponytail.mjs(3,773 字节)就是那个 OpenCode 2 拒绝加载的 V1 入口,旁边是 ponytail-frontmatter.cjs(1,054);pi-extension/index.js 7,171 字节。
ponytail-mcp/ 与 benchmarks/
v4.8.0 标题里那个 MCP 服务:index.js 1,922、instructions.js 1,181、README.md 1,507、package.json 365。测量这边是 benchmarks/ 下 17 个文件、benchmarks/results/ 下 9 个文件,以及 benchmarks/agentic/ 的 5 个文件 103 KB(tasks.py 50,646、run.py 26,677、judge.py 9,987、complete.py 7,944)。
tests/、scripts/ 与 assets/
十六个测试文件 84 KB,每个适配器一个——hooks.test.js 21,189、cursor-hooks.test.js 15,639、hermes-plugin.test.js 9,613、correctness.test.js 6,382。scripts/ 六个文件 20 KB:发布 OpenClaw skill、核对规则副本、核对版本号、装与卸 Cursor 钩子、卸载。assets/ 14 个文件 1,127 KB,其中 logo.png 一个就 567,655 字节——正是 #939 从 npm 包里剔掉的那批。

取舍,以及它替代了什么

  • 留住安全底线,不砍校验、错误处理、安全与无障碍 替代 一句“尽量写成一行”的提示词

    README 先把规则写死,再用测量背书:“The rule was never ‘fewest tokens.’ It is: write only what the task needs, and never cut validation, error handling, security, or accessibility. The code ends up small because it is necessary, not golfed.” 在基准表里,“YAGNI + one-liners”那一组在对抗性安全档上只有 95%,而它是 100%。

  • 在共享函数上一次性修根因 替代 按报告点名的路径各补一处

    这条被写进 AGENTS.md 当成规则,而不是留给临场判断:“a report names a symptom. Grep every caller of the function you touch and fix the shared function once — one guard there is a smaller diff than one per caller, and patching only the path the ticket names leaves a sibling caller still broken.” 同一份文件也承认搞错位置的代价:“The smallest change in the wrong place isn’t lazy, it’s a second bug.”

  • 砍掉一角,并留下标注天花板的 ponytail: 注释 替代 现在就把它做对

    出自 AGENTS.md:“Mark deliberate simplifications that cut a real corner with a known ceiling (global lock, O(n²) scan, naive heuristic) with a ponytail: comment naming the ceiling and upgrade path.” 而 ponytail-debt 这个 skill 的存在就是为了把这些标记收进台账,“so ‘later’ doesn’t become ‘never’”。

  • Gemini 适配器不带根目录的 hooks/hooks.json 替代 给每个宿主都发同一份生命周期钩子文件

    README 把这写成有意为之:“Gemini auto-loads that path, while Ponytail’s lifecycle hooks use Claude/Codex event names.” 这个适配器改用扩展安装,并让 skill 单独随行。

  • Grok Build 不接生命周期钩子 替代 像别的插件宿主那样接上去

    README 给的是机制层面的原因而不是偏好:“Grok lifecycle hooks are not used because their SessionStart output cannot inject instructions.” Grok 用户改为启用插件、按名字调用 skill。

依据AGENTS.md(2,590 字符全文打印;磁盘上 2,593 字节)、README.md(23,529 字符,其中报告打印了前 6,000 字符,其余取自默认分支上的原始文件)、完整的 166 个文件树及其体积、两级的目录汇总、16 个 release 标题,以及三十个 issue 与 pull request 及其评论串。docs/cursor-hooks.md(13,264 字节)、docs/platform-native.md(9,434)与 docs/agent-portability.md(6,878)只在树里给出了名字和体积,内容未读;assets/ 的 1,127 KB 也只按名字与体积记录。

制作过程

6 个阶段
  1. 01

    十七天发完十四个版本,然后沉默三十九天

    仓库建于 2026-06-12,第一次提交是当天 00:52:37 的 Initial commit;报告里最后一次提交是 2026-09-14T14:34:42Z 的 chore: release v4.10.0 (#870)。94 天里一共 224 次提交,而且几乎全堆在前两个月:六月 155 次、七月 51 次、八月 4 次、九月 14 次。16 个 release 的标题比提交数更会讲故事。v1.0.0 — He ships. 发于 2026-06-12T02:43:54Z,距第一次提交不到两小时;同一天跟上 v4.0.0: production grade, still lazy;2026-06-13 是 v4.1.0: three more agents 与 v4.2.0: lazy in OpenCode now;2026-06-15 一天里发出 v4.3.0: more agents, still lazy、v4.4.0: field-tested, still lazy、v4.5.0: lazy in Copilot,四小时后又是 v4.6.0: help, reluctantly。2026-06-16 是 v4.7.0: lazy in OpenClaw now;2026-06-23 与 06-24 的四个是 v4.8.0: comprehension first, now with an MCP server、v4.8.1: consistent versioning、v4.8.2: now on npm、v4.8.3: lazy in subagents too;2026-06-29 的 v4.8.4: lazy in Hermes now 收尾——16 个 release 里有 14 个挤在十七天内。此后空白三十九天,直到 2026-08-07 的 v4.9.0: 53 commits of doing less,标题里数着 53 次提交,而按月表给的是七月 51、八月 4;再往后是 2026-09-14 的 v4.10.0,标题只有版本号。周围是 148,962 个星、8,009 个 fork、356 个 watcher、319 个 open issue——对 224 次提交来说,大约每 665 个星对应一次提交——仓库体积 2,666 KB,语言一栏写着 JavaScript。

  2. 02

    整个产品就是一份文档加六个命令

    被装进去的东西短到可以直接引用。AGENTS.md(2,593 字节)开头是:“You are a lazy senior developer. Lazy means efficient, not careless. The best code is the code never written.” 接着是七级阶梯,每一级都是一个问句:这东西需要被造出来吗(YAGNI);代码库里已经有了吗;标准库能做吗;平台原生能力覆盖了吗;已安装的依赖能解决吗;能写成一行吗;都否,才写刚好能跑的最小实现。阶梯是在理解问题之后才爬,而不是用来代替理解。同一份文件还写明什么不许省——信任边界上的输入校验、防止数据丢失的错误处理、安全、无障碍、“the calibration real hardware needs”——并要求非平凡逻辑“leaves ONE runnable check behind”,而“trivial one-liners need no test”。四周是六个 skill:/ponytail 把强度设成 lite、full、ultra 或 off,不给参数就报告当前档位;/ponytail-review 审当前 diff 的过度设计并交出一份删除清单;/ponytail-audit 对整仓库做同一件事;/ponytail-debt 把标在刻意妥协上的标记收进一本台账,“so ‘later’ doesn’t become ‘never’”;/ponytail-gain 打印实测记分板;/ponytail-help 把其余命令列出来。默认档位是 full,可以用 PONYTAIL_DEFAULT_MODE 环境变量或 ~/.config/ponytail/config.json 里的 defaultMode 改。

  3. 03

    一半的提交把一个模型写成共同作者

    224 次提交里有 112 条共同作者尾注,其中最大的几群写的是模型而不是人:Claude Opus 4.8 三十二条、Claude Opus 4.8 (1M context) 三十一条、Claude Fable 5 七条、Claude Opus 5 三条,另有一条只写 Claude。另有四条写的是工具或机器人——Cursor、Copilot、Devin、google-labs-jules[bot],各一条。人也在这份名单里:Emeriko 七条、Dietrich Gebert 五条、Admin 两条,其后是一长串各一条。其余归属在账号统计里:224 次提交有 215 次能关联到账号,其中 114 次就挂在他自己的账号下,另有 9 次完全没有关联账号。按邮箱看,103 次来自 dietrich.gebert@gmail.com,8 次来自 dgebert@Dietrichs-MacBook-Pro.local,他自己的两个地址合计 111 次。按作者名统计有 70 个不同名字,其中 Emeriko 的 23 次在按账号的那张表里找不到对应项。贡献者名单列了 50 个人:Lakshya77089 十次,ousamabenyounes 八次,之后是 dhedhialy、hamza-ali-shahjahan、salaamdev 各四次。让这件事不只是花絮的,是 AGENTS.md 的最后一行——它把这套规则掉转过来对准了这份仓库自己:“(Yes, this file also applies to agents working on the ponytail repo itself. Especially to them.)”

  4. 04

    二十个宿主,一套规则,八份副本

    README 给了 Claude Code、Codex、GitHub Copilot CLI、Pi agent harness、OpenCode、Gemini CLI、Qoder、Antigravity CLI、Hermes Agent、CodeWhale、Swival、Devin CLI、OpenClaw、Grok Build 和 Cursor 的安装办法,另外还点名了只读规则文件的宿主:Windsurf、Cline、Copilot Chat、Aider、Kiro、Zed。README 顶部一枚徽章写着“works with 20 agents”。文件树能看出这套面积要付什么:同一份规则文本以八种宿主格式各存了一份——.agents/rules/ponytail.md、.clinerules/ponytail.md、.cursor/rules/ponytail.mdc(2,620 字节)、.github/copilot-instructions.md、.kiro/steering/ponytail.md(2,560)、.qoder/rules/ponytail.md、.windsurf/rules/ponytail.md、AGENTS.md,多数是 2,495 字节——靠 scripts/check-rule-copies.js(2,981 字节)和 node scripts/check-versions.js 让副本与版本号保持一致。有插件系统的宿主拿到的是代码:hooks/ 有十二个文件、34 KB,包括 ponytail-activate.js(4,601)、ponytail-config.js(5,881)、ponytail-instructions.js(5,487)、ponytail-mode-tracker.js(6,194)、ponytail-subagent.js(2,683),每个宿主还有一份钩子清单(claude-codex-hooks.json 966、qoder-hooks.json 704、copilot-hooks.json 539、cursor-hooks.json 320)。同样六个命令还写了两遍:六个 .opencode/command/*.md(510 到 1,141 字节)与六个 commands/*.toml(515 到 1,152 字节)。

  5. 05

    OpenCode 2 的移植,在公开场合定夺

    报告里最热闹的一条线不是关于少写代码,而是某个宿主的插件 API 换了形状。2026-09-26 开的 #941 报的是 @dietrichgebert/ponytail@4.10.0 在 OpenCode v2 上根本加载不了:“Plugin must export a default definition with an id and an effect or setup function. (cause: SchemaError(Expected object at ["default"]))”。同样的失败在 Windows 11 + Node v24.19.0 的 v2.0.18、Linux x64 + Node v22.23.2、macOS arm64 上都被复现;#930 早先对着 v2.0.15 开过,又被报告者自己以“filed prematurely”关掉。接下来的是一队互相竞争的修法:#928 被当作 #915 与 #907 的重复关掉,然后是 #933、#940、#943。在 #943 里逐条对比时,一位评论者把 #907、#940、#933、#864、#729、#734 都列为备选,并称 #943 最干净;同一条讨论里还报告:在 2.0.20 上,几个补丁都用的 { id, setup, server } 双出口会注册 0 个命令、0 个 skill,而从同一个文件里删掉 server 键就能注册六个——日志里分别是 commands: 2, ponytail: 0 与 commands: 8, ponytail: 6。另一条 #939 走的是体积:npm 包里塞进了 assets/ 和 pi-extension 的测试,而包里没有任何在运行的东西引用它们,砍掉后发布包从 997 kB 降到 49 kB,文件数从 54 降到 38。

  6. 06

    那组数字,以及它自带的更正

    README 的招牌说法是“~54% less code (up to 94%) · ~20% cheaper · ~27% faster · 100% safe”,方法是一次无头 Claude Code 会话去改 tiangolo 的 full-stack-fastapi-template——一个真实的 FastAPI + React 仓库——按它留下的 git diff 计分:十二个功能工单,同一个 agent 带 skill 与不带 skill 各跑一遍,n=4,模型 Haiku 4.5。表格给出的 ponytail 是代码行数 −54%、token −22%、成本 −20%、时间 −27%,在一个单独的对抗性安全档上是 100%;啰嗦文风对照组 caveman 是 −20% / +7% / +3% / +2%、安全 100%;“YAGNI + one-liners”提示词是 −33% / −14% / −21% / −30%、安全 95%。砍得最狠的地方正是 agent 容易过度建造的地方:日期选择器从 404 行变成 23 行,取色器从 287 行变成 23 行,“because it reaches for a native <input> instead of a component”。这组数字值得记的原因在于 README 会改自己的旧数字:更早的单轮跑分报的是“80-94% less code”,它被留在折叠段落里,并附了一句说明——#126“fairly pointed out that the bare-model baseline pads its answer with prose and options, so that gap is partly a conversational-baseline artifact”;徽章上则写着那个平铺数字是“the per-task ceiling, not the average”。benchmarks/results/ 下九个结果文件带着日期,从 2026-06-12 到 2026-06-22,最大的一份是 12,226 字节的 agentic 报告。

相关档案

全部档案 →