AI 工具 20 min read

prototype skill 實測:AI 一次做 4 版 UI,有 1 版是壞的

prototype 是 Emil Kowalski 開源的 Claude Code skill,把一個 UI 元件做成幾版不同原型,放進切換器讓你挑。repo 有 48.2k stars(15 支共用);我實測點名時做出 4 版卡片 hover、沒碰正式程式,但 1 版全黑沒自驗,不點名不載入。

prototype skill 實測:AI 一次做 4 版 UI,有 1 版是壞的
本文目錄 · 10
懶人包
  • prototype 是 Emil Kowalski 收在 emilkowalski/skills(MIT)裡的 Claude Code skill:把你描述的一個 UI 元件做成幾個方向真的不同的版本,放進一個固定規格的切換器(PICKER.md),讓你一個一個切換比較,挑中再整合。
  • 它設了 disable-model-invocation: true,只有你打 /prototype 才會跑。我用同一句需求不點名跑一次,Claude 完全沒讀它,直接改了 3 支正式程式檔。
  • 點名那次(Sonnet、175 秒)做出 4 個卡片 hover 版本,全放在獨立的 prototype.html 與 src/prototypes/,正式程式一行沒動;切換器的數字鍵、方向鍵與 ?v= 網址參數我用 Playwright 驗過都正常。
  • 坑:4 個版本裡有 1 個打開就是壞的,三張卡片的內文區整片黑底、字看不見。Claude 自己回報「沒有在瀏覽器裡實際看過」,skill 要求的逐一檢查被跳過了,切換器開起來要自己逐版看過。
  • repo 在 2026-10-21 是 48,160 stars、2,785 forks,這是 15 支 skill 共用的數字。安裝指令 npx skills@latest add emilkowalski/skills --skill prototype 我實際跑過,會裝進 SKILL.md 與 PICKER.md 兩個檔。
  1. prototype skill 是什麼?
  2. 它的流程怎麼走?
  3. PICKER.md 是什麼?
  4. 為什麼一定要打 /prototype?
  5. 怎麼安裝到 Claude Code?
  6. 實測:替部落格文章卡片做 hover 原型
  7. 不點名會怎樣?
  8. 適合誰、不適合誰?
  9. 限制與坑
  10. 延伸資源

🧪 prototype skill 是什麼?

prototype 是一份給 AI coding agent 讀的 SKILL.md,98 行,另外附一份 197 行的 PICKER.md。它在 2026-07-27 以 commit「Add /prototype skill」加進 emilkowalski/skills,2026-09-15 又小改過一次。

它自稱是一支「divergence skill」,只做一件事:你描述一塊 UI(例如「一個 toast」「價格卡片」「長按刪除的按鈕」),它做出幾個方向真的不同的版本,放到一個切換器後面,讓你在瀏覽器裡一個一個切換,選出要留下的那一個。

它刻意不做的事也寫得很清楚:審查既有 UI 是 review-animations 的工作,規劃修正是 improve-animations,挑選依賴套件是 pick-ui-library。prototype 只負責「發散」。

skill 對「發散」的要求很硬:三個只是換了顏色的同一個想法,等於浪費切換器,因為你來回切也學不到東西。每個版本都得是「單獨拿出來也能出貨」的方向,同時還要守住 Emil Kowalski 的工藝標準:進場用 ease-out、UI 動畫低於 300ms、只動 transform/opacity、處理 reduced-motion。

repo 本身在 2026-10-21 查是 48,160 stars、2,785 forks、MIT 授權。GitHub 只能對整個 repo 加星,所以這是 15 支 skill 共用的數字,不是 prototype 一支的熱度。作者背景與整個 repo 的來龍去脈,我在 apple-design skill 實測 那篇寫過,這裡不重複。

🔁 它的流程怎麼走?

skill 把一次執行拆成 6 個階段,每個階段都有完成條件:

