Ponytail:让 AI 编程代理少写代码的规则
Ponytail 让 AI 编程代理在第一个可行方案处停止:日期选择器基准从 404 行降至 23 行。了解其发布内容、基准结果,以及今天如何复制这套规则。
Ponytail 的定义
Ponytail 是一组规则,用于让 AI 编程代理少写代码。该项目用一句话介绍自己:“让 AI 代理像团队中最懒的资深开发者一样思考。最好的代码,就是你从未编写的代码。”它采用 MIT 许可证。它本身不包含运行时,也不会执行任何操作。它只是写入代理指令的文本:对于支持加载技能的宿主,打包为技能;对于不支持加载技能的宿主,则作为普通规则文件提供。
该仓库是 DietrichGebert/ponytail。它创建于 2026 年 6 月 12 日,并在 2026 年 8 月 1 日前获得了 90,000 个 star。截至 2026 年 8 月 1 日,最新的带标签版本是 v4.8.4,发布于 2026 年 6 月 29 日;仅 6 月 14 日至 29 日期间,发布页面就列出了 10 个标签。项目以这样的速度变化,等您阅读时内容可能已经不同。因此,在基于它构建任何内容之前,请固定一个标签。
工具之前的理念:在第一个成立的台阶处停止
Ponytail 的核心是一套决策阶梯。代理在编写任何内容前先逐级检查,并在第一个成立的台阶处停止。
- 这项功能是否真的需要存在?这就是 YAGNI(你不会需要它)。如果答案是否定的,就跳过它。
- 该功能是否已经存在于此代码库中?复用已有的辅助函数或模式。
- 标准库是否能完成这项工作?使用标准库。
- 原生平台功能是否能满足需求?使用原生平台功能。
- 已安装的依赖项是否能解决问题?使用它。
- 是否可以用一行代码完成?就写成一行。
- 只有在此之后,才编写能够工作的最少代码。
发挥作用的是这套顺序,而不是其中的某个台阶。代理收到“实现日期选择器”的要求后,就会编写日期选择器,因为它被要求这样做。这套阶梯会让它先检查第 4 个台阶,而第 4 个台阶会指出浏览器已经提供了 <input type="date">。项目自己的基准测试记录准确记录了这个案例:不使用该规则时,日期选择器最终有 404 行代码;使用该规则后只有 23 行,因为代理选择了原生输入控件,而不是构建组件。颜色选择器也出于相同原因从 287 行减少到了 23 行。
这里的“偷懒”并不意味着粗心,规则集也明确说明了这一点。“绝不在这些方面偷懒”的清单包括:在做决定前理解问题、在信任边界验证输入、防止数据丢失的错误处理、安全性、可访问性,以及用户明确提出的任何需求。规则集还要求为每段非平凡逻辑编写一个小型可运行检查。该规则限制的是自行发明,不是正确性。
仓库实际发布的内容
AGENTS.md,始终启用的规则集,用一个您可以在五分钟内读完的文件完整表达这一理念。skills/ponytail/SKILL.md,技能定义,参数提示为lite、full或ultra。.cursor/rules/和.windsurf/rules/等编辑器专用目录下的规则文件,供读取规则但不加载技能的主机使用。hooks/、benchmarks/、examples/和scripts/。
强度参数会改变规则施加约束的程度。lite 会构建您要求的内容,并在一行中给出更宽松的选项。full 是默认设置,会强制执行这一层级。ultra 是 YAGNI 的极端设置:它倾向于删除而不是添加,并且会质疑需求本身。
支持技能的主机还会获得斜杠命令。/ponytail 设置级别,/ponytail-review 检查差异中是否存在过度设计,/ponytail-audit 检查整个仓库,/ponytail-debt 收集您推迟处理的快捷项,/ponytail-gain 输出基准评分卡。只读取规则文件的主机只能获得规则集,不能使用命令。
如果您想在信任源代码前先阅读它,请克隆标签,而不是分支:
git clone --depth 1 --branch v4.8.4 https://github.com/DietrichGebert/ponytail.git在 Claude Code 上,项目改为说明插件安装方式;以下两行是截至 1 August 2026 的文档内容:
/plugin marketplace add DietrichGebert/ponytail
/plugin install ponytail@ponytail插件路径遵循默认分支,而不是标签。因此,每次会话之间,引导代理的说明可能会发生变化。这是使用更新命令所需接受的取舍。
为什么在 VPS 上使用“懒惰”的代理更省钱
代理编写的差异不会离开对话。在下一轮中,模型会再次读取它,以及代理为生成该差异而打开的每个文件。因此,500 行更改会增加会话后续每一轮的负担,而不只是生成它的那一轮。这就是为什么失控的重构会让代理随着会话进行而显得越来越慢、越来越不可靠:上下文窗口被代理自己的输出填满,留给实际代码的空间就会缩小。控制这一点,就是 管理编码代理的上下文窗口 的全部内容。
输入和输出都会计费,因此大小减半的差异会节省两次成本:生成时节省一次,之后每轮重新读取时再节省一次。如果您在自托管环境中关注费用,指令文件是一个无需额外成本即可调整的控制手段。控制 AI 代理的成本 要从输出量开始,而 编码代理如何消耗其令牌 解释了为什么重新读取的影响比人们预期的更大。
人仍然需要阅读差异。本应只有 20 行的 400 行更改会消耗审阅者的注意力,而注意力是最先耗尽的资源。没有人会像审阅当天第一份长差异那样认真地审阅第四份,因此过度构建不仅浪费时间,还会悄然降低用于发现错误的审阅质量。
在服务器上,风险更高,因为代理通常在无人监控的情况下运行。在 tmux 会话中或按计时器运行的代理,可能需要数小时才能让一个错误决策不断扩大,而您还没有发现。这正是 在 VPS 上运行编码代理 的实际风险,也是进行 循环工程 的人员如此重视常驻指令,而不是单个提示的原因。始终启用的文件中的规则会应用到第 200 轮。您在聊天中输入的规则只会应用到第 3 轮。
新依赖是另一项隐性成本。第 5 条要求使用已安装的内容。代理自行添加的每个软件包,之后都需要您进行修补,并且最终会进入从该代码库构建的每个容器镜像。
Ponytail 自身的基准测试数据说明了什么
该项目发布了两组结果,但两者相差很大。这两组数据都来自项目自身发布的结果,均不是独立测试。
The data behind this chart
[
{
"label": "Lines of code",
"single_shot_pct": 93,
"agentic_pct": 54
},
{
"label": "Cost per run",
"single_shot_pct": 63,
"agentic_pct": 20
},
{
"label": "Wall clock time",
"single_shot_pct": 74,
"agentic_pct": 27
}
]“单次生成”列来自一个基础模型:在有规则和无规则的情况下回答一小组提示词,并对 2026 年 6 月 13 日和 17 日进行的多次运行取中位数。“代理式”列来自一次无界面的 Claude Code 会话。该会话在 tiangolo 的 full-stack-fastapi-template(一个真实的 FastAPI 和 React 代码库)中处理 12 个功能工单;每个工单在 Haiku 4.5 上运行 4 次,并根据最终留下的 git diff 进行评分。
请看第二列。代理式结果的代码行数少 54%,成本低 20%,实际耗时少 27%;单次生成设置下,相同指标分别为 93% 和 74%。README 直截了当地说明了原因:单次生成基线是一个基础模型,它会“提供多个选项并附带说明”,这种任务很容易被超越。与真正执行实际工作的代理相比,优势会缩小。不过,这个结果仍然成立,而这才是更有用的信息。
项目还提出了一个限制条件,而它决定了该规则是否对您有帮助。在确实存在过度构建风险的地方,节省最明显;对于原本就已经足够精简的代码,节省接近于零。在一个 Python 和 TypeScript 代码库中测试 12 个工单,不能代表您的代码库。如果这个数字对您很重要,请使用您自己的工单,在启用和不启用该规则的情况下分别运行比较,并自行统计代码行数。
今天无需安装即可复制的模式
这个阶梯是文本,因此无需安装插件即可使用这一思路。将类似下面的代码块粘贴到代理已经读取的指令文件中,无论该文件是 AGENTS.md、CLAUDE.md,还是编辑器的规则文件。
## Before you write code
Climb this list in order. Stop at the first line that applies.
1. Does this need to exist? If not, say so and stop.
2. Does this repo already have it? Reuse the helper.
3. Does the standard library do it? Use it.
4. Does the platform do it natively? Use it.
5. Does an installed dependency do it? Use it.
6. Can it be one line? Write one line.
7. Otherwise write the minimum that works.
Never take the shortcut on: reading the code before changing it, validating
input that crosses a trust boundary, error handling that would otherwise lose
data, security, accessibility, or anything I asked for by name.
Do not add an abstraction I did not ask for. Do not add a dependency without
saying why in one line. Prefer deleting code to adding it.
Mark a deliberate simplification with a comment naming its ceiling and the
upgrade path.最后一条规则值得单独说明。Ponytail 的约定是使用带工具名称标签的注释:
# ponytail: global lock, per-account locks if throughput matters这条注释只需两行,却解决了一个本来需要一轮审查才能确定的问题。它告诉下一位读者,简单版本是经过取舍后的决定,并说明该决定在什么条件下不再适用。没有这条注释,审查者无法判断这是经过考虑的简化方案,还是代理遗漏了某些内容,因此只能提出疑问。
代码块的放置位置和内容同样重要。代理每次运行都会加载的文件会影响每次运行,包括您没有监控的运行。这正是 编写代理真正遵循的 AGENTS.md 所讨论的问题,也是该模式应放入已提交文件而不是 shell 历史记录的原因。
规则不再适用的情况
这套阶梯适用于已有代码库中的功能开发,此时通常可以复用现有代码,而且复用通常是正确的。它不太适合从零开始的项目,因为第 2 级没有可复用的内容,第 5 级也没有已安装的组件,因此代理每次都会直接落到第 7 级。它也不适合您确实需要抽象的时刻。如果您即将添加同一段复制代码的第 4 个调用方,“最短差异”会让您再复制出第 5 份。
ultra 级别会质疑您的需求。这正是该级别的作用;但如果您已经做出决定,只想完成工作,这也确实会增加成本。日常工作使用 full;如果您怀疑问题出在功能请求本身,则使用 ultra。
任何指令块都无法避免对问题的错误理解。规则集的第 1 项本身就是在做决定前理解代码,而这正是最耗时的部分,也是文本无法替您完成的部分。在错误的函数中进行最小修改,仍然是错误的修复;而且现在这个错误修复很小,更容易获批。
坦率地说,Ponytail 是一份编写得很仔细、分发得很完善并附有数字的提示词。它并不要求使用该插件。这个项目提供的是:有人正确编写了这份列表,在真实代码库中进行了测试,并将方法与结果一同发布。
FAQ
Ponytail 能与 Claude Code 以外的代理配合使用吗?
可以。它以 skill 形式提供,适用于能够加载 skill 的主机,包括 Claude Code、Codex、OpenCode、Gemini,以及 README 中列出的其他工具。Cursor、Windsurf、Cline 和 Copilot 等只能读取规则文件、但不会加载 skill 的编辑器,会从匹配的 rules 目录读取始终启用的规则集,但不会获得斜杠命令。两种方式使用的是相同文本,因此真正的区别在于:您的主机是否在每一轮都将这些文本保留在上下文中,还是仅在触发 skill 时加载。
惰性代理会跳过测试、验证或安全措施吗?
不会,规则集对此有直接说明。“绝不在以下方面偷懒”列表包括信任边界上的输入验证、防止数据丢失的错误处理、安全性和可访问性;同时要求为每段非简单逻辑提供一个可运行的小型检查。该规则取消的是凭空增加的结构:没人要求的抽象,以及没人需要的依赖。如果安装后代理开始删除测试,原因是您自己的配置中存在优先级更高的其他指令。因此,请读取代理最后加载的文件。
已发布的速度和成本数据可靠吗?
这些数据是项目自行测量并发布的,并附有测量方法;应按这一背景理解。单次执行数据是与一个仅回复选项和说明的基础模型进行比较,而 README 本身已指出这是一种较弱的基线。代理执行数据来自一次无头 Claude Code 会话,使用一个 FastAPI 和 React 代码仓库、12 个工单、每个工单运行 4 次,并使用 Haiku 4.5。这些数据对该配置而言是真实可靠的。但它们不是您代码库的预测值,因为项目还说明,对于原本已经精简的代码,节省量会接近于零。
要获得这些好处,必须安装某些东西吗?
不需要。这套规则本质上是文本。将等效内容粘贴到代理已经读取的指令文件中,即可获得大部分效果。该插件提供维护后的措辞、强度级别、审查命令和更新路径。先尝试复制的文本块,可以回答是否确实需要安装插件;这也是第 1 级方案的做法。
如何阻止无人值守的代理在夜间过度构建?
将规则放入始终启用的指令文件,而不是聊天消息中。这样它会在长时间运行的第 200 轮继续生效,而不只是在第 3 轮生效。然后单独限制风险:为代理提供一个允许其破坏的 checkout,不要提供唯一副本;并要求人工审查 diff 后才能合并。最小 diff 规则可以减少您需要阅读的内容。但它不会决定哪些更改最终合并,也不应由它决定。