第一週結束時它已經能操作產品,也留得下東西,只是留得很粗糙:截圖是隨手截的、console 是整包倒出來的,哪些重要、哪些是雜訊分不出來。今天把「有留」變成「留得對」,主角是 evidence-package 這個 skill,底下靠 Playwright 的 screenshot、trace、network 產出硬證據。段落順序照 2026-08-02 拍板的節次走,數字都是那天實跑量到的。
現在還沒開始找 bug,先教蒐證看起來像繞路。反過來想:等到真的找到東西才學留證,那一刻你手上只有一句「我剛剛看到它壞掉」,重現要重跑、細節靠回憶、開單前還得再走一次。這是新手最常付的一種學費。
留證還會逼出誠實。一份證據包會逼出兩件事:你只能寫得出檔案接得住的結論,而且你必須把看到的跟推論的分開寫。趁還沒有「我找到大 bug 了」的興奮感,先把這兩個習慣立起來,之後才擋得住誇大。
所以今天的示範情境刻意選最無聊的:登入成功、鎖定帳號被擋。重點不是抓到什麼,是留下 before/after 截圖與 trace;順手發現的小問題(例如錯誤後帳號欄未清空)要克制地標成待確認,不要當成缺陷回報。
2026-08-02 實跑一輪,Toolshop 登入到結帳前,產出長這樣:
output/evidence/20260802-toolshop-checkout/
01-home-after.png
02-login-before.png
03-login-filled-before.png
04-account-after-login.png
05-home-loggedin-after.png
06-product-before-addcart.png
07-product-after-addcart.png
08-cart-after.png
09-checkout-step2-signin-after.png
10-checkout-step3-billing-after.png
console.log
network.log
manifest.md
notes.md
trace.zip
四類檔案各有分工:
manifest.md:任務目標、環境、時間、trace 狀態、UI 對 API 的對照結論、步驟與截圖的對應表、各檔位置notes.md:目標、步驟(每步引截圖)、觀察(只寫看到的)、結論(每條至少一項證據)console.log 與 network.log:分開兩份,非 2xx 全部標記trace.zip:可回放的完整紀錄這一輪的實際收穫在 console.log 裡:畫面全綠、十張截圖都正常,但那份檔案有 29 筆 TypeError: Cannot read properties of undefined (reading 'cart_items'),全部集中在結帳頁。
十張截圖一張都拍不到這件事。如果 console 沒有獨立成一份檔案,這一輪的結論會是「流程正常」,而且沒有任何人會發現這句話錯在哪裡。
預設拍的是 viewport,要整頁得加 --full-page。
playwright-cli screenshot --filename output/evidence/<YYYYMMDD>-<slug>/03-login-before.png
playwright-cli screenshot --full-page --filename output/evidence/<YYYYMMDD>-<slug>/04-cart-after.png
--filename 一定要給含證據夾的完整相對路徑。只給檔名會掉在 repo 根目錄,而指令仍然回報成功,這個坑今天踩過。
一組 before/after 長這樣:

06-product-before-addcart.png:按之前,購物車徽章是空的。