階段做什麼關鍵規則
1 Scope把需求縮成一個元件,用一句話重述一次只做一個;需求太大(「整個 dashboard」)就挑最有影響的那塊,其餘列為後續
2 Recon盤點技術棧、design token、產品個性、元件會出現的位置每個版本都要用專案自己的 token,看起來明天就能上線
3 Choose directions先列出每個版本的名字與「軸」預設 3 個,使用者要求或設計空間很寬時最多 5 個;名字要描述方向,不准叫 Option A/B/C
4 Build harness蓋切換器與各版本有 dev server 就開獨立路由(如 /prototypes/<slug>),一個版本一個檔;沒有專案就產單一自足 HTML
5 Verify跑起來,逐版切過,console 要乾淨有瀏覽器工具就逐版截圖;交出一張「版本/軸/何時選它/代價」的表,然後停下來等你選
6 Promote你選定後整合進正式程式照專案慣例整合,接著刪掉原型區
貫穿全程的 5 條 Hard Rules,我覺得最有價值的是第一條:探索期間絕不碰正式程式碼。所有版本都住在隔離的原型區,只有你選中的那一個,在第 6 階段才會進到正式程式。

選完之後的指令也有固定說法:

指令效果
/prototype <描述>完整流程,預設 3 個版本
/prototype <描述> x5指定版本數,上限 5
riff <版本名>保留切換器,以某個版本為中心再發散一輪
keep <版本名>把該版本整合進正式程式並刪掉原型區
keep <版本名>, leave the picker整合,但保留原型區
另外有個細節:如果你只打 /prototype 不帶需求,skill 規定 Claude 只回一句準備好了的開場白,其他什麼都不說,等你開口。

🎛️ PICKER.md 是什麼?

PICKER.md 是切換器的完整規格,連 HTML 結構、CSS 與鍵盤行為都寫死,skill 要求「逐字照抄」。它不是把多個方案並排成縮圖比較,剛好相反:一次只顯示一個版本,全尺寸,放在真實的周邊情境裡。skill 的理由是縮圖會扭曲間距與比例,UI 不該在郵票大小下評判。

切換器長這樣:畫面底部正中央一顆深色半透明膠囊(rgba(10,10,10,0.82) 加 12px 模糊),裡面是各版本名稱,目前選中的那顆底下有一塊高亮會滑過去(250ms、cubic-bezier(0.23, 1, 0.32, 1))。下面那張實測截圖底部就是它。

規格裡幾個值得知道的設計:

  • 它是外框,不是參賽者。外觀不跟專案主題走,不做亮暗模式,z-index 直接設 2147483647。唯一允許的修改是版本本身佔用底部中央時,改成 data-position="top" 移到上方。
  • 鍵盤:數字鍵 1–N 直接跳版本,←/→ 循環切換,R 重播動畫;焦點在輸入框或按著修飾鍵時不攔截。
  • 網址記得狀態:目前版本寫進 ?v=2 這樣的參數,重新整理不會跑掉,也能直接把網址傳給別人。
  • 切換是瞬間的:切換版本本身不做動畫,因為一次探索可能切上百次。每次切換會重新掛載該版本,讓進場動畫重新播放。
  • 重播鈕只在需要時出現:版本有動畫才放「Replay」,純 hover 的元件不放。

🔒 為什麼一定要打 /prototype?

prototype 的 frontmatter 有一行 disable-model-invocation: true,description 也直說「Only runs when explicitly invoked; it does not trigger on its own」。

Claude Code 官方 skills 文件 對這個欄位的說明是:設了之後,你可以用 / 叫它,但 Claude 不會自己決定去用;它的 description 不會放進 Claude 的 context,只有你叫用時才載入完整內容。文件還提到它同時會阻止 skill 被預載到 subagent。

我在同一個 repo 裡數了一下,15 支 skill 中設了這個欄位的有 3 支:prototype、pick-ui-library、review-animations。這三支有個共同點,都是「一跑就會產出一大包東西或改變專案狀態」的流程型 skill,讓使用者自己決定何時開跑很合理。

實際影響是:你不打 /prototype,它就不存在。下面的對照實驗會看到,同一句需求不點名時,Claude 連這份 skill 都沒讀,走的是完全不同的做法。

⚙️ 怎麼安裝到 Claude Code?

在專案根目錄跑:

npx skills@latest add emilkowalski/skills --skill prototype

我在 2026-10-21 確認 skills CLI 的 latest 是 1.7.4,--skill 參數存在。想要非互動、直接複製檔案(不建 symlink)到 Claude Code,可以帶完整參數:

