让 AI agent 拥有
懒人 senior 的判断力
一个 SessionStart + UserPromptSubmit 双 Hook 注入的行为约束层——在模型每次开口写代码之前,逼它先过一遍「这真的需要写吗」的六步决策梯。结果:80-94% 更少代码、3-6× 更快、47-77% 更便宜。
「懒」不是缺陷,是方法论
Ponytail 解决的是一个所有大模型都有的系统性偏差:模型倾向于过度构建——你要一个日期选择器,它装 flatpickr、套组件、加样式表、讨论时区。你说「加缓存」,它写一个带 TTL 的类。
「你认识他。长马尾,椭圆眼镜。在公司待得比版本控制还久。你给他看 50 行代码;他看了一眼,什么也不说,用一行替换掉。」
Ponytail 把这个「沉默 senior」的思维模式编码成一套可执行的行为约束——不是系统 prompt,不是 few-shot 示例,而是一套在每次代码生成前都必须走的决策梯,以及每行代码产出后「什么可以跳过、什么时候该加回来」的标注规范。
它的核心洞察是:模型在「想清楚不写」和「写出来」之间的决策成本不对称——写出来容易,停下来难。Ponytail 用 Hook 把「停下来」的门槛变低,把「写之前先想」变成默认行为。
Stop at the first rung that holds
每写一行代码之前,先问自己这六个问题,能在第几步停就在第几步停。
这个梯子和 YAGNI / DRY / SOLID 一样是老生常谈,但模型从来不会自发地执行它——它们看到需求就开工,因为「完成」比「判断」更容易被评估。Ponytail 把这个梯子变成每次响应的第一个 token 之前必须经过的强制路径。
functools.lru_cache、JS Intl.DateTimeFormat、Go regexp.MustCompile……<input type="date"> 替代整个日期选择器库。ponytail:当故意走捷径时,必须用注释标注。「// ponytail: global lock, per-account locks if throughput matters」——把天花板和升级路径写进注释,让接手的人(或者下一个 agent)知道这个简化是有意的、已知局限的、有方向的。
强度分级对应不同的「梯子严格程度」:
| 模式 | 行为 |
|---|---|
| lite | 建完要建的,但告诉用户「其实一行就行」——用户决定是否回退 |
| full | 梯子强制执行。Stdlib 和原生优先。最短可工作代码。默认。 |
| ultra | YAGNI 原教旨主义。先发一行,再质疑其余需求。删除优于添加。 |
| review | 独立模式。用于 code review 场景——只看别人的代码,标注在哪里可以懒。 |
SessionStart × UserPromptSubmit:双生命周期钩子
Ponytail 用两个生命周期事件在不同时间点注入约束——SessionStart 保证「启动即激活」,UserPromptSubmit 追踪用户对模式的实时调整。
SessionStart Hook
匹配 startup | resume | clear | compact 时触发。激活 Ponytail 模式,将 skill 内容注入当前会话上下文。Node.js ponytail-activate.js 负责把 skill body 拼接进系统 prompt。
UserPromptSubmit Hook
每次用户提交 prompt 时触发。ponytail-mode-tracker.js 解析 /ponytail lite|full|ultra|off 命令和「stop ponytail」/「normal mode」关键词,更新持久化状态。
// 支持 Claude Code · Codex · Copilot,三平台共用同一 hooks.json
{
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear|compact",
"hooks": [
{
"type": "command",
"command": "command -v node >/dev/null 2>&1 && node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-activate.js\" || exit 0",
"commandWindows": "if (Get-Command node ...) { node ... }",
"timeout": 5,
"statusMessage": "Loading ponytail mode..."
}
]
}
],
"UserPromptSubmit": [...]
}
}
三平台兼容的关键是同一个 hooks.json——Ponytail 在 .claude-plugin/、.codex-plugin/、.opencode/ 各有一份副本,平台启动时加载自己的。跨平台时行为完全一致,不存在「在 Claude Code 里用得好在 Codex 里降级」的问题。
Windows 支持同样精心打磨——Shell 命令用 POSIX command -v 检测 Node 存在性,Windows 端用 Get-Command node -ErrorAction SilentlyContinue 做等效检测,逻辑完全等价。
三平台同一状态文件:跨厂商的 Mode 追踪
ponytail-runtime.js 是 Ponytail 的状态引擎——在 Claude Code、Codex、Copilot 三套完全不同的插件 API 之间,它用同一份 ~/.claude/.ponytail-active 状态文件实现模式跨会话持久化。
const STATE_FILE = '.ponytail-active';
const isCopilot = Boolean(process.env.COPILOT_PLUGIN_DATA);
const isCodex = Boolean(process.env.PLUGIN_DATA);
// Claude Code → ~/.claude/ Codex → $PLUGIN_DATA Copilot → $COPILOT_PLUGIN_DATA
let stateDir = getClaudeDir();
if (isCodex) stateDir = process.env.PLUGIN_DATA;
if (isCopilot) stateDir = process.env.COPILOT_PLUGIN_DATA;
function writeHookOutput(event, mode, context) {
if (isCopilot) {
// Copilot: additionalContext on SessionStart
process.stdout.write(JSON.stringify({ additionalContext: context }));
return;
}
if (isCodex) {
// Codex: systemMessage prefix + hookSpecificOutput
process.stdout.write(JSON.stringify({
systemMessage: `PONYTAIL:${mode.toUpperCase()}`,
hookSpecificOutput: { hookEventName: event, additionalContext: context }
}));
return;
}
// Claude Code: plain text output
process.stdout.write(context);
}
这是一个被严重低估的设计细节——三个插件 API 的 Hook 输出格式完全不同:
- Claude Code:直接写 stdout 文本,追加到上下文中
- Codex:JSON
systemMessage前缀 +hookSpecificOutput结构化字段 - Copilot:只读
additionalContext,其他字段全部忽略
同一套代码通过 process.env 探测平台,自动切换输出形状——这让用户换平台时零迁移成本,mode 状态完整携带。
// 优先级:环境变量 → 配置文件 → 默认值
function getDefaultMode() {
// 1. PONYTAIL_DEFAULT_MODE 环境变量
if (envMode && VALID_MODES.includes(envMode)) return envMode;
// 2. XDG_CONFIG_HOME/ponytail/config.json 或平台默认值
const config = JSON.parse(fs.readFileSync(configPath));
// 3. 'full'
return DEFAULT_MODE; // = 'full'
}
off · lite · full · ultra · review
Ponytail 不是非开即关的二值开关——它有五个模式,对应不同的「懒度」,用户可以随时切换,模式名本身就是命令。
模式切换通过两种途径:
- 用户命令:
/ponytail lite、/ponytail full、/ponytail ultra、/ponytail off、/ponytail-review - 关键词检测:「stop ponytail」或「normal mode」自动关闭
- 环境变量:
PONYTAIL_DEFAULT_MODE=ultra覆盖配置文件
切换后状态写入 .ponytail-active 文件,下次 SessionStart 时恢复该模式——不会因会话重启而丢失。
ponytail-instructions.js 的 filterSkillBodyForMode() 在注入前按模式过滤 SKILL.md 内容——lite/full/ultra 在同一个文件里通过表格行和示例标签做分支,同一个文件支持三个强度的内容,按需注入不同文本。review 模式是独立 skill(/ponytail-review),因为它的行为与其他三个完全不同。
不只是主技能:五个配套 Skill
Ponytail 不只是一个行为规范——它是一个以「懒」为核心的技能矩阵,五个 Skill 覆盖开发全生命周期。
ponytail
主技能——六步决策梯 + 三级强度。激活即生效,/ponytail lite|full|ultra 切换。
ponytail-help
「这能懒吗?」——给定一个需求,告诉用户用平台特性 / stdlib / 一行替代的方案。
ponytail-debt
标记代码中的「懒债」——哪些 ponytail: 注释存在但还没补升级路径。
ponytail-audit
审计模式——扫描项目中所有 ponytail: 注释,生成「技术债 → 升级路径」清单。
ponytail-review
Code review 技能——review 别人的 PR 或代码片段,标注在哪里可以更懒,提供升级建议。
这五个技能组合覆盖了一个完整生命周期:
开发时 ponytail 强制约束 → ponytail-help 实时查替代方案 → Review 时 ponytail-review 挑过度工程 → 合并后 ponytail-audit 建懒债清单 → ponytail-debt 跟踪偿还进度。
有数字的懒:Promptfoo 实证
不是营销语言,是可复现的 Promptfoo benchmark。三个模型(Haiku / Sonnet / Opus),五个日常任务,十次中位数。
| 指标 | Arm | Haiku | Sonnet | Opus |
|---|---|---|---|---|
| 代码行数 | baseline | 518 | 693 | 256 |
| caveman | 116 | 120 | 67 | |
| ponytail | 39 | 44 | 51 | |
| API 成本(5 任务) | baseline | $0.032 | $0.141 | $0.135 |
| ponytail | $0.010 | $0.032 | $0.071 | |
| 延迟(秒) | baseline | 37.7 | 124.1 | 58.7 |
| ponytail | 9.9 | 20.1 | 18.0 |
↑ ponytail vs baseline 代码削减幅度
correctness.js 提取 fenced code block 并执行真实检查(email/debounce/CSV 用 Node/Python 跑,React/FastAPI 用结构化正则)。一个得分好看但跑不通的代码会被标记为 FAIL——「少代码」不等于「错代码」。
任务:email validator、JS debounce、CSV sum、React countdown timer、FastAPI rate limiter。都是典型「模型会过度工程化」的场景。
结果在所有模型、所有任务上稳定胜出——不是一个巧合,是「强制决策梯」这一简单约束在概率上的必然胜利。
13 个 Agent,一个 Ponytail
不绑定任何一家厂商——通过插件化架构,Ponytail 同时覆盖 Claude Code、Codex、Copilot、OpenClaw、OpenCode、Pi、Windsurf 等 13 个平台。
支持方式分三类:
- 官方插件目录:Claude Code
/plugin marketplace add、Codexcodex plugin marketplace add、Copilotcopilot plugin marketplace add - OpenClaw / OpenCode / Pi:通过
.openclaw/、.opencode/、pi-extension/适配层集成 - 其他:Cody / Windsurf / Continue / Gemini extension 通过通用 skill 格式或 API 挂载
在「能力」和「克制」之间搭桥
Ponytail 的出现回答了一个大模型应用里被忽视的问题:模型的能力上限不是问题,模型的过度建设惯性才是。
2025-2026 年,所有主流 coding agent 都经历了同样的轨迹:能力越来越强,输出越来越长,过度工程化越来越严重。用户想要一个「过滤重复字符串」,模型装了 lodash。用户要「当前时间」,模型写了 moment.js 初始化。这不是模型笨——这是强化学习训练信号里「完成任务」和「写得多」高度相关的历史包袱。
Ponytail 的解法优雅在于:它不修改模型,不微调,不改 API,只改输入时的约束。通过 Hook 在「模型准备开口」和「模型真的开口」之间插入一个 gate——六步决策梯。这个 gate 成本极低(几毫秒的 Node.js),效果可测量(promptfoo benchmark),适用范围极广(13 个平台)。
它还带来了一个意外的工程价值:ponytail: 注释本身就是一份「已知技术债 → 升级路径」的元数据。传统技术债的问题是「未来某天会有人想起来修」,ponytail-debt 把这个问题变成了「升级路径已经在代码里」,reviewer 可以直接看到哪些简化是有意的、哪些是历史遗留。
对 coding agent 生态来说,Ponytail 是一个行为规范层面的基础设施——不是又一个 code agent,而是一种让所有 code agent 变得更高效的通用约束协议。
「写之前先问:需要写吗?标准库能搞定吗?平台特性覆盖了吗?已装依赖能解决吗?一行够吗?只有最后才写。」