AI 工具 17 min read ★ Featured

app-screenshots 是什麼?讓 Claude Code 自動產「標註版截圖文件」的 skill

app-screenshots 是 Alexander Opalic 寫的 Claude Code skill:你只要說「幫我截圖這個網站做文件」,AI 就自己開頁、找元素、在截圖上畫好帶編號的語意標註(紅框圈按鈕、藍圈標連結)、產出圖文對照的 Markdown。底層靠 agent-browser 驅動 Chrome + 一支 298 行純前端 SVG 注入腳本 annotate.js。本文拆解它的六階段工作流、那支沒被作者講清楚的標註引擎(canvas 量測字寬、六候選點避讓、失敗大聲回報)、三種標註類型(box/click/circle)怎麼選、實際跑出來長怎樣、安裝使用、以及適合誰不適合誰。附我用它底層引擎跑出來的真實標註圖。

app-screenshots 是什麼?讓 Claude Code 自動產「標註版截圖文件」的 skill
本文目錄 · 12

# 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 文件/導覽/驗收報告的人;一次性截一張圖用不到它。

重點速覽

它解決什麼問題

先講清楚它不是什麼:它不是給你手動塗鴉的畫圖工具(那種需求用 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/-screenshots.md

    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 注入,完全不靠任何後端繪圖:

  • 注入一層 overlay:在 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 這種滿版元素用 circlebox——你會得到一個橫跨整個畫面的巨框,毫無資訊量。要標的話,標它裡面的具體項目

    還有一條:每種頁型該標什麼,skill 直接給了 checklist——首頁標 hero CTA / 搜尋框 / 一個 nav 範例;商品頁標價格 / 加入購物車 / 規格選擇;儀表板標一個 metric 卡 / 一個圖表 / 主要動作。不用自己想。

    實際跑出來長怎樣

    下面這張是我用它底層的 annotate.js 對一個真實頁面跑出來的實際成品(agent-browser 開頁 → 注入標註 → 截圖):

    app-screenshots 標註實際輸出:紅框標主標題、藍圈標連結,帶編號 badge

    可以看到:紅色虛線框 + ❶ 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.mdreferences/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.png03b-actions.png),而不是硬塞一張。這其實是好文件的通則——一次講一件事。窄視窗(mobile)更狠,建議降到每張 2 個。

    同樣的「克制」也體現在它要求「先驗 selector 再標註」「截完讀回圖確認」——這個 skill 的價值不只在自動化,更在它把「怎麼產出一張好的標註圖」的隱性知識寫成了明確流程。

    踩過的坑

    我實際把它跑起來時,踩到幾個值得先知道的點:

    • cookie / consent 橫幅會擋畫面:live 站第一步一定要先關掉同意橫幅,否則截出來半張圖被灰色遮罩蓋住。skill 用 find text "Accept" click 語意定位,比猜 selector 穩。
    • 廣告 / 追蹤腳本會拖慢或蓋版:skill 內建 network route ... --abort 把 doubleclick、googlesyndication、gtm 這些擋掉,截圖才乾淨。
    • selector 打錯 = 隱形標註:這是自動化最陰的坑。手動標註你眼睛會發現「咦這個框沒畫上」,自動流程不會——所以 annotateMultiFAILED: 回報和 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 態都能標。

    ---

    延伸資源

    author
    陳彥彤

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

    support

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

    related

    相關文章

    [工程實作] · 19min
    我怎麼把別人的 skill 吸進自己產線,做成更強的 skill:一次語意標註實作覆盤
    看到好用的 skill,大部分人裝來用;如果你有自己的產線,更值錢的做法是拆它的零件焊進你的流程。我原本有一套截圖審查+手冊產線(/screenshot-review),但手冊圖是「乾圖」沒有圖上標註——這正是 app-screenshots 的 annotate.js 補得上的洞。本文覆盤:我怎麼把它拆進產線,過程撞到一個架構級的坑(標註截不進圖=OVERLAY GONE:agent-browser 每個 CLI 指令是獨立 CDP 呼叫,eval 注入的 overlay 下一指令就蒸發),查根因、用 batch 把 open→eval→screenshot 綁進同一 session 解掉、封裝成 annotate-shot.sh、寫回自己的 skill。全程真的跑真的驗,附 batch 解法的真實成果圖與踩坑總表。
    [AI 工具] · 15min
    agent-browser 截圖標註:3 招讓 AI 看著畫面操作
    agent-browser 能在截圖上畫圖、寫字——不是給人塗鴉的小畫家,而是自動把 AI 看得懂的標記畫進截圖像素裡。這篇接續上一篇純文字流,實測它在截圖上畫東西的三種畫法——screenshot --annotate(在每個可互動元素上畫編號 [1][2][3] 並寫出對照清單,每個對應 @eN ref,截完可直接 click @e2)、highlight(在指定元素外畫高亮框做聚焦驗證)、diff screenshot(把畫面差異畫成像素級比對圖,抓「長相變了」,配合 diff snapshot 抓「結構變了」)——把只能讀純文字 snapshot(一頁 200-400 tokens)的 agent 升級成「看著畫面操作」,補上 icon 按鈕、canvas、純視覺狀態這些純文字抓不到的盲區。核心是 annotate 把視覺感知跟動作指令對齊:畫上去的 @eN 編號文字流跟視覺流共用同一套 ref,多模態模型看圖推理完直接產生跟純文字流一樣的指令。踩坑含 annotate 只支援 CDP 後端(Chrome/Lightpanda)Safari 不行、ref 會過期、diff threshold 不調會一直假警報。版本 v0.27.2,全程 Mac 實測。
    [AI 工具] · 17min
    agent-browser 是什麼?AI agent 專用瀏覽器自動化 CLI 實戰(含 Claude Code 接法)
    agent-browser 是 Vercel Labs 出的 AI agent 專用瀏覽器自動化 CLI,用 Chrome 跑、不依賴 Playwright。它最大的差別是「snapshot + refs」——回傳精簡的可訪問性元素清單(每頁約 200-400 tokens),而不是整坨 HTML。我今天把它裝到 Mac、跑通一個登入流程、再裝成 Claude Code skill,全程實測。這篇是覆盤:安裝怎麼裝、登入流程怎麼跑(snapshot→fill→click→截圖 round-trip)、踩了哪些坑(Hacker News 被反爬擋、ref 會過期、nvm 路徑可攜性),以及怎麼用「薄存根 + CLI 動態供給」把它接進 Claude Code 對話直接調用。