npx -y skills@1.7.4 add emilkowalski/skills --skill prototype --agent claude-code --copy -y

驗證安裝:

find .claude/skills/prototype -type f
.claude/skills/prototype/PICKER.md
.claude/skills/prototype/SKILL.md

兩個檔都要在。SKILL.md 在第 4 階段會叫 Claude 去讀 PICKER.md,少了它切換器就沒有規格可照抄。裝好後在 Claude Code 裡打 /prototype 加上你的需求就會開始。

🧪 實測:替部落格文章卡片做 hover 原型

我想知道兩件事:點名時它真的會照 6 個階段走、把正式程式擋在外面嗎?做出來的版本能不能直接拿來挑?

環境:Vite 8.3 + React 19.3 + TypeScript 的小專案,畫面是三張仿我部落格風格的文章卡片(粗黑框、黃色分類標籤)。Claude Code 2.1.306,模型 Sonnet,claude -p 非互動模式,沒有接任何 MCP,所以這次 Claude 手上沒有瀏覽器工具。

需求我寫得像真的在問:

/prototype 這是我部落格的文章列表(src/App.tsx、src/ArticleCard.tsx)。我想替文章卡片做滑鼠 hover 效果,但還沒決定風格,想先看幾種真的不一樣的做法、在瀏覽器裡切換比較再決定。不要裝新套件、不要用 CDN。做完就結束,最後告訴我在哪個網址看、怎麼切換。

結果:175 秒、18 輪、花費 0.35 美元。

項目觀察
版本數4 個。我沒要求數量,skill 預設是 3 個
正式程式App.tsx、ArticleCard.tsx 完全沒動,git status 只多出 prototype.html 與 src/prototypes/(共 367 行)
切換器照 PICKER.md 實作,只省略了用不到的分隔線、重播鈕與 data-position="top" 規則;hover 不需要重播,所以沒放 Replay 是對的
自我檢查跑了 tsc、oxlint、curl 確認頁面回 200;沒有在瀏覽器裡看過任何一個版本
交付一張「版本/做法/適合情況/代價」表,最後提示可以回 keep 2 或 riff 3,然後停下
它給的 4 個方向,軸確實拉得開:
#版本做法它自己寫的代價
1Hard Shift卡片往左上浮起,黑色硬陰影變大,按下去沉回陰影往右下延伸,24px 間距會擠
2In-place卡片不動,封面浮出斜線紋,「閱讀文章」被黃色條掃過反應集中在下半部,整體較小
3Ink Fill整張卡片從底部填黑,文字反白,連結變黃長列表一路掃過去會一直閃
4Pointer Tilt卡片跟著滑鼠做 3D 傾斜,黃色光暈跟著游標和扁平粗框風格最不搭,只有滑鼠有效
我另外用 Playwright 打開切換器逐版 hover 截圖,並測鍵盤:按 3 跳到 Ink Fill、按 → 跳到 Pointer Tilt、重新整理後網址的 ?v=4 讓它停在原處。切換器本身的行為全部符合規格。 prototype 切換器的 Ink Fill 版本:滑鼠停在第一張卡片上,卡片內文區從底部填成黑底、文字反白,底部膠囊切換器選中 Ink Fill prototype 切換器的 Pointer Tilt 版本:第一張卡片隨游標位置 3D 傾斜,封面上有一團黃色光暈

問題出在第 1 版。Hard Shift 一打開,三張卡片的內文區整片是黑的,標題和摘要都看不見,跟有沒有 hover 無關:

prototype 切換器的 Hard Shift 版本渲染錯誤:三張卡片的內文區都是黑底,標題與摘要文字看不見,只剩分類標籤與 tag

原因在 CSS:它用一個 ::before 黑色底層當硬陰影,同時在卡片上設了 isolation: isolate。

.p-shift .card { position: relative; isolation: isolate; height: 100%; }
.p-shift .card::before {
  content: '';
  position: absolute;
  inset: -2px;
  background: var(--color-ink);
  z-index: -1;
}

