Ponytail:让 AI 编码 Agent 像"最懒的资深开发"一样写代码的完整实践指南
Ponytail 是一个给 AI 编码 Agent 装上"懒资深开发"人格的开源规则集与多宿主插件:它在 Agent 写代码之前强制走一遍"是否需要存在 → 代码库是否已有 → 标准库 → 平台原生特性 → 已安装依赖 → 一行代码 → 最后才写最小实现"的决策阶梯,从而显著减少过度构建的代码量。读完本文,你将掌握 Ponytail 的核心机制(七级阶梯与强度分级)、在 20 余种 Agent 宿主(Claude Code、Codex、Copilot CLI、OpenCode、Gemini CLI、Qoder 等)上的完整安装配置方式、六个内置命令的用法与底层提示词实现,以及如何复现其基准测试来验证"少写代码但不牺牲安全性"这一核心主张。
背景:Agent 过度构建的痛点
Ponytail 的出发点是 AI 编码 Agent 的一个典型行为模式:你让它做一个日期选择器,它安装 flatpickr、写一个包装组件、加一份样式表,然后开始讨论时区。README 中给出的对照是:
<!-- ponytail: browser has one -->
<input type="date">
启用 Ponytail 后,Agent 的第一反应是"浏览器原生就有这个能力"。仓库的 examples/ 目录收录了更多"幸存者"——这些是基准测试中真实模型输出的原文,同一任务分别由无 skill 和有 skill 的同一模型作答,可逐行对比。例如 email-validation.md(75 行 vs 3 行)、debounce.md(116 行 vs 10 行)、react-countdown.md(267 行 vs 9 行)、rate-limit.md(128 行 vs 10 行),完整对照表见 examples/README.md。
数字:基准测试如何证明"更少的代码,且依然安全"
README 给出的核心数字是:~54% 更少的代码(最高 94%)、~20% 更低成本、~27% 更快、100% 安全。这些数字的测量方式值得细看,因为项目方曾公开修正过自己的测量方法。
可复现的 agentic 基准
当前主数字来自一个真实的 agent 化测量:在无头(headless)Claude Code 会话中编辑真实开源仓库(FastAPI + React 的 full-stack-fastapi-template,固定 commit),以留下的 git diff 为评分依据。12 个功能工单、同一 Agent 有无 skill 各 n=4 次、Haiku 4.5。对比表如下:
| 对比无 skill 基线 | LOC | tokens | cost | time | safe |
|---|---|---|---|---|---|
| ponytail | -54% | -22% | -20% | -27% | 100% |
| caveman(简洁话术对照组) | -20% | +7% | +3% | +2% | 100% |
| "YAGNI + 一行代码" 提示词 | -33% | -14% | -21% | -30% | 95% |
ponytail 是唯一在全部指标上同时降低、且保持完全安全的对照组。削减最大的地方正是真实的过度构建陷阱:日期选择器从 404 行降到 23 行、颜色选择器从 287 行降到 23 行(因为用原生 <input> 替代了组件);而在代码本身已经最小化时(如后端 CRUD),各对照组基本收敛,Ponytail 不"发明"不存在的节省。
完整的测量方法、逐任务数据与局限性声明在 benchmarks/results/2026-06-18-agentic.md。几点从该文档中可以确认的细节:
- 基线是"同一个 Claude Code Agent 但不加载 skill",而不是裸 API 模型。早期的单轮(single-shot)基准(80–94% 降幅)因基线模型爱输出散文和多个选项而被 issue #126 指出存在对话基线偏差,agentic 版是修正后的可辩护版本;
- 安全是单独对抗性测试层:6 个"只实现一个函数"的工单,评分器会用路径穿越、SQL 注入、伪造 token 等对抗输入实际执行产物代码。ponytail 20/20 全部安全,而"YAGNI + 一行代码"提示词在
safe-path任务上 4 次运行中 1 次被../../文件名逃逸——它写出的代码最短(6 行),但恰好砍掉了路径穿越检查。这正是 Ponytail 规则"信任边界处的输入校验永不裁剪"要防住的事; - 测量过程自身也做过污染排查:早期一版 agentic 运行因
SessionStarthook 在所有对照组(包括基线)上都触发,导致基线"偷偷"加载了 skill,发现后通过--setting-sources project,local加逐组--plugin-dir隔离修复。复现方式见 benchmarks/agentic/README.md,单轮版则可用npx promptfoo eval -c benchmarks/promptfooconfig.yaml复现。
规则不是"token 最少"
README 特别强调:规则从来不是"最少的 token",而是"只写任务需要的,且绝不裁剪校验、错误处理、安全性或可访问性"。 代码变短是因为它是必需的,而不是被压缩(golfed)的。成本与延迟下降只是遵循阶梯的模型的副产品——某些模型会用思考 token 反复斟酌阶梯的每一步,反而可能变慢。
工作原理:七级决策阶梯
Ponytail 的核心是一段注入给 Agent 的规则文本(规则集)。Agent 在写代码之前,停在第一个"成立"的梯级:
1. Does this need to exist? → no: skip it (YAGNI)
2. Already in this codebase? → reuse it, don't rewrite
3. Stdlib does it? → use it
4. Native platform feature? → use it
5. Installed dependency? → use it
6. One line? → one line
7. Only then: the minimum that works
这条阶梯运行在理解问题之后,而不是代替理解问题:Agent 会先读改动涉及的代码、追踪真实流程,再选梯级。"对方案懒惰,对阅读永不懒惰"。
规则集的完整形态
README 中的阶梯是精简版。仓库里实际注入的完整规则集见 AGENTS.md,其内容与阶梯一致,并补充了几条 README 未展开的实操规则:
- Bug 修复 = 根因,不是症状:先 grep 被改函数的所有调用方,在共享函数里加一次守卫,比在每个调用方各打一个补丁的 diff 更小——只修工单点名的路径会留下兄弟调用方仍然坏掉;
- 禁止未经请求的抽象、可避免的新依赖、没人要的样板代码;删除优于新增,无聊优于聪明,文件数最少优先;
- 面对两个体量相当的 stdlib 方案,选边界情况正确的那个——"懒"意味着代码更少,而不是算法更脆弱;
ponytail:注释约定:凡是做了"有已知天花板"的刻意简化(全局锁、O(n²) 扫描、朴素启发式),必须留一条ponytail:注释写明天花板和升级路径。这条注释约定被/ponytail-debt命令回收成债务台账(下文详述)。
skill 形态的规则集在 skills/ponytail/SKILL.md,frontmatter 中声明了触发条件(任何编码任务,或用户说出 "ponytail"、"be lazy"、"yagni" 等关键词),正文在阶梯之外还定义了输出纪律:代码优先,之后最多三行短说明(跳过了什么、何时再加),"如果解释比代码长,删掉解释——每段为简化辩护的散文都是夹带回来的复杂度"。
强度分级:lite / full / ultra
规则集定义了三个强度等级,默认是 full:
| 等级 | 行为 |
|---|---|
| lite | 照做你要求的功能,但用一行点出更懒的替代方案,由用户决定 |
| full | 强制执行阶梯:标准库和原生优先,最短 diff、最短解释。默认 |
| ultra | YAGNI 极端主义:先删除再新增,交付一行方案的同时质疑需求本身 |
以"为这些 API 响应加缓存"为例,三档的典型输出(摘自 skills/ponytail/SKILL.md):
- lite:「完成,缓存已加。顺便说一句:
functools.lru_cache一行就能覆盖,如果你想少维护一个缓存类。」 - full:「在 fetch 函数上加
@lru_cache(maxsize=1000)。跳过了自研缓存类,等 lru_cache 可测量地不够用时再加。」 - ultra:「profiler 说话之前不建缓存。真需要时:
@lru_cache。手写的 TTL 缓存类是带命中率的 bug 农场。」
规则集同时划出不可懒惰的红线:信任边界的输入校验、防数据丢失的错误处理、安全措施、可访问性基础、以及任何被明确要求的实现(用户坚持要完整版就照做,不再争辩)。针对真实硬件还有一条工程化细节:平台永远不是纸面理想值——时钟会漂、传感器读数会偏——所以该留校准旋钮时就留校准旋钮,而不只是留更少的代码。另外,"懒代码没有检查就是未完成":非平凡逻辑(分支、循环、解析器、资金/安全路径)要留下一个可运行的最小自检(assert 式自测或一个小测试文件,不引入框架);平凡的一行代码则不需要测试,YAGNI 同样适用于测试。
安装:适配 20 余种 Agent 宿主
Ponytail 是一个多宿主项目,安装方式分三类:插件/skill 体系宿主(有模式切换与 hook)、指令文件宿主(靠 AGENTS.md 等规则文件)、以及纯指令文件复制。以下命令以当前仓库内容为准。
前置条件:Claude Code 与 Codex 插件会运行两个很小的 Node.js 生命周期 hook,因此 node 需要在 PATH 上(Nix/nvm 用户注意:必须在非交互式 shell 的 PATH 上)。若不在 PATH 上,skill 本身仍可用,只是"常开激活"保持静默而不在每条提示上报错。
Claude Code
/plugin marketplace add DietrichGebert/ponytail
/plugin install ponytail@ponytail
两条命令需要作为两个独立提示分别发送。Claude Code Desktop 的 Code 标签页同样可用:把两条 /plugin 命令输入提示框,或点击 + 按钮选择 Plugins → Add plugin 浏览已配置的 marketplace。
Codex
codex plugin marketplace add DietrichGebert/ponytail
codex plugin add ponytail@ponytail
运行 codex 后打开 /hooks,审查并信任其两个生命周期 hook,然后开新线程。桌面版同理:安装后重启应用即自动加载。
GitHub Copilot CLI
copilot plugin marketplace add DietrichGebert/ponytail
copilot plugin install ponytail@ponytail
交互式会话中可用等价的斜杠命令 /plugin marketplace add ... 与 /plugin install ...。注意 Copilot CLI 按插件名做命令命名空间,调用形如:
/ponytail:ponytail ultra
/ponytail:ponytail-review
Pi agent harness / OpenCode / Gemini CLI
pi install git:github.com/DietrichGebert/ponytail
OpenCode 在 opencode.json 中添加:
{ "plugin": ["@dietrichgebert/ponytail"] }
或从本地 checkout 运行(插件复用 hooks/ 与 skills/ 目录):
{ "plugin": ["./.opencode/plugins/ponytail.mjs"] }
插件每轮以当前等级注入规则集并注册 /ponytail 系列命令;OpenCode 还会自动加载本仓库的 AGENTS.md,因此没有插件时规则也生效。./ 路径相对项目里的 opencode.json 解析;若要跨项目共享一个 checkout,改为指向 .mjs 的绝对路径(它会相对自身文件位置寻找 hooks/ 和 skills/)。
Gemini CLI:
gemini extensions install https://github.com/DietrichGebert/ponytail
该扩展把规则集作为每会话常开上下文加载并注册 /ponytail 命令,skills/ 一并随行。从源码结构看,Gemini 适配层刻意不提供根目录 hooks/hooks.json:Gemini 会自动加载该路径,而 Ponytail 的生命周期 hook 用的是 Claude/Codex 事件名,两者不兼容。
Qoder / Antigravity / Hermes / CodeWhale / Swival / Devin / OpenClaw
- Qoder:自动加载仓库根
AGENTS.md,从 checkout 运行零配置。项目级规则可将.qoder/rules/ponytail.md复制到你的项目。若要完整插件级支持(每次提示自动激活模式并注入规则集),把hooks/qoder-hooks.json中的 hook 加入.qoder/settings.json(把PONYTAIL_DIR替换为你 checkout 的路径):UserPromptSubmithook 在首个提示时激活默认模式并每轮注入规则集,PreToolUse(matcher 为task|Task)把规则集注入子 Agent;/ponytail lite|full|ultra|off切换自动可用。 - Antigravity CLI(Google 将 Gemini CLI 更名为 Antigravity CLI,二进制名
agy):agy plugin install https://github.com/DietrichGebert/ponytail,复用本仓库的 gemini-extension.json。区别是 Antigravity 把/ponytail命令转成 skill,需要把命令作为消息输入聊天(如把/ponytail-review当消息发);迁移完成前gemini extensions install仍可用。 - Hermes Agent:
hermes plugins install DietrichGebert/ponytail --enable,安装后重启。插件在每个 LLM 轮次前注入当前模式,把 bundled skills 注册为ponytail:<skill>,并添加六个/ponytail*命令。共享网关中建议用 Hermes 的斜杠命令访问控制把/ponytail限制给可信用户——运行时模式是进程局部的。 - CodeWhale:读取项目根
AGENTS.md,零配置;把 AGENTS.md 拷到项目,或直接从本仓库 checkout 运行。 - Swival:先 stage 到技能库再按需添加:
swival skills add --global https://github.com/DietrichGebert/ponytail(stage 进~/.config/swival/library),然后swival skills add ponytail(当前项目)或swival skills add --global ponytail(所有项目)。命令行上用$前缀显式激活 skill,如$ponytail-review。 - Devin CLI:
devin plugins install DietrichGebert/ponytail,skill 以/ponytail:ponytail、/ponytail:ponytail-review等形式可用。 - OpenClaw:
clawhub install ponytail安装为 skill,另五个(review/audit/debt/gain/help)同理clawhub install ponytail-review等;OpenClaw 在编码任务上自动应用它,并暴露为/ponytail命令。无 ClawHub 时把.openclaw/skills/ponytail复制到~/.openclaw/skills/。
指令文件宿主(纯规则复制,无命令无 hook)
Cursor、Windsurf、Cline、GitHub Copilot Chat(VS Code / JetBrains / Visual Studio 编辑器扩展,不是独立 Copilot CLI)、Aider、Kiro、Zed、CodeWhale、Swival、Qoder 等宿主,直接复制对应的规则文件即可(如 .cursor/rules/、.windsurf/rules/、.clinerules/、.github/copilot-instructions.md、AGENTS.md、.kiro/steering/)。各文件与各 Agent 的映射关系见 docs/agent-portability.md。
- Kiro:把
.kiro/steering/ponytail.md拷到~/.kiro/steering/(全局)或项目的.kiro/steering/; - Copilot CLI 兜底(纯指令模式):读取项目内
AGENTS.md与.github/copilot-instructions.md,或把规则拷到~/.copilot/copilot-instructions.md全局生效。此路径保留常开指导,但没有插件模式切换与 hook; - VS Code + Codex 扩展:读取
AGENTS.md,本仓库自带,仓库根目录零配置可用(~/.codex/AGENTS.md可全局生效); - JetBrains Junie:需在 Settings → Tools → Junie → Project Settings → Guidelines Path 指到
AGENTS.md(目前不是自动的);.junie/guidelines.md是旧路径; - Amp (Sourcegraph):从工作目录及父目录向上直到
$HOME读取AGENTS.md,零配置(~/.config/amp/AGENTS.md全局生效); - Jules (Google):读取仓库根
AGENTS.md,零配置。
模式持久化与子 Agent 注入
安装后规则集每个会话常开。每次新会话的默认等级可用环境变量 PONYTAIL_DEFAULT_MODE(lite/full/ultra/off)或 ~/.config/ponytail/config.json(Windows 为 %APPDATA%\ponytail\config.json)中的 defaultMode 字段设置,解析顺序为:环境变量 → 配置文件 → 默认 full(从 commands/ponytail-help.toml 的提示词可确认该顺序)。
一个容易忽略的配置点是子 Agent 注入范围:激活期间,规则集还会注入到通过 Agent 工具派生的每个子 Agent。若要把范围限定到特定 Agent 类型(例如对只读的检索型 Agent 关闭),设置环境变量 PONYTAIL_SUBAGENT_MATCHER 为正则,作用于子 Agent 的 agent_type:正则不加锚点、忽略大小写,explore|general 匹配任一,^general$ 是精确匹配,插件型 Agent 的类型形如 plugin:name。未设置(默认)= 注入所有子 Agent;正则非法或平台不报告类型时,也会回退为注入。
卸载
| 宿主 | 命令 |
|---|---|
| Claude Code | /plugin remove ponytail |
| Codex | codex plugin remove ponytail |
| Devin CLI | devin plugins remove ponytail |
| Pi agent | pi uninstall ponytail |
| Cursor / Windsurf / Cline / Qoder 等 | 删除复制的规则文件 |
这些命令只删插件自身文件。Ponytail 在插件目录外还会留下少量状态:模式标志、~/.config/ponytail/config.json,以及(若你接受过安装引导)~/.claude/settings.json 里的一条 statusLine。运行 node scripts/uninstall.js(见 scripts/uninstall.js)可一并清理——务必先于上表的宿主删除命令运行,因为该脚本本身就是插件文件,先删插件就把它删掉了(或从另一个 clone 里运行)。它只清理指向 Ponytail 自身脚本的 statusLine 条目,你自己配置的 statusline 不会被动。
命令:六个斜杠命令及其提示词实现
在支持 skill 的宿主上(Claude Code、Codex、Devin CLI、OpenCode、Gemini、pi、Swival、Hermes Agent、Qoder),Ponytail 提供六个命令。纯指令宿主只加载常开规则集,没有命令。命令定义见 commands/ 目录下的 TOML 文件,每个文件就是一段描述 + 提示词:
| 命令 | 作用 |
|---|---|
/ponytail [lite | full | ultra | off] |
设置强度或关闭;不带参数则报告当前等级 |
/ponytail-review |
审查当前 diff 的过度工程,交回一份"可删清单" |
/ponytail-audit |
审计整个仓库的过度工程,而不只是 diff |
/ponytail-debt |
把散落的 ponytail: 捷径注释收割成债务台账,防止"以后再说"变成"永远不会" |
/ponytail-gain |
展示基准测试中的实测收益记分板(更少代码、更少成本、更快速度) |
/ponytail-help |
上述命令的快速参考 |
在 Codex 中它们是 skill,用 @ 调用(@ponytail-review)。
从 TOML 提示词可以看到各命令的确切输出契约,比 README 表格更有实操价值:
/ponytail-review(commands/ponytail-review.toml):只审过度工程、不审正确性,每条发现一行L<行号>: <tag> <删什么>. <替代方案>,标签共五种——delete(死代码/臆想功能)、stdlib(重造标准库)、native(依赖在做平台的事)、yagni(只有一个实现的抽象)、shrink(同逻辑更少行);结尾必须给出净可删行数;无发现时输出 "Lean already. Ship."/ponytail-audit(commands/ponytail-audit.toml):与 review 相同的标签体系,但扫描整个仓库树而非 diff,按"最大可删"排序,结尾给出净可删行数与依赖数;/ponytail-debt(commands/ponytail-debt.toml):用grep -rnE '(#|//) ?ponytail:' .(跳过 node_modules/.git/构建产物)全树收割ponytail:注释,每个 marker 一行:<file>:<line> — 简化了什么 / ceiling: 注释里写的上限 / upgrade: 重新评估的触发条件;没有写升级路径的 marker 会被标记为no-trigger("这些会悄悄腐烂");只报告不修改;/ponytail-gain(commands/ponytail-gain.toml):一次性渲染已发布基准的中位数记分板(LOC 6–20%、成本 23–53%、速度 3–6x),并明确禁止输出"本仓库节省数字"——未写出的代码没有基线可减,真实的项目级数字应指向/ponytail-debt与/ponytail-audit;/ponytail(commands/ponytail.toml):切换强度,无参数时落到full,提示词本身就内联了阶梯与ponytail:注释约定。
开发与测试:保持多份规则副本一致
由于同一套压缩规则文本被复制到多个宿主的适配文件中(AGENTS.md、.cursor/rules/、.windsurf/rules/、skill 等),修改规则文本时必须保持各副本对齐。仓库提供了对应工具链(见 package.json,npm 包名 @dietrichgebert/ponytail):
node scripts/check-rule-copies.js # 校验各 agent 规则副本一致
npm test # 测试套件
npm test 实际运行 node --test tests/*.test.js 并递归跑 pi-extension/ 与 ponytail-mcp/ 两个子包各自的测试。几个开发相关事实:
- OpenClaw skill 包是生成物:
.openclaw/skills/从skills/生成,改动 skill 后要重跑node scripts/build-openclaw-skills.js,测试套件会因副本过时而失败。发布到 ClawHub 需先clawhub login,再运行 scripts/publish-openclaw-skills.js(一次性发布全部六个 skill,版本号取package.json;--dry-run预览); - 正确性基准会 spawn Python 做 email 与 CSV 检查,优先尝试
python3;CSV 检查需要本地安装pandas; - 基准测试代码位于 benchmarks/:
behavior.js/correctness.js/loc.js等是行为、正确性与 LOC 评分器,arms/目录存放各对照组(baseline.js、ponytail.js、caveman.js)的规则文本,agentic/子目录是无头 Claude Code 会话的 agentic 运行框架(run.py、tasks.py、judge.py、complete.py)。
常见问题(FAQ)
README 的 FAQ 值得原文继承,因为它划定了 Ponytail 的边界:
能和 caveman 一起用吗? 可以,而且推荐。Caveman 压缩 Agent 的话,ponytail 压缩 Agent 的构建。两者是互补的半边,不重叠:caveman 对代码保持逐字节不动,ponytail 不碰行文。基线数据也支持这一点:agentic 基准中 caveman 对照组只降了 20% 代码却多花了 7% token——简洁话术解释了差距的一部分,但不是主要部分。
需要配置文件吗? 不需要。可选的 ~/.config/ponytail/config.json 或 PONYTAIL_DEFAULT_MODE 环境变量可以设置默认等级,但什么都不配也能跑。
我真的需要一个 120 行的缓存类呢? 你不需要。你坚持,他会给你建。慢慢地。正确地。一边看着你。
它能 scale 吗? 你从未写出的代码无限 scale:零 bug、零 CVE、自始至终 100% 在线。
为什么叫 "ponytail"? 你心知肚明。
小结:适用前提与边界
Ponytail 的完整主张可以概括为:在真实工单上,存在过度构建陷阱的功能削减 60–94% 代码,已经最小化的代码上基本持平,且从不以牺牲信任边界安全为代价(agentic 基准中 100% 安全通过,而纯"一行代码"提示词是唯一漏掉守卫的对照组)。使用时应注意其适用前提:主数字基于 Haiku 4.5 单模型、n=4 的无头 Claude Code 会话;安全层是 6 个确定性对抗检查构成的下限而非安全证明;效果依赖宿主是否正确加载规则集(hook 依赖 node 在非交互式 PATH 上)。对于只想了解"文件与 Agent 的映射"的读者,从 docs/agent-portability.md 入手;想验证数字本身,则直接跑 benchmarks/agentic/ 提供的复现脚本——该项目连自己的基准污染 bug 都写在文档里,这种可审计性是它数字可信的底层原因。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00