Webwright 完整教學

Microsoft Research 出品的極簡瀏覽器 agent framework — 用 ~1.5k LoC 在 Online-Mind2Web 拿下 86.7% SOTA,在 Odysseys long-horizon benchmark 上比前一 SOTA 高 15.6 點。


1. 專案定位

1.1 一句話

Webwright 不是另一個「點擊機器人」,是「會寫 Playwright 程式的 LLM 工程師」。

1.2 為什麼要看這個專案

1.3 跟 browser-use / Stagehand / agent-browser 的差異

維度Stagehandagent-browser (Vercel)browser-useWebwright
行為空間NL → Playwright離散 subcommandindexed click/type自由 Python
狀態定義browser sessionbrowser sessionbrowser sessionlocal workspace
Loop 形狀imperative一次 CLI = 一個 micro-stepobserve→predict→executewrite code → execute → inspect → repair
強項開箱易用多 agent 共用DOM 控制完整long-horizon + 可重跑

1.4 為什麼「code-as-action」優於 coordinate prediction

  • 抗 token 爆炸:一次寫完 10 步驟程式 = 一次 LLM call,傳統 step-by-step = 10 次 call
  • 可重跑:產出 final_script.py 可加上 argparse 變成 CLI tool(--craft 模式)
  • 可除錯:失敗時看 Python traceback 比看 LLM 的「我以為點到 X」容易得多

2. 安裝指南

2.1 環境需求

項目版本
Python≥ 3.10
Chromium透過 Playwright 安裝
API KeyOpenAI / Anthropic / OpenRouter 至少一家

2.2 三種安裝方式

A. 直接 clone + pip 開發模式(最透明)

1git clone https://github.com/microsoft/Webwright.git
2cd Webwright
3uv venv && source .venv/bin/activate     # 我們的 §6.2 規範用 uv 不用 pip
4uv pip install -e .
5playwright install chromium

B. 作為 Claude Code Plugin(最快)

1/plugin marketplace add microsoft/Webwright
2/plugin install webwright@webwright

重啟 Claude Code session 後,/webwright:run/webwright:craft 兩個 slash command 即可用。

C. 作為 Codex Plugin(OpenAI CLI)

1codex plugin marketplace add microsoft/Webwright
2codex
3/plugins   # 選 webwright 安裝

2.3 安裝流程圖


flowchart TD
    Start([開始])
    Check{已有 Claude Code 或 Codex?}
    InstallA[git clone + uv pip install -e .]
    InstallB["/plugin marketplace add"]
    Playwright[playwright install chromium]
    EnvKey{選擇 backend}
    KeyA[export OPENAI_API_KEY]
    KeyB[export ANTHROPIC_API_KEY]
    KeyC[export OPENROUTER_API_KEY]
    Test[python -m webwright.run.cli --help]
    Done([可用])

    Start --> Check
    Check -- "否,獨立 CLI" --> InstallA
    Check -- "是,當 plugin" --> InstallB
    InstallA --> Playwright
    InstallB --> Playwright
    Playwright --> EnvKey
    EnvKey -- OpenAI --> KeyA
    EnvKey -- Anthropic --> KeyB
    EnvKey -- OpenRouter --> KeyC
    KeyA --> Test
    KeyB --> Test
    KeyC --> Test
    Test --> Done


3. 核心架構解析

3.1 整體系統圖


flowchart TB
    User[User Task 指令]
    CLI["webwright/run/cli.py
typer entry
~150 LoC"] Config["config/
base.yaml + model_*.yaml
stack-merge"] Agent["agents/default.py
核心 prompt-observe-execute loop
~450 LoC"] Model["models/
openai_model | anthropic_model | openrouter_model
each ~150-200 LoC"] Env["environments/
local_workspace + local_browser
~860 LoC"] Tools["tools/
image_qa + self_reflection
+ persistent_local_browser"] Playwright[(Playwright Chromium)] Workspace[(local workspace
plan.md + final_runs/ + screenshots)] Output[outputs/<task_id>_<timestamp>] User --> CLI CLI --> Config CLI --> Agent Config --> Agent Agent <--> Model Agent <--> Env Env --> Playwright Env --> Workspace Tools -.被 LLM 調用.-> Agent Agent --> Output

3.2 Agent loop 的「Three Field Contract」

Agent 每次 LLM call 期待回傳三個欄位:

欄位用途
thoughtLLM 的 reasoning(不執行)
bash_command要在 workspace 執行的 bash(會被 subprocess.run(shell=True) 跑)
done是否任務完成(bool)

設計優雅之處:所有行為都壓在一個 bash 欄位 — LLM 可以寫 python -c "..."cat > foo.py <<EOFpytestplaywright codegen,自由度極高且 surface area 極小。

3.3 三種 environment 對比

