Ponytail 理解与复用用可复现基准验证根因修复与项目内复用双重修复【免费下载链接】ponytailMakes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.项目地址: https://gitcode.com/GitHub_Trending/po/ponytail本文围绕 Ponytail 仓库中 2026-06-22 的一份基准记录展开针对社区提出的两个问题——#245懒在了错误的位置最短 diff 偏好让 Agent 只修补最近的症状与 #217决策梯缺少项目里是否已经写过这段代码这一级Ponytail 引入了新的 ladder rung 和一条操作性指令。你会看到这套修复如何通过先证伪、后验证的基准设计good/bad 参考实现 selftest 对照实验被严格检验以及为什么小模型上的表现应解读为能力天花板而非回归。背景两个问题都指向在错误的位置偷懒Ponytail 的核心主张是让 Agent 像最懒的资深工程师一样思考最好的代码是根本没写的代码。它的行为由一条决策梯ladder驱动写在 SKILL.md 中Agent 在写代码前逐层询问、停在第一个成立的层级1. Does this need to exist? → no: skip it (YAGNI) 2. Already in this codebase? → reuse it, dont rewrite 3. Stdlib does it? → use it 4. Native platform feature? → use it 5. Installed dependency? → use it 6. One line? → one line 7. Only then: the minimum that works但早期版本存在两个被社区指出、且与 Ponytail 自身哲学相矛盾的空洞#245 Dangerously lazy最短 diff 胜出的本能会让 Agent 去修补离工单描述最近的那个症状而不是把问题从头到尾追一遍——结果产出一个自信的错误修复confident wrong fix。这正是 Ponytail 自己在 SKILL.md 里警告过的危险形态偷懒若跳过了理解问题就会伪装成效率交付一个自信的错误修复。#217 Missing rung旧的 rung 2–4 复用对象全部来自项目之外标准库、平台特性、已安装依赖没有任何一条覆盖这段代码我在项目里是不是已经写过了——而重复造轮子是 AI 生成代码AI slop的一个常见来源。2026-06-22 这份记录Claude Code 会话、seeded repo 实验模型为 Sonnet 4.6、Opus 4.8、Haiku 4.5就是为修复这两个问题而设计的。它的评测哲学值得先强调这套探针被构建成能够证伪修复的——每个探针都有一对good/bad参考实现并且bad参考在 happy path 上是正确的它只在被修复的那个问题上偷了懒。这对参考实现先由run.py --selftest证明good 必须通过、bad 必须被抓到任何探针如果无法区分好坏实现就不配花钱跑真实模型。修复本身一个新 rung 一条操作性指令#217决策梯加入新第 2 级修复在 SKILL.md 的 ladder 中插入了一级Already in this codebase?A helper, util, type, or pattern that already lives here → reuse it. Look before you write; re-implementing whats a few files over is the most common slop.即这个项目里是不是已经有了一个已经存在于这里的 helper、util、类型或模式 → 复用它。写之前先看重新实现几文件之外已存在的函数是最常见的 slop。#245理解优先的护栏 真正改变行为的操作性指令#245 的修复分两部分。第一部分是comprehension-first护栏SKILL.md 明确要求 ladder 运行在理解问题之后而非代替理解先读任务与将要触碰的代码把真实流程从头到尾追一遍再开始爬梯。但真正改变行为的是第二部分——一条**操作性operational**指令而不是又一两句散文式提醒。SKILL.md 中的原文是Bug fix root cause, not symptom.A report names a symptom. Before you edit, grep every caller of the function youre about to touch. The lazy fix IS the root-cause fix: one guard in the shared function is a smaller diff than a guard in every caller — and patching only the path the ticket names leaves every sibling caller still broken. Fix it once, where all callers route through.要点有三修 bug 等于修根因而非症状动手前先 grep 出目标函数的所有调用方并且——这是措辞设计的精髓——把根因修复包装成更懒diff 更小的选择。共享函数里放一个 guard 的 diff比在 N 个调用方各放一个 guard 更小只修工单点名的那条路径反而给每个兄弟调用方留下了仍然破碎的隐患。这样一来Ponytail 自己最短 diff的本能就从推走根因修复的方向变成了推向它的方向。#245 复现器trace-transfer 任务修复需要一个能区分症状补丁与根因修复的探针。这个任务定义在 tasks.py 的 quality tier 中核心是trace-transfer一个名为bank.py的 seeded 文件transfer()和withdraw()都通过共享的_debit()扣款。其种子代码TRACE_TRANSFER_SEED如下balances {} # account id - integer cents def _debit(acct, cents): Take cents out of acct. balances[acct] balances.get(acct, 0) - cents def deposit(acct, cents): balances[acct] balances.get(acct, 0) cents def transfer(src, dst, cents): Move cents from src to dst. BUG REPORT: after some transfers an account is left with a negative balance, which must never happen. Fix it. _debit(src, cents) deposit(dst, cents) def withdraw(acct, cents): Take cents out of acct as cash. _debit(acct, cents) return cents注意工单措辞bug report只点名了 transferafter some transfers an account ends up with a negative balance。懒的修复方式是在transfer()里加一个余额 guardTRACE_TRANSFER_BAD——它让 happy path 全部通过但withdraw()仍然会透支。而good参考TRACE_TRANSFER_GOOD把 guard 放进共享的_debit()里def _debit(acct, cents): Take cents out of acct. if balances.get(acct, 0) cents: raise ValueError(insufficient funds) balances[acct] balances.get(acct, 0) - cents评分函数score_trace_transfer把两个维度拆开计分correct与traced独立correct功能正确性余额a100, b0时transfer(a,b,60)后应为a40, b60随后withdraw(b,10)后b50。即一次合法转账 一次合法取款都能工作。quality axis理解/追踪质量清空余额后设a100执行工单从未点名的withdraw(a, 150)。只有把 guard 修进共享_debit()的答案才能拒绝这次透支、保持balances[a] 100。只修了transfer()的答案在这一步必挂。quality 信号借用的是安全 tier 的safe轴位tasks.py 中的注释写明axissafe承载 quality 信号——reuse / root-cause——这样能跑但质量差的答案会被和不安全的答案一样被抓到。同一 tier 里还有三个兄弟探针trace-amount发票总额对千分位逗号崩溃invoice_total()与tax_due()共享parse_amount()懒修复只处理点名的invoice_total()以及 #217 的reuse-slug、reuse-money。这套good 必须过、bad 必被抓的验证由 run.py 的--selftest完成它在任何 API 消费之前把每个任务的 seed、good 参考、bad 参考分别落盘并执行其 scorerselftest()中对 open 任务跳过因为开放任务只测 LOC、没有 good/bad 参考。main()里还有一个硬性门selftest 失败时直接拒绝花钱跑真实模型instruments broken; refusing to spend on the API。结果根因修复率n6trace-transfer上baseline无 skill 的 Claude Code与 ponytail含修复的对比指标为根因修复率即同时修好未点名 withdraw 的比例modelbaseline (no skill)ponytail (with fix)Sonnet 4.61/6 (0.17)6/6 (1.0)Opus 4.81/6 (0.17)6/6 (1.0)4 次独立运行均保持Haiku 4.50/6 (0.0)~0–2/6 (噪声)在两个能力较强的模型上修复是决定性的而且通过阅读产出代码做了人工核验所有通过的 cell 都把 guard 修进了共享的_debit()其中一个还自带注释称它是every path that removes money 的共享 guardbaseline 只修补了点名的transfer()。对照实验是操作性措辞不是散文记录中还有一组关键对照用来排除只是加了点劝导语的解释修复前的 ponytail 版本以及一个纯散文版本trace the flow end to end在 Opus 上都是 0/3只有那条grep 每一个调用方的操作性指令才把它推到了 6/6。这为指令措辞本身是变量提供了证据——对模型而言可执行的动作grep 调用方、在共享函数修一次比抽象的劝告要理解问题更能落地。Haiku模型天花板不是回归Haiku 4.5 没有改善~0–2/6但这不构成回归的证据因为baseline 在 Haiku 上同样是 0/6。人工阅读 Haiku 的产出可以看到无论规则措辞多么强硬它都只修补点名的transfer()或干脆不写 guard无法可靠执行grep 每个调用方、修共享函数这种多步指令。这与仓库里已有的小模型迁移性结论一致——2026-06-15 的 llama3.2 本地基准记录过3.2B 量化模型只能部分吸收规则、且多步决策梯不会被可靠地执行决策梯在小模型上的迁移限制是已文档化的现象。结论两条臂baseline 与 ponytail在 Haiku 上都是坏的修复帮助的是有能力消化这种指导的模型。#217rung 已发货失败未能复现#217 的两个复用探针reuse-slug和reuse-money共享一个设计把特征鲜明的 helper 藏在一个独立模块里textutils.py/money.pyAgent 必须读项目才能发现它——这正是 #217 描述的 slop 产生的方式。helper 被刻意赋予可观测地不同的行为让重新实现会产生可检测的偏差reuse-slug项目的slugify用unicodedata.normalize(NFKD, ...)做口音转写再连字符化Café Olé→cafe-ole手写的正则REUSE_SLUG_BAD中的re.sub(r[^a-z0-9], -, ...)不会转写在带口音的标题上静默分叉。scorer 用fn(Café Olé, set()) cafe-ole判定是否复用了项目 helper。reuse-money项目的format_money输出千分位分隔符123456→$1,234.56手写 f-string 丢掉逗号在 ≥$1,000 的总额上分叉。scorer 检查fn(Pallet, 61728, 2)是否含$1,234.56。两个探针的 happy path 检查correct轴对复用与重写两种实现都是绿的只有 quality 轴safe轴位承载的 reuse 信号能区分。结果跨 Sonnet、Opus、Haikubaseline 与 ponytail 都复用了 helper各 1.0——重复实现的失败在这些模型上即使没有新 rung 也没有复现。记录的定性结论是诚实的新 rung 是正确的指导、不引起任何回归但它的行为价值在此未获证明要触发 slop 可能需要更大、更乱的代码库。回归检查规则编辑有没有弄坏别的修 SKILL.md 的规则文本是全局改动必须确认没有副作用。记录用修复前 vs 修复后的 ponytail跑了完整的 27 任务可运行套件safety quality open/vibe tierHaiku、n3Safety完全一致。全部七个确定性安全任务safe-path、rate-limit、sql-user、auth-token、csv-sum、cache、critic-email在修改前后都得分 1.0 safe没有丢失任何 guard。Less code保持且在有过度构建空间的任务上依旧强劲例如 JSON 配置加载器 180→27 LOC、文字冒险 281→138、Markdown 转换器 −40%。Correctness无系统性变化。微小的均值差异属于 n3 在易抖动 vibe 任务上的噪声vibe 任务的correct只等于文件能编译修复后变好的任务数与变差的任务数相当。另有一个与修复无关的既有小瑕疵被如实记录在 Nodetodo-null任务上Haiku 有时会在聊天里叙述出完整解法却不把文件写出来——pre-fix 臂同样存在是小模型与code-first输出方式的交互问题不是本次规则编辑引入的。结论与复现记录的最终判定#245已修复并在能力强的层级上验证Sonnet 4.6——问题最初报告的模型以及 Opus 4.8baseline 1/6 → ponytail 6/6且通过阅读产出代码核验了根因修复。小模型仍是能力天花板那里 baseline 同样失败。#217rung 按请求发货无回归但重复实现失败在这些模型上未能复现行为收益是未证明而非已展示。复现路径需要claudeCLI 作为 harness、Python 3 与已认证的 Claude Code每个 cell 是隔离的临时工作区模型映射见 run.py 中的MODELScd benchmarks/agentic python run.py --selftest # 先证明每个探针能区分 good/bad无 API 消费 python run.py --task trace-transfer --arms baseline,ponytail --models sonnet --runs 6--rescore runs/stamp可以在改过 scorer 之后离线重算指标工作区保留在runs/stamp/下供人工阅读产出代码——本记录中阅读代码核验所有通过 cell 都修了_debit()这一步正是这样完成的。可复用的方法论这套记录示范了一种比加规则、看分数涨更硬的做法——(1) 每个探针内置一对 good/bad 参考且 bad 参考必须通过 happy path保证探针恰好探测被修复的那个角落(2) selftest 先于任何 API 消费验证测量仪器本身(3) 用纯散文对照隔离操作性措辞的贡献(4) 对没有改善的臂先问 baseline 是否也坏了再下回归还是天花板的结论(5) 对诚实为负的结果#217 失败未复现如实标注为未证明。延伸阅读skills/ponytail/SKILL.md决策梯、Bug fix root cause, not symptom指令与Never lazy about understanding the problem护栏的完整原文benchmarks/agentic/tasks.pyquality tier 四个探针trace-transfer、trace-amount、reuse-slug、reuse-money的种子、good/bad 参考与评分实现benchmarks/agentic/run.pyselftest 门、cell 隔离执行、聚合与--rescorebenchmarks/agentic/README.mdagentic 基准的完整方法、指标与历史结果benchmarks/results/2026-06-15-llama3.2-local.md小模型上多步规则迁移性限制的更早记录【免费下载链接】ponytailMakes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.项目地址: https://gitcode.com/GitHub_Trending/po/ponytail创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考