iT邦幫忙

2026 iThome 鐵人賽

DAY 12
1
AI Engineering

同一把尺,30 天橫評 AI Agent Skill:從單篇實測到一份能查的選用指南系列 第 12 篇

Day 12 | 一個「AI 本來就該做到」的原則,裝上 skill 之後差在哪

  • 分享至 

  • xImage
  •  

Day 8 排隊的兩個候選,caveman 上禮拜測完了,今天輪到另一個:ponytail——GitHub 上有 14 萬多顆星星、一個把 YAGNI 原則(你不會需要它)塞進 AI 編碼判斷的 skill。這個 skill 有意思的地方,是它主張的東西——不要過度設計、不要加沒人要求的抽象層——本來就已經是 Claude 系統層級教過的原則。今天想測的問題不是「這個原則對不對」,是「裝了這個 skill,跟這個原則本來就內建在模型裡,兩者之間有沒有可以測出來的差異」。

技能卡|ponytail

  • 名稱:ponytail,作者 Dietrich Gebert,MIT 授權,官方一句話宣稱:「讓你的 AI agent 像房間裡最懶的資深工程師一樣思考。最好的程式碼,是你從來沒寫過的那段。」
  • 運作機制:不是靠使用者下指令觸發,是掛在 SessionStart(session 一開始)、SubagentStart(子代理啟動時)這幾個掛鉤上,自動把整套規則注入進去——預設模式是 full,代表裝好、啟用之後,不用做任何事就會一直生效,這點跟一定要打 /i-have-adhd才會啟動的設計完全相反
  • 核心方法「七階梯」:動手寫程式前,從第一階往下問,卡在哪一階就停在那一階——這需不需要做(YAGNI)?專案裡已經有現成的嗎?標準函式庫做得到嗎?平台原生功能涵蓋了嗎?已經裝好的套件能解決嗎?能不能濃縮成一行?以上都不行,才寫真正的新程式碼
  • 特殊慣例:故意簡化、砍掉某個角落的地方,要用 ponytail: 開頭的註解標記,講清楚簡化的天花板在哪、之後要怎麼升級——不是悄悄簡化,是留下明講的紀錄
  • 明文的例外清單:不准簡化掉的東西包含理解問題本身(不能為了求快跳過搞懂需求這一步)、信任邊界的輸入驗證(外部輸入一律當不可信)、防止資料遺失的錯誤處理(寫入、刪除這類操作不能省略錯誤處理)、安全機制、無障礙基本功能、使用者明講要保留的東西——這份清單本身就在替「懶」畫一條線:懶用在多餘的抽象與說明上,不用在這幾類會直接影響正確性或使用者安全的地方上
  • 這次證據狀態:同一個容易被寫成過度設計的程式任務,跑「不裝 ponytail 的基線」與「ponytail 預設啟用」各 1 次

七階梯判斷法:卡在哪一階,就停在那一階

把今天的任務套進七階梯走一遍:第一階「這需不需要做」——註冊表單需要擋掉明顯打錯的 email,答案是需要,往下走;第二階「專案裡已經有現成的嗎」——這是一個獨立的測試腳本,沒有既有專案脈絡,跳過;第三階「標準函式庫做得到嗎」——Python 內建的 re 模組正則表達式完全能處理格式檢查,答案是可以,梯子在這裡停住,不用往下走到「要不要裝新套件」或「能不能濃縮成一行」。實際輸出也正好停在這一階:用 re.compile 加幾行長度與字元檢查,沒有引入任何外部套件(例如 email-validator 這類現成套件),也沒有為了炫技把整個檢查硬塞成一行難以閱讀的正則。基線版本雖然也停在同一階(同樣用 re),但額外多做的 docstring、isinstance 防呆、五點條列說明,某種程度上是把「這階做完就好」的界線往外推了一點——不是換了更複雜的手段,是在同一個手段上多包了一層說明與防禦性檢查,而這些防禦性檢查(呼叫方傳非字串)不在任務描述的假設範圍內,表單輸入本來就一定是字串。

三種啟動方式,哪一種適合你

三種啟動方式,今天測的是第三種

這系列測到現在,已經看過兩種不同的技能啟動方式:Day 8 的 i-have-adhd 靠 disable-model-invocation: true 加上系統層級的防繞過機制,只有使用者明講才會生效,而且刻意設計成不能被「模型自己判斷該不該用」繞過;Day 11 的 caveman 靠明確的觸發詞(lite/full/ultra/wenyan 各一組指令),沒打指令就是平常的樣子。這兩種都需要「使用者主動做一件事」才會啟動。

