Ponytail 成本验证实战:用 promptfoo 复现并审计"42–75% 更便宜"的开销声明
本文基于 ponytail 仓库中一份真实的成本验证报告(2026-06-17),完整拆解其实验设计、复现命令、成本采集口径与全部结果数据:以三个实验臂(no-skill / caveman / ponytail)、五个日常编码任务、每格 30 次重复的 promptfoo 评测,验证 ponytail 技能在 Claude 上"42–75% 更便宜"的开销结论,并解释为什么该结论在 OpenAI 推理模型上会反转。读完你可以掌握一套"声明 → 可复现实验 → 数据审计 → 结论修正"的完整方法论,并能直接照仓库配置跑出自己的数字。
背景:为什么要重新验证"47–77% 更便宜"
ponytail 的项目卖点是用一句"最懒资深工程师"的系统提示词(完整规则在 skills/ponytail/SKILL.md)让 Agent 写出更短的代码。早期单轮基准中,README 头条曾宣称 ponytail 比无技能基线"47–77% 更便宜"。但声明会随模型版本、价格与缓存策略漂移,因此仓库于 2026-06-17 做了一次全新复现来给这个数字背书,并额外增加 OpenAI 与 Gemini 两个厂商臂,测试这个结论"能走多远"。
验证的目标很明确:
- 用当前模型与当前价格重新测量,确认区间是否仍然成立;
- 把范围从 Claude 扩展到 OpenAI,看跨厂商是否一致;
- 同步验证正确性(correctness)是否付出代价。
实验设计:三臂、五任务、中位数口径
三个实验臂(arms)
Claude 侧是完整的三臂对比(无技能、caveman、ponytail),OpenAI 侧是基线对 ponytail 两臂。每个臂本质是一个 promptfoo 的 prompt 函数:
- benchmarks/arms/baseline.js 最简,只发一条 user 消息(任务本身),不带任何系统提示;
- benchmarks/arms/ponytail.js 直接读取仓库自己的
skills/ponytail/SKILL.md全文作为 system 消息——注释里明确这是 "Single source of truth"(唯一事实来源),即评测用的规则集与用户实际安装到 Agent 里的技能是同一份文件,避免"评测配置与发布技能漂移"; - benchmarks/arms/caveman.js 使用 vendored 的 caveman 技能(MIT 许可的散文压缩类技能,保留"正常"代码、主要压缩文字),作为中间参照臂。
五个日常任务
三套厂商配置(benchmarks/promptfooconfig.yaml、benchmarks/promptfooconfig.gpt-newest.yaml、benchmarks/promptfooconfig.gemini.yaml)使用完全相同的五道任务,保证可比性:
- 写一个 Python 邮箱校验函数;
- 用原生 JavaScript 写可复用的
debounce(fn, delay); - 写 Python 代码读取
sales.csv并对amount列求和; - 构建一个从给定秒数倒数的 React 倒计时组件;
- 给 FastAPI 端点加限流,防止被刷。
这是刻意选择的"日常任务"集:基线 Agent 在这类任务上会自然过度工程化(加多余抽象、注释、防御代码),从而放大差异;benchmarks/README.md 的 Notes 也说明,生产级规格下无约束 Agent 的膨胀会更严重,那是 results/ 里其他报告的主题。
被测模型
- Claude(benchmarks/promptfooconfig.yaml):
claude-haiku-4-5-20251001、claude-sonnet-4-6、claude-opus-4-8,统一max_tokens: 8192, temperature: 1; - OpenAI(benchmarks/promptfooconfig.gpt-newest.yaml):
gpt-5.5(顶配)、gpt-4.1-mini、gpt-5.4-mini; - Gemini(benchmarks/promptfooconfig.gemini.yaml):
gemini-3.5-flash、gemini-3.1-pro-preview,需要.env里的GOOGLE_API_KEY。
成本与指标的采集口径
- 成本来自 promptfoo 的 API 遥测(
response.cost),不是按 token 数事后换算; - 聚合方式:每个任务先取重复次数内的中位数成本,再把五个任务的中位数相加,得到"5 tasks"总成本。中位数口径让单次 API 波动不会污染结论;
- 重复次数:Claude 侧三次运行池化(pooling)为每格 30 次重复;OpenAI 侧 10 次重复(原因见下文缓存问题);
- 正确性是硬门禁:断言脚本 benchmarks/correctness.js 提取围栏代码块后真正 spawn Python/Node 执行(邮箱、debounce、CSV 三道题为运行时执行校验;React 倒计时与 FastAPI 限流为结构性正则检查,benchmarks/README.md 对此有明确标注);配套的 benchmarks/loc.js 只统计非空非注释代码行(LOC),永远通过、仅作测量。这意味着"更便宜"的前提是"没坏"——一个写崩的一行代码在 LOC 上得分再高也会被判错。
如何复现
报告给出的复现命令(需要 .env 中配置对应厂商的 API key,并满足 benchmarks/README.md 所述前置条件:Python 3、pandas、Node.js ≥ 22.22.0——这是 promptfoo 引擎的版本约束):
npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml --env-file .env --repeat 10
npx promptfoo@latest eval -c benchmarks/promptfooconfig.gpt-newest.yaml --env-file .env --repeat 10
注意 --env-file 必须显式指定:promptfoo 从当前工作目录读取 .env,而 key 文件放在仓库根目录(benchmarks/README.md 专门解释了这一点)。原始评测 JSON 被 gitignore、可随时再生,报告只保留聚合后的数字——这也是仓库"数字可再生"的审计思路。
Claude 结果:区间成立,但两端各偏乐观几个点
三臂 × 三模型池化 30 次重复后,5 个任务的总成本(USD)如下:
| model | baseline | caveman | ponytail | ponytail vs baseline |
|---|---|---|---|---|
| Haiku | 0.0299 | 0.0139 | 0.0110 | 63.1% cheaper |
| Sonnet | 0.1367 | 0.0458 | 0.0348 | 74.5% cheaper |
| Opus | 0.1368 | 0.0724 | 0.0789 | 42.3% cheaper |
结论与原始声明的对照:
- 复现区间是 42–75% 更便宜,方向完全成立,但与公布的 47–77% 相比,下限(Opus 42%)与上限(Sonnet 75%)各乐观了约 5 个百分点;
- 时延同样成立:ponytail 比基线 3.1–5.8x 更快,落在 README 宣称的 "3–6x" 之内;
- 正确性零代价:ponytail 在三个 Claude 模型上全部 100%。反过来,无技能基线在 Claude Sonnet 上掉到 76%——报告注明那是一个真实的过度工程化 bug(校验函数返回了 dict 而不是 bool),恰好印证了正确性门禁存在的意义:基线的"更便宜的代码"里混进了坏代码。
一个值得注意的结构性细节:caveman 臂在 Haiku/Sonnet 上明显优于 ponytail,但在 Opus 上(0.0724 vs 0.0789)反而略输。从 benchmarks/README.md 的 Notes 可以解释:caveman 是散文压缩技能(代码保持"正常"),优势主要在省文字 token;ponytail 直接砍代码行,在便宜的小模型上省输入/输出更彻底,在贵的 Opus 上两者差距被基线的过度生成摊薄。
OpenAI 结果:声明在推理模型上反转
OpenAI 侧 10 次重复的数据:
| model | baseline | ponytail | ponytail vs baseline | latency | correctness |
|---|---|---|---|---|---|
| gpt-4.1-mini | 0.0026 | 0.0015 | 39.6% cheaper | 2.5x faster | 100% |
| gpt-5.4-mini | 0.0060 | 0.0075 | 26.2% more expensive | 1.5x faster | 100% |
| gpt-5.5 | 0.0714 | 0.0990 | 38.7% more expensive | 0.9x (slower) | 100% |
反转的机制在报告里说得很直白:规则集在每次调用时都作为输入重新发送(always-on system prompt),而推理模型的基线输出本身已经很短,省下的几行代码抵消不了固定的输入开销加上推理 token 的额外消耗。从 run 1 反推的有效每 token 单价佐证了这一点:gpt-5.5 约 $5/$30(每百万输入/输出 token),gpt-5.4-mini $0.75/$4.50,gpt-4.1-mini 约 $0.13/$1.61——在 gpt-4.1-mini 上输出便宜($1.61/M),省代码就能赢;在 gpt-5.5 上输出极贵($30/M)但基线输出本来就只有几百 token,固定输入税反超了节省。
由此得出的适用范围结论:这个开销数字是关于"在 Claude 上做代码生成"的结论,不是跨厂商的普适承诺。在 OpenAI 的推理模型上——包括最新的顶配 gpt-5.5——ponytail 更贵而不是更便宜。
方法论细节:为什么 OpenAI 只有 10 次重复
这是这份报告里最见功力的一段。OpenAI 第 2、3 次运行无法池化,原因是 OpenAI 的自动 prompt 缓存:对完全相同的重复 prompt,API 把 token 遥测报为 cached,且 prompt/completion/cost 全部归零,成本数据直接失真,只有 run 1 有效。Claude 侧之所以能干净地池化到 30 次,是因为 Anthropic 的缓存是显式开启(opt-in)、默认不触发。
10 次重复的数字是否稳定?报告用一次独立的更早的 10 次运行做了交叉验证,两批数据相差约 4 个百分点以内(gpt-4.1-mini:35.7% vs 39.6%;gpt-5.4-mini:贵 28.7% vs 贵 26.2%),足以说明结论不是单次噪声。
Gemini:挂起,且说明了原因
Gemini(gemini-3.5-flash 对标 mini、gemini-3.1-pro-preview 对标 top)的结果标记为 Pending:30 次重复的运行中途撞上了 Google AI Studio 免费层 600 请求/天的配额上限,数据被污染(部分请求失败/截断),因此整组作废,推迟到配额刷新日重跑。这一条体现了报告的数据卫生原则:宁可留白也不发布被污染的数字——对一篇以"验证数字"为主题的文档来说,这一点和主结果同等重要。
结论与建议
报告的 Takeaway 可以归纳为三条:
- 方向成立,幅度微调:Claude 上池化复现区间为 42–75% 更便宜,所有 Claude 模型上更快,且无正确性代价;建议把 README 头条从 "47–77% cheaper" 改为 "42–75% cheaper",并保留 "Claude" 这个范围限定;
- 跨厂商结论反转:OpenAI 推理模型上(含最新 gpt-5.5)ponytail 成本更高。任何引用该数字的场景都应声明厂商与任务类型前提;
- 这是单轮生成成本数字,不是会话成本承诺:benchmarks/README.md 的 Notes 中同样强调,这些是 single-shot 调用数据,真实多轮 Agent 会话里规则集会反复重注入、每轮都要"爬梯子",单次会话成本可能高于也可能低于这些数字,prompt 缓存会部分抵消重注入开销。
从当前仓库状态看,这条建议已经被采纳:benchmarks/README.md 的汇总表已标注 "cost re-verified at 30 runs, 2026-06-17",成本表数字(0.011 / 0.035 / 0.079)与本报告完全一致,且头条改为"costs 42–75% less"。
数据卫生备注
- 1350 次 Claude 重复(3 臂 × 3 模型 × 5 任务 × 30 次)中有约 22 次因瞬时空响应被丢弃,未计入中位数——在该样本量下影响可忽略;OpenAI 运行 100% 完整;
- 复现一律从已提交的配置出发:
promptfooconfig.yaml(Claude)、promptfooconfig.gpt-newest.yaml(OpenAI)、promptfooconfig.gemini.yaml(Gemini),原始评测 JSON 不进版本库、可再生。
这套验证方法可以复用的要点
剥离掉具体数字,这份报告提供了一套可迁移的"声明审计"流程:
- 声明与实验同源:被测臂直接读取发布的技能文件(benchmarks/arms/ponytail.js 注释中的 single source of truth),杜绝"评测配置 ≠ 用户实际拿到物"的漂移;
- 正确性是门禁而非附带指标:benchmarks/correctness.js 对可执行任务真实运行代码,使"更便宜/更短"永远不会与"坏了"同时成立;
- 理解遥测失真源:厂商缓存策略(OpenAI 自动缓存归零遥测 vs Anthropic 显式开启)直接决定能否池化重复,做成本基准前必须确认这一点;
- 用中位数 + 独立批次交叉验证替代均值 + 单次运行,并如实记录丢弃样本数(22/1350)与配额污染(Gemini 600/天);
- 区分"单轮生成成本"与"会话成本",在结论中显式声明适用范围(Claude、单轮、五类日常任务),防止数字被过度外推。
这套流程同样适用于任何需要为 LLM 技能、提示词工程或模型选型给出可辩护数字的团队:先写清口径,再跑复现,最后让结论与数据逐字对齐。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00