低难度,10 分钟上手 1 小时跑完首个 benchmark,治一治你的 AI 写代码"刹不住车"的毛病。
前言
你有没有这种经历——让 Claude Code 写个日期选择器,它一本正经地装上 flatpickr,写一个 wrapper 组件,加一份 CSS,开始跟你讨论时区处理,最后交给你 287 行。
你想说的是"我要个能选日期的输入框",它给你交付了一个"日期选择框架"。
这就是 AI Agent 的"过度设计病":模型被训练成"看起来很专业",于是它会自动加抽象层、加配置项、加错误处理、加测试覆盖——而你要的可能就一个 <input type="date">。
Ponytail 就是来治这个病的。它由 Dietrich Gebert 开源,核心理念就一句话:「最好的代码,是从未被写出来的代码」。
Ponytail 不是模型,不是 IDE 插件,它是一套「懒人高级工程师」风格的规则集。它给 AI 装上一条 6 阶梯子:
1. 这个东西真需要写吗? → 不需要:跳过 (YAGNI)
2. 标准库能不能干? → 用它
3. 平台原生能力能不能干? → 用它
4. 已经装好的依赖能不能干? → 用它
5. 一行代码能不能干? → 写一行
6. 实在不行:写满足需求的最小代码
在 tiangolo 的 full-stack-fastapi-template 真实仓库上、12 个 feature ticket、n=4、Haiku 4.5 的对照实验里,Ponytail 拿到了这份成绩单:
| vs 无规则基线 | LOC | tokens | cost | time | safe |
|---|---|---|---|---|---|
| Ponytail | -54% | -22% | -20% | -27% | 100% |
| 裸 "YAGNI + 一行" prompt | -33% | -14% | -21% | -30% | 95% |
| caveman (硬缩短 prompt) | -20% | +7% | +3% | +2% | 100% |
Ponytail 是唯一所有指标都往下掉的方案,也是唯一砍代码不丢安全性的方案。颜色选择器从 287 行砍到 23 行、日期选择器从 404 行砍到 23 行——因为它直接用了浏览器自带的 <input type="color"> 和 <input type="date">。
它兼容 14 个 AI 编程工具:Claude Code、Codex、Cursor、Windsurf、Cline、Copilot CLI、Aider、Kiro、Zed、CodeWhale、OpenCode、Pi、Gemini CLI、OpenClaw。今天我们就把这套规则装进 Claude Code,30 秒治好你 Agent 的"过度设计病"。
目标读者
- 日常用 AI Agent 写代码的 1-5 年开发者
- 觉得"AI 写代码太长、装了一堆用不到的依赖"的体感派
- 想给团队统一编码风格、但又不想写死板 ESLint 规则的人
- 关注 AI 编程成本、token 账单肉疼的小老板 / Tech Lead
核心依赖与环境
- Node.js 18+(必须,Ponytail 的 lifecycle hook 用 Node 跑;nvm 用户注意要装到非交互 shell 的 PATH 上)
- 一个支持的 AI Agent(演示用 Claude Code)
- 一个 LLM API Key(演示用 Defapi 的 Claude Haiku 4.5,半价)
- 可选:Python 3.10+(跑 benchmark 时用到 pandas)
- 可选:Git(克隆仓库)
TIP
关于 API Key 成本:Ponytail 本身开源免费。但你要让 AI Agent 跑起来,就得烧 token。如果你也在意账单,我强烈建议用 Defapi——它提供官方半价的 Claude、GPT、Gemini 全系列,接口完全兼容 OpenAI / Anthropic 协议,换个 base URL 就行。下面的教程会演示怎么切过去。
完整项目结构
ponytail/
├── AGENTS.md # 核心规则(被所有 agent 共读的"懒人哲学")
├── README.md / README.es.md # 中英西三语 README
├── package.json # pi-agent 包定义
├── commands/ # 6 个 slash command
│ ├── ponytail.toml # /ponytail [lite|full|ultra|off]
│ ├── ponytail-review.toml # /ponytail-review(砍当前 diff)
│ ├── ponytail-audit.toml # /ponytail-audit(扫整个仓库)
│ ├── ponytail-debt.toml # /ponytail-debt(收账 ponytail: 注释)
│ ├── ponytail-gain.toml # /ponytail-gain(看 benchmark 成绩单)
│ └── ponytail-help.toml # /ponytail-help
├── skills/ # 6 个 skill 镜像
│ ├── ponytail/ # 主规则
│ ├── ponytail-review/ ... # 其余 5 个
├── hooks/ # Claude / Codex 生命周期 hook
│ ├── ponytail-config.js # 模式解析(env + config.json)
│ └── ponytail-instructions.js
├── ponytail-mcp/ # MCP server 适配(给 MCP-only 主机用)
│ ├── index.js
│ ├── instructions.js
│ └── test/
├── examples/ # 12 个真实"过度设计 vs 一行"对比
│ ├── date-picker.md / color-picker.md(web 内置)
│ ├── deep-clone.md(structuredClone)
│ ├── debounce.md
│ ├── email-validation.md(75 行 → 3 行)
│ └── ... 共 12 个
├── benchmarks/ # promptfoo + agentic 基准
│ ├── promptfooconfig.yaml # 单轮基准
│ ├── benchmark-local.py # agentic 真实仓库基准
│ ├── agentic/ # 12 个 ticket 脚本
│ └── results/2026-06-18-agentic.md # 完整数据
├── docs/
│ ├── agent-portability.md # 哪个 agent 装哪个文件
│ └── platform-native.md
├── .openclaw/ # OpenClaw 适配 skill(自动生成)
├── .cursor/ .windsurf/ # Cursor / Windsurf 规则文件
├── .clinerules/ # Cline 规则
├── .kiro/steering/ # Kiro 规则
└── tests/ # 规则一致性的测试
手把手教程
步骤 1: 装 Ponytail 到 Claude Code
Ponytail 在 Claude Code 里就是一个 plugin marketplace,30 秒搞定。
# 把 Ponytail 仓库加到你的 plugin marketplace 列表
/plugin marketplace add DietrichGebert/ponytail
# 安装主 skill(一次会话装一次)
/plugin install ponytail@ponytail
装完开一个新会话,startup 文字会显示当前模式(默认 full)。你会看到类似这样的输出:
Ponytail v0.1.0 [full] Lazy senior dev mode active
1. Need to build? 2. Stdlib? 3. Platform? 4. Installed dep?
5. One line? 6. Minimum that works.
WARNING
nvm / Nix 用户注意:Claude Code 的 lifecycle hook 跑在非交互 shell 里,Node 必须在那个 shell 的 PATH 上。如果你用 nvm,确保在 ~/.zshrc 或 ~/.bashrc 里 source 了 nvm。光在当前终端能跑 node -v 没用。
如果你想换强度,输入:
/ponytail lite # 轻拍模式(保护 1-2 阶梯)
/ponytail full # 默认
/ponytail ultra # 强删模式(连一层抽象都不放过)
/ponytail off # 关掉
/ponytail # 不带参数 = 显示当前档位
也可以持久化:
# 永久默认 ultra
export PONYTAIL_DEFAULT_MODE=ultra
或者写一份 config:
// ~/.config/ponytail/config.json
// Windows: %APPDATA%\ponytail\config.json
{ "defaultMode": "ultra" }
步骤 2: 跑一个反例对比
我们直接看效果。准备两个完全一样的 prompt:
Prompt A(关闭 Ponytail):先 /ponytail off,然后问
Add a color picker to the settings page
你会得到大约 287 行的回答:装一个 react-color 或自己造个 5 文件组件、加 prop 验证、加 onChange 节流、加无障碍 label、加 CSS 变量。
Prompt B(打开 Ponytail):先 /ponytail full,同样的话再问一次。
你会得到:
// ponytail: browser has one
<input type="color" />
一行。完事。
Ponytail 的 AGENTS.md 里就写了这一段核心规则(原文):
Before writing any code, stop at the first rung that holds:
1. Does this need to be built at all? (YAGNI)
2. Does the standard library already do this? Use it.
3. Does a native platform feature cover it? Use it.
4. Does an already-installed dependency solve it? Use it.
5. Can this be one line? Make it one line.
6. Only then: write the minimum code that works.
注意最后一行:「Only then」——它不是不让你写,是要你先走完前 5 步。
步骤 3: 用 Defapi 跑通,省一半 token 钱
Ponytail 帮你砍代码量,但要跑 AI Agent 本身,你得给 Claude / GPT 烧 token。Defapi 提供官方半价的 Claude / GPT / Gemini,接口完全兼容。
我们切到 Defapi 跑一个 benchmark:
步骤 3.1:拿 Defapi Key
去 defapi.org 注册、拿一个 dk-xxx 开头的 key,写到 Ponytail 的 .env:
# 在 ponytail 仓库根目录
cat > .env <<'EOF'
ANTHROPIC_API_KEY=dk-你的defapi-key
ANTHROPIC_BASE_URL=https://api.defapi.org
EOF
步骤 3.2:直接用 curl 验证能用
curl -s https://api.defapi.org/api/v1/messages \
-H "Authorization: Bearer dk-你的defapi-key" \
-H "content-type: application/json" \
-d '{
"model": "anthropic/claude-haiku-4.5",
"max_tokens": 256,
"messages": [
{"role": "user", "content": "用一个 emoji 描述 ponytail 这个词"}
]
}'
返回:
{
"id": "msg_01H...",
"role": "assistant",
"content": [{"type": "text", "text": "🦄 (它根本不该出现)"}],
"usage": {"input_tokens": 22, "output_tokens": 12}
}
步骤 3.3:让 promptfoo 走 Defapi
Ponytail 自带 promptfoo 基准,编辑 benchmarks/promptfooconfig.yaml:
providers:
- id: anthropic:messages:anthropic/claude-haiku-4.5
config:
baseURL: https://api.defapi.org
apiKey: ${ANTHROPIC_API_KEY}
跑:
npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml
TIP
Defapi 关键事实:
- 接口兼容
v1/chat/completions(OpenAI 协议) - 接口兼容
v1/messages(Anthropic 协议) - 接口兼容
v1beta/models/(Gemini 协议) - 同一个
dk-key 走遍 Claude / GPT / Gemini - 价格示例:Claude Sonnet 4.5 官方 $3 / $15,Defapi $1.5 / $7.5;Claude Haiku 4.5 官方 $1 / $5,Defapi $0.5 / $2.5
省下来的钱(按 Ponytail benchmark 的 12 个 ticket × n=4 = 48 次跑的体量估算):
| 模型 | 官方成本 / 月 | Defapi 成本 / 月 | 省下 |
|---|---|---|---|
| Claude Sonnet 4.5 | ~$60 | ~$30 | $30 |
| Claude Haiku 4.5 | ~$20 | ~$10 | $10 |
| Claude Opus 4.5 | ~$250 | ~$125 | $125 |
Ponytail 砍 20% 成本,Defapi 再砍 50%,两个一起开 = 实际账单打 4 折。
步骤 4: 跑 /ponytail-review 砍当前 diff
光靠 Ponytail 在写入时把关还不够——你已经有了一坨"过度设计"的存量代码。这时候用 review 命令:
# 在一个有改动的仓库里
/ponytail-review
它只审当前 git diff,输出格式是固定的:
L12: delete unused `cache` parameter; no caller passes it
L34: stdlib Array.prototype.sort is stable since ES2019; drop `lodash.orderby`
L88: native `URLSearchParams` covers this; remove custom `parseQuery`
L102: yagni `BaseRepository` has one implementation; inline it
L150: shrink loop into `arr.filter(x => x.active).map(x => x.id)`
---
Net removable: 47 lines, 1 dependency
Tag 体系:
delete— 死代码 / 投机性 featurestdlib— 重新发明标准库native— 已有依赖干的活 / 平台原生能干yagni— 只有一个实现的抽象层shrink— 同逻辑但行数更少
最后一行给你"净可删行数"——这就是你的 tech debt 量化指标。
如果输出是 Lean already. Ship.,说明你的代码已经够瘦了,可以安心 merge。
步骤 5: 跑 /ponytail-audit 扫整个仓库
review 看 diff,audit 看全树。
/ponytail-audit
输出格式类似,但按"砍得最多"排序:
delete src/utils/cache.ts (412 lines) — only used in 1 place; inline
stdlib src/utils/deep-clone.ts — use structuredClone
native src/components/DatePicker/ (287 lines) — <input type="date">
yagni src/repositories/BaseRepository.ts (180 lines) — 1 impl, inline
shrink src/api/users.ts:42-78 — same logic, 60 → 18 lines
---
Net removable: 1,247 lines, 4 dependencies
实操建议:先 review 再 audit。review 改 diff、合并,audit 帮你排下一波清理的优先级。
步骤 6: 在其他 Agent 里启用
Ponytail 的核心优势就是"一次规则,到处生效"。它给每个主流 AI 编程工具都准备了适配文件:
Codex(CLI 模式)
codex plugin marketplace add DietrichGebert/ponytail
codex
# 打开 /plugins → 选 Ponytail → 安装
# 打开 /hooks → 信任两个 lifecycle hook → 开新线程
Cursor
直接把 .cursor/rules/ponytail.mdc 拷到你的项目里:
cp .cursor/rules/ponytail.mdc ~/your-project/.cursor/rules/
或者全局:
cp .cursor/rules/ponytail.mdc ~/.cursor/rules/
Windsurf
cp .windsurf/rules/ponytail.md ~/.codeium/windsurf/memories/
GitHub Copilot CLI
copilot plugin marketplace add DietrichGebert/ponytail
copilot plugin install ponytail@ponytail
OpenClaw(如果你已经在用)
# 最优雅的一条命令
clawhub install ponytail
或者手动复制:
cp -r .openclaw/skills/ponytail ~/.openclaw/skills/
Gemini CLI
gemini extensions install https://github.com/DietrichGebert/ponytail
Pi / Aider / Kiro / Zed / CodeWhale
这些 agent 直接读 AGENTS.md:
# 项目级
cp AGENTS.md ~/your-project/AGENTS.md
# 全局(pi / Aider / CodeWhale 都能识别)
cp AGENTS.md ~/.pi/AGENTS.md
完整对照表(摘自项目 docs/agent-portability.md):
| Agent | 装载方式 | 是否支持 /ponytail 命令 |
|---|---|---|
| Claude Code | marketplace | ✅ |
| Codex | marketplace + hooks | ✅ |
| OpenCode | plugin + opencode.json | ✅ |
| OpenClaw | clawhub | ✅ |
| Gemini CLI | extension | ✅ |
| Pi | pi install | ✅ |
| Copilot CLI | plugin | ✅(带 ponytail: 命名空间) |
| Cursor | .cursor/rules/ | ❌(只读规则) |
| Windsurf | .windsurf/rules/ | ❌ |
| Cline | .clinerules/ | ❌ |
| Kiro | .kiro/steering/ | ❌ |
| Aider | AGENTS.md | ❌ |
| Zed | AGENTS.md | ❌ |
| CodeWhale | AGENTS.md | ❌ |
| GitHub Copilot (editor) | .github/copilot-instructions.md | ❌ |
步骤 7: 跑你自己的 benchmark
Ponytail 的真实数据不是拍脑袋的,是 benchmarks/benchmark-local.py 跑出来的。你也可以挑 5 个自己的真实任务复现一下:
步骤 7.1:准备 prompts
编辑 benchmarks/prompts.json(或用现成的 5 个):
[
{ "id": "date-picker", "task": "Add a date picker to the settings page" },
{ "id": "color-picker", "task": "Add a color picker to the settings page" },
{ "id": "email-validate", "task": "Write a Python function that validates email addresses" },
{ "id": "deep-clone", "task": "Deep clone this object: {sample}" },
{ "id": "debounce", "task": "Write a debounce function in JavaScript" }
]
步骤 7.2:跑三个 arm 对照
# baseline:什么都不加
npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml
# ponytail:加了 skill 的 plugin arm
PONYTAIL_DEFAULT_MODE=full npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml
步骤 7.3:看结果
输出 benchmarks/output.json,包含每个 prompt 在每个 arm 下的:
loc— 代码行数tokens— 总 tokencost— 美元time— 端到端时间passed_safety— 是否通过安全测试(输入验证、错误处理、a11y)
通常 ponytail arm 在 LOC 上比 baseline 少 50-80%。
步骤 8: 跑 ponytail-mcp(高级)
如果你的 AI host 只能用 MCP(比如某些桌面 App),Ponytail 也有 MCP server 适配:
cd ponytail-mcp
npm install
node index.js # 启动 stdio MCP server
在 host 的 MCP 配置里加:
{
"mcpServers": {
"ponytail": {
"command": "node",
"args": ["ponytail-mcp/index.js"]
}
}
}
它暴露:
- Prompt
ponytail:返回规则文本,可选mode参数(lite / full / ultra) - Tool
ponytail_instructions:同上,但带structuredContent,给 code-execution 风格的 host 用
WARNING
MCP 模式是"用户手动调用"的——你在 prompt 菜单里点它一次,它就生效一次。它不是"每轮自动注入"。如果你需要 always-on 行为,请用 Claude Code / Codex 的 plugin 模式,而不是 MCP。
常见问题排查
Q1:装完没反应,startup 文字不显示?
99% 是 Node 不在非交互 shell 的 PATH。验证:
# 这个要在新 shell 里跑(模拟非交互)
bash -lc 'node -v' # bash
zsh -lc 'node -v' # zsh
如果返回 command not found,把 nvm source 写到 ~/.bashrc / ~/.zshrc,或者直接装 system Node:
# macOS
brew install node@20
# Windows
winget install OpenJS.NodeJS.LTS
Q2:"我就要那个 120 行的 cache 类"——强需求时怎么办?
两种解法:
# 临时关掉
/ponytail off
# 或局部允许:直接在 prompt 里说
"Build a 120-line cache class, ignore ponytail for this task"
Ponytail 是个规则集不是镣铐,模型收到显式 override 会听。
Q3:Ponytail 跟 ESLint / Prettier 冲突吗?
不冲突,分工不同:
- Ponytail:管"该不该写"——有没有这个抽象、有没有装这个依赖、有没有写这个 wrapper
- ESLint:管"写得对不对"——命名、风格、未使用变量
- Prettier:管"格式好不好看"——缩进、分号、换行
三个一起开效果最好。Ponytail 在最上游决定代码长啥样,ESLint / Prettier 在下游保证细节。
Q4:团队怎么统一规则?
AGENTS.md 是仓库级文件,提交到 git 就行:
# 在你团队仓库的根目录
curl -o AGENTS.md https://raw.githubusercontent.com/DietrichGebert/ponytail/main/AGENTS.md
git add AGENTS.md
git commit -m "chore: adopt ponytail team-wide coding rules"
所有读 AGENTS.md 的 agent(CodeWhale、Aider、Zed、Pi、Kiro、Codex extension)都会自动遵守。
Q5:Ponytail 会让安全测试退化吗?
不会,这是 Ponytail 在 benchmark 里最关键的一项指标。对比表里 baseline / caveman / Ponytail 都是 100% 安全通过,只有裸 "YAGNI + 一行" prompt 掉到 95%。
Ponytail 的 AGENTS.md 里专门写了一段:
Not lazy about: input validation at trust boundaries, error handling that prevents data loss, security, accessibility, the calibration real hardware needs.
翻译:懒不懒,看地方。业务逻辑、UI 包装能省就省;输入校验、错误兜底、安全、a11y 不许省。
Q6:怎么在 CI 里跑?
把 /ponytail-review 的逻辑抽成一个独立脚本(Ponytail 仓库的 benchmarks/correctness.test.js 给了一个参考实现),然后:
# .github/workflows/ponytail.yml
name: ponytail
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: node scripts/ponytail-review.js origin/main
env:
ANTHROPIC_API_KEY: ${{ secrets.DEFAPI_KEY }}
ANTHROPIC_BASE_URL: https://api.defapi.org
PR 里失败 = 当前 diff 让 Ponytail 觉得"还能再瘦"。
Q7:MCP 模式 vs always-on 模式,我该选哪个?
看你的 host:
| Host 类型 | 推荐模式 |
|---|---|
| Claude Code / Codex | always-on(plugin + hook) |
| OpenCode | always-on(plugin) |
| Cursor / Windsurf / Cline | always-on(rules 文件) |
| Gemini CLI | always-on(extension) |
| Pi / Aider / Zed | always-on(AGENTS.md) |
| 只能用 MCP prompt 菜单的桌面 App | MCP(手动触发) |
| 完全自定义的 agent 框架 | MCP + tool 模式 |
扩展阅读 / 进阶方向
Ponytail 的哲学根源
- Rich Hickey 的 "Simple Made Easy" 演讲(Clojure 之父谈"易"和"简单"的区别)
- Sandi Metz 的 "The Magic Tricks of Testing"(最小化测试覆盖的原则)
- Ted Neward 的 "Thirty Years of 'WTF'"(讽刺企业代码膨胀)
- 6 阶梯子的另一面表述:Coad 的 "Just Enough Architecture"
自己写 ponytail 风格的注释
ponytail: 注释是给"未来读到这段代码的开发者"留的便条。约定格式:
// ponytail: <理由>,<已知限制 / 升级路径>
例子:
# ponytail: stdlib re 模块够用,没必要装 email-validator
# 已知限制:不验证 RFC 5322 全部边缘情况;如需支持 [email protected] 的 edge case,换 email-validator
import re
def is_valid_email(email: str) -> bool:
return bool(re.match(r'^[^@]+@[^@]+\.[^@]+$', email))
/ponytail-debt 命令会扫所有 ponytail: 注释生成一份 tech debt ledger,"later" 不会变 "never"。
集成到团队 Code Review 流程
把 /ponytail-review 当 lint 跑,PR 模板里加一条:
## Ponytail review
- [ ] Ran `/ponytail-review` on this diff
- [ ] Net removable lines: ___
- [ ] If > 0, justification: ___
完整 benchmark 数据
benchmarks/results/2026-06-18-agentic.md 是 12 个 ticket × 3 个 arm × 4 轮跑的完整方法学 + 局限说明。值得读,特别是 "fair agentic baseline" 的部分——之前 80-94% 的"单轮神话"是 conversational baseline 的人为放大,54% 才是诚实的数字。
关于 Ponytail 的边界
Ponytail 砍代码的前提是"代码正确"。它不验证:
- 业务逻辑是否对(这个你得自己写测试)
- 性能是否够(O(n²) 的 ponytail 注释里会标,但不会自动改)
- 边界 case 是否覆盖(lazy 注释会列,不会替你加测试)
它是个起点,不是终点。装上 Ponytail 之后,AI 写的代码少了,但你 review 的负担也轻了——这两件事是同一个硬币的两面。
最后一句话总结:Ponytail 不是"少写代码",是"先问一句要不要写"。
下一步推荐:用 Defapi 拿一个半价 Claude key,配合 Ponytail 跑一遍你自己的真实任务——你会发现账单上砍掉的那 60%,一半来自 Ponytail 砍 token、一半来自 Defapi 砍单价。