Expo 技能評估
評估 plugins/expo/skills/ 中的技能,針對觸發準確性、生成程式碼品質,以及在 Expo Go 中的運行時渲染。
需求:macOS 搭配 Xcode(iOS 模擬器)、Android SDK(至少一個 AVD)以及 bun。不假設其他裝置工具。
工作區根目錄:/private/tmp/expo-skill-eval-<技能名稱>/iteration-N/(例如 /private/tmp/expo-skill-eval-expo-ui/iteration-4/)。
開始之前 — 釐清範圍
在開始任何管線工作之前,先確認以下所有項目 — 不要遺漏任何一項(如果請求已明確指定某個選擇,則可跳過該項)。將它們批次放入 AskUserQuestion 呼叫中,每次最多 4 個問題,按以下順序:
- 要評估哪個技能(如果請求中不明確)。
- 提示詞 — 驅動評估的提示詞。內建提示詞(來自技能的評估案例)預設全部選取;可以取消選取任何一個、新增自訂文字提示詞,或從上傳的螢幕截圖建立(技能必須重現的目標使用者介面)。請參閱提示詞部分。
- 要驗證的項目 — 三個選項的多選:運行時 + 螢幕截圖 / 觸發準確性 / 程式碼檢查(無需裝置)。請參閱要驗證的項目部分。
- Expo SDK — 最新版本(預設,自動偵測)或固定版本。
- 執行器 — Expo Go(預設)或開發建置。
- 平台 — iOS / Android / Web(總是提供所有三個選項)。
claude -p的權限標記 — 跳過權限(預設)或接受編輯。- 查看器交付方式 — 僅限本機(預設)或發布可分享的 Artifact。
- 如果選擇了觸發準確性 — 確認已發布的
expo外掛程式已停用(或未安裝)。
以下詳細說明每一項。第 4–6 項(SDK、執行器、平台)自然適合放在一個 AskUserQuestion 呼叫中。
如果請求中不明確要評估哪個技能,則列出 plugins/expo/skills/ 中可用的技能,並詢問要評估哪一個。
如何載入待測技能 — 每個階段有兩種機制(不要全域選擇一種):執行器透過檔案路徑引用技能(SKILL_PATH = plugins/expo/skills/<skill>/SKILL.md,明確讀取),而觸發評估則將其作為外掛程式載入(--plugin-dir plugins/expo,讓模型可以根據其描述自動選取)。兩者都指向儲存庫中的本機版本 — 這就是您要評估的內容。您不需要任何特殊標記來啟動測試工具工作階段本身(測試工具透過儲存庫路徑找到技能);這些機制適用於它產生的 claude -p 子程序。請參閱步驟 1 和 3,了解每個階段為何不同。一個預先執行的檢查(當觸發評估在範圍內時必須執行): 如果已發布的 expo 外掛程式已安裝/啟用,請在啟動測試工具之前將其停用(透過 /plugin),並在之後重新啟用。單次停用是一個全域設定變更,此工作階段和產生的 claude -p 子程序都會繼承。為什麼觸發評估需要這個:該階段透過 --plugin-dir 載入本機技能,而第二個已安裝的 expo 會與其衝突 — 模型可能會觸發已發布的 expo:expo-ui,而且由於偵測只看到工具呼叫名稱,您會默默地為已發布的描述而非您的本機編輯內容評分(衝突也可能只會導致錯誤)。執行器 / 運行時 / 靜態階段不會受到影響 — 它們透過本機的 SKILL_PATH 讀取待測技能,而不使用 --plugin-dir — 因此沒有觸發評估的執行可以跳過停用。停用 expo 並不會停用 expo-skill-eval(這是一個獨立的專案技能,不是 expo 外掛程式的一部分),因此測試工具仍然可用。
將此作為明確的預先確認呈現給用戶 — 就像您確認要評估哪個技能一樣。當觸發評估在範圍內時,在開始步驟 1 之前,要求用戶確認已發布的 expo 外掛程式已停用(或未安裝);如果它仍然啟用,請暫停並讓用戶透過 /plugin 將其停用。在他們確認之前,不要執行觸發評估 — 測試工具無法可靠地自行偵測已安裝的外掛程式(讀取全域外掛程式設定或 claude plugin list 會提示),因此這是手動確認,而非自動檢查。
選擇提示詞 — 內建、自訂或目標螢幕截圖。 提示詞是驅動執行器(有技能和無技能)的輸入;它們與您要驗證的內容不同。使用 AskUserQuestion 確認它們(如果請求已指定提示詞,則跳過):
- 內建提示詞 — 您透過閱讀待測技能(其
SKILL.md+references/)和references/runtime-matrix.md產生的代表性提示詞,涵蓋技能的標準使用案例。(如果技能已有evals/evals.json下的評估案例,也將它們的prompt欄位納入 — 但大多數技能沒有,因此您通常需要自行衍生。)預設全部選取,因此預設執行會涵蓋技能的標準案例;讓用戶可以取消選取任何一個。 - 自訂文字提示詞 — 用戶輸入的一次性提示詞。不要為此花費一個專用選項位置:
AskUserQuestion會自動新增一個 「輸入內容」 / 其他項目,而輸入的任何內容都將成為一個自訂文字案例。 - 從上傳的螢幕截圖建立 — 用戶提供一個目標螢幕截圖(要重現的使用者介面)的路徑。執行器被告知要開啟它 —
claude -p使用其 Read 工具讀取 PNG — 並建立一個與之相符的應用程式;該案例將路徑記錄為reference_image,評分會將生成的應用程式與該目標進行比較(步驟 6)。這是對使用者介面技能最強的視覺測試:「建立這個」。
在遵守 AskUserQuestion 每個問題最多 4 個選項的限制下,使用以下優先順序(要避免的錯誤:上傳選項在四個位置填滿時會被靜默丟棄):
- 始終為「從上傳的螢幕截圖建立」保留一個位置。 這是視覺評估的重點,絕不能是那個被丟棄的選項。
- 不要新增明確的「自訂文字提示詞」選項 — 自動的「輸入內容」/ 其他項目已涵蓋。
- 用內建/代表性提示詞填滿剩餘的 ≤3 個位置,預設選取。如果提示詞超過 3 個,將它們摺疊成一個預設選取的 「所有內建提示詞(預設)」 選項,並在簡短的後續詢問中提供子集選擇,以便上傳選項仍然能容納。
將其呈現為一個多選。當選取「從上傳的螢幕截圖建立」時,在後續詢問中要求提供目標影像路徑。每個選取的提示詞(內建、輸入的或影像)都將成為一個評估案例(使用技能和不使用技能運行)。
始終確認要驗證的內容,除非請求已明確說明。呈現這些選項,讓用戶選擇一個或多個(根據技能的 references/runtime-matrix.md 條目,粗體顯示預設值):
| 選項 | 功能 | 何時建議作為預設值 |
|---|---|---|
| 運行時 + 螢幕截圖 | 完整管線:固定範本 → 執行器 → 靜態閘道 → 在 iOS/Android 上執行應用程式並截圖。執行器(Expo Go 或開發建置)是一個單獨的問題 — 不要在這裡提及。 | 預設用於任何渲染應用程式畫面的技能(references/runtime-matrix.md 中的 expo-go/dev-build 行)。需要已啟動的模擬器/模擬機。 |
| 觸發準確性 | 透過 claude -p 執行實際提示詞,檢查技能是否被讀取。衡量召回率(僅限應觸發的查詢)。 | 作為獨立檢查始終有用。 |
| 程式碼檢查(無需裝置) | tsc --noEmit + 差異感知 lint + expo export,加上評分者根據您提供的任何自訂期望檢查生成的程式碼。無需裝置。 | static-only 和 n/a 技能的預設值,以及當您想在無需執行應用程式的情況下驗證程式碼模式(正確的匯入路徑、Host 包裝器…)時。 |
| 將其作為一個多選問題呈現 — 「您想要驗證什麼?」 這些是評分維度(如何判斷建置的內容) — 與提示詞階段(要建置什麼)不同。用戶可以選擇任何組合。當提示詞是上傳的螢幕截圖(請參閱提示詞)時,請包含**「運行時 + 螢幕截圖」**,以便測試工具捕捉生成的應用程式,評分者可以將其與目標進行比較。 |
在建議之前,閱讀 references/runtime-matrix.md 以找到技能的預設模式。如果請求已指定模式(例如「只檢查是否觸發」、「在裝置上執行」),則跳過問題並繼續。
選擇 Expo SDK 版本 — 一次,預先進行。 使用 bash /abs/path/expo-skill-eval/scripts/latest-sdk.sh 偵測最新版本(它會列印主版本號,例如 56;內部使用 bun 執行 npm view expo dist-tags --json 並透過 JSON.parse/semver 讀取主版本號,並且受 bash 腳本規則保護 — 因此不要自己內聯執行登錄查詢,這會提示)。然後使用 AskUserQuestion 確認:預設為該最新 SDK,或讓用戶固定一個較舊的版本(例如為了重現特定版本的錯誤)。在建立固定範本的所有地方使用選擇的版本 — 將其作為 <sdk> 參數傳遞給 make-fixture.sh,並將其寫入每個評估案例的 runtime.sdk。如果請求已指定版本(「在 SDK 54 上評估」),則跳過偵測並使用該版本。
預設使用最新版本 — 它與 expo start 在裝置上安裝的 Expo Go 保持相容。將 SDK 固定為比裝置上安裝的 Expo Go 更舊的版本,會使 expo start 嘗試提示「安裝建議的 Expo Go 版本?」;如果沒有 TTY(快照腳本從 /dev/null 讀取標準輸入),它會因 需要輸入,但 'npx expo' 處於非互動模式 而失敗,並且每個快照都會失敗。因此,只有在您也在模擬器/模擬機上預先安裝了匹配的 Expo Go 時,才固定較舊的 SDK — 否則堅持使用最新版本。
選擇執行器 — Expo Go(預設)或開發建置。 使用 AskUserQuestion 詢問(如果請求已指定哪個,則跳過):
- Expo Go(預設) — 快照腳本按原樣使用
expo start --ios/expo start --android執行應用程式。速度快(無需原生編譯),並且可以執行 Expo Go 捆綁的任何內容(包括 SDK 56+ 上的@expo/ui)。無法執行自訂原生程式碼(expo-modules、config 外掛程式、Expo Go 中沒有的原生依賴項)。 - 開發建置 — 快照腳本改為執行
expo run:ios/expo run:android,為每個固定範本編譯一個原生開發用戶端。對於輸出需要自訂原生程式碼的技能(否則這些案例將是static-only)使用此選項。速度慢得多 —expo run會為每個固定範本預先建置並原生編譯(數分鐘,尤其是第一次),並且需要完整的 iOS/Android 建置工具鏈 — 因此僅在技能確實需要原生程式碼時選擇它。磁碟空間消耗大: 每個固定範本的原始建置都是多 GB 的。快照階段會在每個固定範本之後執行clean-fixture.sh,以將峰值使用量控制在約一個建置範圍內,但仍建議對於開發建置執行,使用較少的評估案例和單一平台,並保留幾 GB 的可用空間。clean-fixture.sh會移除每個固定範本的建置輸出(node_modules、ios、android、.expo、dist以及該固定範本的 iOS DerivedData),並保留應用程式原始碼和 git。開發建置的磁碟空間槓桿是較少的評估案例 + 單一平台 — 它只回收每個固定範本的建置輸出,絕不會觸碰共享的依賴項快取,因此不會重新下載任何內容。
將選擇透過 EXPO_SKILL_EVAL_RUNNER 環境變數(expo-go 預設,或 dev-build)傳遞給快照腳本,並反映在每個評估案例的 runtime.mode(expo-go 或 dev-build)中。請參閱步驟 5。
選擇平台 — 無論技能為何,總是詢問。 提供 iOS / Android / Web(多選)並使用 AskUserQuestion;預設為 iOS + Android,但總是將 Web 作為選項呈現 — 不要根據技能預先過濾。Web 對大多數技能來說都是有效的選擇:@expo/ui 的通用元件(Host、Row、Column、Button、List…)會在 Web 上渲染,expo-dom、NativeWind/Tailwind、API 路由和純 React Native 也是如此。唯一不會在 Web 上顯示的是平台特定的原生樹(@expo/ui/swift-ui 或 @expo/ui/jetpack-compose),它會在那裡渲染為空白 — 而這個空白本身也是一個有用的信號,因此它仍然是用戶的決定。Web 透過 snapshot-web.sh(expo start --web + Playwright/Chromium)執行,無論執行器為何(expo run 是原生專用的;沒有 Web 開發建置),並且這是最少被測試的路徑。將選擇的平台集合寫入每個評估案例的 runtime.platforms,並讓 run_snapshots.py 對它們進行迴圈處理。
確認 claude -p 子程序如何執行 — 一次,在開始之前。 使用 AskUserQuestion 詢問它們是否可以使用 --dangerously-skip-permissions 執行,然後將相同的答案應用於此執行的每個子程序(切勿在執行中重新提示):
- 跳過權限(建議) — 傳遞
--dangerously-skip-permissions。每個子程序在/private/tmp/expo-skill-eval-*下的可拋棄固定範本中無人值守執行,並且可以寫入檔案和執行設定指令,而無需提示。 - 僅接受編輯 — 改為傳遞
--permission-mode acceptEdits。Bash/安裝會自動拒絕(無 TTY),因此某些評估可能會產生部分輸出。
一個不帶任何標記的裸 claude -p 根本無法寫入檔案。如果請求已指定偏好(「跳過權限」、「不要使用危險標記」),則跳過問題。
確認如何交付結果檢視器 — 一次,預先進行。 發布到 claude.ai 是對外的,因此切勿在執行中意外進行;在相同的預先 AskUserQuestion 中詢問(與權限標記一起):
- 僅限本機(預設) —
generate_viewer.py寫入viewer.html並在本機瀏覽器中開啟。沒有資料離開機器。 - 發布可分享的 Artifact — 另外在最後將檢視器渲染為 claude.ai Artifact(一個預設為私有的網頁,用戶可以與團隊成員分享)。僅當用戶在此處選擇加入時才執行此操作。
如果請求已指定是否分享/發布,則跳過問題。請參閱檢視器部分以了解發布機制。
評估案例架構
您為執行生成評估案例 — 每個選擇的提示詞一個 — 並將它們寫入 <workspace>/iteration-N/evals.json(檢視器從那裡讀取它們)。每個案例 e
…
[為翻譯而截斷]