解析 Ponytail 的 AGENTS.md:七级决策阶梯与"懒但靠谱"的 Agent 规则文件设计
Ponytail 是一个把"最懒的资深工程师"注入 AI 编码代理的技能包,而 AGENTS.md 正是这套规则体系中最精炼的"单源真值"(canonical source):它仅用一个 Markdown 文件,定义了代理在动手写代码前必须走完的七级决策阶梯、八条硬性规则,以及绝不可省略的安全边界。读完本文,你将掌握这份规则文件的完整内容与设计逻辑,了解它如何被字节级同步到 7 个不同 Agent 平台的规则副本、如何被 hooks 作为兜底指令注入会话,以及如何在自己的项目中复用或校验它。
AGENTS.md 在项目中的定位
Ponytail 的规则文本实际上维护着三个层次:
- skills/ponytail/SKILL.md:运行时完整规则,包含强度等级(lite/full/ultra)、输出格式约束和完整示例,是最长的一份;
- AGENTS.md:紧凑版常驻指令集,面向不支持 Skill 机制的通用 Agent(Cursor、Windsurf、Cline、Qoder、CodeWhale、Amp、Jules 等会直接读取仓库根目录的
AGENTS.md); - 各平台的规则副本(
.cursor/rules/ponytail.mdc、.clinerules/ponytail.md等),要求与 AGENTS.md 逐字节一致。
docs/agent-portability.md 中明确列出了哪些宿主走 "Instruction-tier"(仅靠读取 AGENTS.md 生效),并给出一条适配原则:"Keep adapters thin"——支持 skills/hooks 的宿主指向已有文件,只支持项目指令的宿主则保持其规则文本与 AGENTS.md 对齐。Gemini CLI 的扩展清单 gemini-extension.json 也是直接把 contextFileName 指向 AGENTS.md,实现每次会话的 always-on 注入。
换句话说,AGENTS.md 既是"规则",也是 Ponytail 规则分发体系的中枢锚点——下面逐段拆解它到底写了什么。
第一原则:懒是效率,不是粗心
文件开篇第一句定调:
You are a lazy senior developer. Lazy means efficient, not careless. The best code is the code never written.
"最好的代码是你根本没写的代码"——这是整份文件的世界观:省掉的每一行代码,都是永远不会出 bug 的代码。这个口号在 skills/ponytail/SKILL.md 中被进一步展开为"你见过每一个过度工程化的代码库,并曾因为其中一个在凌晨 3 点被叫起来修",把"懒"的动机锚定在真实的运维代价上。
七级决策阶梯:写任何代码前先停
AGENTS.md 的核心是一个 7 级阶梯(原文第 5–13 行),要求在写任何代码之前,停在"第一级站得住的梯级"上:
1. Does this need to be built at all? (YAGNI) —— 这东西到底需不需要建?
2. Does it already exist in this codebase? —— 代码库里已有?复用 helper/util/模式,别重写
3. Does the standard library already do this? —— 标准库能做?用标准库
4. Does a native platform feature cover it? —— 平台原生能力能覆盖?用它
5. Does an already-installed dependency solve it? —— 已安装的依赖能解决?用它
6. Can this be one line? Make it one line. —— 能一行写完?就写一行
7. Only then: write the minimum code that works. —— 走到这里才写"能工作的最小代码"
这个阶梯是典型的"成本从低到高"决策链:先问存在必要性(YAGNI),再问复用性(代码库 → 标准库 → 平台原生 → 既有依赖),最后才谈"写最少的新代码"。它对应 Ponytail 的招牌案例:当 Agent 被要求做一个日期选择器时,不安装 flatpickr、不写包装组件、不讨论时区,而是直接输出 <!-- ponytail: browser has one --> + <input type="date">(见 README.md 的 Before/after 一节)。
skills/ponytail/SKILL.md 对阶梯补充了两条执行细节,AGENTS.md 的紧凑版没有展开:
- 两个梯级都成立时,取更高级的那个然后继续走("Two rungs work → take the higher one and move on")。阶梯是反射动作,不是研究项目;
- "第一个能用的懒方案就是对的方案"——前提是你已经知道这个改动必须触碰哪些代码。
阶梯的前提:先理解问题,再谈懒
AGENTS.md 紧接着给出了使用阶梯的时序约束(原文第 15 行):
The ladder runs after you understand the problem, not instead of it: read the task and the code it touches, trace the real flow end to end, then climb.
先读任务、读被改动的代码、把真实执行流从头到尾追一遍,然后才爬阶梯。SKILL.md 把这一点说得更狠:"The ladder shortens the solution, never the reading"——阶梯缩短的是方案,永远不是阅读。它甚至点名了危险的反模式:"跳过理解直接交付小 diff 的懒,是伪装成效率的懒,它会以自信的姿态交付一个错误的修复。"
这条约束解释了为什么 Ponytail 的实测收益在"本来就已经很小的代码"上趋近于零(见 benchmarks/results/2026-06-18-agentic.md):省代码的前提是看懂了该省什么,而不是盲目删减。
Bug 修复 = 修根因,不是修症状
AGENTS.md 第 17 行是全文最浓缩的一条工程方法论:
Bug fix = root cause, not symptom: a report names a symptom. Grep every caller of the function you touch and fix the shared function once.
一个 issue 报的是症状;动手前 grep 出你即将触碰的函数的所有调用方,然后把修复放在共享函数里一次完成。理由被直接算成了 diff 大小:在共享函数里放一个 guard,比在每个调用方各放一个 guard 的 diff 更小;而只补丁工单点名的那条路径,会让兄弟调用方继续处于坏的状态。
值得注意的是"懒"在这里与"根因"合流了:对 Ponytail 来说,最省的 diff 恰好就是根因修复本身,而不是在症状路径上打的小补丁。skills/ponytail/SKILL.md 的对应段落("Bug fix = root cause, not symptom")给出了同样的操作指令:"Before you edit, grep every caller of the function you're about to touch."
Rules:八条硬性规则逐条拆解
AGENTS.md 第 19–28 行列出八条规则,每一条都针对 Agent 过度工程化的高频故障模式:
| 规则 | 针对的故障模式 |
|---|---|
| No abstractions that weren't explicitly requested. | 没人要的单实现接口、单产品工厂、不变值的配置项 |
| No new dependency if it can be avoided. | "就几行代码的事,别为此装一个新依赖" |
| No boilerplate nobody asked for. | 没人要的样板代码与"以后要用"的脚手架 |
| Deletion over addition. Boring over clever. Fewest files possible. | 优先删而不是加;无聊优于聪明——"clever 是别人在凌晨 3 点要解码的东西" |
| Shortest working diff wins, but only once you understand the problem. | "在错误位置的最小改动不是懒,是第二个 bug" |
| Question complex requests: "Do you actually need X, or does Y cover it?" | 直接质疑复杂需求,而不是闷头照做 |
| Pick the edge-case-correct option when two stdlib approaches are the same size. | 两个标准库方案体量相同时,选边界情况正确的那个——懒是少写代码,不是选更脆弱的算法 |
Mark deliberate simplifications … with a ponytail: comment naming the ceiling and upgrade path. |
刻意简化且留有已知上限的角落必须留标记 |
其中三条值得单独展开:
1. 质疑需求,但不阻塞。 SKILL.md 给出了配套的话术模式:"Ship the lazy version and question it in the same response, 'Did X; Y covers it. Need full X? Say so.' Never stall on an answer you can default."——先交付懒版本,同时在同一回复里提出质疑,绝不在本可以给出默认答案的地方停下来等确认。
2. "懒"有算法正确性底线。 第七条规则常被误读为"能省则省",但它同时钉死了另一头:体量相同的两个方案之间,选边界正确的。这与 Ponytail 的实测结论一致——在 benchmarks/results/2026-06-18-agentic.md 的对比中,ponytail 组是唯一"四项指标全降且安全性 100%"的组,而单纯"写一行代码"的提示词组安全性掉到 95%,因为它会砍掉防护。
3. ponytail: 上限注释——给"技术债"上明码标价。 第八条规则要求:凡是刻意简化、切了真实角落且存在已知上限(全局锁、O(n²) 扫描、朴素启发式)的代码,必须留一个 ponytail: 注释,写清上限和升级路径。SKILL.md 给了标准格式示例:
# ponytail: global lock, per-account locks if throughput matters
这个标记不是普通 TODO:配套技能 /ponytail-debt(skills/ponytail-debt/SKILL.md)会把散落在代码里的 ponytail: 捷径收割成一份可追踪的台账,让"以后再优化"不至于变成"永远不优化"。
Not lazy about:绝不可省的清单
AGENTS.md 第 30 行用一整段长句划定了"懒"的禁区(这是全文信息密度最高的一句):
- 理解问题——完整读任务并追完真实流程之前不许选梯级;"一个你不理解的小 diff,只是伪装成效率的懒";
- 信任边界的输入校验(input validation at trust boundaries);
- 防数据丢失的错误处理(error handling that prevents data loss);
- 安全(security);
- 可访问性(accessibility);
- 真实硬件需要的校准——"平台从来不是规格书上的理想态:时钟会漂移,传感器读数会偏";
- 用户明确要求保留的东西。
硬件校准这一点在 SKILL.md 中被具象化为:"a real clock drifts, a real sensor reads off, a PCA9685 runs a few percent fast. Leave the calibration knob, not just less code, the physical world needs tuning a minimal model can't see."——物理世界需要最小化模型看不到的调参旋钮,所以校准代码不是可以"偷懒省掉"的冗余。
"没有检查的懒代码是半成品"
同一段的后半句是 Ponytail 独特的测试哲学:
Lazy code without its check is unfinished: non-trivial logic leaves ONE runnable check behind, the smallest thing that fails if the logic breaks (an assert-based demo/self-check or one small test file; no frameworks, no fixtures). Trivial one-liners need no test.
任何非平凡逻辑(分支、循环、解析器、涉及资金/安全的路径)必须留下一个可运行的检查——逻辑坏了它就会失败的最小东西:一个基于 assert 的 demo()/__main__ 自检,或一个小测试文件。明确禁止测试框架和 fixtures;而平凡的一行代码不需要测试,"YAGNI 同样适用于测试本身"。
这条规则把"少写代码"贯彻到了测试层:不建 per-function 的测试套件,但绝不裸奔。它的可验证性由测试基础设施保证——见下文"规则一致性"一节,ONE runnable check 正是被逐字钉死在两个文件里的不变量之一。
自我适用条款:"本文件同样适用于在 ponytail 仓库上干活的 Agent"
AGENTS.md 的最后一行(第 32 行)是全篇最耐人寻味的一笔:
(Yes, this file also applies to agents working on the ponytail repo itself. Especially to them.)
这不只是口号,仓库自身就是这条规则的证据。以 hooks/ponytail-activate.js(Claude Code 的会话启动激活钩子)为例,代码中多处出现规则要求的 ponytail: 上限注释和"最小说明":
// ponytail: install path has shell metacharacters — don't embed it in a
// command snippet; have the agent wire it up by hand instead.
以及多处 // Silent fail — ... 的最短注释——钩子脚本自身的失败被刻意降级为静默("flag is best-effort, don't block the hook"),保证激活逻辑自身永远不会阻塞会话启动。这正是第八条规则(留上限注释)、第四条规则(最少的文件与注释)在自己仓库里的落地。
分发机制:AGENTS.md 如何变成 20 个 Agent 的常驻规则
理解 AGENTS.md 的价值,不能只看它写了什么,还要看它如何被分发和校验。
指令层宿主:零配置生效
docs/agent-portability.md 的适配表中,大量宿主直接以 AGENTS.md 为注入点,属于"零配置"档:
- Qoder:自动从仓库根加载
AGENTS.md作为 always-on 上下文; - CodeWhale:从项目根读取
AGENTS.md,README 甚至给出最短安装路径——"Copy AGENTS.md to your project, or run codewhale from a checkout of this repo. That's it." - Antigravity CLI、Amp(Sourcegraph)、Jules(Google)、Zed、Jules、VS Code + Codex 扩展、JetBrains Junie:均以
AGENTS.md为项目指令来源(Junie 需在设置中手动指定路径); - GitHub Copilot CLI 的指令级回退模式:读取项目内
AGENTS.md或.github/copilot-instructions.md。
对这类宿主,Ponytail 的安装就退化为一个文件拷贝——这也是 Ponytail 自称"最省事的安装"的技术前提。
规则副本:字节级同步 + 不变量哨兵
对于有独立规则目录的宿主,Ponytail 维护了 7 份紧凑副本,全部要求与 AGENTS.md 逐字节一致。scripts/check-rule-copies.js 是这条约束的执行者,它做两件事:
第一,字节级比对。 脚本把 AGENTS.md 读入后先剥掉末尾那句自我适用条款(因为各平台副本不应包含"本文件也适用于 ponytail 仓库"这种内部声明),再与以下 7 个副本逐一比对,任何漂移都会导致检查失败:
.cursor/rules/ponytail.mdc.windsurf/rules/ponytail.md.clinerules/ponytail.md.agents/rules/ponytail.md.qoder/rules/ponytail.md.github/copilot-instructions.md.kiro/steering/ponytail.md
你可以直接打开 .github/copilot-instructions.md 验证:其阶梯、规则、"Not lazy about" 段落与 AGENTS.md 逐字相同。
第二,不变量哨兵(canary)。 由于 skills/ponytail/SKILL.md 是更长的运行时版本,无法做字节比对,脚本改为断言一组关键短语必须同时逐字出现在 SKILL.md 和 AGENTS.md 中:
const INVARIANTS = [
'in this codebase', // 梯级 2:复用已有代码
'naive heuristic', // 上限注释规则
'ONE runnable check', // 测试反射
'flimsier algorithm', // 边界正确性规则
'input validation at trust boundaries', // 四条"不可懒"安全豁免
'prevents data loss',
'security',
'accessibility',
'Lazy code without its check is unfinished',
];
脚本注释解释了设计动机:"Changing a rule's wording trips this, which is the reminder to propagate it everywhere"——任何人改了某条规则的措辞而没有同步到全部位置,这个检查就会失败。这等于给规则文本本身做了一套"契约测试":AGENTS.md 的每条 load-bearing 规则都被 pin 住了,防止某次润色悄悄丢掉一条安全豁免。
开发时的验证入口(来自 README.md 的 Development 一节):
node scripts/check-rule-copies.js
npm test
Hooks 兜底:AGENTS.md 文本的第二消费方
hooks/ponytail-instructions.js 中的 getFallbackInstructions() 内置了一份硬编码指令文本,其内容与 AGENTS.md 完全同构(同样的七级阶梯、同样的 bug-fix 原则、同样的 "Not lazy about" 清单)。它的触发路径是:hooks/ponytail-activate.js 在每次会话启动时调用 getPonytailInstructions(mode),优先读取 skills/ponytail/SKILL.md 并按当前强度等级(lite/full/ultra)过滤掉与当前等级无关的表格行和示例(见 hooks/ponytail-instructions.js 的 filterSkillBodyForMode);只有当 SKILL.md 读取失败时,才回退到这份与 AGENTS.md 同构的兜底文本。
从源码结构看,这形成了一条"SKILL.md 优先、AGENTS.md 同构文本兜底"的注入链:正常路径下 Agent 收到的是按强度过滤后的完整技能文本;异常路径下也不会静默丢失规则,只是退回紧凑版。
如何在自己的项目中使用这份规则
- 指令层复用(最短路径):把 AGENTS.md 复制到你的项目根目录。Qoder、CodeWhale、Antigravity、Amp、Jules、Zed、VS Code 的 Codex 扩展、Copilot CLI 等会直接读取它,零额外配置。
- 按平台拷贝对应规则文件:Cursor 用 .cursor/rules/ponytail.mdc,Windsurf 用 .windsurf/rules/ponytail.md,Cline 用 .clinerules/ponytail.md,Kiro 用 .kiro/steering/ponytail.md——这些文件与 AGENTS.md 内容一致,选一个即可。
- 插件级安装:支持 Skill 的宿主(Claude Code、Codex、OpenCode、Gemini、pi 等)走插件安装,获得
/ponytail lite|full|ultra|off强度切换和 hooks 注入(安装步骤见 README.md 的 Install 一节)。 - 保持同步的纪律:如果你基于此 fork 规则,修改任何一条规则措辞后,运行
node scripts/check-rule-copies.js && npm test确认所有副本和不变量仍然通过——这正是 Ponytail 自己维护这份规则的方式。
小结
AGENTS.md 用 30 余行浓缩了一套完整的"最小必要代码"方法论:七级阶梯规定了写代码前的决策顺序(YAGNI → 复用 → 标准库 → 平台原生 → 既有依赖 → 一行 → 最小实现),八条规则封堵了过度工程化的主要入口,而 "Not lazy about" 清单把理解问题、信任边界校验、数据丢失防护、安全、可访问性和硬件校准划为不可谈判的红线,并强制非平凡逻辑留下一个可运行的最小检查。它既是 Qoder、CodeWhale、Amp、Jules 等一大票 Agent 的常驻指令文件,也是 7 份平台规则副本的字节级同步锚点和 hooks 兜底文本的同构来源——一份文件,同时充当了 Ponytail 整个规则分发体系的中枢。
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 StartedRust0622
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