環境設定檔適用場景
local_workspacebase.yaml純程式碼任務,無瀏覽器
local_browserlocal_browser.yaml用本地真實 Chrome/Edge over CDP(保留 user-data-dir)
persistent_browserpersistent_browser.yaml跨步驟保留 Chromium subprocess(含 cookies / open tabs)

3.4 模型 routing(2026-05-27 修正後)

之前 issue #3 反映「只有 ANTHROPIC_API_KEY 跑不起來」— 因為 image_qaself_reflection 兩個 inner tool 硬編 OpenAI。修正後(PR #5 + refactor #10):所有 inner tool 透過 tools/_model_config.py 統一讀取 agent.model_class 設定。


4. Helper Scripts 詳細用法

4.1 CLI 主入口

1python -m webwright.run.cli \
2    -c base.yaml -c model_claude.yaml \
3    -t "Search for flights from SEA to JFK on 2026-08-15 to 2026-08-20" \
4    --start-url https://www.google.com/flights \
5    --task-id demo_claude \
6    -o outputs/default
Flag說明
-c設定檔(可疊加,後者覆蓋前者)
-t任務指令(自由文字)
--start-url初始頁
--task-id輸出子資料夾名
-o輸出目錄

4.2 設定檔 stack 順序

 1# 純 OpenAI 跑網路爬
 2-c base.yaml -c model_openai.yaml
 3
 4# 純 Anthropic 跑網路爬(fix #3 後)
 5-c base.yaml -c model_claude.yaml
 6
 7# 切換到 persistent browser(跨步驟保留 Chromium)
 8-c base.yaml -c persistent_browser.yaml -c model_claude.yaml
 9
10# 走 task showcase mode(會額外產 report.json)
11-c base.yaml -c model_claude.yaml -c task_showcase.yaml
12
13# 跑 craft 模式(產可重跑 CLI)
14-c base.yaml -c model_claude.yaml -c crafted_cli.yaml

4.3 Slash command(plugin 模式)

指令行為
/webwright:run <task>一次性任務,產 final_script.py(hard-coded 參數)
/webwright:craft <task>把任務寫成可重跑 CLI(含 argparse、Google-style docstring)

4.4 Persistent browser 的隱藏工具

1# 啟動持久 Chromium subprocess
2python -m webwright.tools.persistent_local_browser \
3    --workspace-dir /path/to/ws create --out .lb_session.json
4
5# 之後 Playwright 透過 CDP 連線
6# session 檔含 id / pid / connectUrl / userDataDir

5. 應用場景

場景用 Webwright 做什麼替代什麼現有工作流
BD 對手 IR 抓近期新聞自動跑 IR site / SEC EDGAR 抓 8-K手動巡邏 + opencli adapter
競品 pipeline 比對跑 ClinicalTrials.gov + Cortellis 截圖手抓 + Excel 整理
學會議程錄影盤點跑 ASCO / AACR session list 抓 abstractmeeting-intel skill 觸發前的素材蒐集

5.2 跟 opencli 的功能切分

Webwright 適合

  • 一次性、不可預期、需要 LLM 判斷的爬取
  • 探索性研究(不知道對方 site map)
  • 寫好之後變成可重跑 CLI(/webwright:craft 模式)

opencli 適合

  • 固定 endpoint、固定 JSON schema
  • 高頻、需要 zero LLM cost
  • 已有 adapter 維護的 site

5.3 跟 paper-tutorial / gh-tutorial-qd 的關係

Webwright 是「對網頁的 tutorial」生成器;本專案的 paper-tutorial / gh-tutorial-qd 是「對 paper / repo 的 tutorial」生成器。互不取代,未來可能整合:Webwright 抓 paper full text → docling 轉 md → paper-tutorial 整合教學。


6. 資安掃描報告

6.1 紅黃綠燈總結

等級項目說明
🟡 中subprocess.run(shell=True) 跑 LLM 生成 bashenvironments/local_workspace.py:192 — 設計上必要,但代表「LLM 可以執行任意 shell」,必須在容器或 VM 內跑
🟡 中LLM 可自由寫檔到 WORKSPACE_DIR寫檔範圍受 WORKSPACE_DIR 限制,但 LLM 可以 cat > ~/.ssh/... 若沒有額外 sandbox
🟢 低API key 管理走 env var (OPENAI_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY / BROWSERBASE_API_KEY),未硬編
🟢 低無 pickle / eval / __import__ 動態載入程式碼乾淨,無常見 RCE 模式
🟢 低網路呼叫僅呼叫官方 API endpoint(api.openai.com / api.anthropic.com / openrouter.ai / api.browserbase.com)
🟢 低LicenseMIT,可自由商用

