Ponytail 完整教學

讓 AI Agent 像最懶的資深工程師一樣寫程式 — 最好的程式碼,就是你從來沒寫的那段。

1. 專案定位

這是什麼?

Ponytail 是一個跨平台的 AI agent skill / plugin,它把一個理念灌輸到你的 AI coding assistant 裡:寫程式之前,先問「這段程式碼真的需要存在嗎?」

名字來自一個刻板形象:那位留著馬尾辮、戴橢圓眼鏡、在公司待得比版本控制系統還久的資深工程師。你給他看 50 行程式碼,他看了一眼,什麼都沒說,然後用 1 行取代。

它解決什麼問題?

AI coding agent 的通病是 over-engineering(過度工程化)

  • 你要一個日期選擇器 → agent 裝了 flatpickr、寫了 wrapper component、加了 stylesheet、開始討論時區
  • Ponytail 的答案:<input type="date">(瀏覽器已經有了)

核心數據

指標效果
程式碼量80-94% 更少(vs 無 skill baseline)
速度3-6x 更快
成本47-77% 更便宜
測試基準5 task × 3 model (Haiku/Sonnet/Opus) × 10 runs

誰適合用?

  • 用 Claude Code / Codex / Copilot CLI / Gemini CLI 等 AI agent 做日常開發的工程師
  • 覺得 AI 生成的程式碼太冗長、太多 boilerplate 的團隊
  • 想要 YAGNI (You Aren’t Gonna Need It) 原則自動執行的人

2. 安裝指南

前置需求

  • Node.js(需在 PATH 上;Nix/nvm 使用者注意非互動 shell 的 PATH)
  • 任一支援的 AI agent CLI

Claude Code(推薦)

1/plugin marketplace add DietrichGebert/ponytail
2/plugin install ponytail@ponytail

安裝完即生效,每個 session 自動啟動。

Codex

1codex plugin marketplace add DietrichGebert/ponytail
2codex

開啟 /plugins 選 Ponytail marketplace 安裝,然後到 /hooks review 並信任兩個 lifecycle hooks。

GitHub Copilot CLI

1copilot plugin marketplace add DietrichGebert/ponytail
2copilot plugin install ponytail@ponytail

互動 session 中用 /ponytail:ponytail ultra 切換強度。

Gemini CLI / Antigravity CLI

1# Gemini CLI
2gemini extensions install https://github.com/DietrichGebert/ponytail
3
4# Antigravity CLI (Google renaming)
5agy plugin install https://github.com/DietrichGebert/ponytail

OpenCode

從 checkout 執行 OpenCode,opencode.json 加:

1{ "plugin": ["./.opencode/plugins/ponytail.mjs"] }

OpenClaw

1clawhub install ponytail

其他 Agent(instruction-only 模式)

Cursor / Windsurf / Cline / Kiro / Aider / VS Code Copilot:複製對應的 rules 檔案到專案或全域設定目錄。詳見 docs/agent-portability.md

3. 核心架構解析

「懶惰階梯」— The Ladder

Ponytail 的核心邏輯是一個 6 階決策階梯。Agent 在寫任何程式碼之前,從第 1 階開始往下走,停在第一個成立的階層