07-product-after-addcart.png:按之後,徽章變成 1。兩張要成對留,只留後面那張,你證明不了那個 1 是這次按出來的。
trace 是一份可回放的紀錄:每一步的畫面快照、DOM、network、console 全在裡面。錄製:
playwright-cli tracing-start
# ...操作...
playwright-cli tracing-stop
打開有兩條路:
# 本機
npx playwright show-trace output/evidence/<YYYYMMDD>-<slug>/trace.zip
或把 trace.zip 拖進 https://trace.playwright.dev/,純前端,檔案不會上傳。交給別人重現時用這個,對方不用裝任何東西。
/evidence-package先掛載 skill:
bash scripts/link-skills.sh
然後給目標,不要給步驟:
/evidence-package 登入 saucedemo.com 使用 standard_user 是否能夠正常登入
/evidence-package 使用 locked_out_user 是否可以正常登入 saucedemo.com
skill 自己會做的事:建證據夾、開瀏覽器、開錄 trace、關鍵操作前後截圖、收工前導出 console 與 network、停錄打包、寫 manifest.md 與 notes.md。
playwright-cli 的說明第一行寫著「run playwright mcp commands from terminal」,套件是 @playwright/cli。它跟 @playwright/mcp 是兩個獨立套件(@playwright/cli 只相依 playwright,原始碼裡沒有 mcp),但命令面與回傳格式是同一套:兩邊都是 ### Page / - Page URL / ### Snapshot,open 和 navigate 回一個指向 .yml 的連結,snapshot 才把 YAML 整包吐出來。
| Playwright MCP | playwright-cli |
|
|---|---|---|
| 誰呼叫 | Claude 直接呼叫工具 | Claude 透過 Bash 下指令 |
| 工具定義 | 35 個工具的 schema 進 context | 沒有,借用既有的 Bash |
| 回傳內容 | 一樣 | 一樣 |
| 能不能先過濾 | 不能,整包進 context | 能,stdout 可以接 grep |
| trace 落地 | --output-dir 指定處 |
.playwright-cli/traces/ |
安裝:
npm install -g @playwright/cli@latest
playwright-cli --help
預設 headless,想看畫面在 open 加 --headed。
一、工具定義的固定開銷。 實測 Playwright MCP 的 tools/list:35 個工具、schema 共 25,907 字元,約 6,500 到 7,900 token。最肥的是 browser_take_screenshot(1,617 字元)、browser_fill_form(1,223)、browser_drop(1,137)。
這筆錢是「寫一次、讀很多次」:用 Day 7 那張表的單價估,一次性 cache write 約 $0.04,之後每個請求 cache read 約 $0.0035,二十幾步一輪累計約 $0.12。對照 Day 7 實測一輪 $3.5,不到 4%。playwright-cli 這邊是 0,因為 Bash 本來就在。
二、真正的大頭:回傳內容進不進得了篩子。 Day 7 算過那一輪 cache read 佔六成三,錢花在「每一步都要重讀前面走過的路」,路上最重的是頁面快照。
實測 8 月 2 日那一輪:9 份 snapshot 共 43,711 bytes,中位 2,961,最大 13,081;console 另外 27,982 bytes。全讀進 context 約一萬一到一萬二千 token,比工具 schema 大一個量級,而且每多走一步就再累積一次。
playwright-cli 的輸出是 stdout,可以在進 context 之前先過濾:
playwright-cli snapshot | grep -A4 'textbox'
playwright-cli network --raw | grep -v '=> \[2'
MCP 沒有這個位置,工具回什麼就整包進 context。
官方自己也這樣講。 @playwright/cli 的 README 有一節「Playwright CLI vs Playwright MCP」:CLI 之所以省,是因為它避開了 large tool schemas 與 verbose accessibility trees 進 context,賣點寫成「Does not force page data into LLM」。
但同一段給 MCP 的適用情境,不利於本系列的選擇:它建議 exploratory automation、self-healing tests、long-running autonomous workflows 這類需要持續瀏覽器脈絡的場景走 MCP。那正好是第三週到第五週要做的事。
這點不要迴避。Day 8 這個階段(照步驟蒐證、產出可攜證據包)確實是 CLI 的甜蜜點;等第三週真的放它自主探索,值不值得換回 MCP 要重新評估。
claude mcp add playwright -- npx @playwright/mcp@latest --caps=devtools --output-dir ./output/evidence/_traces
claude mcp get playwright
claude mcp remove playwright # 裝錯要重來
npx 前面那個 -- 不能省。少了它,後面的 --caps=devtools 會被當成 claude mcp add 自己的參數。
本專案已經有 .mcp.json,內容是上面那條指令的等價寫法。改走 MCP 的話 scripts/pack-trace.sh 要自己指路,因為它預設讀 playwright-cli 的暫存區:
PW_TRACE_DIR=./output/evidence/_traces bash scripts/pack-trace.sh output/evidence/<YYYYMMDD>-<slug>
trace 很肥。 今天那份 trace.zip 是 127 MB,一輪。跑三十輪就是幾個 GB。所以:只在失敗時留 trace 和影片、設保留期限(我用七天)、證據不進版控。
截圖和 trace 會把祕密拍進去。 trace 錄的是完整 network,含 request header 裡的 token;登入頁的截圖會拍到帳號,密碼欄雖然是圓點但填入的值在 trace 裡看得到。交出去之前要想過這件事,尤其是把 trace.zip 丟到線上 viewer 或附在 issue 上的時候。
playwright-cli 自己也帶一份 skill。 playwright-cli install --skills 會裝上官方版的瀏覽器操作 skill。它跟本專案的 evidence-package 不衝突:官方那份教「怎麼操作瀏覽器」,evidence-package 管「怎麼把過程組裝成一份可攜證據包」。
沒有 trace 怎麼辦。 tracing-start 失敗時,煙霧測試可以降級(截圖加 console 加 network 頂替,manifest 裡聲明「無 trace」);但要拿去開 bug 單就停手回報,不要拿降級的證據去開單。
多個瀏覽器同時跑。 playwright-cli -s=<session> <command> 可以開多個 session,驗越權(A 帳號的 token 讀 B 的資源)時用得上。
其他沒展開的命令。 video-start / video-stop / video-chapter 錄影,route 攔截並 mock 網路請求,storage-state 重用登入狀態。這些後面幾天會用到。
給目標而不是給步驟,讓 evidence-package 自己建夾、開錄、逐步截圖、收工導出 console 與 network,最後打包成一份別人拖進線上 viewer 就能重現的證據包。四類檔案各管一段:截圖管看得見的、console 與 network 管畫面說不出來的、manifest 與 notes 管「哪個結論由哪個檔案接住」。交出去之前確認兩件事,敏感資訊有沒有被拍進去,還有每一條結論是不是都指得到檔案。
給目標,不給步驟
│
▼
/evidence-package 自己跑
│
┌─────────┬───────┴───────┬─────────┐
▼ ▼ ▼ ▼
截圖 console.log network.log trace.zip
看得見的 畫面說不出來的 發了什麼 可回放全紀錄
│ │ │ │
└─────────┴───────┬───────┴─────────┘
▼
manifest.md / notes.md
(每條結論指得到一個檔案,觀察與推論分開寫)
│
▼
交出去之前先問兩句
祕密拍進去了嗎?結論接得住嗎?
趁還沒找到 bug 的時候先學留證,等興奮起來才學,第一份報告就會是憑記憶寫的。畫面全綠也不等於沒事,那一輪十張截圖都正常,console 裡有 29 筆 TypeError。而證據包的門檻是可攜:別人不必裝任何東西、不必重跑一次,就看得懂你的結論從哪來。
今天四類檔案都留下來了,但它們現在是平的:你手上有一疊證據,卻沒有規矩告訴你該先開哪一份。
明天處理這件事。同一個缺陷會同時落在兩份檔案上,一份寫症狀、一份寫原因,挑錯來源,缺陷就從你眼前走過去。
--caps 選項claude mcp add 的參數與 scopeSKILL.md 的結構與載入時機output/evidence/20260802-toolshop-checkout/ - 十張截圖、console 那 29 筆 TypeError 的原始檔