AI 工具 15 min read

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 實測。

agent-browser 截圖標註:3 招讓 AI 看著畫面操作
本文目錄 · 10
TL;DRagent-browser在截圖上畫圖、寫字——screenshot --annotate 在每個可互動元素上畫編號 [1][2][3] 並寫出對照清單、highlight 在指定元素外畫高亮框、diff screenshot 把畫面差異畫成像素級比對圖。重點不是給人塗鴉的小畫家,而是自動畫出 AI 看得懂的標記,把只能讀純文字 snapshot(一頁 200-400 tokens)的 agent 升級成「看著畫面操作」,補上 icon 按鈕、canvas、純視覺狀態這些純文字抓不到的盲區。版本 v0.27.2,全程 Mac 實測。

接續上一篇 agent-browser 是什麼。那篇把純文字流跑通了:snapshot 拿到 @eN refs、fillclick、截圖 round-trip。但寫完我自己卡在一個地方——有些頁面,純文字 snapshot 就是不夠用。

agent-browser 截圖標註 CLI 的 vercel-labs GitHub 專案頁

📌 目錄

🧩 純文字 snapshot 抓不到的那一塊

agent-browser 真的能在截圖上畫圖、寫字——它會把元素編號 [1][2][3]、對照清單、高亮框直接畫進截圖的像素裡。差別只在「畫什麼」:它不是給人塗鴉的小畫家,而是自動在截圖上畫出 AI 看得懂的標記與文字,把「只能讀文字的 agent」升級成「看著畫面操作」。這篇就把這三招畫法實測一遍。

為什麼需要在圖上畫東西?前一篇講的純文字 snapshot 很省 token,但它本質上是把頁面的可訪問性樹(accessibility tree)轉成文字。a11y tree 抓不到的東西,snapshot 就是空白:

  • 沒有文字標籤的 icon 按鈕——一個只有齒輪圖示、沒有 aria-label 的設定鈕,在 snapshot 裡可能根本看不出是什麼
  • canvas 畫的內容——圖表、白板、遊戲畫面,canvas 對 a11y tree 來說就是一塊黑盒
  • 純視覺狀態——某個元素變紅了、loading spinner 在轉、彈窗蓋住了底層,這些「看得到但讀不到」的狀態
這時候你需要的是讓 AI 真的看一眼畫面。但截圖丟給多模態模型有個老問題:模型看得到按鈕,卻沒辦法精準告訴你「點哪個」。agent-browser 的解法就是——在截圖上把資訊畫上去:畫編號、畫高亮框、寫對照文字。下面三招就是它在圖上畫東西的三種畫法。

🏷️ annotate:在截圖上疊元素編號

screenshot --annotate 是三招裡最核心的。它截圖的同時,在每個可互動元素上疊一個編號標籤 [N],而且每個 [N] 直接對應到純文字流的 @eN ref。

agent-browser screenshot --annotate

回傳長這樣(截圖檔 + 一份對照清單):

Screenshot saved to /tmp/screenshot-2026-02-17T12-00-00-abc123.png
  [1] @e1 button "Submit"
  [2] @e2 link "Home"
  [3] @e3 textbox "Email"

關鍵在最後一段話:截完 annotate 後,refs 會進快取,你可以馬上拿編號去操作。

agent-browser screenshot --annotate ./page.png
agent-browser click @e2     # 直接點截圖上標 [2] 的 "Home" 連結

這就是它設計得巧妙的地方——同一套 @eN ref,文字流跟視覺流共用。多模態 AI 看著截圖上的 [2] 推理「我要點首頁」,產生的指令 click @e2 跟純文字流一模一樣,不用兩套座標系統。官方把它形容成「你的可訪問性樹的視覺除錯器」(a visual debugger for your accessibility tree),蠻貼切的。

它解決的具體場景

  • 沒標籤的 icon:截圖一看就知道齒輪在右上角標 [7]click @e7 收工,不用猜 selector
  • 重疊/被遮擋的元素:snapshot 看不出哪個蓋住哪個,標號截圖一目了然
  • 給多模態模型當地圖:把 annotate 截圖丟進模型,它能「看圖點號」,比純文字描述精準得多

🔦 highlight:高亮單一元素

highlight 比 annotate 輕量,只做一件事:把指定的元素框起來高亮

agent-browser highlight @e1      # 高亮 ref
agent-browser highlight "button.submit"   # 也吃 CSS selector

用途跟 annotate 不一樣。annotate 是「全頁掃描」,一次標所有可互動元素;highlight 是「聚焦驗證」——我已經知道要操作哪個了,截圖前先 highlight 它,截出來確認「對,就是這顆」,避免點錯。

實際跑的時候,我常拿它做這種事:自動化流程跑到一半懷疑點錯按鈕,highlight @e5 + screenshot,肉眼確認一下再往下,比盲改 selector 快。

📊 diff screenshot:截圖像素級比對

第三招是視覺回歸測試的味道。diff screenshot現在的畫面跟一張 baseline 截圖做像素級比對。

agent-browser diff screenshot --baseline before.png        # 跟基準圖比
agent-browser diff screenshot --baseline b.png -o diff.png  # 輸出差異圖到指定路徑
agent-browser diff screenshot --baseline b.png -t 0.2       # 調色彩 threshold(0-1)

這跟它的另一個指令 diff snapshot 要分清楚——一個比畫面、一個比文字:

agent-browser diff snapshot                          # 比 a11y tree(文字層)
agent-browser diff snapshot --baseline before.txt    # 跟存檔的 snapshot 比
agent-browser diff screenshot --baseline before.png  # 比像素(視覺層)