ponytail 是第三種:不靠使用者輸入觸發,也不靠模型自己判斷要不要用,是掛在 session 生命週期的事件上——SessionStart 在一個新 session 開始時觸發,SubagentStart 在子代理啟動時觸發,兩者都會呼叫對應的 .js 檔案,把整套規則文字寫進當時的上下文。翻開 ponytail-config.js,裡面寫死 const DEFAULT_MODE = 'full';——這代表只要這個 plugin 是啟用狀態,规則就會在每一個新開的 session、每一個新啟動的子代理身上自動生效,不需要任何人講一句話。這也是為什麼今天測試時,第一次嘗試在同一個既有 session 裡直接呼叫裝好的 skill 沒有生效——SessionStart 只在 session 真正重新開始時觸發一次,用同一個舊 session 硬測,掛鉤根本沒有機會執行,最後改用全新的 headless claude -p 行程才讓規則正確注入。這個操作上的細節,剛好呼應了系列裡重複出現的同一條教訓:新裝的能力,要用一個真正全新的行程去驗證,不能假設舊 session 會自動感知到。

測試設計:一個典型會被寫成過度設計的任務

問題是「寫一個函式,檢查使用者在註冊表單輸入的字串是不是合法的 email 格式」。這題經典的陷阱在於,稍微不節制一點,很容易被寫成一個完整的 EmailValidator 類別,帶著可設定的驗證規則、可擴充的檢查器介面、支援多種驗證嚴謹程度的參數——結果使用情境其實就是表單擋一下明顯打錯的輸入,用不到那麼多。這題沒有標準答案,重點是看兩邊怎麼拿捏「夠用」跟「完整」之間的分寸。

基線的結果:不算過度設計,但有幾個「順手加的」

沒裝 ponytail 的版本,寫的是一個函式,不是類別,用的是標準函式庫 re,這點是對的,沒有掉進最誇張的過度設計陷阱。但看細節,還是加了幾個沒人要求的東西:完整的 docstring(含 Args、Returns 區塊)、一個防呼叫方傳非字串進來的 isinstance 檢查、程式碼後面接了一段五點條列的「設計上的幾個重點」說明,最後還主動問「如果需要更嚴謹(例如要擋一次性信箱、要驗證 MX record),可以再告訴我,我可以加上去」——這句話本身就是在往外延伸範圍,不是被要求的事。整體不算誇張,但明顯比「剛好夠用」多做了一截。

ponytail 的結果:幾條具體規則對得上

裝了 ponytail 的版本,程式碼本身更精簡(26 行,沒有 docstring),但更值得看的是它精準對上了規則裡幾條很具體的條款,不是含糊地「看起來比較簡單」而已:

規則說故意簡化的地方要用 ponytail: 註解標記天花板跟升級路徑,實際輸出的第一行程式碼就是:

# ponytail: pragmatic format check, not full RFC 5322; real proof = send confirmation email

一句話講完「這不是完整規範、只是務實檢查」跟「真的要確認信箱存在,得靠寄驗證信」——天花板跟升級路徑都在這一行裡。

規則說非小可的邏輯要留一個可以直接跑的檢查,實際輸出不只是把測試案例印出來看,是寫了 assert 陳述式、存成檔案、自己執行過確認全部通過,回報裡明講「實際跑過,全部通過」。我事後重新獨立執行這個檔案,assert 全部通過——不是它自己說有測,是真的測過了。

規則說輸出格式是「程式碼優先,最多三行短說明」,實際輸出程式碼後面剛好是三段簡短說明(會擋掉哪些格式、不支援哪些格式、格式對不代表信箱真的存在),沒有像基線那樣延伸成五點條列,也沒有主動問要不要加更多功能。

這題剛好踩到規則自己寫的例外

重讀 ponytail-instructions.js 裡那份「不准簡化掉」的清單,第二條寫的是「信任邊界的輸入驗證」——而今天測的任務,剛好就是一個信任邊界的輸入驗證:使用者從註冊表單輸入的字串,在還沒確認格式之前,對系統來說就是不可信的外部輸入。這代表這次測試其實同時測到了兩件事:一是「懶」的判斷夠不夠精準,二是這個 skill 有沒有真的守住自己寫的例外——會不會因為追求精簡,把這題該有的嚴謹度也一起砍掉。

