# app-screenshots 是什麼?一個讓 Claude Code 自動產「標註版截圖文件」的 skill
有一種文件寫起來最煩:產品操作說明、UI 導覽、功能驗收報告。內容不難,煩的是那一堆截圖——你得一頁一頁開、一張一張截,再拿去小畫家或 Figma 上畫紅框、標「① 點這裡送出」「② 這是搜尋框」,標到手軟。改版一次,整批重來。
Alexander Opalic(alexop.dev)寫了一個 Claude Code skill 叫 app-screenshots,把這整條流程自動化:你只要說「幫我截圖這個網站做文件」,它會自己開頁、找元素、在截圖上畫好帶編號的語意標註、產出一份圖文對照的 Markdown。這篇拆解它是什麼、怎麼運作、底層那個沒被作者部落格講清楚的標註引擎,以及它適合誰。
本文是「介紹篇」。我另外寫了一篇覆盤,講我怎麼把它的零件吸進自己原本的截圖手冊產線做成更強的 skill,想看實作進階的可以接著讀。
TL;DR:app-screenshots 是一個 Claude Code skill,自動產「帶標註的截圖文件」——你講一句話,AI 自己開網頁 → 找元素 → 在圖上畫紅框/圈/箭頭 + 編號 → 產圖文對照 Markdown。底層靠 agent-browser + 298 行純前端 SVG 注入腳本 annotate.js。適合常產 UI 文件/導覽/驗收報告的人;一次性截一張圖用不到它。
重點速覽
- app-screenshots 是一個 Claude Code skill,自動產「帶標註的截圖文件」:AI 自己開網頁 → 找元素 → 在圖上畫紅框/圈/箭頭 + 編號 → 產圖文對照 Markdown。
- 底層靠 agent-browser(Vercel Labs 的 AI 專用瀏覽器 CLI)驅動 Chrome,加一支
annotate.js(298 行純前端 SVG 注入腳本)畫標註。 - 三種標註類型:
box(虛線框,標區塊)、click(實心圓+箭頭,標按鈕)、circle(圈+箭頭,一般提示);顏色自動輪替紅→藍→綠→琥珀→紫;每張最多 3 個標註;編號自動遞增,對得上 Markdown 內文的 (1)(2)(3)。 - 一句話定位:它把「開頁 → 截圖 → 手動標註 → 寫說明」這條純手工鏈,變成一句自然語言就跑完。
- 適合誰:要常產 UI 文件 / 產品導覽 / 驗收報告的人。不適合:一次性截一張圖,那手動更快。
- 它解決什麼問題
- 怎麼運作:六個階段
- 底層的標註引擎:annotate.js 到底做了什麼
- 三種標註類型怎麼選
- 實際跑出來長怎樣
- 安裝與使用
- 它的設計取捨:為什麼「每張最多 3 個標註」
- 踩過的坑
- 適合誰、不適合誰
- FAQ
它解決什麼問題
先講清楚它不是什麼:它不是給你手動塗鴉的畫圖工具(那種需求用 macOS 預覽、Skitch、Figma 就好)。它是讓 AI 自動把它「看懂的東西」畫進截圖裡,產出可以直接貼進文件的成品。
傳統做一份「網站操作手冊」的流程:
app-screenshots 把 1~4 收成一句話:「screenshot 這個網站,做成文件」。AI 幫你開頁、判斷每頁該標什麼、畫上帶編號的標註、產出圖文對照的 Markdown。改版時重跑一次指令即可。
怎麼運作:六個階段
skill 本體是一份 Markdown(給 Claude 讀的工作流指南),定義了六個階段:
Phase 1|決定目標——是 live 網站還是本機 dev server?live 站要先處理 cookie / consent 橫幅(用語意定位 find text "Accept" click),本機 server 要找對 port(3000/5173/4321/8080)、self-signed 憑證加 --ignore-https-errors。
Phase 2|盤點頁面——開首頁,先用 screenshot --annotate 快速掃一張「自動標所有互動元素」的survey 圖了解版面,再 snapshot 導覽列找出有哪些頁。SPA 還會提醒去 source code 撈 route 定義(不是每條路由都掛在 nav 上)。然後停下來問使用者確認頁面清單,live 站建議 5-10 頁。
Phase 3|逐頁截圖——這是核心,每頁一個嚴謹的迴圈:驗證 selector → 注入標註 → 檢查有沒有 FAILED → 讀圖驗品質 → 修或繼續。特別強調「先驗 selector 再標註」,因為失敗的 selector 會產生「隱形標註」(畫了等於沒畫),這在自動化流程裡最難抓。
Phase 4|產 Markdown——用編號 (1)(2)(3) 交叉引用圖上的標註 badge,產出 docs/。
Phase 5|環境比對(選配)——staging vs production、改版前後,用 diff url / diff screenshot / diff snapshot 做像素級與結構級比對。
Phase 6|收尾——解除網路攔截、關瀏覽器。
整個流程最值得學的是它的驗證紀律:每截一張圖都要「讀回那張圖」確認標註可見、沒重疊、沒被 cookie 橫幅擋住、頁面真的載完——不是截完就當成功。這跟我自己一直堅持的「round-trip 驗證」是同一套精神。
底層的標註引擎:annotate.js 到底做了什麼
作者的部落格文把 skill 的「用法」講得很清楚,但沒細講那支 annotate.js 怎麼把標註畫上去的。我把 298 行讀完了,機制其實很漂亮——它是純 client-side 的 SVG 注入,完全不靠任何後端繪圖:
document.body 尾巴塞一個 ,裡面一張撐滿全頁的 。關鍵是它用 position:absolute 而非 fixed——這樣配合 --full 全頁截圖時,標註會跟著內容一起延伸,不會只黏在視窗那一格。
canvas 量測 label 寬度:要畫「① 送出按鈕」這種帶底色的標籤,得先知道文字多寬才能畫對底色矩形。它用一個離屏 canvas 的 ctx.measureText() 實際量測字寬(還加了左右各 8px padding),所以中文、英文、長短標籤都貼合,不會爆框或留白。
六候選點避讓演算法:每個標籤預設想放在目標元素的右上角,但如果那裡已經有別的標籤,它會依序試 top-right → top-left → bottom-right → bottom-left → far-right → far-left 六個候選位置,挑第一個「在畫面內 + 不跟已放標籤重疊」的。全被佔滿還會做垂直微調(nudge)。這就是為什麼多個標註擠在一起時,標籤不會疊成一團看不清。
箭頭用三角形 marker:SVG 定義箭頭,Math.atan2 算出標籤到目標的角度,把箭頭尾端精準指到圈的邊緣(乘 0.85 留一點距離)。
編號 + 顏色狀態機:模組層有 __ann_counter 累加編號、__ann_placed[] 記錄已放位置。annotateMulti() 一次標多個時,顏色跟著 index 輪替 ['#ef4444','#3b82f6','#22c55e','#f59e0b','#8b5cf6'](紅藍綠琥珀紫)。
失敗大聲回報:annotateMulti 最聰明的一步——它檢查每個 selector 有沒有命中,只要有一個 Element not found,整個回傳字串前面就掛上 FAILED:,讓上層(Claude)一眼看到「這張有標註沒畫上」,而不是默默產出一張少標記的圖。這就是 Phase 3 那句「先驗 selector」能落地的原因。
這支腳本 298 行、零外部依賴、純 DOM + SVG,是整個 skill 最扎實的部分。
三種標註類型怎麼選
類型 長相 用途 選用規則 click實心圓 + 中心點 + 箭頭 + 編號 按鈕、連結、輸入框、icon 小元素首選(圓半徑有上限,不會爆開) box虛線外框 + 編號 卡片、表單群組、側欄、區塊 中型區域,框會貼合元素形狀 circle虛線圈 + 箭頭 + 編號(預設) 一般提示 通用 callout
作者給了一條很實用的反面規則:絕不要對整條 navbar / header 這種滿版元素用 circle 或 box——你會得到一個橫跨整個畫面的巨框,毫無資訊量。要標的話,標它裡面的具體項目。
還有一條:每種頁型該標什麼,skill 直接給了 checklist——首頁標 hero CTA / 搜尋框 / 一個 nav 範例;商品頁標價格 / 加入購物車 / 規格選擇;儀表板標一個 metric 卡 / 一個圖表 / 主要動作。不用自己想。
實際跑出來長怎樣
下面這張是我用它底層的 annotate.js 對一個真實頁面跑出來的實際成品(agent-browser 開頁 → 注入標註 → 截圖):
可以看到:紅色虛線框 + ❶ badge 框住主標題(box 類型)、藍色實心圓 + ❷ 箭頭指向連結(click 類型)。編號、顏色輪替、箭頭指向、標籤避讓全部自動——這張圖從開頁到產出,沒有任何一個像素是手動畫的。文件裡的內文就能寫「主標題 (1) 說明了……,點 (2) 進入下一步」,跟圖上的編號一一對應。
安裝與使用
前置:先裝 agent-browser(它是 skill 的引擎)。
npm i -g agent-browser && agent-browser install
agent-browser install 會抓一份獨立的 Chrome for Testing(裝在 ~/.agent-browser/browsers/,不動你日常的 Chrome)。
裝 skill:把作者的 skill 目錄放進 ~/.claude/skills/app-screenshots/(含 skill.md 和 references/annotate.js)。
用法:不需要打任何斜線指令。skill 是靠語意觸發的——你在 Claude Code 對話裡直接用白話講:
幫我截圖 https://example.com 做成操作文件
screenshot 我本機 localhost:5173 的 app
幫這個網站做視覺導覽
Claude 讀到「screenshot the app」「document this website」這類語意就會自動接上這個 skill,不用你記指令。
它的設計取捨:為什麼「每張最多 3 個標註」
這個限制乍看像偷懶,其實是刻意的設計。一張圖上標超過 3 個東西,會發生兩件事:(1) 標籤開始互相擠、避讓演算法再聰明也救不回來;(2) 讀的人失焦——文件的重點是「引導視線」,不是「把所有東西都圈起來」。
所以 skill 的建議是:標的東西多,就拆成多張圖(03a-top.png、03b-actions.png),而不是硬塞一張。這其實是好文件的通則——一次講一件事。窄視窗(mobile)更狠,建議降到每張 2 個。
同樣的「克制」也體現在它要求「先驗 selector 再標註」「截完讀回圖確認」——這個 skill 的價值不只在自動化,更在它把「怎麼產出一張好的標註圖」的隱性知識寫成了明確流程。
踩過的坑
我實際把它跑起來時,踩到幾個值得先知道的點:
- cookie / consent 橫幅會擋畫面:live 站第一步一定要先關掉同意橫幅,否則截出來半張圖被灰色遮罩蓋住。skill 用
find text "Accept" click 語意定位,比猜 selector 穩。 - 廣告 / 追蹤腳本會拖慢或蓋版:skill 內建
network route ... --abort 把 doubleclick、googlesyndication、gtm 這些擋掉,截圖才乾淨。 - selector 打錯 = 隱形標註:這是自動化最陰的坑。手動標註你眼睛會發現「咦這個框沒畫上」,自動流程不會——所以
annotateMulti 的 FAILED: 回報和 Phase 3 的「先驗 selector」是必須遵守的,不是可選的。 - ref 會過期:agent-browser 的
@eN ref 每次 snapshot 重編號,頁面一變(導航 / submit / re-render)舊 ref 立刻失效,標註前要重新 snapshot。
適合誰、不適合誰
適合:
- 要常產 UI 操作文件、產品導覽、release note 配圖的人
- 做 UI 驗收 / QA,需要「標註版截圖 + 說明」當交付物的人
- 想給 AI 一個「看著畫面標重點」能力的多模態工作流
不適合:
- 一次只截一張圖 → 手動截 + 標更快,不用動用整套 skill
- 需要精細美術設計的行銷素材 → 它的標註是功能導向(紅框編號),不是視覺設計
- 沒有 agent-browser 環境、也不想裝 Node 工具鏈的人
FAQ
Q:app-screenshots 跟直接叫 AI「截個圖」差在哪?
差在「標註 + 結構化 + 紀律」。直接叫 AI 截圖你只拿到一張乾圖;這個 skill 會幫你在圖上畫好帶編號的語意標註、產出圖文對照的 Markdown,而且內建「先驗 selector、截完讀回確認」的驗證流程,不會給你一張標歪或漏標的圖。
Q:一定要用 agent-browser 嗎?能用 Playwright 嗎?
skill 本身綁 agent-browser(它的 annotate.js 是靠 agent-browser 的 eval 注入的)。原理上 annotate.js 是純前端 SVG,理論上任何能執行頁面 JS + 截圖的工具(含 Playwright)都能套,但 skill 的工作流指令是照 agent-browser 寫的,換工具要自己改接法。
Q:標註是畫進圖片像素裡,還是另外一層?
截圖那一刻,標註是頁面上一層真實的 SVG DOM,所以會被一起截進 PNG 像素裡,產出的是「已經有標註的圖檔」,不是圖 + 另存的座標檔。這也是為什麼它能直接貼進 Markdown 就用。
Q:中文標籤會爆版嗎?
不會。annotate.js 用 canvas measureText 實際量測每個標籤的字寬再畫底色矩形,中文、英文、長短標籤都會貼合。我實測中文 label 顯示正常。
Q:它能標互動後的狀態嗎(例如展開的選單、搜尋建議)?
能。skill 有「interactive screenshots」段落:先 snapshot 拿 ref → 用 ref 點擊 / 輸入觸發狀態 → 再標註結果 → 截圖。搜尋建議、modal、hover 態都能標。
---
延伸資源