Ponytail: 治一治 AI Agent 的"过度设计病",实测少 54% 代码

2026年6月21日

低难度,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 无规则基线LOCtokenscosttimesafe
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 — 死代码 / 投机性 feature
  • stdlib — 重新发明标准库
  • 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 Codemarketplace
Codexmarketplace + hooks
OpenCodeplugin + opencode.json
OpenClawclawhub
Gemini CLIextension
Pipi install
Copilot CLIplugin✅(带 ponytail: 命名空间)
Cursor.cursor/rules/❌(只读规则)
Windsurf.windsurf/rules/
Cline.clinerules/
Kiro.kiro/steering/
AiderAGENTS.md
ZedAGENTS.md
CodeWhaleAGENTS.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 — 总 token
  • cost — 美元
  • 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 / Codexalways-on(plugin + hook)
OpenCodealways-on(plugin)
Cursor / Windsurf / Clinealways-on(rules 文件)
Gemini CLIalways-on(extension)
Pi / Aider / Zedalways-on(AGENTS.md)
只能用 MCP prompt 菜单的桌面 AppMCP(手动触发)
完全自定义的 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 砍单价。

Updated 2026年6月21日
    Ponytail: 治一治 AI Agent 的"过度设计病",实测少 54% 代码 | OpenClaw API 文档中心 - 开源 AI 助手集成指南