差別在於:文字 diff 抓「結構改了」,像素 diff 抓「長相改了」。 一個按鈕從藍變紅、間距跑掉、字型 render 不一樣——這些 a11y tree 文字一字不差,但 diff screenshot 一比就現形。-t 調 threshold 是為了過濾抗鋸齒造成的微小色差,免得每次都報「有變化」。

它甚至能直接比兩個 URL:

agent-browser diff url https://v1.com https://v2.com --screenshot

新舊版上線前比個版面,這招很省事。

⚖️ 三招比較:什麼時候用哪個

指令做什麼典型場景比對對象
screenshot --annotate全頁疊元素編號 [N],對應 @eN給多模態 AI 當操作地圖、找沒標籤的 icon
highlight 高亮單一元素操作前聚焦驗證「是不是這顆」
diff screenshot現況 vs baseline 像素比對視覺回歸、版面跑版偵測✓ 像素
diff snapshot現況 vs baseline 文字比對結構/內容變動偵測✓ 文字
選的邏輯很單純:
  • 不知道頁面長怎樣、要 AI 看圖操作annotate
  • 已知目標、只想確認沒點錯highlight
  • 要抓「長相變了」diff screenshot
  • 要抓「結構/內容變了」diff snapshot

🧠 為什麼多模態 AI 需要看著有標號的畫面

這是整篇的核心。官方 README 對 annotate 的用途寫得很明白:它是給「能推理視覺佈局、沒標籤的 icon 按鈕、canvas 元素,或文字可訪問性樹捕捉不到的視覺狀態」的多模態 AI 模型用的。

把這句話拆開來看,背後的設計取捨是:

  • 純文字流省 token,但有盲區——一頁 200-400 tokens 很划算,但 icon/canvas/視覺狀態是它的天花板

  • 純截圖丟模型,模型看得到卻點不準——「點那個藍色按鈕」對模型來說,要換算成精準的點擊指令很容易出錯

  • annotate 把兩者接起來——截圖(給模型看)+ 編號(給模型一個精準的可操作 handle),[2] 對應 @e2,看圖推理完直接 click @e2
  • 換句話說,annotate 不是「截個圖」,是幫多模態 AI 把視覺感知跟動作指令對齊。模型負責「看懂這是首頁連結」,agent-browser 負責「首頁連結 = @e2 你點就對了」。這個分工是它比「直接餵截圖給模型」好用的原因。

    screenshot --annotate

    看圖

    推理: 我要點首頁=2

    執行

    網頁畫面

    標號截圖 + @eN 對照表

    多模態 AI 模型

    click @e2

    ⚠️ 踩坑紀錄

    annotate 只支援 CDP 後端,Safari 不行

    這是查 README 時最該記的一條限制:

    Annotated screenshots are supported on the CDP-backed browser path (Chrome/Lightpanda). The Safari/WebDriver backend does not yet support --annotate.

    annotate 只在 CDP 後端(Chrome / Lightpanda)能用,Safari/WebDriver 後端目前不支援。 如果你在 Mac 上習慣跑 Safari 後端,--annotate 會無效。要用視覺標註就乖乖切 Chrome。

    ref 會過期,annotate 也救不了

    承襲前一篇講過的坑:@eN ref 是「這一次 snapshot 的快照」,頁面一重整、一導航、DOM 一變動,ref 就失效。annotate 截圖快取的 ref 也一樣——截完 annotate 別拖太久才操作,中間如果頁面動了,先重截一次。我踩過一次:annotate 完去做別的事,回來 click @e3 點到不存在的元素。

    diff threshold 不調,每次都報有變化

    diff screenshot 不帶 -t 用預設值時,抗鋸齒、字型 sub-pixel render 的微小差異會被算成「有變化」。做視覺回歸時記得 -t 0.1 ~ -t 0.2 過濾雜訊,不然 CI 會一直假警報。

    ❓ 常見問題

    Q1:agent-browser 可以在截圖上畫圖、寫字嗎?
    可以,而且這正是它的賣點。--annotate 會在截圖上畫出元素編號 [N] 並寫出對照清單highlight 會在指定元素外面畫高亮框diff screenshot 會把差異畫在輸出圖上——這些都是直接畫進截圖像素裡的標記與文字。它不是讓你手動塗鴉的小畫家(要手畫框寫字用 macOS 預覽、Skitch 那類工具),而是自動畫出 AI 看得懂的標註,畫的目的是讓多模態模型看圖就能精準操作。

    Q2:annotate 的編號 [N] 和純文字 snapshot 的 @eN 是同一套嗎?
    是。這是它設計得最聰明的地方——[2] 對應 @e2,視覺流跟文字流共用同一套 ref,不用維護兩套座標。

    Q3:diff screenshot 跟 diff snapshot 差在哪?
    diff screenshot 比像素(長相變了沒),diff snapshot 比可訪問性樹(結構/內容變了沒)。按鈕變色、跑版用前者;DOM 結構、文字內容變動用後者。

    Q4:為什麼 Safari 後端不能用 annotate?
    annotate 需要 CDP(Chrome DevTools Protocol)的能力來掃描並疊加元素標籤,Safari 走的是 WebDriver 協定,目前還沒實作這塊。要用 annotate 就切 Chrome 或 Lightpanda 後端。

    Q5:這些指令適合接進 Claude Code 嗎?
    適合。跟前一篇的純文字流一樣,這三招都是 CLI 指令,可以用「薄存根 + CLI 動態供給」的方式接進 Claude Code,讓對話裡直接調用。多模態場景(要 AI 看圖)特別適合用 annotate 當輸入。

    🔗 延伸資源

    author
    陳彥彤

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

    support

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

    related

    相關文章

    [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 對話直接調用。
    [工程實作] · 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 工具] · 17min
    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)怎麼選、實際跑出來長怎樣、安裝使用、以及適合誰不適合誰。附我用它底層引擎跑出來的真實標註圖。