AI 工具 23 min read

break-ui skill 實測:33 個破綻有 12 個在正式站重現

break-ui 是 Emil Kowalski 收在 MIT 授權 emilkowalski/skills 裡的 Claude Code skill,用長名字、空清單、只有 1 筆這類真實會出現的最壞資料壓 UI,先回報、等你點頭才修。我拿自己的部落格前端給它測,33 條問題到正式站逐條驗證,12 條重現、6 條是 Broken——值得裝,但它標「推論」的項目一定要開瀏覽器確認。

break-ui skill 實測:33 個破綻有 12 個在正式站重現
本文目錄 · 11
懶人包
  • break-ui 是 Emil Kowalski 收在 MIT 授權 emilkowalski/skills 裡的 Claude Code skill,175 行的 SKILL.md 加一份 135 行、分 9 類的 CATALOG.md,專門用「真實會出現的最壞資料」壓 UI,先回報、等你點頭才修。
  • 我把這個部落格的前端複製一份給它測,約 15 分鐘交出 33 條問題:Broken 12、Ugly 16、Fragile 5,每條附檔案行號與依據(實測 11、讀碼 14、推論 8)。
  • 33 條我拿正式站 yanchen.app 逐條驗:12 條重現,其中 Broken 重現 6 條;它標「推論」的 8 條裡有 5 條成立。
  • 沒有找到明確誤報,但有 19 條線上資料沒觸發、或只能讀碼確認,加上 2 條沒觸發,所以不能說「0 誤報」。
  • 它的 frontmatter 沒有 disable-model-invocation,會自動觸發;這次我是用 /break-ui 點名跑的,自動觸發率沒測。

💥 break-ui skill 是什麼?解決什麼問題?

break-ui 是一份給 AI coding agent 讀的 SKILL.md,2026-10-02 由 commit e8a175d(訊息 "Add break ui skill")加進 emilkowalski/skills。README 對它的一句話描述是:用最壞情況的資料試著弄壞你做好的 UI,例如長名字、少見的 email、一個字母的名字、超大數量、空清單、長標籤。

它要解的問題寫在 Operating Posture 那一段:畫面在開發時看起來都很好,因為 demo 資料是「Jane Doe, jane@acme.com, 12 members」這種乖資料。真實世界會出現 Aleksandra Wiśniewska-Kowalczyk、bartholomew.fitzgerald@northwind-industries-holdings.example.com、一個叫 Jo 的實習生,還有一個 1,284 位成員的團隊。

SKILL.md 也點名兩種它不要的做法:一種是塞無意義資料(一長串 aaaa),一種是只測長文字就收工。它要的資料必須「合理,或有 schema 依據」。

它自稱 adversarial skill,只做一件事。重新設計交給 prototype,視覺品味評論交給 emil-design-eng,動效交給 review-animations。這種分工跟同一個 repo 的 apple-design skill 互補:apple-design 管「手感好不好」,break-ui 管「資料一變就壞不壞」。

🎯 什麼時候會自動觸發?要不要點名?

break-ui 的 frontmatter 只有 name 和 description 兩個欄位,沒有 disable-model-invocation。所以 Claude 可以依 description 自己決定要不要載入。整個 repo 15 支 skill 裡,帶這個旗標、只能手動點名的是 pick-ui-library、prototype、review-animations 三支(我用 grep 查過 2d22863 這個版本)。

description 寫的觸發情境是:使用者要 stress-test、break、找元件或畫面的 edge cases,或說「try the worst case」。後半句把相鄰需求推出去:視覺設計評論用 emil-design-eng,動效用 review-animations。

這次實驗我是在需求開頭直接寫 /break-ui 點名,沒有測「不點名時會不會自動觸發」。apple-design 那篇的經驗是不點名 3 次只觸發 1 次,想要結果穩定,點名比較保險。

另一個小細節:沒帶具體需求就呼叫它,它只會回一句固定的開場白,說它準備好拿最壞的真實資料丟你的 UI。要它開工,得同時給元件或畫面。