從結果看,兩件事都測到了正確方向:程式碼確實比基線短,但沒有省略任何一項該擋的格式檢查——空字串、缺少 @、多個 @、長度上限、連續點號、標籤前後的連字號,這些跟資安或資料完整性有關的邊界一項都沒有少,反而比基線多防了幾種。「懶」省下來的地方,是文件字數(沒有 docstring)跟輸出的說明篇幅,不是驗證邏輯本身的嚴謹度。這剛好對應規則清單裡的分界線:懶要用在「多餘的解釋、沒人要的擴充功能」上,不能用在「輸入驗證」這種明講不准簡化的項目上。如果今天測到的是相反結果——程式碼變短、但漏掉了某幾種原本該擋的輸入——那就代表這個 skill 把「精簡」跟「省略必要的嚴謹度」搞混了,那會是一個值得寫進文章的負面發現。這次沒有出現這種情況,但值得記下來:往後如果要測 ponytail 在更明顯踩到例外清單邊界的任務(例如牽涉安全機制、無障礙功能的題目),這個「有沒有守住自己畫的線」才是更嚴格的考驗。

同一題,兩種輸出:ponytail 對上了哪幾條具體規則

意外的加分:更短,但抓的邊界情況更多

比對兩邊擋掉的輸入情境,基線測了空字串、缺 @、@ 重複、有空白、前後空白、網域缺失這幾類;ponytail 版本額外多防了連續兩個點(a..b@x.com)、點出現在 local part 的開頭或結尾(.a@x.com、a.@x.com)、網域標籤用連字號開頭或結尾(a@-x.com、a@x-.com)——這幾種都是真實世界裡偶爾會出現、規則寫得鬆的驗證函式容易漏掉的邊界情況。程式碼變短,但涵蓋的邊界情況變多,這跟 Day 11 測 caveman 時看到的現象是同一種模式:省下來的篇幅不是靠犧牲完整性換來的。

邊界情況覆蓋:基線測了 6 類,ponytail 多測了 3 類

這對「已經內建的原則」測出了什麼

回到一開始想問的問題:Claude 本來就有「不要過度設計」的系統層級指引,這次基線也確實沒有寫出誇張的過度設計,那 ponytail 到底多帶來了什麼?答案不是「從會過度設計變成不會」,兩邊都沒有過度設計;差別在具體的、可以逐條對應規則文件的行為細節——固定格式的簡化說明註解、真的執行過的測試而不是印出來看看、明確的輸出長度紀律。這些細節不是「更謹守 YAGNI」這種抽象方向,是幾個具體到可以逐字對照規則文件的行為,這代表就算大方向本來就對,一份寫得夠具體的規則文件,還是能在執行細節上留下可以驗證的痕跡,不是重複而已。

這個發現也回應了系列前幾天一直在驗的同一件事:判斷一個規則有沒有生效,不能只看「結果感覺起來對不對」,要看有沒有可以指出來的具體痕跡。Day 9 測 CodeQL 跟 Semgrep 的差別,靠的是能不能重建完整的跨檔資料流路徑;Day 10 測 codex 對抗式審查,靠的是它有沒有量出具體數字(一萬個快取項目、一千萬字元)而不是含糊地說「有風險」。今天的判準是同一種邏輯:不是問「ponytail 讓程式碼看起來比較懶惰嗎」,是問「規則文件裡寫的具體條款,有沒有在輸出裡留下可以逐字對照的痕跡」。三天測的技能性質完全不同,但驗證的方法論是同一套——找得到具體證據的說法才算數,找不到就只是印象。

這對你有什麼用

  • 判斷一個「Claude 本來就會這樣做」的 skill 值不值得裝,不要只看大方向重不重複,要看它有沒有把大方向拆成具體到可以驗證的小規則。 今天的 ponytail 規則裡「用固定格式的註解標記簡化」「輸出最多三行」這類具體規定,是靠這些細節帶來可觀察的差異,不是靠重申「請節制一點」這種空泛指令。
  • ponytail: 這種標記慣例,就算不裝這個 skill,自己手動採用也有價值。 故意簡化的地方留一句話講清楚天花板在哪、之後怎麼升級,這個習慣本身就值得參考,不需要依賴工具才能做到。
  • 這類自動啟用、不需要使用者手動觸發的 skill,裝之前先確認自己能不能接受「預設就是這個風格」。 跟 caveman、i-have-adhd 都需要主動觸發不一樣,ponytail 裝好就是預設行為,如果你偶爾需要比較完整、偏保守的實作方式,得記得明講關掉,不是自己選要不要用。
  • 檢查一個「精簡」的實作有沒有偷工,看它有沒有漏掉邊界情況,不是只看行數少不少。 今天剛好是行數少、邊界情況還更完整,但這不是保證,每次都該實際核對邊界案例,不能看到程式碼短就直接假設品質沒問題。
  • 如果你的任務剛好落在對方規則清單寫明的「例外」裡(安全、輸入驗證、防資料遺失),核對重點要放在「有沒有被一起簡化掉」,不是放在「有沒有變短」。 今天的驗證邏輯沒有被犧牲,但這個核對步驟不能省,尤其在牽涉資安或使用者資料的任務上。
  • 靠 SessionStart/SubagentStart 這類掛鉤自動啟動的 skill,裝好之後最好在一個全新的 session 裡確認它真的生效過一次,不要假設裝了就一定有作用。 這類啟動方式不像明講觸發詞那樣有清楚的「我現在啟動了」訊號,最保險的做法是像今天一樣,直接觀察輸出裡有沒有出現規則要求的具體痕跡(例如那行 ponytail: 註解),而不是憑感覺判斷。