6.2 Apotek 內部使用建議

  1. 絕對不要在公司 production server 上直接跑 Webwrightshell=True + LLM 等於潛在 RCE
  2. 建議跑在 Docker container 內:限制 mount、限制網路、限制 user
  3. Workspace 目錄要隔離:每個任務一個 tmpfs 或 ephemeral docker volume
  4. API key 走 .env + 環境變數注入,不要寫進 config yaml
  5. 生產用途請先過 IT 安全審查 — 屬於「LLM-driven RCE 設計」家族

7. FAQ

Q1:為什麼不是用 browser-use 或 Stagehand? A:Webwright 的 long-horizon 表現(Odysseys 60.1% vs 前 SOTA 44.5%)顯著優於 step-by-step 的 baseline。對於 5+ 步驟、需要 loop / 條件分支的任務,code-as-action 設計上就有優勢。

Q2:跑一次任務大概多少 token? A:根據 README 與 Online-Mind2Web 描述,100-step budget 是上限;典型任務 30–60 步、每步含 ARIA snapshot ~10–20k token。換算 GPT-5.4 / Claude Opus 4.7 一個 task 大約 $0.5–$3 USD。

Q3:能跑 headless 嗎? A:可以。local_browser.yaml 預設 headless;persistent_browser.yaml 預設也是 headless 的 Chromium subprocess。

Q4:可以用本地模型嗎? A:透過 OpenRouter 可接到很多 hosted open-weight 模型;如要完全本地(vLLM / Ollama),可以 fork models/openai_model.py 改 endpoint,但 README 描述 Qwen-3.5-9B 是「+tools available」才能跑,純小模型不建議。

Q5:可以跨 session 保留 login? A:用 local_browser.yaml 模式接到本地 Edge/Chrome 的 user-data-dir,即可保留 cookies / login。但要注意:LLM 會看到所有 cookie content(在 ARIA snapshot 內)。

Q6:跟 meeting-intel skill 衝突嗎? A:不衝突。meeting-intel 是「會前情資文件編寫」工作流;Webwright 可作為其「自動抓資料」的子工具,但抓回的 raw data 要進 docs/superpowers/specs/,不能進 projects/research-*/(CLAUDE.md §機密邊界)。


8. 進階技巧

8.1 自製 config 疊加

1# my_custom.yaml — 放在 src/webwright/config/
2agent:
3  step_limit: 30                  # 預設 15,長任務拉高
4  attach_plan_md_after_observation: true   # 每步附 plan.md,幫助一致性
5model:
6  max_output_tokens: 8000         # 預設 4000,長 code generation 可拉高

8.2 用 summary_every_n_steps 控制 context 壓縮

預設 0(不壓縮)。對 50+ 步驟任務建議設 10 — 每 10 步 LLM 自己寫 summary,後續用 summary 取代原始 transcript。

8.3 監測 final script 品質

final_runs/run_<id>/ 內含:

  • final_script.py — LLM 寫的 Playwright code
  • final_script_log.txt — 執行 log
  • screenshots/ — 每個 critical-point 的截圖

可用 self_reflection tool 自動跑 vision check:對截圖問「這個 critical-point 達成了嗎?」

8.4 用 BrowserBase 跑遠端

base.yamlbrowser_mode: browserbase + 設好 BROWSERBASE_API_KEY / BROWSERBASE_PROJECT_ID — 任務跑在 BrowserBase cloud,避開本地 Chromium 安裝問題(但每分鐘 ~$0.10 USD)。


9. 整合進其他工作流

9.1 跟 ai-knowledge template 19 layers 的關係

Layer整合可能性
Layer 1 ai-saveWebwright 抓到的網頁 → 走 ai-save 進 inbox
Layer 8 doclingWebwright 抓到 PDF → docling 解析
Layer 9 paper-search互補:paper-search 走 API;Webwright 走 web scraping
Layer 14 meeting-intelWebwright 是 meeting-intel 的子工具(抓對手最新 PR)
Layer 18 research-pipeline-v2Stage 2-3「探索」階段可用 Webwright sub-agent

9.2 包成 Apotek 內部 skill

未來可在 .claude/skills/webwright-driver/SKILL.md 包一層 thin wrapper:

1- 觸發:`web: <task>`
2- 行為:呼叫 `python -m webwright.run.cli`,把結果寫到 `inbox/web-<date>-<task>.md`
3- 結合 ai-save:抓到的網頁自動轉 md 進 inbox

10. 重點摘要 Checklist

  • 看完知道 Webwright 是「會寫 Playwright 的 LLM」,不是「會點按鈕的 LLM」
  • 知道安裝有三條路:clone / Claude plugin / Codex plugin
  • 認得 base.yaml + model_*.yaml 的疊加邏輯
  • 知道 /webwright:craft/webwright:run 的差異
  • 認知 shell=True + LLM 是 🟡 中等資安風險,必須容器化跑
  • 知道跟 Apotek 既有 opencli / paper-tutorial 工作流的切分

11. 進一步閱讀