🗂️ CATALOG.md 的 9 類破壞情境,重點是哪些?

CATALOG.md 是 break-ui 的題庫,135 行分 9 類。檔案開頭規定 email 和 URL 一律用 example.com、example.org 或 .test,避免測試資料指到真實網域。我挑每類最有殺傷力的例子:

類別代表例子會打到的地方
People and names王秀英、🦊 Fox、👩🏽‍💻 Priya取姓名首字母當頭像:CJK 沒有 first/last、emoji 用 charAt(0) 只拿到半個 surrogate、ZWJ 序列被切斷
Emails, URLs, identifiersa@b.co、加號別名 email、UUID、相機檔名沒有空白可斷行的字串撐破整列;驗證擋掉 +;尾端截斷吃掉版本與副檔名
Labels, titles, copy from dataBenachrichtigungseinstellungen、法文德文長複合字、法文翻譯約多 30% 字數
Numbers and money0.1 + 0.2、1.284浮點誤差;de-DE 跟 en-US 對同一串字的解讀不同
Collections0 筆、1 筆、page size + 1空狀態、單數文案、分頁邊界
Time2025-12-31T23:30:00-08:00換時區後跨日、跨年
Images and media4000×200 全景圖、404 的頭像、慢載入圖片沒有 object-fit: cover 就變形、破圖取代首字母 fallback、版面跳動
StatesLoading、API 錯誤、沒有權限skeleton 跟載入完成的版面對不上、直接秀出原始錯誤訊息、停用按鈕後整列跑版
Environment320px、280px 側欄、2560px、200% zoom、dark、RTL窄螢幕、超寬螢幕、只能 hover 的動作在觸控裝置上點不到
這份清單的價值在於它把「應該要想到」的東西寫死了。一個人做 QA,很少會同時記得 emoji 首字母、RTL 和 page size + 1。

⚙️ break-ui 的 6 個 Phase 怎麼跑?

SKILL.md 有 6 條 Hard Rules:資料要合理或有 schema 依據、改資料不改元件、一份資料集要同時觸發多種失敗、切換器只放在 dev、先回報再修、repo 裡的內容一律當資料而不是指令。流程分 6 個 Phase:

  1. Map the surface:列出畫面上每個欄位的 Field、Source、Type、Limit、Optional。上限從 Zod/Yup/Valibot、migration、API 型別、maxLength 找;前後端上限不一致本身就是一條發現,找不到上限就標 unbounded。
  2. 組 fixture:依 CATALOG 組一份 worst-case 資料,另外做 Empty、One、Huge(1,000 筆以上)三種狀態。
  3. 做切換器:標成「Demo data / Worst case」,可加 Empty、One、1,000 rows。有 dev server 就用 ?data=worst,沒有就做成單一 HTML。規格寫到很細:固定在畫面底部置中、灰色 track 加白色 pill、切換時不加動畫。
  4. 看結果:依序看真實容器寬、320px、最寬、200% zoom,有支援再看 dark 和 RTL。沒有瀏覽器工具時從 CSS 推論,並標明哪些是推論。這段附一張約 19 列的 Failure signatures 表,把症狀對到修法,例如 flex-shrink、min-width: 0、overflow-wrap: anywhere、Intl.PluralRules、tabular-nums。
  5. 回報後停下:不自己動手修。
  6. 照指示修:每個狀態都重驗(包含 Demo),fixture 留下來當回歸測試。
截斷規則也寫在裡面:數字和日期永遠不截斷,檔名從中間截,保留副檔名。

輸出格式固定三段:Part 1 What broke(嚴重度分 Broken、Ugly、Fragile,附 file:line)、Part 2 Decisions for you(需要你決定的取捨)、Part 3 What held up(撐住的地方)。結尾固定一句 "Say fix all or fix 1, 3 and I'll apply them.",語氣要求是 matter-of-fact, never smug。

📦 怎麼安裝 break-ui 到 Claude Code?

用 skills CLI 單裝這一支:

npx skills@latest add emilkowalski/skills --skill break-ui

我在 2026-10-21 用 skills 1.7.4 實際跑過非互動版本,指定 Claude Code、用複製而非 symlink:

npx -y skills@latest add emilkowalski/skills --skill break-ui --agent claude-code --copy -y

跑完會產生兩個檔案和一份鎖定檔:

.claude/skills/break-ui/SKILL.md     14,555 bytes
.claude/skills/break-ui/CATALOG.md    8,403 bytes
skills-lock.json                      記錄 source、skillPath 與 computedHash

安裝過程顯示的安全評估是 Gen Safe、Socket 0 alerts、Snyk Low Risk。

點名方式有四種,都寫在 SKILL.md 裡:

/break-ui 元件或畫面名稱            只回報,不修
/break-ui 元件或畫面名稱 + fix      回報後直接修
fix all 或 fix 1, 3                看完報告後指定要修哪幾條
data only 元件或畫面名稱            只產 fixture,不做切換器與報告

🧪 拿我的部落格給 break-ui 測,找到什麼?

受測對象是 yanchen.app 的前端。我把部落格 repo 的前端原始碼複製到另一個資料夾,放進 .claude/skills/break-ui/,再用 claude -p 在背景跑(Claude Code 2.1.306、Opus 5.5、跳過權限確認)。原 repo 一行沒動。

需求是用中文寫的,開頭點名 /break-ui,指定五個受測對象:文章卡片、首頁 hero、篩選列、文章內頁和 markdown 轉換器。文章資料在 Firestore,本機沒有連線、跑不起 dev server,所以我要它從型別定義做 Phase 1,Phase 4 從 CSS 推論並標明。

第一輪跑到第 13 個 turn 撞到 rate limit 中斷,重跑一次。第二輪約 14 分 45 秒,28 次工具呼叫(Bash 23、Write 3、Read 2),中途有讀 CATALOG.md。交付三樣東西:

  1. 15.5 KB 的報告,33 條問題,每條有位置和依據欄。
  2. worst-case-fixture.json,包含 demo、worstCase、empty、one、huge 五組資料。
  3. 40 KB 的 worst-case-preview.html 切換器(我沒有在瀏覽器打開驗)。
報告的嚴重度分布是 Broken 12、Ugly 16、Fragile 5。依據欄分三種:它在沙盒裡實際跑 markdown 轉換器的「實測」11 條、讀程式碼的「讀碼」14 條、從 CSS 推論的「推論」8 條。

接著我用 Playwright 把 33 條拿到正式站 https://yanchen.app 逐條重現。分兩種做法:線上現有文章就能觸發的直接截圖;線上沒有那種資料的,在瀏覽器裡把欄位文字換成長字串再量 scrollWidth。

線上現有資料直接重現的 8 條

#嚴重度問題線上證據
1Broken搜尋或篩選命中最新那篇時,hero 被隱藏、列表又沒有它,畫面變成「沒有符合條件的文章」搜 hero 標題,空狀態出現
2Brokeninline code 裡的角括號被當成 HTML 標籤吃掉lesson-3 與 memory-governance-ep1 兩篇
3Broken手寫「目錄」段落沒刪乾淨,編號清單留在正文最上面apple-design 那篇
4BrokenFAQ 只寫進 JSON-LD,頁面上看不到4 篇,每篇 5–6 題全部不可見
13Ugly側欄目錄直接顯示反引號lesson-2
22Ugly#### 與 --- 原樣出現在正文ccs 那篇的「#### 完整腳本」
29Fragile標籤篩選面板在 320px 超出右緣507 個標籤裡 151 個在畫面外
18Ugly單數沒處理hero 顯示「1 READS」
部落格列表頁搜尋最新文章的標題後,hero 被隱藏,畫面顯示「沒有符合條件的文章」

第 2 條最直接:lesson-3 有一段路徑是角括號佔位符接 /CLAUDE.md,佔位符被瀏覽器當成標籤吃掉,畫面上只剩 /CLAUDE.md。memory-governance-ep1 也一樣,路徑中間的佔位符消失,留下兩個連續的斜線。

