Ponytail:讓 AI 代理程式少寫程式碼
Ponytail 以決策階梯讓 AI 代理程式採用最小可行修改;日期選擇器從 404 行降至 23 行,並說明如何立即套用這項規則。
Ponytail 是什麼
Ponytail 是一組規則,讓 AI 程式碼代理程式少寫一些程式碼。專案用一句話描述自身:「讓你的 AI 代理程式像團隊中最懶惰的資深開發人員一樣思考。最好的程式碼,就是你不必撰寫的程式碼。」它採用 MIT 授權。Ponytail 本身沒有執行階段,也不會執行任何內容。它是要放入代理程式指示中的文字,會以 skill 的形式提供給能載入 skill 的主機,也會以純規則檔案的形式提供給無法載入 skill 的主機。
儲存庫位於 DietrichGebert/ponytail。它建立於 12 June 2026,並在 1 August 2026 前突破 90,000 顆星。1 August 2026 的最新標記版本是 v4.8.4,發布日期為 29 June 2026;僅 14 June 至 29 June 期間,release 頁面就列出十個標記。這種開發速度代表你閱讀本文時,專案可能已經變更,因此在以它為基礎進行任何建置前,請先固定使用某個標記版本。
工具之前的想法:停在第一個成立的階梯
Ponytail 的核心是決策階梯。代理程式在寫入任何內容前會先依序檢查,並停在第一個成立的階梯。
- 這項功能是否根本不需要存在?這就是 YAGNI(你不會需要它)。如果答案是否定的,就略過。
- 這項功能是否已存在於這個程式碼庫中?重複使用現有的輔助程式或模式。
- 標準函式庫是否能處理?使用它。
- 原生平台功能是否能涵蓋?使用它。
- 已安裝的相依套件是否能解決?使用它。
- 能否寫成一行?就寫成一行。
- 只有在這之後,才撰寫能運作的最少程式碼。
真正發揮作用的是整個順序,而不是其中任何一個階梯。代理程式收到製作日期選擇器的要求時,就會製作日期選擇器,因為它被要求做這件事。這個階梯會讓它先檢查第 4 階,而第 4 階指出瀏覽器已經具備 <input type="date">。專案自己的基準測試筆記正好記錄了這個案例:未套用這項規則時,日期選擇器有 404 行;套用後則只有 23 行,因為代理程式改用原生輸入控制項,而不是自行建立元件。色彩選擇器也因為相同原因,從 287 行降到 23 行。第 2 階最容易悄悄失效,因為代理程式如果看不到你已經有的輔助程式,就會很自然地再寫一份;可查詢的程式碼庫對照表正是要填補這個缺口。
這裡的「偷懶」並不代表粗心,規則集也直接說明了這一點。其中的「不可偷懶」清單涵蓋:在決定前先理解問題、在信任邊界驗證輸入、防止資料遺失的錯誤處理、安全性、無障礙,以及你明確要求的任何內容。規則也要求每段非簡單邏輯都提供一個小型且可執行的檢查。這項規則會減少不必要的發明,但不會降低正確性。
實際發布的內容
AGENTS.md,持續套用的規則集。全部核心概念都集中在這個檔案中,5 分鐘內即可讀完。skills/ponytail/SKILL.md,技能定義,參數提示為lite、full或ultra。- 特定編輯器目錄下的規則檔案,例如
.cursor/rules/和.windsurf/rules/,適用於會讀取規則但不載入技能的主機。 hooks/、benchmarks/、examples/和scripts/。
強度參數會改變規則的約束程度。lite 會建立你要求的內容,並在一行中指出較寬鬆的選項。full 是預設值,會強制遵循這個層級。ultra 是 YAGNI 的極端設定:它偏好刪除而不是新增,甚至會質疑需求本身。
支援技能的主機也會取得 slash command。/ponytail 設定等級,/ponytail-review 檢查 diff 是否過度工程化,/ponytail-audit 檢查整個 repository,/ponytail-debt 收集你延後處理的捷徑,/ponytail-gain 顯示基準測試評分表。只讀取規則檔案的主機則只會取得規則集,不會取得任何 command。
若要在信任來源前先閱讀原始碼,請 clone tag,而不是 branch:
git clone --depth 1 --branch v4.8.4 https://github.com/DietrichGebert/ponytail.gitClaude Code 改為記錄 plugin 安裝方式;以下兩行是截至 2026 年 8 月 1 日的文件內容:
/plugin marketplace add DietrichGebert/ponytail
/plugin install ponytail@ponytailplugin 路徑會跟隨 default branch,而不是 tag。因此,指導 agent 的指示可能會在不同工作階段之間變更。這是換取 update command 便利性時必須接受的取捨。
為什麼較少介入的 agent 在 VPS 上成本更低
agent 寫出的差異不會離開對話。在下一個回合中,模型會再次讀取這些內容,以及它為了產生差異而開啟的所有檔案。因此,500 行的變更不只會增加產生該變更之回合的負擔,也會影響工作階段後續的每個回合。這就是為什麼失控的重構會讓 agent 隨著工作階段進行而變得更慢、更不可靠:內容視窗被 agent 自己的輸出填滿,留給實際程式碼的空間就會縮小。管理 coding agent 的內容視窗的核心就是控制這個問題。
輸入與輸出都會計入 token 費用,因此差異縮減一半會帶來兩次成本節省:第一次是在寫入時,之後每次重新讀取時又節省一次。這項節省是否會反映在帳單上,取決於你的付費方式,因為固定費用的 Pro 或 Max 訂閱會吸收額外 token,而按 token 計費的 API 則會為每個 token 收費。如果你在自架環境中留意帳單,指示檔案是一個不需額外成本即可調整的控制點。控制 AI agent 的成本應從輸出量開始,而coding agent 如何使用 token則說明了重新讀取為何比多數人預期的更加重要。
人類仍然需要閱讀差異。原本只需 20 行、實際卻變成 400 行的變更,會消耗審查者的注意力,而注意力是最先耗盡的資源。沒有人能以審查當天第一個差異時的仔細程度,來檢查當天第 4 個冗長差異。因此,過度建置不只會浪費時間,也會悄悄降低原本應負責找出錯誤的審查品質。
在伺服器上,風險程度會改變,因為 agent 經常在無人監看的情況下執行。agent 在 tmux 工作階段或排程中執行時,可能有數小時的時間,在你發現問題前持續建立在錯誤決策之上。這就是在 VPS 上執行 coding agent的實際風險,也是進行loop engineering的人會如此重視常駐指示,而不是個別提示的原因。always-on 檔案中的規則會套用到第 200 回合;你在聊天中輸入的規則只會套用到第 3 回合。它也會套用到你在同一台主機上啟動的第 2 個工作階段。該工作階段會讀取已提交的檔案,但不會繼承你在第 1 個工作階段中輸入的任何內容,即使兩個工作階段可以互相傳送訊息。
新增相依性是另一項不易察覺的成本。第 5 條要求使用已安裝的元件。agent 每次自行新增的套件,之後都需要由你負責修補,而且最終會進入你從該 repository 建置的每個容器映像檔。
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 儲存庫。測試使用 Haiku 4.5,處理 12 個功能票證,每個票證執行 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 歷史記錄裡的原因。在 monorepo 中,這個模式應放在多個已提交的檔案中,因為 每個套件各自使用一個 AGENTS.md,能讓每個目錄的規則保持簡短,不必讓代理程式每次執行都讀取整個樹狀目錄的慣例。不過,放置位置並不是保證;在認定這個階梯需要更強的措辭前,也值得先了解 代理程式為何會略過已載入的規則。
規則不適用的情況
這套階梯是針對已存在的程式碼庫中的功能開發調整的。此時通常有可重用的程式碼,而且重用通常是正確做法。它不適合全新專案,因為第 2 級沒有可重用的內容,第 5 級也沒有已安裝的工具。因此,代理程式每次都會落到第 7 級。當你確實需要抽象化時,它也不適合。例如,你即將加入相同複製區塊的第 4 個呼叫端時,「最短差異」會產生第 5 份複本。
ultra 層級會質疑你的需求。這正是該層級的用途;但如果你已經做出決定,只想完成工作,這也會產生實際成本。一般工作使用 full;懷疑功能需求本身有問題時,再使用 ultra。
任何指令區塊都無法避免你誤解問題。這套規則的第 1 項就是先理解程式碼再做決定,而這也是最耗時、且文字內容無法代替你完成的部分。在錯誤函式中採用最小差異,仍然是錯誤修正,而且現在變成容易核准的小型錯誤修正。
坦白說,Ponytail 是一份撰寫周詳、妥善發布並附有數據的提示。它不要求使用該外掛程式。這個專案真正提供的是:有人正確撰寫了這份清單,對照實際儲存庫進行測試,並將這套方法與結果一併發布。
FAQ
Ponytail 能與 Claude Code 以外的 agents 搭配使用嗎?
可以。Ponytail 以 skill 形式提供給會載入 skills 的 hosts 使用,Claude Code、Codex、OpenCode、Gemini,以及 README 中列出的其他工具都包含在內。只會讀取規則檔、但不會載入 skills 的 editors,例如 Cursor、Windsurf、Cline 和 Copilot,會從相符的 rules directory 取得 always-on ruleset,但不會取得 slash commands。兩種方式使用的文字相同,真正的差異在於 host 是否會在每一輪都將這些文字保留在 context 中,或只在觸發 skill 時載入。
lazy agent 會略過測試、驗證或安全性檢查嗎?
不會,ruleset 已直接說明這一點。其中的「never lazy about」清單列出信任邊界的輸入驗證、可避免資料遺失的錯誤處理、安全性與無障礙性,並要求每段非簡單邏輯都提供一個可執行的小型檢查。這項規則移除的是憑空增加的結構:沒有人要求的抽象,以及不需要的相依套件。如果安裝後 agent 開始刪減測試,原因是你自己的設定中有其他指示的優先順序高於這項規則,因此請讀取 agent 最後載入的檔案。
已發布的速度與成本數字可信嗎?
這些數字是專案自行測量的結果,並附有測量方法,因此應以這個前提解讀。single shot 數據是與只回覆選項和說明的 bare model 比較,而 README 本身也指出這是較弱的基準。agentic 數據來自一個 headless Claude Code session,測試對象是單一 FastAPI 和 React repository,包含十二個 tickets,每個執行四次,使用 Haiku 4.5。這些數字對該設定而言是可靠的。但它們不是你程式碼庫的預測結果,因為專案也指出,對原本已經精簡的程式碼,節省幅度會降至接近零。
必須安裝任何東西才能獲得效益嗎?
不必。這個 ladder 的內容是文字;將等效區塊貼入 agent 已經會讀取的 instruction file,就能獲得大部分效果。plugin 提供維護過的措辭、強度層級、review commands,以及更新途徑。先嘗試貼上的區塊,是回答「是否真的需要安裝」這個問題的 rung 1 作法。
如何避免 unattended agent 在夜間過度建置?
將規則放在 always-on instruction file,而不是 chat message 中,這樣它會套用到長時間執行的第 200 輪,而不只套用到第 3 輪。接著分開限制可能造成的損害:提供一個 agent 可以任意修改的 checkout,不要交付唯一的副本,並要求在任何內容 merge 前進行 human diff review。minimal diff rule 能減少你需要閱讀的內容,但它不會決定哪些內容可以提交,也不應該由它決定。