誠實交代這次測試的限制

  • 樣本數是 1 個任務、各跑 1 次,今天測到的這幾條具體對應(註解慣例、真的執行測試、三行說明),只能說這一次的執行確實精準對上了規則文件,不能保證每次執行都會這麼乾淨地對應上。
  • 只測了一種任務類型(一個相對單純、容易边界化的驗證函式),沒有測到規模更大、YAGNI 判斷更需要拿捏(例如要不要現在就加一層抽象、要不要現在就拆檔案)的情境,那種情境下兩邊的差異可能會更明顯,也可能更難分辨。
  • 基線這次沒有寫出誇張的過度設計,這代表這次的比較是「本來就不差 vs 更精確對上規則」,沒有測到「本來就會過度設計 vs 裝了 ponytail 之後修正」這種更戲劇性的對比情境,之後如果想測到後者,可能需要換一個更容易誘發過度設計的任務。
  • ponytail 的「七階梯」判斷法,今天的任務因為夠單純,沒有真正走到需要在標準函式庫、平台功能、已安裝套件之間做選擇的那幾階,這個機制的完整判斷力今天沒有被逼出來。
  • 今天的任務剛好落在規則清單「不准簡化輸入驗證」的例外範圍內,而測試結果剛好是守住了這條例外,這只證明了「這一次沒有踩到反例」,不能證明這個 skill 在所有牽涉安全或資料完整性的任務上都會守住同一條線,之後如果想更嚴格地驗證這點,需要專門設計一個更容易誘發「懶到犧牲必要嚴謹度」的任務。
  • 沒有測到 SessionStart 掛鉤在長時間、多輪對話的 session 裡會不會因為上下文被壓縮、規則被稀釋而逐漸失效,今天測的是掛鉤剛觸發、規則剛注入的第一手效果,沒有測到規則在長 session 裡的持久度。

跟前面幾天放在一起看

前面測 i-have-adhd、caveman,都是在測「一個持久生效的風格規則,會不會影響輸出的樣子」;今天測 ponytail,問的是同一類問題的更深一層:如果模型本來就有類似的傾向,這個 skill 還剩下多少價值?答案不是「沒有價值」,是「價值換了個位置」——不在於扭轉一個原本會犯的錯,在於把一個模糊的好習慣,變成幾條可以逐一核對、逐一驗證的具體規則。這系列走到第十二天,量的東西一直在變,但方法沒變:不管測的是能力、是審查方式、還是一個原則裝不裝 skill 有沒有差,答案永遠是拿出來跑一次才知道,不是用猜的。

回頭看這系列已經測過的十二個技能,啟動方式分成三種:需要明講才生效、需要打特定指令才生效、不需要任何動作就自動生效。哪一種比較適合你,答案不在「哪個原則比較好」,在於你想不想讓一個規則永遠開著。如果你多數時候都想要精簡、只有偶爾需要完整版,ponytail 這種預設自動啟用、需要時再明講關掉的模式比較省事;如果你只在特定場合(例如快速原型、除錯)才想要這種風格,需要主動觸發的模式反而比較安全,不會在不該精簡的場合也被套用。這是今天測完之後,比「哪個 skill 比較厲害」更值得帶走的判斷依據。

這系列接下來還是每篇一個獨立的技能卡,累積起來變成一份你自己就能查的 skill 選用清單。


上一篇
Day 11 | 官方說省 65% token,我量出來是 39%
下一篇
Day 13 | 性質測試最值得學的一課,不是「讓亂數幫你找 bug」
系列文
同一把尺,30 天橫評 AI Agent Skill:從單篇實測到一份能查的選用指南 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言