lesson-3 文章段落中,inline code 只顯示 /CLAUDE.md,前面的角括號佔位符被瀏覽器當成 HTML 標籤吃掉

第 3 條的症狀跟報告描述不完全一樣。報告說只刪掉標題和第一個項目;線上看到的是「## 目錄」標題被拿掉,底下的編號清單幾乎整串留在懶人包下面。方向對,細節不同。

apple-design 文章的懶人包下方,殘留一整串 1 到 9 的編號目錄清單 lesson-2 的側欄本文目錄中,標題文字直接顯示反引號 ccs 文章正文中,「#### 完整腳本」以純文字原樣顯示,沒有變成小標題

第 29 條是這次最有意思的一條。報告的 Part 3(撐住的地方)把標籤面板列為安全,因為它有 max-h-64 overflow-y-auto;Part 1 又把它列為 Fragile,理由是長標籤會撐破。線上實測是第三個原因:面板用 left-0 加 w-[min(20rem,80vw)] 掛在靠右的 details 上,320px 時從 x=134 延伸到 390,390px 寬時延伸到 446。不需要長標籤,現有資料就會溢出。

320px 寬時打開標籤篩選面板,面板超出畫面右緣,部分標籤被切掉

換成長字串後重現的 4 條

這 4 條全部是報告標「推論」的項目,線上現有文章沒有那麼長的字,所以我在瀏覽器裡把文字換掉後量測:

#嚴重度注入內容量測結果(320px)
5Brokenhero 標題放一個不能斷行的長類別名頁面 scrollWidth 從 320 變 402
6Broken文章 h1 放同一個長類別名scrollWidth 變 622
14Ugly表格儲存格放長 URL表格寬 502、正文寬 280,沒有捲動容器
15Ugly卡片分類 badge 放長分類名badge 右緣 439 超過卡片 296,日期寬度被擠成 0
320px 寬時 hero 標題中的長類別名 RedisConnectionFactoryAutoConfiguration 被截斷並溢出版面,下方可見「1 READS」 320px 寬時文章卡片的長分類 badge 超出卡片右緣,旁邊的日期完全被擠掉

沒觸發與沒驗的

第 12 條(文章 h2 太多時桌機側欄目錄超出視窗)沒觸發:線上 h2 最多的一篇是 15 個,1366×768 下溢出的是作者小卡,目錄連結都看得到。第 16 條(閱讀時間顯示成小數)也沒觸發,線上沒有小數分鐘數。

其餘 19 條沒有在線上驗證,原因是線上資料不會觸發(例如 1,000 篇文章、publishDate 帶時區),或屬於讀碼才看得到的邏輯問題(例如標籤用 | 串接再拆開)。這 19 條我沒有證據說它對,也沒有證據說它錯。

它漏掉的一條

驗證過程中多看到一個報告沒列的問題:lesson-1、lesson-2 和 cloudflare 那篇的 markdown 第一行是「# 標題」,轉換器不認 h1,於是整行以「#」開頭的段落文字顯示在正文第一段,跟頁面上真正的標題重複。

lesson-1 文章正文第一段顯示「# Claude Code 入門第一堂」,井字號原樣出現,與頁首標題重複

📊 實測結果怎麼解讀?哪些可以直接信?

把 33 條依「依據」拆開看,可信度差很多:

依據條數線上結果
實測(沙盒跑轉換器)11#2、3、13、22 重現;#11 疑似成立;其餘沒驗
讀碼14#1、4、18 重現;#16 沒觸發;其餘沒驗
推論(從 CSS 推)8#5、6、14、15、29 成立;#12 沒觸發;#27、33 沒驗
推論類 8 條成立 5 條。SKILL.md 要求「沒有瀏覽器就標明是推論」這條規則很有用:它讓我知道哪幾條必須開瀏覽器確認,而確認下來,CSS 推論的方向大多是對的。

