# 我怎麼把別人的 skill 吸進自己的產線,做成更強的 skill:一次語意標註的實作覆盤
看到一個好用的 Claude Code skill,大部分人的反應是「裝來用」。但如果你原本就有一條自己的產線,更值錢的做法是:把它的零件拆下來,焊進你自己的流程,補上它有、你沒有的那一塊。
上一篇我介紹了 Alexander Opalic 的 app-screenshots skill——它能讓 AI 自動在截圖上畫語意標註(紅框圈按鈕 + 帶編號的說明)。我原本就有一套自己的截圖手冊產線(/screenshot-review),能 debug + 看 UI/UX + 產操作手冊,但手冊裡的圖是「乾圖」——沒有圖上標註。這正是 app-screenshots 補得上的一塊。
這篇是實作覆盤:我怎麼把它的 annotate.js 拆進我的產線,過程中撞到一個架構級的坑(標註截不進圖),查出根因、用 batch 解掉、封裝成一支可重用的 wrapper,最後寫回我自己的 skill。全程真的跑、真的驗。
TL;DR:看到好用的 skill,大部分人裝來用;如果你有自己的產線,更值錢的是拆它的零件焊進你的流程。我把 app-screenshots 的 annotate.js 標註能力接進自己的截圖手冊產線,過程撞到架構級的坑(OVERLAY GONE:agent-browser 每個 CLI 指令是獨立 CDP 呼叫,eval 注入的 overlay 下一指令就蒸發),查根因後用 batch 把 open→eval→screenshot 綁進同一 session 解掉,封裝成 annotate-shot.sh 寫回自己的 skill。
重點速覽
- 起點:我有
/screenshot-review(自產的截圖審查+手冊產線),它產的手冊圖是乾圖,沒有「圖上紅框 + 中文說明」這種語意標註。 - 借的零件:app-screenshots 的
annotate.js(純前端 SVG 注入,能畫 box/click/circle + 編號 + 中文 label)。 - 撞到的坑:agent-browser 每個 CLI 指令是獨立的 CDP 呼叫,
eval注入的 SVG overlay 到下一個指令就蒸發(我叫它 OVERLAY GONE)。分兩步「先注入、再截圖」永遠截到空圖——這是架構特性,不是 bug(0.27 / 0.31 都一樣)。 - 解法:把
open → eval(注入) → screenshot塞進同一個agent-browser batch,同 session 頁面狀態保留,overlay 才留得到截圖那一刻。 - 成果:封裝成
annotate-shot.sh,一行產出中文語意標註圖;把這個能力 + 這個坑寫回我自己的' ' /screenshot-review,產線升級。 - 關鍵判斷:原生
screenshot --annotate也能標,但只有冷冰冰的[1][2]數字、無語意分類、不能寫中文——要語意標註就得走 annotate.js + batch 這條路。 - 我原本的產線長怎樣
- 缺的那一塊:圖上語意標註
- 第一次嘗試,撞牆:OVERLAY GONE
- 查根因:為什麼標註會蒸發
- 解法:batch 把注入和截圖綁進同一個 session
- 封裝成可重用的 wrapper
- 為什麼不直接用原生 --annotate
- 焊回自己的產線
- 這次「吸收式升級」的方法論
- 踩坑總表
- FAQ
我原本的產線長怎樣
我有一個自寫的 Claude Code command /screenshot-review,它的定位是「一舉三得」:對一個專案的所有 UI 截圖做批判性審查,看 → 不行就修 code → 重截 → 重看,循環到能誠實說出「邏輯合理、UI/UX 優秀」,順帶把驗過的截圖收斂成一份同模板的操作手冊。
它的靈魂是「反橡皮圖章」——不是看一眼說「都很棒」就交差,而是用設計師 + 資深工程師的眼睛逐張挑毛病,毛病解掉才准說「優秀」。手冊呈現有固定骨架(單檔 HTML、base64 inline 圖、左側欄佈局),跨專案看起來像同一條產品線出來的。
這套很成熟,但有一個一直沒補的洞。
缺的那一塊:圖上語意標註
我的手冊圖是乾圖——就是一張乾淨的頁面截圖。要說明「點這裡送出」「這是搜尋框」,我只能寫在圖外面的文字 caption 裡。
問題是:操作手冊最有效的表達,是圖上直接畫——紅框圈住那個按鈕、旁邊寫「① 送出」。讀的人視線不用在「圖」和「文字說明」之間來回跳。這正是 app-screenshots 的 annotate.js 做的事,而我的產線沒有。
所以目標很明確:把 annotate.js 的語意標註能力,接進我的手冊產線,讓 /screenshot-review 產的圖可以帶「紅框 + 中文說明 + 編號」。
第一次嘗試,撞牆:OVERLAY GONE
annotate.js 的用法看起來很直覺——它是純前端腳本,靠 agent-browser 的 eval 注入頁面。我照著最自然的分步流程跑:
agent-browser open https://example.com
agent-browser eval --stdin <<EOF # 注入 annotate.js + 呼叫 annotateMulti
$(cat annotate.js)
annotateMulti([{sel:'h1', label:'主標題', type:'box'}])
EOF
agent-browser screenshot out.png # 截圖
eval 那步回傳 annotated box #1: 主標題——標註確實畫上去了。但 screenshot 截出來的 out.png……是一張沒有任何標註的乾圖。標註憑空消失了。
第一反應是「selector 錯了吧」「時序問題吧」,試了加 wait、換 selector、確認 #__annotations overlay 真的被建立……全都沒用。eval 回報成功,screenshot 就是截不到。
查根因:為什麼標註會蒸發
停下來,不再瞎試。去理解 agent-browser 的執行模型。
關鍵事實:agent-browser 的每個 CLI 指令,是一次獨立的 CDP(Chrome DevTools Protocol)呼叫。agent-browser eval ... 和 agent-browser screenshot ... 是兩個分開的進程呼叫,即使 daemon 讓瀏覽器跨指令保持開著、頁面沒重新載入——
我在 0.27 和 0.31 兩個版本上都驗過——行為一致。所以這不是某版的 bug,是它「每指令獨立 CDP 呼叫」這個架構的必然結果。我把它記成 這個認知是整件事的轉折點:問題不在「怎麼注入」,在「注入和截圖必須在同一次 session 上下文裡發生」。 agent-browser 有一個 同一個 batch 內,頁面狀態在指令之間保留, ( 跑起來,截圖裡真的有標註了。下面這張是實際輸出——同一段流程,分兩步截到空圖、用 batch 一氣呵成截到有標註: 紅色虛線框 + ❶「主標題」框住 h1、藍色實心圓 + ❷「更多資訊連結」箭頭指向連結——中文 label 正常、box/click 兩種語意都對、顏色紅→藍輪替。這張圖從開頁到產出零手動。 解法有了,但每次手打 base64、拼 batch 太煩,而且容易忘掉 例如: 它內部做三件事:(1) 定位 annotate.js(同目錄或常見安裝位置);(2) 把 annotate.js 全文 + 現在產一張中文語意標註圖是一行指令的事,而且把「必須用 batch」這個非顯而易見的知識封在裡面,下次不用再重新踩坑。 有人會問:agent-browser 自己就有 因為兩者做的事不一樣。原生 但我要的是操作手冊——我要選定幾個重點元素、給它們語意分類(這是可點的按鈕 vs 這是一整塊區塊)、寫中文說明(「點這裡送出」不是「[2]」)。原生 所以這是一個清楚的分工: 最後一步:把這個能力寫回我自己的 這樣下次任何人(包括未來的我)跑 回頭看,這次做的不是「裝一個 skill」,是一套可複製的動作: Q:為什麼不乾脆直接用作者的 app-screenshots skill 就好,幹嘛自己焊? Q:OVERLAY GONE 是 agent-browser 的 bug 嗎?會被修掉嗎? Q:annotate-shot.sh 一定要 node 24 / agent-browser 0.31 嗎? Q:一張圖可以標幾個? Q:這套只能標 example.com 這種簡單頁嗎?真實 App 行不行? Q:焊進 ---eval 注入的那層 screenshot),它拿到的頁面狀態已經不含那層剛注入的 overlay 了。overlay 沒了,截圖自然是乾的。
OVERLAY GONE。解法:batch 把注入和截圖綁進同一個 session
batch 指令,能把多個操作塞進同一次 session 執行。這正是解藥——把 open、eval(注入)、screenshot 三步綁成一氣呵成:agent-browser batch --bail \
"open https://example.com" \
"eval -b <base64 的 annotate.js + annotateMulti 呼叫>" \
"screenshot out.png"eval 注入的 overlay 撐到 screenshot 那一刻還在,標註就進圖了。--bail 讓任何一步失敗就停,不會默默截出一張沒標註的空圖。eval -b 用 base64 傳 JS,是為了避開把整支 annotate.js + JSON 塞進 shell 時的跳脫地獄——引號、換行、中文全部包成一段 base64 就沒事了。)
封裝成可重用的 wrapper
--bail、忘掉 round-trip 驗。所以我把它固化成一支 wrapper annotate-shot.sh,放進 skill 的 references/ 下:annotate-shot.sh <url> <out.png> '<annotateMulti 的 JSON 陣列>'annotate-shot.sh https://example.com out.png \
'[{"sel":"h1","label":"主標題","type":"box"},
{"sel":"a.cta","label":"送出","type":"click"}]'annotateMulti(...) 呼叫 base64 編碼;(3) 用 agent-browser batch --bail 跑 open → eval → screenshot。跑完提醒你用 Read 開圖確認框真的畫出來(標註若回 FAILED: 代表 selector 錯,別交空圖)。為什麼不直接用原生 --annotate
screenshot --annotate,為什麼不用它?--annotate 是自動標所有互動元素,標籤是冷冰冰的 [1][2][3](對應 @eN ref,給 AI 看著操作用的),它的定位是「讓多模態 AI 看圖點按鈕」。--annotate 三件都給不了:不能選、只有數字、不能中文。
我借的正是原生給不了的那一塊。
需求 用哪個 AI 看圖自動操作(給機器讀) 原生 screenshot --annotate([N] = @eN)操作手冊語意標註(給人讀) annotate.js + batch(box/click + 中文 + 編號) 焊回自己的產線
/screenshot-review,不是讓它躺在一支孤立的腳本裡。我在那個 command 的「截圖踩過的坑」區塊,加了一條:手冊要「圖上有語意標註」→ 用 agent-browser batch,別信原生
--annotate:要語意標註(box/click + 自訂中文)得用 app-screenshots 的 annotate.js。坑:agent-browser 每個 CLI 指令是獨立 CDP 呼叫,eval 注入的 overlay 到下一個指令就蒸發(OVERLAY GONE,0.27/0.31 皆然,是架構特性)。解:把 open → eval → screenshot 塞進同一個 agent-browser batch --bail。已封裝成 references/annotate-shot.sh。/screenshot-review 產手冊,想在圖上加標註時,產線本身就會告訴他:用 annotate-shot.sh、別踩 OVERLAY GONE。知識固化進流程,而不是留在某個人的記憶裡。這次「吸收式升級」的方法論
annotate.js(298 行純 SVG,零依賴)。整包吞會帶進你不需要的工作流。--annotate vs annotate.js 的分工想清楚,才不會借錯——我要的是「給人讀的語意標註」,不是「給機器讀的自動編號」。踩坑總表
坑 症狀 根因 解 OVERLAY GONE eval 回報標註成功,但 screenshot 截到乾圖每個 CLI 指令是獨立 CDP 呼叫,注入的 overlay 下一指令蒸發 用 agent-browser batch 把 open→eval→screenshot 綁同 sessionshell 跳脫地獄 把 annotate.js + JSON 塞進 eval 引號/中文爆掉 多層引號 + 換行 + 中文 eval -b 用 base64 傳整段 JS靜默空圖 batch 有一步失敗但還是產了張沒標註的圖 沒設失敗中止 加 --bail,任一步失敗就停selector 打錯 = 隱形標註 圖產出來但少了某個標記 annotateMulti 命中不到元素 看回傳有沒有 FAILED:,截完 Read 開圖確認版本錯覺 以為升到 0.31 就會好 OVERLAY GONE 是架構特性不是版本 bug 0.27/node22 一樣能跑,核心是 batch 不是版本 FAQ
因為我原本就有一條成熟的截圖審查 + 手冊產線(/screenshot-review),它做的 debug + 反橡皮圖章審查 + 同模板手冊是 app-screenshots 沒有的。我要的不是換一套流程,是在我的流程上補一塊標註能力。拆零件焊進去,比整包換划算。
不是 bug,是它「每個 CLI 指令 = 一次獨立 CDP 呼叫」這個架構的必然結果。我在 0.27 和 0.31 都驗過,行為一致。所以別等它「修好」,正解就是用 batch 把注入和截圖綁進同一次 session。
不用。我實測 node v22 + agent-browser 0.27 一樣能跑。這支腳本的核心是「用 batch 保住 session」,不綁特定版本。0.31 只是需要 node ≥24,跟標註能不能截進圖無關。
沿用 annotate.js 的設計:每張最多 3 個標註(顏色輪替紅藍綠琥珀紫最多 5 色,但擠太多會互相避讓到看不清)。要標更多就拆成多張圖,這也是好手冊的通則——一張圖講一件事。
真實 App 完全行,這正是它的用途——標你自己專案的 dev server 頁面產操作手冊。真實站要多注意的是先關 cookie 橫幅、擋廣告腳本(annotate.js 那篇有講),以及 selector 要先驗(避免隱形標註)。/screenshot-review 後,我要怎麼觸發標註?
產手冊那一步,想在某張圖加語意標註時,直接呼叫 references/annotate-shot.sh <頁面url> <輸出png> '。command 的踩坑區已經寫明用它 + 為什麼要用 batch,所以流程本身會提醒你正確用法。延伸資源