【Ponytail】核心架构与设计原理深度解析 让 AI Agent 学会那个不说话的资深工程师
Ponytail:把”最懒的资深开发”装进 AI Agent
“He says nothing. He writes one line. It works.”
—— DietrichGebert/ponytail 仓库副标题
如果一个 Coding Agent 接到”加个日期选择器”的需求,跑去 npm install flatpickr、写一个 400 行的 React wrapper、引入样式表、讨论时区——这大概是 2026 年最常见的”AI 过工程化”现场。
Ponytail(DietrichGebert/ponytail,⭐ 90,373,MIT)则用一行 <input type="date"> 结束战斗。
这个项目在 1 个半月内从 0 冲到 9 万 ⭐,是 2026 年上半年最被广泛安装的 Coding Agent 增强 skill。它不写框架、不跑 LLM、不做训练——只是一份 Markdown 规则集加 4 个 Node 生命周期 hook,但被同时塞进 20 个不同的 Coding Agent(Claude Code、Codex、Copilot CLI、Cursor、Windsurf、Cline、Qoder、Swival、Hermes、Jules、Amp、Kiro、Antigravity、Zed、Junie、CodeWhale、OpenClaw、OpenCode、Pi、Devin),让”少写代码但永远不丢安全”成为 Agent 的肌肉记忆。
这篇博客会讲清楚:
- Ponytail 的**”7 阶 Ladder”**怎么把”偷懒”和”删安全检查”分开
- 4 个 100 行不到的 Node hook 怎么让 20 个异构 Agent 拥有同一份肌肉记忆
- agentic 三裁判评测体系(LOC + Safety + Completeness)怎么把”少写 80% 代码”的营销话术打到 13.9 LOC 的真实数字
- 与 5 个同类”AI 编码规则”项目(caveman、addyosmani/agent-skills、awesome-claude-skills、Leonxlnx/taste-skill、code-yeongyu/oh-my-openagent)的设计差异
一、项目定位与核心价值
1.1 一句话定义
Ponytail 是一份可移植的 AI 编码纪律:一个 Markdown 规则集 + 一组生命周期 hook + 一组 Slash 命令,跨 20 个 Coding Agent 部署,目的是让 Agent 在每条响应里都遵循”先问要不要做、再问能不能复用、最后才写代码”的 YAGNI 阶梯。
1.2 仓库关键统计
| 维度 | 数值 | 来源 |
|---|---|---|
| Star | 90,373(2026-07-28 实时) | stargazers_count |
| Fork | 4,975 | forks_count |
| 主语言 | JavaScript(hook + tests)+ Python(评测) | language |
| License | MIT | license.spdx_id |
| 创建 | 2026-06-12(46 天) | created_at |
| 最近推送 | 2026-07-15 | pushed_at |
| 体积 | 2,253 KB | size |
| 适配 Agent 数 | 20(README badge 标注 “works with 20 agents”) | README.md |
| 文件数 | 156(含 28+ 平台分发文件) | git tree |
1.3 核心能力矩阵
| 能力 | 实现方式 | 验证证据 |
|---|---|---|
| 规则注入 | SessionStart 钩子把 SKILL.md 塞进 system prompt | hooks/ponytail-activate.js:42-45 |
| 跨 Agent 适配 | 20 份规则文件分发(.cursor/rules/、.windsurf/rules/、.clinerules/、.github/copilot-instructions.md、AGENTS.md、.kiro/steering/、.qoder/rules/、.claude-plugin/plugin.json、.codex-plugin/plugin.json、.openclaw/skills/、.opencode/plugins/、.qoder-plugin/plugin.json、.devin-plugin/plugin.json、.github/plugin/plugin.json、.agents/plugins/、.agents/rules/、.opencode/command/、.opencode/plugins/、.clinerules/、hooks/qoder-hooks.json、hooks/claude-codex-hooks.json、hooks/copilot-hooks.json、gemini-extension.json、.env.example、pi-extension/index.js) | tree.json 28+ 路径 |
| 强度切换 | 4 阶 ladder:off / lite / full(默认)/ ultra | skills/ponytail/SKILL.md:78-88 |
| 模式跟踪 | 状态文件 $CLAUDE_CONFIG_DIR/.ponytail-active 持久化 | hooks/ponytail-runtime.js:6-21 |
| 子 Agent 注入 | SubagentStart 钩子(修复 #252:SessionStart context 不会自动到 subagent) | hooks/ponytail-subagent.js:23-29 |
| 平台差异适配 | 同源规则文本走 3 套 JSON 协议:Copilot 用 additionalContext、Codex/Qoder 用 hookSpecificOutput.hookEventName、Claude 用裸 stdout | hooks/ponytail-runtime.js:36-75 |
| 模式按 Agent 类型限定 | PONYTAIL_SUBAGENT_MATCHER 正则(默认注入所有 subagent,匹配则跳过) | hooks/ponytail-subagent.js:32-77 |
| 评测闭环 | benchmarks/agentic/run.py + judge.py + complete.py 三裁判 | benchmarks/agentic/ 目录 |
| debt 跟踪 | ponytail: 注释标记 → /ponytail-debt skill 收账 | skills/ponytail-debt/SKILL.md:18-21 |
二、整体架构
Ponytail 的”反框架”哲学贯穿整个仓库:所有”框架味”都集中在 4 个 < 100 行的 Node hook,所有”业务规则”都集中在 1 份 Markdown。
flowchart TB
subgraph 用户入口
CMD["用户 /ponytail lite<br/>full/ultra/off"]
HOST["Coding Agent 主机<br/>Claude Code/Codex/Copilot CLI/<br/>Cursor/OpenCode/Qoder/..."]
end
subgraph 规则源 single-source-of-truth
SKILL["skills/ponytail/SKILL.md<br/>+5 衍生 skills"]
CONFIG["~/.config/ponytail/config.json<br/>PONYTAIL_DEFAULT_MODE"]
end
subgraph 生命周期 hooks Node JS
ACT["ponytail-activate.js<br/>SessionStart<br/>写入状态 + 注入规则"]
MODE["ponytail-mode-tracker.js<br/>UserPromptSubmit<br/>解析 /ponytail 命令"]
SUB["ponytail-subagent.js<br/>SubagentStart<br/>向 subagent 注入规则"]
INST["ponytail-instructions.js<br/>filterSkillBodyForMode<br/>按强度裁剪规则"]
CONF["ponytail-config.js<br/>getDefaultMode/isShellSafe/..."]
RUNTIME["ponytail-runtime.js<br/>setMode/clearMode/writeHookOutput"]
end
subgraph 跨平台分发
RULES["20 份规则文件<br/>.cursor/.windsurf/.clinerules/<br/>AGENTS.md/.kiro/.qoder..."]
PLUGIN["5 份 plugin manifest<br/>.claude-plugin/.codex-plugin/<br/>.qoder-plugin/.devin-plugin/<br/>.github/plugin"]
MCP["ponytail-mcp/<br/>MCP server 兜底"]
end
subgraph 评测闭环
BENCH["benchmarks/agentic/run.py<br/>headless Claude Code x 4 arm x 12 task"]
JUDGE["judge.py<br/>LLM-judge over-engineering<br/>0-3 评分"]
COMPLETE["complete.py<br/>LLM-judge stub detection"]
end
HOST -->|启动事件| ACT
HOST -->|每个 prompt| MODE
HOST -->|spawn agent| SUB
CMD -->|slash 命令| MODE
ACT --> INST
MODE --> RUNTIME
SUB --> INST
ACT --> CONF
MODE --> CONF
INST --> SKILL
RUNTIME -->|写 .ponytail-active| CONFIG
RULES --> SKILL
PLUGIN --> SKILL
MCP --> SKILL
BENCH --> SKILL
JUDGE --> SKILL
COMPLETE --> SKILL关键观察:
skills/ponytail/SKILL.md是 single source of truth——所有 20 份规则文件、5 份 plugin manifest、4 个评测 arm 都从这里生成。scripts/check-rule-copies.js在 CI 里验证一致性。- 4 个 hook 总共 < 500 行 JS——所有”框架味”压到 4 个职责单一的 Node 进程里。
- 3 套 JSON 输出协议——同一个
writeHookOutput()函数按 host 形态分支(Copilot / Codex / Qoder / Claude),靠process.env检测而非 if-else 链路。
2.1 平台分发矩阵
flowchart LR
CORE["SKILL.md<br/>7 阶 Ladder + 4 阶强度"]
CORE --> C1["Claude Code<br/>plugin manifest + 4 hooks"]
CORE --> C2["Codex<br/>plugin manifest + 4 hooks"]
CORE --> C3["GitHub Copilot CLI<br/>plugin manifest"]
CORE --> C4["OpenCode<br/>plugin.mjs + plugin.json"]
CORE --> C5["Pi<br/>pi-extension/index.js"]
CORE --> C6["Gemini CLI<br/>gemini-extension.json"]
CORE --> C7["Hermes Agent<br/>plugin manifest<br/>pre_llm_call hook"]
CORE --> C8["OpenClaw<br/>6 skills 打包"]
CORE --> C9["Swival<br/>skills add --global"]
CORE --> C10["Qoder<br/>.qoder-plugin + hooks/qoder-hooks.json"]
CORE --> C11["Devin CLI<br/>.devin-plugin"]
CORE --> C12["Antigravity<br/>复用 gemini-extension.json"]
CORE --> R1["Cursor<br/>.cursor/rules/ponytail.mdc"]
CORE --> R2["Windsurf<br/>.windsurf/rules/ponytail.md"]
CORE --> R3["Cline<br/>.clinerules/ponytail.md"]
CORE --> R4["VS Code Codex ext<br/>AGENTS.md"]
CORE --> R5["JetBrains Junie<br/>AGENTS.md"]
CORE --> R6["Aider / Amp / Jules<br/>AGENTS.md"]
CORE --> R7["Kiro<br/>.kiro/steering/ponytail.md"]
CORE --> R8["CodeWhale / Zed / Swival<br/>AGENTS.md"]
CORE --> R9["Qoder<br/>.qoder/rules/ponytail.md"]双层适配:有 plugin 系统的(Claude Code / Codex / Copilot CLI / OpenCode / Hermes / OpenClaw / Qoder / Devin)走”hook 注入” + “slash command”通道;只读规则文件的(Cursor / Windsurf / Cline / Aider / Kiro / Zed / Junie)走”AGENTS.md 或 .
三、核心引擎一:7 阶 Ladder
这是 Ponytail 的全部”业务核心”——一个 7 行的优先级链,决定 Agent 在每个响应里”问几次再写代码”。
3.1 规则文本(来自 skills/ponytail/SKILL.md)
1 | ## The ladder |
—— 来自 skills/ponytail/SKILL.md:32-48
关键设计:ladder 是 “reflex, not a research project”——它在”理解问题之后”运行(不是替代理解),但严格按 7 阶优先级回退:用得着才建、能用现成的就复用、能用平台能力就别装包、能一行就别两行。
3.2 4 阶强度切换
1 | | Level | What change | |
—— 来自 skills/ponytail/SKILL.md:78-88
举个缓存的例子:
1 | # "Add a cache for these API responses." |
关键设计:强度切换不是”加约束”,而是”减防护“——lite 还会建但给提示,full 直接走 ladder,ultra 强制质疑需求本身。这避免了常见误区:”prompt 里多说点 → Agent 过度自律”。
3.3 强度裁剪的运行时
1 | // 来自 hooks/ponytail-instructions.js:11-41 |
关键设计:
- 不重新写一份 lite/full/ultra 三份规则文本——一份全量规则在发送时按行过滤。single source of truth 防止三份规则逐渐漂移。
- 表格行匹配要求 label 必须形如
| **xxx** |——避免把普通规则行误判为模式行。 - 示例匹配要求 label 后必须是
"——避免把- Full: ...这种普通规则行误判为 worked example。 INDEPENDENT_MODES集合——review是会话级模式,不会成为默认(#377 修复),与off/lite/full/ultra严格隔离。
3.4 完整 filterSkillBodyForMode 单元测试用例
1 | // 来自 tests/instructions.test.js(节选) |
—— 来自 tests/instructions.test.js(测试代码隐含在 filterSkillBodyForMode 注释中)
实战经验:这个过滤函数就是 Ponytail 工程化最关键的一步——SKILL.md 是普通 Markdown,可以直接被任何 Agent 读取;运行时按强度裁剪则让”一份规则服务 4 种行为”成为可能。
四、核心引擎二:4 阶段生命周期
4 个 Node 进程 + 1 个状态文件,撑起”在所有 Coding Agent 里都活”的目标。
4.1 状态机的核心:ponytail-runtime.js
1 | // 来自 hooks/ponytail-runtime.js:6-21 |
关键设计:
- 状态文件 = single source of truth——所有 hook 读写同一个文件,避免在 4 个 hook 里分别维护状态。
- 多平台状态目录优先级:
isCodex > isCopilot > isQoder > Claude default——同一份代码不靠 hostname 检测,靠环境变量检测。 mkdirSync { recursive: true }——第一次使用时自动建目录,避免”目录不存在”错误。
4.2 平台差异的 3 套 JSON 输出协议
1 | // 来自 hooks/ponytail-runtime.js:36-75 |
关键设计:
- 同函数 4 形态——不抽象出 Adapter 类,3 个 if 分支覆盖 4 种输出协议。100 行可读性 > 5 个类文件。
SubagentStart强制 JSON——SubagentStart在 Claude Code 里要求hookSpecificOutput包装,裸 stdout 会被丢弃。这条注释是踩坑后写下的”必读”。SessionStartClaude 接受裸文本——历史遗留的简化协议,新事件用 JSON。
4.3 SessionStart 钩子:规则注入的入口
1 | // 来自 hooks/ponytail-activate.js:21-96(节选) |
关键设计:
- off 模式完全跳过——不写 flag、不发规则,让”用户主动 off”绝对安静。
- 状态文件写入与规则发送解耦——
setMode失败不阻塞规则发送;writeHookOutput失败不污染 session。 - statusLine nudge 只发一次——
.ponytail-statusline-nudgedflag 文件防止每次 session start 都弹同一段提示(“重复一次就成 nag”)。 - UTF-8 BOM 剥离——Windows 某些编辑器保存的 JSON 开头有 BOM,
JSON.parse会失败。
4.4 UserPromptSubmit 钩子:模式切换
1 | // 来自 hooks/ponytail-mode-tracker.js:23-89(节选) |
关键设计:
/ponytail default <mode>vs/ponytail <mode>严格区分——default写配置文件(永久),不带default只写 flag(会话级)。这是 issue #377 的修复:用户用default写review模式会导致 review 变成永久默认,但 review 是 session-only 模式。/ponytail(无参)只报模式——isReportOnly = true,不写 flag,让”查当前模式”成为安全操作。/[@$]ponytail三种前缀——/(Claude Code)、@(Codex 里的 skills)、$(Swival 的显式激活)——一份代码服务三套 slash 习惯。
4.5 SubagentStart 钩子:跨 agent 注入的精妙
1 | // 来自 hooks/ponytail-subagent.js:13-77 |
关键设计:
- issue #252 修复:
SessionStart的 additionalContext 不会自动传到 subagent——每个 subagent 需要SubagentStart钩子单独注入。这是 Claude Code 的隐藏行为,绝大多数 SKILL 写作者不知道。 - issue #443 修复:Windows PowerShell
if {}包装会吞掉 piped JSON,导致stdin 'end'永不触发,hook 永久挂起。修法:默认路径完全异步(不读 stdin),setTimeout 1s 兜底。 PONYTAIL_SUBAGENT_MATCHER正则——支持explore|general(不区分大小写、不锚定)或^general$(精确)。未匹配或错误一律 fail-open(注入),避免”scoping 静默丢规则”。unref()——保证 setTimeout 不会延迟主进程退出(“normal path 永远不阻塞”)。
4.6 模式切换的状态机时序
sequenceDiagram
participant User
participant Host as Claude Code/Codex/...
participant Activate as ponytail-activate.js
participant Tracker as ponytail-mode-tracker.js
participant Sub as ponytail-subagent.js
participant Skill as skills/ponytail/SKILL.md
participant Flag as $XDG_CONFIG_HOME/.ponytail-active
Host->>Activate: SessionStart
Activate->>Flag: write mode (lite/full/ultra/off)
Activate->>Skill: readFile SKILL.md
Skill-->>Activate: 120 lines Markdown
Activate->>Activate: filterSkillBodyForMode(body, mode)
Activate->>Host: writeHookOutput(SessionStart, mode, rules)
User->>Host: /ponytail ultra
Host->>Tracker: UserPromptSubmit(prompt="/ponytail ultra")
Tracker->>Tracker: parseCommand → mode="ultra"
Tracker->>Flag: write "ultra"
Tracker->>Host: writeHookOutput(UserPromptSubmit, "ultra", "PONYTAIL MODE CHANGED")
User->>Host: Task(subagent_type="general-purpose")
Host->>Sub: SubagentStart({ agent_type: "general-purpose" })
Sub->>Flag: read mode = "ultra"
alt no PONYTAIL_SUBAGENT_MATCHER
Sub->>Skill: readFile SKILL.md
Sub->>Sub: filterSkillBodyForMode(body, "ultra")
Sub->>Host: writeHookOutput(SubagentStart, "ultra", rules)
else matcher set, matches
Sub->>Host: writeHookOutput(SubagentStart, "ultra", rules)
else matcher set, no match
Sub->>Host: process.exit(0) — skip
end3 个事件 × 4 个 hook × 1 个状态文件 撑起”在所有 Coding Agent 里活”。
五、核心引擎三:7 阶”边界”规则
7 阶 Ladder 解决”少写”,但 Agent 容易”少写到丢安全”——这 6 条”Never”就是 Ponytail 的安全地板。
5.1 永不偷懒的边界
1 | ## When NOT to be lazy |
—— 来自 skills/ponytail/SKILL.md:90-112
关键设计:
- “Ladder 缩短的是方案,不是阅读”——这是 Ponytail 哲学的核心:先完整读,再走 ladder。偷懒不偷读。
- “用户坚持要全版 → 建,无争论”——尊重用户主权。
- “硬件不是纸面理想”——真实时钟漂移、传感器误差、PCA9685 频率偏差 3-5%,必须留校准旋钮。
- “懒代码无自检 = 未完成”——非平凡逻辑必留一个 runnable check(
assert守卫的demo()或if __name__段),但禁止写测试框架。
5.2 ponytail: 注释:技术债标记
1 | # ponytail: global lock, per-account locks if throughput matters |
关键设计:每个被 ponytail 主动”砍掉”的角落必须用 # ponytail: <ceiling>, <upgrade path> 标记,然后 /ponytail-debt skill 收集到一个总账里:
1 | $ /ponytail-debt |
—— 来自 skills/ponytail-debt/SKILL.md:18-44
关键设计:
- “用 ceiling 量化”——不是”以后改”,而是”超过 X 时改”。
upgrade: <触发条件>——明确”什么算’压力’到头了”,避免技术债偷偷腐烂。/ponytail-debt只 grep 注释前缀——ponytail:前缀让普通包含 “ponytail” 的文字不会被收账。
5.3 ponytail vs caveman 的明确分工
Ponytail README 的 FAQ 里写了它与 caveman 的边界:
Can I use it with caveman?
Yes, and you should. Caveman shrinks what the agent says; ponytail shrinks what it builds. Different halves, no overlap: caveman leaves code byte-for-byte exact, ponytail stays out of the prose. Terse talk about minimal code.
—— 来自 README.md:313-316
设计洞察:caveman 砍”话术”,ponytail 砍”代码”——两者互不重叠,可以同时开。
六、Provider 抽象层:跨 20 平台分发
Ponytail 的”20 平台适配”靠的不是抽象层,而是20 份规则文件 + 3 套 JSON 输出协议。
6.1 平台检测矩阵
flowchart TB
HOOK[hook 启动]
HOOK --> A1{process.env<br/>COPILOT_PLUGIN_DATA?}
A1 -->|yes| P1[Copilot CLI<br/>output: additionalContext]
A1 -->|no| A2{process.env<br/>PLUGIN_DATA?}
A2 -->|yes| P2[Codex<br/>output: hookSpecificOutput + systemMessage]
A2 -->|no| A3{process.env<br/>QODER_SESSION_ID?}
A3 -->|yes| P3[Qoder<br/>output: hookSpecificOutput]
A3 -->|no| P4[Claude Code<br/>SessionStart: raw stdout<br/>SubagentStart: hookSpecificOutput]—— 来自 hooks/ponytail-runtime.js:7-14, 36-75
关键设计:
- 3 个
process.env检测——同一份 hook 代码根据环境变量切换输出协议,没有if (host === 'claude')这种 if 链路。 - state dir 优先级:
isCodex > isCopilot > isQoder > Claude default——多平台互斥时按检测顺序降级。 isCopilot优先级最高——Copilot 也设PLUGIN_DATA,但意义不同,先用更特定的COPILOT_PLUGIN_DATA判断。
6.2 Hermes 适配的特殊形态
Hermes Agent 是 Ponytail 第一个非 Claude 系 Coding Agent,hook 协议叫 pre_llm_call 和 pre_gateway_dispatch:
1 | # 来自 plugin.yaml |
—— 来自 plugin.yaml:5-21
关键设计:
- Hermes 的 hook 协议命名不同——
pre_llm_call而非UserPromptSubmit,pre_gateway_dispatch而非PreToolUse。 - Hermes 的 slash command 通过
provides_commands列表声明——而非 Claude Code 的commands/xxx.toml目录扫描。 - Hermes 的 skill 通过
provides_skills暴露——命名空间是ponytail:<skill>(如ponytail:ponytail-review)。
6.3 OpenCode 的 plugin.mjs 适配
1 | // 来自 .opencode/plugins/ponytail.mjs(节选) |
—— 来自 .opencode/plugins/ponytail.mjs(概念代码)
关键设计:
- OpenCode 用
chat.message事件注入规则——非 SessionStart 钩子,而是每次 LLM 调用前修改 messages。 - 共享
ponytail-config.js的filterSkillBodyForMode——同一份裁剪函数在 4 个不同 runtime 里复用。 worktree参数——OpenCode 是 git worktree 原生支持的多 worktree 工作流,plugin 拿到的 directory 不一定是项目根。
七、评测闭环:三裁判架构
Ponytail 是 GitHub 上罕见的”自带评测 + 自带反评测“项目——一个 50k+ ⭐ 的 skill 在 release 后被 issue #126 公开质疑,于是专门写了 3 份评测脚本来证伪自己。
7.1 评测任务定义(benchmarks/agentic/tasks.py)
1 | # 来自 benchmarks/agentic/tasks.py:1-22 |
关键设计:
- 每个任务必带 seed 文件——
raise NotImplementedError起始,强制 agent 必须修改文件。如果 agent 只是说”done”就退出,scorer 会给它 fail。 - 安全性要求保持隐式——prompt 里只写 “untrusted” 或 “abusive clients”,不写”必须有 path traversal check”,模拟真实 ticket 风格。
- 每个 scorer 配
good和bad参考实现——good必须 pass,bad必须 fail 在axis(默认safe)维度。--selftest在任何 API 调用前验证。 - 反评测设计:故意把”bad”实现写得”happy path 正确 + adversarial input 漏防”——这正是”一行的 prompt”会写出的代码,让 bench 不会放过”省略安全检查”。
7.2 6 个安全任务的 good/bad 对照
1 | # 来自 benchmarks/agentic/tasks.py:67-130 |
—— 来自 benchmarks/agentic/tasks.py:88-106
关键设计:
GOOD是 6 行——其中 4 行是os.path.commonpath检查(”绝不删的安全门”)。BAD是 1 行——return os.path.join(base_dir, filename),happy path 正确但../../etc/passwd漏防。BAD是 yagni-oneliner prompt 会写出的代码——bench 的反评测设计就是让”短 prompt + 短代码 = 丢安全”被捕获。
7.3 LLM-judge:over-engineering 评分
1 | # 来自 benchmarks/agentic/judge.py:28-39 |
—— 来自 benchmarks/agentic/judge.py:28-39
关键设计:
- judge 的 rubric 完全公开——任何人都能 audit “0-3 分” 的判分标准。
--selftest强制要求”over > minimal”——judge 必须把”故意 over” 评得比”故意 minimal” 严格高,否则不信任 judge 的任何输出。- 每个评分要求 cite 具体的 construct——不是 “feels over-built”,而是 “AbstractRepository with one implementation”。
7.4 三裁判架构图
flowchart LR
A[benchmarks/agentic/run.py<br/>headless Claude Code 跑 4 个 arm]
A --> LOC[git diff added lines<br/>文件数 / LOC / test LOC]
A --> SAFE[score_X function<br/>deterministic stdlib]
A --> STUB[complete.py<br/>LLM-judge completeness]
LOC -->|12 feature tasks| Result1[feature tasks 平均]
SAFE -->|6 safety tasks| Result2[safety tasks 平均]
STUB -->|open tasks| Result3[completeness 0-3 分布]
Result1 --> Final[3 个 metric 表格<br/>+ 4 个 arm 对比]
Result2 --> Final
Result3 --> Final
Judge[judge.py<br/>LLM-judge over-engineering] -.->|optional 第二轮| Final关键设计:
run.py同时算 LOC + deterministic safety——所有 12 feature tasks + 6 safety tasks 一次性出分。judge.py是 over-engineering 第二轮评分——只在需要”主观评判”时调用(用 Sonnet 4.6,温度 0,每 cell ~$0.003)。complete.py是 stub 检测——防”少写代码因为少做事”——open tasks 没有 deterministic scorer,靠 LLM 评分。
7.5 最终结果:ponytail 真在 13.9 LOC,magic 在安全门
1 | # 来自 benchmarks/results/2026-06-18-agentic.md 的最终表格 |
—— 来自 benchmarks/results/2026-06-18-agentic.md:158-173
关键观察:
- feature tasks 上 ponytail 砍 54% LOC——远高于 yagni-oneliner 的 33%,原因是 ladder 强制走”4 阶”(native feature first)。
- safety tasks 上 ponytail 仍然 100% safe——而 yagni-oneliner 在 20 次运行里漏防 1 次(
safe-path6 行版本)。 - token 节省 22%——和 LOC 不是 1:1,因为 always-on 的 ruleset 占了 system prompt 一部分。
- 诚实声明:”−54%” 是 12 个 task 的平均,个体范围从 ~0%(不可压缩的 backend CRUD)到 −94%(date picker)。
7.6 早期 vs 真实评测的反思
Ponytail 早期用 promptfoo 跑 single-shot benchmark,号称”80-94% 砍 LOC”,但 issue #126 指出:
- A single completion is not how a coding agent is used. Real work is an agent editing a real codebase over many turns.
- The baseline was a bare, chatty model. It emitted prose, caveats, and multiple options, so “lines of the answer” counted commentary, not code.
- “Prefer one-liners” might trade away safety. If the discipline is “write less,” does it drop input validation and error handling to get there?
- A short prompt (“Follow YAGNI principles, and prefer one-liner solutions”) might do the same job as a whole skill.
—— 来自 benchmarks/results/2026-06-18-agentic.md:11-24
Ponytail 的应对:写了一份《论我们如何在自家数字里发现污染事件》的复盘——发现 baseline 跑时 SessionStart 钩子被 ponytail plugin “感染”(因为 plugin 启用),导致 baseline 偷偷带 ponytail。修法是 --setting-sources project,local 排除用户全局 plugin + 每个 arm 单独 --plugin-dir 加载。这次的 4-arm 设计直接把”短 prompt 是否够”作为对照组(yagni-oneliner arm),结果短 prompt 在 date picker 上 162 行,ponytail 23 行。
八、与同类项目对比
8.1 对比表
| 项目 | 形态 | 核心机制 | 适配 Agent | 评测体系 | 关键差异 |
|---|---|---|---|---|---|
| Ponytail | Markdown + 4 hook | 7 阶 ladder + 4 阶强度 | 20 个 | 3 裁判(LOC + safety + completeness)+ LLM-judge over-engineering | 唯一自带 3 裁判闭环 |
| caveman (JuliusBrussee/caveman) | Markdown SKILL | 短句输出约束 | Claude Code 为主 | 无 | 砍话术不砍代码,与 ponytail 互补 |
| Leonxlnx/taste-skill | Markdown SKILL | “品味”风格约束 | Claude Code | 无 | 强调”不写无聊代码”,不量化 |
| addyosmani/agent-skills | 80+ skill 集 | 通用 skill 集 | Claude Code | 无 | 多而广,ponytail 是单点深耕 |
| ComposioHQ/awesome-claude-skills | 资源列表 | curated 列表 | Claude Code | 无 | 资源聚合,不是 single skill |
| code-yeongyu/oh-my-openagent | 配置 + slash command | 多维度配置 | Claude Code | 无 | 含 Sentry/Context7/Linear 工具集成 |
8.2 关键设计差异
(1) Ponytail vs caveman:分砍话术 vs 分砍代码
Ponytail README 直接说:”Caveman shrinks what the agent says; ponytail shrinks what it builds.”
实测验证:在同一个 email-validator 任务里:
1 | baseline: "Sure! Here's an email validator. We need to consider RFC 5321, RFC 5322, edge cases..." |
caveman 砍了 95% 的话术但代码完全不变;ponytail 砍了 95% 的代码但话术短小;yagni-oneliner 两个都砍但丢了 path traversal 之类的 guard。三者正交不重叠。
(2) Ponytail vs addyosmani/agent-skills:单点深耕 vs 多点广度
agent-skills 是 80+ 个 skill 的合集(React best practices、code review、commit messages 等),每个 skill < 100 行 Markdown,广度优先。Ponytail 是 1 个 skill 配 4 阶强度 + 3 裁判评测 + 20 平台分发,深度优先。
对比维度:
| 维度 | Ponytail | addyosmani/agent-skills |
|---|---|---|
| 核心原则 | “少写代码”(YAGNI 量化) | “写对代码”(每语言最佳实践) |
| 强度切换 | lite/full/ultra/off 4 阶 | 无(单阶规则) |
| 跨平台 | 20 个 host | 主要 Claude Code |
| 评测 | 3 裁判 + LLM-judge | 无 |
| 维护成本 | 1 份 SKILL.md 同步 20 处 | 80+ 独立 skill |
(3) Ponytail vs oh-my-openagent:单一纪律 vs 多工具集成
oh-my-openagent 是 Claude Code 的”配置包”——除了 system prompt 约束,还集成了 Sentry、Context7、Linear 等外部工具。Ponytail 不集成任何外部工具,只改 Agent 的判断。
1 | # oh-my-openagent 风格 |
对比洞察:
- oh-my-openagent = “让 Agent 拥有更多工具”——关注 Agent 能做什么
- Ponytail = “让 Agent 决定少做”——关注 Agent 应该克制什么
- 两者互补:装 oh-my-openagent 拿工具,装 Ponytail 决定什么时候不调工具
(4) Ponytail vs taste-skill:量化 vs 风格
Leonxlnx/taste-skill(⭐68k)关注”不让 AI 写无聊代码”——目标是 git diff 出来的代码”有品味”。Ponytail 关注”少写代码”——目标是 LOC 数字下降。
对比洞察:
- taste-skill = “写漂亮”——主观、风格化
- Ponytail = “写少”——客观、可量化
- 写少不等于写漂亮——ponytail 自己也说:”Code first. Then at most three short lines: what was skipped, when to add it.”
九、优缺点分析
9.1 两侧对比表
| 维度 | Ponytail 的表现 |
|---|---|
| 架构简洁性 | ★★★★★ 4 hook + 1 SKILL.md + 1 state file,无任何框架依赖 |
| 可扩展性 | ★★★★☆ 加新 Agent 只需在 tree 加一份规则文件 + 适配 hook |
| 易用性 | ★★★★★ 1 行 install(/plugin marketplace add DietrichGebert/ponytail),4 阶强度切换 |
| 跨平台 | ★★★★★ 20 个 Coding Agent 适配,是同类项目最高 |
| 评测严谨性 | ★★★★★ 3 裁判 + LLM-judge + 反评测设计,自家数字被 issue #126 公开质疑后写 3 份评测脚本 |
| 可维护性 | ★★★★☆ 4 hook 单一职责,但 ponytail-instructions.js 的 filterSkillBodyForMode 承担”模式裁剪”核心逻辑 |
| 首次安装成本 | ★★★★☆ Claude Code/Codex 需 Node.js 在 PATH,否则 always-on 静默 |
| 运行时开销 | ★★★★★ 4 个 Node 进程 < 100ms 启动,state file 0 字节或 5 字节 |
| 主观判断限制 | ★★☆☆☆ “7 阶 ladder”是 Ponytail 团队的设计哲学,不是 universal truth——其他团队可能觉得”先做后问”更合适 |
| AGENTS.md 模式不可分 Agent 启用 | ★★☆☆☆ 一份 AGENTS.md 对所有读它的 Agent 同时生效——不能对 Cursor 装”lite”、对 Claude Code 装”ultra” |
9.2 适用场景
最适合:
- 同时跑 2+ 个 Coding Agent(Claude Code + Cursor + Codex),需要统一”少写代码”纪律
- 团队希望对 LLM 调用 减少 token 成本(实测 22% token 节省、20% 成本节省)
- 代码库已经过工程化严重,需要”清扫”工具
不太适合:
- 只用 1 个 Agent,且已经显式写好 system prompt——Ponytail 提供的 4 阶强度切换才有价值
- 写新代码时希望”先建再问”——Ponytail 默认走 ladder 7 阶,可能太保守
- 不想为规则牺牲可读性——
<input type="date">vsflatpickr在某些 UI 设计上确实 flatpickr 更精致
9.3 真实风险
- 强度切换被忘记——切到
ultra后,session 结束前一直 ultra,下个 session 不会自动回到full。PONYTAIL_DEFAULT_MODEenv var 是唯一全局默认机制。 #443类型的 Windows 兼容问题——尽管已经修,但 Windows PowerShell 包装仍是隐性风险源。SubagentStart注入是隐性开销——每个 subagent spawn 都触发一次规则注入,对 100+ subagent 的并行任务会有可感知的延迟。
十、实践:5 分钟把 Ponytail 跑起来
10.1 Claude Code 部署(推荐)
1 | # Step 1: 加 marketplace |
10.2 Cursor 部署(仅规则文件)
1 | # Cursor 不支持 plugin 钩子,只能复制规则文件 |
注意:Cursor 模式无法用 /ponytail slash command 切换强度,需要直接编辑 .mdc 文件修改强度表。
10.3 跑评测(验证效果)
1 | # Step 1: 克隆 benchmark 仓库 |
10.4 MCP server 模式(programmatic 启用)
1 | # 1. 启动 ponytail-mcp server |
—— 来自 ponytail-mcp/README.md:1-30(节选)
10.5 状态文件诊断
1 | # 查看当前模式 |
十一、趋势与总结
11.1 4 个趋势判断
趋势 1:Skill-as-Policy 成为 Coding Agent 主流分发形态
2026 H1 我们看到:
- Ponytail (⭐90k) 把”少写”做成跨 20 Agent 通用技能
- Open Design (⭐82k) 把”设计品味”做成 174 技能
- addyosmani/agent-skills (⭐80k) 把”工程最佳实践”做成 80+ 技能
- dietrichgebert/taste-skill (⭐68k) 把”代码品味”做成 1 个 skill
判断:到 2026 H2,”/plugin marketplace add
趋势 2:可量化的”少写”比”风格化的漂亮”更容易活下来
Ponytail 的 9 万 ⭐ 不是因为”哲学高大上”,而是因为有 3 份评测脚本能回答”真的少写了吗”。taste-skill 的 6.8 万 ⭐ 至今没有评测。这是规则集 vs 哲学的根本差异——可量化 = 可工程化 = 可规模化。
趋势 3:跨 Agent 适配是 Coding Agent 工具的护城河
Ponytail 适配 20 个 Agent 的工作量大但 incremental——加新 Agent 只需一份规则文件 + 一段 hook 适配。composio (⭐29k) 走的是”1000+ 工具集成”路径,claude-code-router (⭐36k) 走的是”跨 LLM Provider 路由”路径。三者合起来构成”Agent 时代中台”的标准件。
趋势 4:自带评测的 skill 越来越重要
Ponytail 的 3 份评测脚本(run.py + judge.py + complete.py)是 GitHub 上罕见的”skill 主动邀请被证伪”项目。harbor-framework (评测) 走 harness 路线,logfire (可观测性) 走 SDK 路线,但 Ponytail 走的是”我自己的规则我自己量化”路线——这种自证 + 自证伪的工程态度,是 2026 H2 Coding Agent 项目的新基准。
11.2 工程经验提炼
- “少写代码”是一个工程目标,不是一个哲学宣言——必须配 3 裁判评测体系才能避免营销话术。
- 跨平台分发的”5 行 hook” > “5 个类文件”——
ponytail-runtime.js用 85 行覆盖 4 个平台的输出协议,靠process.env检测而非 if 链路。 - always-on 规则注入的”silent fail”哲学——4 个 hook 都 try/catch + process.exit(0),任何失败都不阻塞 session。这是 #443 修复的核心教训。
- 强度切换的”减防护”模型 > “加约束”模型——
lite/full/ultra走的是”少管 → 多管”,让用户自己平衡。 - 规则文件的
single source of truth——skills/ponytail/SKILL.md一份,20 份 platform-specific 文件 + 5 份 plugin manifest 全是它生成。scripts/check-rule-copies.jsCI 验证。
11.3 一句话总结
Ponytail 用一份 Markdown 规则集 + 4 个 100 行不到的 Node hook + 3 份评测脚本,把”少写代码但永远不丢安全”这件看似反直觉的事做成了可安装、可量化、可跨 20 个 Coding Agent 部署的标准件——这才是 2026 H2 Coding Agent 工程的真正胜利:不是把 Agent 做得更能写,而是让 Agent 学会不写。
附录:关键资源
| 资源 | 链接 |
|---|---|
| GitHub 仓库 | https://github.com/DietrichGebert/ponytail |
| npm 包 | @dietrichgebert/ponytail v4.8.4 |
| README | https://github.com/DietrichGebert/ponytail/blob/main/README.md |
| 核心 SKILL | skills/ponytail/SKILL.md |
| 评测入口 | benchmarks/agentic/run.py |
| 评测结果 | benchmarks/results/2026-06-18-agentic.md |
| Caveman(互补) | https://github.com/JuliusBrussee/caveman |
| Agent portability 文档 | docs/agent-portability.md |
| License | MIT |
| 创建日期 | 2026-06-12 |
| 最近版本 | 4.8.4 |