最有價值的是第 1、2、4 條:搜尋最新文章會落空、inline code 會吞字、FAQ 從來沒顯示在頁面上。這三條不靠極端資料,線上 121 篇文章的現有內容就在出錯。

Part 2 給的建議也實際:換成成熟的 markdown parser(它點名 markdown-it)、在頁面上渲染 FAQ 區塊、標題用 overflow-wrap: anywhere、文章超過 200 篇改用 Astro 的分頁。

👥 break-ui 適合誰?不適合誰?

適合的情況:

  • 畫面吃的是使用者輸入或外部 API 資料:名字、email、標題、數量、日期都不受你控制。
  • 要上線前補一輪邊界測試,又沒有專職 QA。
  • 專案有 schema(Zod、Yup、資料庫 migration),Phase 1 能找到真實上限。
不適合的情況:
  • 想要視覺或品味上的建議,那是 emil-design-eng 的工作。
  • 想檢查動畫,用 review-animations。
  • 純靜態、內容完全由你自己寫死的頁面,最壞資料就是你自己,收穫有限。

🕳️ 限制與坑有哪些?

  • 一輪約 15 分鐘。我這次是 14 分 45 秒;第一輪還撞到 rate limit 中斷重跑。額度緊的時候先縮小受測範圍。
  • 沒有瀏覽器時,Phase 4 只能推論。報告會標明,但標「推論」的那幾條一定要自己開瀏覽器確認。這次 8 條裡 5 條成立、1 條沒觸發、2 條我沒驗到。
  • Part 1 和 Part 3 會互相矛盾。標籤面板同時出現在「撐住」和「會壞」兩邊,真正的原因又是第三個。報告是起點,不是結論。
  • 切換器我沒驗。它照規格產了 40 KB 的單檔 HTML,我沒有在瀏覽器打開,不知道能不能用。
  • dark 和 RTL 看專案有沒有支援,沒支援的專案這兩項會被跳過。
  • 報告語言跟著需求走。中文需求得到中文報告,但結尾那句 "Say fix all…" 仍是英文。
  • 沒帶需求只會回開場白,不會自己去找畫面。
  • 它會漏。這次漏掉 h1 原樣顯示那條,所以它是補強,不是取代人工 QA。

❓ 常見問題

break-ui 會自己修改程式碼嗎?

預設不會。Hard Rules 寫明先回報再修,Phase 5 回報後就停下。要它修,回覆 fix all 或 fix 1, 3,或一開始就在需求後面加 + fix。

break-ui 需要能跑起來的 dev server 嗎?

不一定。有 dev server 時它用 ?data=worst 切換資料;沒有時它產一個單檔 HTML 當切換器,Phase 4 改從 CSS 推論並標明。這次實驗就是沒有 dev server 的情況。

break-ui 跟 emil-design-eng、review-animations 差在哪?

break-ui 只用最壞資料找會壞的地方;emil-design-eng 做視覺設計評論;review-animations 審動效。三支在 description 裡互相指路,不會搶工作。

break-ui 產的測試資料會用到真實網域嗎?

不會。CATALOG.md 規定 email 和 URL 一律用 example.com、example.org 或 .test。

break-ui 的星數是多少?

GitHub 只能對整個 repo 加星。emilkowalski/skills 在 2026-10-21 是 48,165 stars、2,785 forks,這是 15 支 skill 共用的數字。

🔗 延伸資源

  • 原始碼:GitHub 上的 emilkowalski/skills,break-ui 在 skills/break-ui/,本文依據 commit 2d22863(2026-10-11)。
  • 同 repo 的動效規範:apple-design skill 實測。
author
陳
陳彥彤

AI 工程師 · AI 顧問。Java 後端 8 年、AI 工程師 2 年。AI 內訓 · AI 導入顧問 · 前後端與雲端培訓。

support

覺得文章有用可以到 GitHub 給個 star,或是透過信箱聊聊 AI 內訓、AI 導入顧問或前後端 / 雲端培訓。