卡片自己成了堆疊環境,z-index: -1 的子層就只會畫在卡片背景之上、內容之下,於是整片蓋住米白底。內文的字也是同一個墨黑色,黑底黑字就消失了。封面有自己的底色,所以只有封面看得到。

這種錯誤 tsc 和 lint 都抓不到,打開頁面看一眼就會發現。skill 第 5 階段寫的是「flip through all of them yourself before showing the user」,Claude 的回報也很誠實:「我沒有在瀏覽器裡實際看過各個版本,也沒看 console」。這次我沒給它瀏覽器工具,它沒辦法照做,這部分是我的實驗設定造成的;但結論對實際使用一樣成立:沒有瀏覽器工具的環境下,第 5 階段等於交給你做。

🆚 不點名會怎樣?

同一個專案、同一句需求,只拿掉開頭的 /prototype,其餘設定相同。

比較點名 /prototype不點名
有沒有讀 skill有,並自己去讀了 PICKER.md沒有,完全沒碰 .claude/skills/prototype
正式程式一行沒動改了 App.tsx、ArticleCard.css、ArticleCard.tsx,+104/-5 行
版本數4 個5 個加一個「無」對照組
切換方式底部膠囊、數字鍵、?v=頁面上方一排按鈕、?hover=flood 參數
收尾等你說 keep,再由它整合並刪原型區叫你自己把不要的變體和按鈕刪掉
耗時與花費175 秒、0.35 美元115 秒、0.15 美元
不點名時 Claude 做的版本:切換按鈕直接加在文章列表標題下方,第一張卡片顯示硬陰影浮起效果

有意思的是,不點名那次的「硬陰影浮起」反而畫對了。兩邊各只跑一次,這不代表哪一邊的視覺品質比較好。差別在流程:不點名的版本把切換按鈕直接寫進文章列表、把五種 hover 樣式塞進正式的 ArticleCard.css,選完之後要自己清;點名的版本整包隔離,選完一句 keep 就收乾淨。

👥 適合誰、不適合誰?

適合:

  • 一個元件還沒定方向,想同時看到幾種完全不同解法的人。尤其是 hover、toast、卡片、按鈕這種「看了才知道」的東西。
  • 專案已經有 design token 和 dev server,想讓 AI 的探索不汙染正式程式的人。
  • 要拿原型去跟別人討論的人。?v= 網址可以直接傳給同事,對方打開就停在同一個版本。
不適合:
  • 已經知道要什麼樣子。這時直接請 Claude 實作就好,跑發散流程是浪費時間和 token。
  • 要一次重做整頁或整個流程。skill 規定一次只做一個元件,需求太大它會先幫你縮。
  • 要審查或修正既有動畫。那是同 repo 的 review-animations 與 improve-animations 的工作;要挑動畫或元件函式庫,看 pick-ui-library。

🚧 限制與坑

  • 不打 /prototype 就不會跑。這是設計,不是 bug。要用就點名,Claude 不會在你描述「想看幾種做法」時自己想起它。
  • 版本數不一定照預設。我沒指定數量,它做了 4 個。想固定數量就在需求後面加 x3。
  • 第 5 階段需要瀏覽器工具。skill 要求 Claude 自己逐版切過、console 乾淨才交付;沒有瀏覽器工具時,它只能做到型別檢查和 lint,畫面是不是壞的要你自己看。我這次 4 版壞 1 版,就是在這一步漏掉的。
  • 它會自己開 dev server。這次 Claude 把 Vite 開在背景,任務結束後 process 還在跑,佔著 5173 埠。用完記得關。
  • 切換器不跟主題走。深色膠囊在任何背景下都長一樣,這是規格刻意的;元件本身固定在底部中央時(例如 bottom sheet、toast),要確認它有改用 data-position="top",不然會互相擋住。
  • 比直接做慢、貴一些。我這兩次是 175 秒對 115 秒、0.35 美元對 0.15 美元。多出來的成本換到的是隔離的原型區和有紀律的收尾。

🔗 延伸資源

下一步建議:挑一個你一直沒定案的小元件,打 /prototype <它的描述> x3。切換器開起來後,先把每一版都切一遍、開著 DevTools console 看一輪,確認沒有壞掉的版本,再開始比較哪個方向對。
author
陳
陳彥彤

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

support

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