flowchart TD
    Q1{"1. 這東西需要存在嗎?
(YAGNI)"} Q2{"2. 標準函式庫做得到?"} Q3{"3. 平台原生功能做得到?
(CSS > JS, DB constraint > app code)"} Q4{"4. 已安裝的套件做得到?"} Q5{"5. 一行寫得完?"} Q6["6. 寫最少能動的程式碼"] Q1 -->|"No, skip it"| SKIP["跳過,說一句為什麼"] Q1 -->|"Yes, needed"| Q2 Q2 -->|"Yes"| USE_STD["用 stdlib"] Q2 -->|"No"| Q3 Q3 -->|"Yes"| USE_NATIVE["用原生功能"] Q3 -->|"No"| Q4 Q4 -->|"Yes"| USE_DEP["用現有套件"] Q4 -->|"No"| Q5 Q5 -->|"Yes"| ONE_LINE["寫一行"] Q5 -->|"No"| Q6 style Q1 fill:#264653,color:#fff style Q6 fill:#e76f51,color:#fff style SKIP fill:#2a9d8f,color:#fff

Hook 架構

Ponytail 透過兩個 lifecycle hooks 運作:


flowchart LR
    subgraph SessionStart["SessionStart Hook"]
        A1["ponytail-activate.js"]
        A1 --> A2["寫 .ponytail-active flag"]
        A1 --> A3["注入 ruleset 到 system prompt"]
        A1 --> A4["檢查 statusline 設定"]
    end

    subgraph UserPrompt["UserPromptSubmit Hook"]
        B1["ponytail-mode-tracker.js"]
        B1 --> B2["偵測 /ponytail 指令"]
        B1 --> B3["更新強度等級"]
    end

    SessionStart --> UserPrompt

    style SessionStart fill:#e8f4fd,stroke:#1976d2
    style UserPrompt fill:#fff3e0,stroke:#f57c00

檔案結構

 1ponytail/
 2├── hooks/                    # 核心 runtime
 3│   ├── hooks.json           # Hook 註冊(SessionStart + UserPromptSubmit)
 4│   ├── ponytail-activate.js # 啟動:注入 ruleset + 設 flag
 5│   ├── ponytail-config.js   # 設定管理(default mode, config dir)
 6│   ├── ponytail-instructions.js # Ruleset 建構器(按模式過濾)
 7│   ├── ponytail-mode-tracker.js # 偵測 /ponytail 指令切換模式
 8│   └── ponytail-runtime.js  # 跨平台 state 管理
 9├── skills/ponytail/SKILL.md # 主要 ruleset(100 行)
10├── commands/*.toml          # 5 個 slash commands
11├── benchmarks/              # promptfoo 測試框架
12├── tests/                   # 單元測試
13└── 多平台設定檔...           # .cursor/, .windsurf/, .clinerules/ 等

三段強度

Level行為範例:「加一個 API response cache」
lite照做,但提一句更懶的替代方案「Done。FYI:functools.lru_cache 一行搞定」
full(預設)強制走 Ladder,stdlib 優先@lru_cache(maxsize=1000) 加在 fetch function 上。跳過自訂 cache class」
ultraYAGNI 極端主義者「先不加 cache,profiler 說需要再加。到時候一行 @lru_cache

4. 核心邏輯詳細用法

ponytail-instructions.js — Ruleset 建構器

這是 Ponytail 的大腦。它做三件事:

  1. 讀取 SKILL.md:從 skills/ponytail/SKILL.md 載入完整 ruleset
  2. 按模式過濾filterSkillBodyForMode() 根據當前強度(lite/full/ultra)過濾表格行和範例
  3. Fallback:如果 SKILL.md 讀不到,用 getFallbackInstructions() 生成硬編碼的精簡版

關鍵設計:SKILL.md 同時服務人類閱讀和機器注入。filterSkillBodyForMode() 用 regex 偵測 | **lite** |- lite: 格式的行,只保留當前模式對應的行。

ponytail-activate.js — SessionStart 啟動流程

每次 session 開始(包括 resume / compact / clear)都會執行:

  1. ponytail-config.js 讀取 default mode(env var PONYTAIL_DEFAULT_MODE > config.json > 硬編碼 full
  2. 呼叫 getPonytailInstructions(mode) 取得 ruleset
  3. 寫入 .ponytail-active flag 檔(statusline 讀取用)
  4. 透過 writeHookOutput() 輸出 ruleset 到 agent 的 system context

ponytail-mode-tracker.js — 模式切換追蹤

每次使用者送出 prompt 都會執行。偵測 /ponytail [level] 指令:

  • 有 level → 更新 state file + 重新注入對應 ruleset
  • off → 清除 flag + 發送空指令
  • 無 level → 報告當前模式

ponytail: comment — 技術債標記

Ponytail 規則要求:每個刻意的簡化都要留 ponytail: 注解,讓簡化看起來是刻意的,不是遺漏。

1// ponytail: global lock, switch to per-account locks if throughput matters
2const lock = new Mutex();

這些注解可以用 /ponytail-debt 指令掃描,收集成技術債清單。

5. 應用場景

場景 1:日常 CRUD 開發

你說「寫一個 email 驗證函式」。沒有 Ponytail 的 agent 可能會裝 validator.js、寫 RFC 5322 正則、處理 IDN。Ponytail 會:

1import re
2def valid_email(e): return bool(re.fullmatch(r'[^@]+@[^@]+\.[^@]+', e))
3# ponytail: covers 99% of real emails. RFC 5322 parser if you handle esoteric addresses.

場景 2:前端 UI

你說「加一個 countdown timer」。Ponytail 不裝 moment.js:

1<script>
2const end = new Date('2026-01-01');
3setInterval(() => {
4  const d = Math.max(0, end - Date.now());
5  document.getElementById('timer').textContent =
6    `${Math.floor(d/864e5)}d ${Math.floor(d%864e5/36e5)}h`;
7}, 1000);
8</script>

場景 3:與其他 Skill 搭配

Ponytail 只管「寫什麼」,不管「怎麼說話」。可以搭配:

  • Caveman(terse prose skill)= 程式碼少 + 說話也少
  • 任何 coding standard skill = Ponytail 管 scope,standard 管 style

場景 4:Code Review

/ponytail-review 掃描現有 diff:

1L15: stdlib — reinvented JSON.parse error handling. Use try/catch.
2L42: yagni — ConfigFactory with one config. Inline the object.
3L78: delete — unused formatTimestamp import.
4Net: -31 lines removable.

6. 資安掃描報告

掃描範圍

掃描 hooks/skills/scripts/benchmarks/pi-extension/ 中的 JavaScript 和 Python 檔案。

掃描結果

風險等級結果
🟢 整體風險:低核心 hooks 僅做檔案讀寫和 JSON stdout,無網路呼叫、無 eval、無 shell exec

詳細發現

位置Pattern風險說明
benchmarks/correctness.jsexecSync, eval🟡 中用於 benchmark 執行測試程式碼,有 10s timeout;不在核心 runtime 中
benchmarks/model-email.jsOPENAI_API_KEY, fetch🟡 中Benchmark 工具呼叫 OpenAI API;需要使用者自行提供 key
benchmarks/robustness-audit.jsexecSync, OPENAI_API_KEY🟡 中同上,穩健性測試工具
benchmarks/claude-email.jsANTHROPIC_API_KEY, fetch🟡 中Benchmark 工具呼叫 Anthropic API
hooks/*.js (全部 5 個)fs, path, require🟢 低只做本地檔案操作,無網路、無 exec
skills/ponytail/SKILL.md純文字 ruleset🟢 低無任何可執行內容

結論

🟢 安全可用。核心功能(hooks + skills)完全本地化,不接觸網路、不執行外部指令。benchmarks/ 中有 execSync 和 API key 使用,但這些是測試工具,不在正常使用路徑中。安裝時只需 review 兩個 hooks(ponytail-activate.js + ponytail-mode-tracker.js),兩者都只做 fs.readFileSync / fs.writeFileSync + process.stdout.write

7. FAQ

Q1:需要設定檔嗎?

不需要。可選的 ~/.config/ponytail/config.jsonPONYTAIL_DEFAULT_MODE env var 可設預設強度,但什麼都不設也能用。

Q2:如果我真的需要那個 120 行的 cache class?

堅持的話,Ponytail 會建。慢慢地。正確地。同時用眼神審判你。

Q3:跟 Caveman 有什麼差別?

Ponytail 管「寫什麼程式碼」(scope),Caveman 管「怎麼說話」(prose style)。兩者可以同時開。

Q4:為什麼叫 Ponytail?

你知道為什麼。(那個留馬尾辮的資深工程師。)

Q5:強度設定會持續到什麼時候?

持續到你切換或 session 結束。跨 session 永久設定用 PONYTAIL_DEFAULT_MODE env var。

Q6:安全相關的程式碼會不會被簡化掉?

不會。Trust-boundary validation、data-loss handling、security measures、accessibility 永遠不在簡化範圍內。這是硬編碼的 carve-out。

8. 進階技巧

設定全域預設強度

1# 環境變數(推薦)
2export PONYTAIL_DEFAULT_MODE=ultra
3
4# 或 config.json
5mkdir -p ~/.config/ponytail
6echo '{"defaultMode": "ultra"}' > ~/.config/ponytail/config.json

技術債收割

定期跑 /ponytail-debt,收集所有 ponytail: 注解成清單,確保「以後再說」不會變成「永遠不做」。

Benchmark 自己跑

1cd benchmarks/
2npx promptfoo eval -c promptfooconfig.yaml

需要 python3 + pandas。GPT 模型需要 .env 裡的 OPENAI_API_KEY

開發時保持 rule copies 同步

1node scripts/check-rule-copies.js   # 檢查跨平台 rule 一致性
2npm test                              # 跑測試

9. 整合進其他工作流

CI/CD 整合

/ponytail-audit 作為 code review 的一環,自動掃描 over-engineering。

團隊 onboarding

新人入職時安裝 Ponytail,自然學會 YAGNI 原則和 stdlib-first 思維。

搭配 TDD

Ponytail 的「non-trivial logic 至少要有一個 runnable check」規則天然與 TDD 搭配:寫最少的程式碼 + 最少但足夠的測試。

10. 重點摘要 Checklist

  • Ponytail 是 AI agent 的「懶惰資深工程師」skill,讓 agent 在寫程式前先問 YAGNI
  • 核心是 6 階 Ladder:YAGNI → stdlib → native → dependency → one-line → minimum
  • 支援 13+ AI agents(Claude Code / Codex / Copilot / Gemini / Pi / OpenCode / OpenClaw / Cursor / Windsurf / Cline / Kiro / Aider / Antigravity)
  • 三段強度:lite(建議)/ full(強制,預設)/ ultra(極端)
  • 效果:80-94% 更少程式碼、3-6x 更快、47-77% 更便宜
  • 安全護欄:trust boundary / data loss / security / accessibility 永不簡化
  • ponytail: 注解標記刻意簡化,/ponytail-debt 收割技術債
  • 安裝只需兩行指令,零設定即可使用
  • 資安 🟢 低風險:核心 hooks 僅本地檔案操作

11. 進一步閱讀

資源說明
README.md官方文件
benchmarks/完整 benchmark 方法與數據
examples/5 個 before/after 範例
docs/agent-portability.md各 agent 對應檔案對照表
skills/ponytail/SKILL.md完整 ruleset 原文(100 行)
Issue #121SDK benchmark 討論:何時 Ponytail 可能增加成本
Issue #100「always-on constraint 是否犧牲 model performance」的討論