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 的差異
| 維度 | Stagehand | agent-browser (Vercel) | browser-use | Webwright |
|---|---|---|---|---|
| 行為空間 | NL → Playwright | 離散 subcommand | indexed click/type | 自由 Python |
| 狀態定義 | browser session | browser session | browser session | local workspace |
| Loop 形狀 | imperative | 一次 CLI = 一個 micro-step | observe→predict→execute | write 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 Key | OpenAI / 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 期待回傳三個欄位:
| 欄位 | 用途 |
|---|---|
thought | LLM 的 reasoning(不執行) |
bash_command | 要在 workspace 執行的 bash(會被 subprocess.run(shell=True) 跑) |
done | 是否任務完成(bool) |
設計優雅之處:所有行為都壓在一個 bash 欄位 — LLM 可以寫 python -c "..."、cat > foo.py <<EOF、pytest、playwright codegen,自由度極高且 surface area 極小。
3.3 三種 environment 對比
| 環境 | 設定檔 | 適用場景 |
|---|---|---|
local_workspace | base.yaml | 純程式碼任務,無瀏覽器 |
local_browser | local_browser.yaml | 用本地真實 Chrome/Edge over CDP(保留 user-data-dir) |
persistent_browser | persistent_browser.yaml | 跨步驟保留 Chromium subprocess(含 cookies / open tabs) |
3.4 模型 routing(2026-05-27 修正後)
之前 issue #3 反映「只有 ANTHROPIC_API_KEY 跑不起來」— 因為 image_qa 與 self_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 抓 abstract | meeting-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 生成 bash | environments/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) |
| 🟢 低 | License | MIT,可自由商用 |
6.2 Apotek 內部使用建議
- 絕對不要在公司 production server 上直接跑 Webwright —
shell=True+ LLM 等於潛在 RCE - 建議跑在 Docker container 內:限制 mount、限制網路、限制 user
- Workspace 目錄要隔離:每個任務一個 tmpfs 或 ephemeral docker volume
- API key 走
.env+ 環境變數注入,不要寫進 config yaml - 生產用途請先過 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 codefinal_script_log.txt— 執行 logscreenshots/— 每個 critical-point 的截圖
可用 self_reflection tool 自動跑 vision check:對截圖問「這個 critical-point 達成了嗎?」
8.4 用 BrowserBase 跑遠端
base.yaml 內 browser_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-save | Webwright 抓到的網頁 → 走 ai-save 進 inbox |
| Layer 8 docling | Webwright 抓到 PDF → docling 解析 |
| Layer 9 paper-search | 互補:paper-search 走 API;Webwright 走 web scraping |
| Layer 14 meeting-intel | Webwright 是 meeting-intel 的子工具(抓對手最新 PR) |
| Layer 18 research-pipeline-v2 | Stage 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. 進一步閱讀
- 官方 blog: Webwright: A Terminal Is All You Need For Web Agents
- Project page: microsoft.github.io/Webwright
- Benchmark:Online-Mind2Web, Odysseys(長 horizon 子集)
- 對比閱讀:
- browser-use — 行為空間:indexed click/type
- Stagehand — Browserbase 出,hybrid code + NL
- agent-browser (Vercel) — CLI tool 給其他 agent 呼叫
- 內部對應文件:
CLAUDE.md§機密邊界.claude/skills/meeting-intel/SKILL.md.claude/skills/research-pipeline-v2/SKILL.md(Stage 2-3 可用作 sub-agent)
Comments