為 LLM(Claude)設計的輕量網頁內容萃取器 —— 不是瀏覽器,而是「省 token 的撈取管線」。
讓 AI agent 抓取網路資料時,不必啟動 Chrome。Chrome 會渲染 DOM、執行 JS、載入圖片/CSS/字型/廣告/追蹤腳本——這些對「讀取內容」毫無幫助,只消耗 CPU、記憶體與時間。
更糟的是 token:一個典型網頁原始 HTML 常 100300 KB,塞滿標籤與 inline script,但真正有用的正文往往只有 38 KB。把整包 HTML 餵給 LLM,token 直接爆炸。
RustBrowser 用一條精簡管線解決這件事:
URL → 輕量 HTTP 抓取(無瀏覽器引擎)
→ (必要時)headless 補渲染 JS 動態站
→ Readability 萃取正文(移除 nav / 廣告 / footer / script)
→ 轉成精簡 Markdown
→ 輸出給 LLM(token 通常砍掉 75~98%)
| 頁面 | 原始 tokens | 萃取後 | 節省 |
|---|---|---|---|
| example.com | 152 | 29 | 80.9% |
| Rust 官方文件頁 | 8,925 | 154 | 98.3% |
| Wikipedia(Rust 條目,重雜訊) | 189,506 | 46,047 | 75.7% |
Release 執行檔約 8 MB 單一靜態檔;熱路徑抓取+萃取(含網路)約 0.5 秒,快取命中再快 ~5 倍。對比 Chrome 動輒數百 MB 記憶體與秒級啟動,這是數量級的差距。
| 目標 | 做法 |
|---|---|
| 省 token | 正文萃取 + HTML→Markdown + 空格壓縮,只保留語義內容 |
| 省硬體 | Rust 無 GC、低記憶體;預設純 HTTP,不開瀏覽器引擎 |
| 快 | 共用 HTTP client、async 並發抓取、rustls 純 Rust TLS、磁碟快取避免重抓 |
| 抓得到 | 對 JS 動態站,auto 偵測並自動用系統 Chrome headless 補抓 |
| 可控 | streaming body 上限、charset-aware 解碼、URL 安全邊界、--stats token 對比 |
核心邏輯放在 library,包裝層共用:
┌─────────────────────────────────────────────┐
│ 包裝層(共用核心) │
│ • CLI rustbrowser fetch <url...> │
│ • MCP server rustbrowser-mcp(Claude 原生呼叫)│
├─────────────────────────────────────────────┤
│ 核心 library (src/lib.rs) │
│ distill() 單頁 · distill_many() 並發批次 │
│ • fetch HTTP 抓取(reqwest + rustls) │
│ • cache 磁碟快取(SHA256 鍵 + TTL) │
│ • render headless fallback(系統 Chrome) │
│ • extract 正文萃取(dom_smoothie) │
│ • convert HTML → Markdown(htmd)+ 空格壓縮 │
│ • structured 連結/表格抽成結構化資料 │
│ • tokens token 估算與節省統計(tiktoken) │
└─────────────────────────────────────────────┘
| 模組 | 檔案 | 職責 |
|---|---|---|
fetch |
src/fetch.rs |
HTTP 抓取、自動解壓、charset 解碼、streaming 上限、重定向與 URL 安全檢查、重試/退避、per-host 並發與速率限制 |
robots |
src/robots.rs |
(opt-in)抓取/解析/快取 robots.txt,強制 Disallow 規則 |
cache |
src/cache.rs |
分層快取 fetch HTML 與 headless render DOM,含 TTL、info/prune/clear 維護 |
render |
src/render.rs |
偵測 JS 動態站,呼叫系統 Chrome --dump-dom 補渲染 |
extract |
src/extract.rs |
Readability 萃取正文(article),或整頁 body 擷取(full,去 script/style) |
budget |
src/budget.rs |
依 token 預算在段落邊界截斷輸出 |
convert |
src/convert.rs |
乾淨 HTML → 精簡 Markdown,壓縮對齊空格 |
structured |
src/structured.rs |
連結(解析相對網址)與表格(headers+rows)抽成資料 |
actions |
src/actions.rs |
action tree:links/forms/buttons/downloads + 穩定 action_id(Browser Use) |
tokens |
src/tokens.rs |
估算原始/輸出 token,回報節省比例 |
| (lib) | src/lib.rs |
distill() / distill_many() 串接整條管線 |
| MCP | src/bin/rustbrowser-mcp.rs |
MCP server,暴露 fetch_url / fetch_urls 工具 |
# 抓取單頁,輸出精簡 Markdown
rustbrowser fetch https://example.com/article
# 一次抓多個 URL(並發批次)
rustbrowser fetch https://a.com https://b.com https://c.com
# 純文字 / 結構化 JSON / 只抓特定 CSS 區塊
rustbrowser fetch <url> --format text
rustbrowser fetch <url> --format json
rustbrowser fetch <url> --selector "main article"
# 結構化擷取連結 / 表格(搭 --format json 最完整)
rustbrowser fetch <url> --links --tables --format json
rustbrowser fetch <url> --links-all # 全頁連結(含 nav),供爬蟲
# JS 動態站:auto(預設,自動偵測)/ always(強制)/ off(純 HTTP)
rustbrowser fetch <spa-url> --js always
rustbrowser fetch <spa-url> --js-wait 5000 # 給 JS 更多等待時間(ms)
rustbrowser fetch <spa-url> --js-wait-for ".results" # 等特定元素出現才抓(CDP)
# token 統計 / 快取與並發控制
rustbrowser fetch <url> --stats
rustbrowser fetch <url> --max-bytes 4194304 # response body 最多保留 4 MiB
rustbrowser fetch <url> --no-cache # 跳過快取,強制重抓
rustbrowser fetch <url> --cache-ttl 600 # 快取新鮮度改為 10 分鐘(預設 3600)
rustbrowser fetch <urls...> --concurrency 4 # 批次並發上限(預設 8)
# 本機開發伺服器:預設拒絕 loopback,需明確開啟(僅放行 loopback,
# private LAN / link-local / metadata 仍被擋)
rustbrowser fetch http://127.0.0.1:8080 --allow-local
# 禮貌抓取 / 穩健性(對伺服器友善 + 容忍暫時性失敗)
rustbrowser fetch <url> --max-retries 3 # 暫時性失敗(連線/逾時、429、5xx)指數退避重試(預設 2)
rustbrowser fetch <urls...> --per-host-concurrency 2 # 同一 host 最多 2 個並發(預設 4;0=不限)
rustbrowser fetch <urls...> --rate-limit 2 # 每個 host 每秒最多 2 次請求(預設 0=不限速)
rustbrowser fetch <url> --respect-robots # 遵守該站 robots.txt,跳過被 Disallow 的路徑
# 擷取 profile / token 預算 / 品質診斷
rustbrowser fetch <url> --profile full # 整個 body(readability 過度刪時用),另有 article(預設)/ metadata
rustbrowser fetch <url> --profile metadata # 只要 title + 一段摘要(最省 token 的「這頁在講什麼」)
rustbrowser fetch <url> --max-output-tokens 800 # Markdown/text 輸出超過 800 tokens 就截斷
rustbrowser fetch <url> --diagnostics # 把擷取品質診斷印到 stderr(JSON 格式則帶在 result 裡)磁碟快取的維護子命令:
rustbrowser cache info # 列出 fetch / render 各自的筆數與占用空間
rustbrowser cache prune --older-than 3600 # 刪除超過 1 小時的舊快取
rustbrowser cache clear # 清空所有快取(fetch + render)磁碟快取存放於系統 cache 目錄下:
rustbrowser/fetch/:快取原始 HTTP HTML,同一頁之後仍能用不同 selector/format 重新萃取。rustbrowser/render/:快取 headless 渲染後 DOM,key 包含 URL、JS 模式、等待時間與 wait selector,避免 JS-heavy 頁面每次 cache hit 仍重開 Chrome。
安全邊界:fetch 只允許 http / https,拒絕 localhost、loopback、private IP(含 CGNAT 100.64/10、0.0.0.0/8)、link-local、metadata IP;IPv6 的 IPv4-mapped 與 NAT64(64:ff9b::/96)內嵌位址會還原後再檢查;每一段 redirect 後的目標 URL、以及從磁碟快取讀回的 URL,都重新檢查。要連本機開發伺服器可加 --allow-local(MCP 為 allow_local)—— 這只放行 loopback,private LAN、link-local 與 metadata 仍一律被擋,連 redirect 想跳到 169.254.169.254 也會被拒。
IP 黑名單的最終把關落在連線層:自訂的 reqwest DNS resolver 在解析當下就對每個位址跑同一套黑名單,只把通過的 IP 交給 reqwest 連線(全部被擋就直接拒絕)。因此 reqwest 撥號的就是「已驗證的那個 IP」——DNS rebinding 已被防護,不再有「安全檢查」與「實際連線」兩次獨立 DNS 解析、可被低 TTL 或惡意 DNS 在連線當下掉包的縫隙。字面 IP、scheme、localhost 等不需 DNS 的檢查仍在送出請求前先擋一道;TLS 的 SNI 與憑證驗證仍以原始 domain 進行。
對 React/Vue 或任何「JS 才渲染內容」的站,純 HTTP 抓到的是空殼。--js auto(預設)會偵測「萃取文字極少 + 頁面 JS 偏重」,自動呼叫系統 Chrome/Edge 的 --headless --dump-dom 取得渲染後 DOM —— 零編譯依賴(不綁瀏覽器引擎),只在必要時才用,保持輕量。
--js off完全不用 headless;--js always強制每頁都 render。--js-wait <ms>給慢載入站更多時間;--js-wait-for "<css>"等特定元素出現才抓 —— 走 CDP(Chrome DevTools Protocol,透過 tokio-tungstenite 連ws://localhost,無需 TLS),適合「要打 API 才出內容」的站。- 找不到瀏覽器時可用環境變數
RUSTBROWSER_CHROME指定執行檔路徑。 - 安全:渲染的是不受信任的網頁,因此 Chrome sandbox 預設保持開啟(不再無條件帶
--no-sandbox)。在容器或以 root 執行、sandbox 無法初始化時,才用環境變數RUSTBROWSER_NO_SANDBOX=1明確關閉。渲染後的 DOM 也有 16 MiB 上限,避免惡意或超大頁面撐爆記憶體。
抓取管線內建一層「對伺服器友善 + 容忍暫時性失敗」的網路政策,預設保持輕快、必要時才更謹慎:
- 自動重試(預設開) — 暫時性失敗(連線/逾時錯誤、
429、5xx)以指數退避 + jitter 重試--max-retries次(預設 2)。收到Retry-After會尊重它(上限 60 秒)。不可重試的情況絕不重試:SSRF 拒絕、4xx(429 除外)、scheme 錯誤。重試用盡後,最後的狀態碼會照常回傳(例如持續 503 就回 503,不是錯誤)。 - 每 host 並發上限(預設 4) —
--per-host-concurrency限制同一 host 同時在飛的請求數,跨整批共用;0= 不限。 - 每 host 速率限制(預設關) —
--rate-limit <每秒次數>為同一 host 的請求之間插入最小間隔(例如2= 每 500ms 一次)。預設0不限速,維持原本的快。 - robots.txt(opt-in,預設關) —
--respect-robots會抓該 origin 的/robots.txt(走同一套 SSRF 防護、每 host 快取一次),用texting_robots解析,跳過對本 UA 被Disallow的路徑。對「指向特定網址的擷取」採 fail-open:robots.txt 不存在(4xx)、抓取失敗或 5xx、無法解析時一律放行,不讓壞掉的 robots 端點擋住你明確要的頁面。需要robotsfeature(預設已含)。
這些限制都是 per-host 且跨整批共用——fetch_urls / 多 URL 批次抓同一站時,並發與速率上限會正確套用到整批。
把「怎麼擷取、輸出多大、品質如何」變成可控、可觀測:
- 擷取 profile(
--profile,MCPprofile)article(預設)—— Readability 主文擷取,去掉 nav/廣告/footer。full—— 整個<body>(script/style/noscript 移除),不過 Readability 過濾。給 Readability 會過度刪的頁面:參考文件、結構化版面、落地頁。metadata—— 只要 title + 一段摘要,最省 token 的「這頁在講什麼」。- (給
--selector時 profile 自動讓位給選擇器。)
- token 預算(
--max-output-tokens/ MCPmax_output_tokens)—— Markdown/text 輸出超過預算就截斷並附標記;優先在段落邊界切,單段太大時切前綴,標記本身也算進硬上限。token 數用 tiktoken(statsfeature)精算,否則以字數估算。 - 品質診斷(
--diagnostics/ MCPdiagnostics)—— 回報 profile、raw bytes、output chars/tokens、extraction_ratio(過低代表可能被過度刪——換full)、連結/表格數、是否用了 headless、是否被截斷,以及low_content警告。CLI 非 JSON 印到 stderr;JSON 格式則帶在結果裡。
函式庫另外提供 distill_html(html, base_url, opts) —— 不抓網路、直接對手上的 HTML 跑整條擷取管線,供離線評測與「已有 HTML 想萃取」使用。倉庫內附固定評測集(tests/fixtures/ + tests/eval.rs):用代表性頁面斷言主文留存、chrome 去除、各 profile 行為與 token 縮減門檻,作為擷取品質的回歸網。
RB 的走向是 RB-first Browser Use —— Observe → Act → Verify → Fallback,Chrome 只當 fallback runtime。v1.1 完成第一步「Observe」:除了頁面摘要,RB 還能輸出一棵 action tree,告訴 agent 這頁有哪些可操作的東西。
--actions(MCPextract_actions)抽出 links / forms / buttons / downloads,每個給穩定action_id(link_3、form_0.submit…)。- links —— 一般導覽連結(可 follow)。
- forms ——
method、action(絕對 URL,尊重<base href>)、fields(name/type/value/options/required)、submit_id。select options 會保留實際提交的value與可見label,可不開瀏覽器直接組 GET/POST。 - buttons —— 表單外的獨立按鈕(多半是 JS 驅動,標示出來供後續 fallback 判斷)。
- downloads —— 指向檔案的連結(從一般 links 分流出來),帶
filename。
--max-actions <n>對每類 action、每個 form 的 fields、每個 select 的 options 設上限;超長文字/URL/value 也會被限制,避免 action tree 爆量。- MCP 新工具
observe_url—— 回傳頁面摘要 + action tree(JSON),專給「接下來能做什麼」的決策用;fetch_url/fetch_urls維持相容(用extract_actions開啟)。
rustbrowser fetch https://example.com/search --actions --format json
rustbrowser fetch <url> --actions --max-actions 30設計刻意不做 pixel-level click、不做完整 JS browser、不讓 agent 未經確認就送任意 POST。後續版本(session、表單提交、action loop、Chrome fallback broker)見
CHANGELOG.md與內部路線圖。
v1.2 讓 session 能 act;v1.3 把每次 act 的回傳整理成 planner-friendly 格式,讓 LLM 能穩定地跑 Observe → Act → Verify 迴圈,而不必每步重讀整包 Distilled。每個 session 工具(session_start/session_observe/session_follow/session_submit_form)的回傳,在既有欄位之外新增:
loop—— 規劃用的精簡視圖:state—— 目前頁面(url / status / title / excerpt / content_chars / action_count / low_content / used_headless / steps_taken)。available_actions—— 把 links/forms/buttons/downloads 攤平成統一形狀,各帶action_id、kind、label、target、(表單的)method與可填fields,以及dangerous(非 GET 標記)。表單fields只列 caller 應填欄位;hidden/default 欄位仍由 RB 內部自動帶上。recommended_next_actions—— 便宜誠實的啟發式提示(像是「這看起來是搜尋表單 / 下一頁連結」),指向真實action_id。只是提示,RB 不會自動執行。failure_reason—— 該步驟未通過 verify(HTTP 錯誤狀態)時才有;None代表看起來正常。
operation_log—— 每步操作的除錯紀錄(step / op / target / status / attempt / outcome / failure_reason),供 debug 與改版用。
Verify + 有限自動重試:idempotent 步驟(observe / follow / GET 表單)抓完會做 verify;遇到可重試的暫時性失敗(429/5xx,或暫時性連線錯誤)會再試最多 max_action_retries 次(預設 1,上限 2),且維持 per-host rate limit。session 內每個 loop attempt 對應一次 HTTP attempt,不會再疊加底層 fetch retry;重試之間會指數退避(含 jitter)並尊重伺服器的 Retry-After。被丟棄的重試嘗試不會推進 session 狀態(redirect_history 每次成功導航仍只記一筆)。高風險(非 GET)提交永遠不會被自動執行,也永遠不會被自動重試。
Fallback Policy 的嚴格分層:RB 解不了 → 才進 Chrome。v1.4 把「什麼時候算解不了」變成明確、可解釋的決策(rustbrowser::fallback),不再是黑箱模式切換:
- fallback 條件(
loop.state.fallback_reason會告訴你是哪一個):challenge—— 偵測到反機器人/captcha 插頁(reCAPTCHA / hCaptcha / Cloudflare Turnstile 等標記)。真瀏覽器可能通過 JS challenge;真 captcha 則需要更高層(planner 自行判斷要不要賭)。js_app—— 未渲染的 client-side app(框架標記 / script-heavy 殼 / canvas / shadow DOM)且萃取內容過薄。no_actions—— 要求 action tree 卻一個可操作元素都沒有,而頁面明顯在跑 script(表單/連結由 JS 動態生成)。forced——js=always強制。
- 升級行為:session 的 idempotent 步驟 settle 後,broker 對該 URL 跑一次有界 headless render(沿用既有 sandbox + DOM 上限),rendered DOM 重新走同一條 token-lean 蒸餾管線 —— LLM 拿到的仍是壓縮後的內容 + action tree,絕不塞 raw DOM 或截圖。render 失敗非致命(保留 HTTP snapshot,log 記
chrome_fallback_failed)。 - 安全邊界:只有 idempotent 步驟會升級;已確認的非 GET 提交結果頁絕不會被瀏覽器重抓。
- v1.7 起,fallback 瀏覽器改為攜帶 session cookies(隔離 profile):session 若已持有正在渲染那個 URL 的 cookie,會透過 CDP
Network.setCookie注入到一個全新、僅此一次的 Chrome--user-data-dir——只送出這一個 URL 該有的 cookie,絕不是整包 jar,且 cookie 值只在這條本機 CDP 連線上出現,絕不寫進operation_log或任何診斷輸出。render 結束前先送Network.clearBrowserCookies,接著刪除該 temp profile 目錄(Windows 上剛結束的 Chrome 可能短暫鎖檔,因此會重試幾次;刪不掉屬安全風險,會留下警告而非靜默放棄)。這代表登入牆後頁面現在能在 fallback 渲染出登入後的內容(先前一律匿名渲染;可由fallback_reason+used_headless判讀)。沒有 cookie 的匿名 session 行為不變。要恢復 v1.7 之前「fallback 一律匿名」的行為,設定環境變數RUSTBROWSER_FALLBACK_NO_COOKIES=1。 - 控制:
session_start的js(off / auto 預設 / always)與js_wait(毫秒)。
rustbrowser-mcp 是 stdio MCP server,暴露三個工具,Claude 呼叫即可拿到精簡內容,原始 HTML 完全不進對話:
fetch_url— 抓單一頁面fetch_urls— 一次並發抓多個頁面(比反覆呼叫fetch_url快得多)observe_url— 抓頁面摘要 + action tree(links/forms/buttons/downloads,JSON),給 Browser Use「接下來能做什麼」的決策用
專案根目錄已附 .mcp.json(指向 release binary)。或手動註冊:
# 專案層級(此專案可用)
claude mcp add rustbrowser -- D:\aiproject\RustBrowser\target\release\rustbrowser-mcp.exe
# 全域(任何專案可用)
claude mcp add --scope user rustbrowser -- D:\aiproject\RustBrowser\target\release\rustbrowser-mcp.exe共同參數:format、selector、stats、timeout_secs、max_bytes、no_cache、cache_ttl、extract_links、extract_tables、links_full、js(off/auto/always)、js_wait、js_wait_for、allow_local(放行 loopback,預設 false)、max_retries(預設 2)、per_host_concurrency(預設 4)、rate_limit(每秒次數,預設 0=不限)、respect_robots(預設 false)、profile(article/full/metadata)、max_output_tokens(預設 20000,0=不限)、diagnostics(預設 false);fetch_urls 另有 urls 與 concurrency。
一般網路環境:
cargo build --release即可。
本機處於受限網路(schannel 無法做 TLS 憑證撤銷檢查),需要兩項本機設定 —— 範本見 .cargo/config.toml.example 與 .mcp.json.example:
- 複製
.cargo/config.toml.example→.cargo/config.toml(設check-revoke = false,讓 cargo 能存取 crates.io)。 - TLS 用 rustls,其 ring 後端在 Windows 需要 NASM(CI 用
ilammy/setup-nasm;本機可放可攜版於.tools/)。
$env:Path = "$env:USERPROFILE\.cargo\bin;$PWD\.tools\nasm-2.16.03;$env:Path"
cargo build --release產出兩個 binary:target/release/rustbrowser.exe(CLI)與 rustbrowser-mcp.exe(MCP server)。headless fallback 直接編入,執行期才需系統 Chrome/Edge。
功能可用 Cargo features 拆分:
# 完整預設 build:CLI + MCP + 精準 token stats + headless JS
cargo build --release
# 較瘦 CLI build:不編入 MCP、tiktoken-rs、CDP websocket 依賴
cargo build --release --no-default-features --features cli
# 指定完整 feature set
cargo build --release --no-default-features --features "cli mcp stats js robots"CI 會執行 fmt、clippy、build、test、release build,並檢查 release binary 大小:CLI ≤ 10 MiB,MCP ≤ 15 MiB。
從 1.0.0 起,本專案遵循 Semantic Versioning。1.x 內保證不破壞的公開介面:
- CLI ——
fetch既有旗標與cache子命令的名稱與語意。 - MCP ——
fetch_url/fetch_urls工具與其參數名稱、型別。 - 函式庫 ——
rustbrowsercrate 的公開 API(distill、distill_many、distill_html、DistillOptions、Distilled等)。 - JSON 輸出 ——
--format json/ MCPformat=json之Distilled結構既有欄位。
不在 semver 保證內(可在 minor/patch 改動):
- 精確的 Markdown 文字輸出 —— 擷取與轉換的啟發法會持續改進,內容會變。
- token 估算的絕對數值(tokenizer 是近似)。
- 診斷欄位的新增、
low_content等門檻的調整。 - 內部模組、未公開項目、磁碟快取格式。
新增旗標/參數/欄位屬於相容變更(minor)。移除或改名既有者屬於破壞變更,只會在下一個 major。棄用會先在文件標記、保留至少一個 minor 週期。完整逐版變更見 CHANGELOG.md;安全防護與威脅模型見 SECURITY.md;凍結介面的完整參考見 docs/API.md。
- ✅ v0.1(MVP) — 核心管線 + CLI:抓取 → 萃取 → Markdown → token 統計
- ✅ v0.2 — 磁碟快取、批次並發抓取
- ✅ v0.3 — MCP server,Claude Code 以原生工具
fetch_url/fetch_urls呼叫 - ✅ v0.4 — headless 自動 fallback(auto 偵測 JS 動態站)+ 連結/表格結構化擷取
- ✅ v0.5 — 全頁連結擷取 · headless 等待控制(
--js-wait/ CDP--js-wait-for)· release 發布自動化 - ✅ v0.6(強化) — wiremock 端到端整合測試 ·
--allow-localloopback 豁免 ·cache維護子命令 · headless sandbox 預設開啟 + DOM 上限 - ✅ v0.7(穩健性) — headless DOM cap 改串流讀取真正限制記憶體 ·
cache失敗回傳非零 exit code · MCP transport 明確處理斷線/錯誤(乾淨關閉、診斷只進 stderr) - ✅ v0.8(禮貌抓取) — 暫時性失敗自動重試(指數退避 +
Retry-After)· per-host 並發上限 · per-host 速率限制 · robots.txt(opt-in) - ✅ v0.9(擷取品質) — 擷取 profile(article/full/metadata)· token 預算截斷 · 品質診斷 ·
distill_html離線管線 + 固定評測集 - ✅ v1.0(穩定版) — CLI/MCP schema 凍結(+ 守門測試)· 完整安全文件(
SECURITY.md)· semver 承諾 +CHANGELOG.md· CI 覆蓋 Linux/Windows/macOS · 三平台 release binaries + checksums - ✅ v1.1(Actionable Observe) — action tree(links/forms/buttons/downloads + 穩定 action_id)· MCP
observe_url工具 · action token 上限 · action 抽取評測。Browser Use 的第一步:RB 先能告訴 agent「這頁有哪些可操作的東西」 - ✅ v1.2(Session + Static Actions) — 有狀態 session(cookie jar / current URL / redirect history / last snapshot)· MCP
session_start/session_observe/session_follow/session_submit_form/session_close· HTML 表單提交(GET 帶 query、POST 帶 body,自動帶 hidden/selected 預設值)· 高風險(非 GET)action 需confirm=true才送 · 跨 origin 307/308 POST body 轉送會被阻擋。Browser Use 第二步:能 act,不只 observe - ✅ v1.3(Action Loop) — planner-friendly 回傳(
loop:state/available_actions/recommended_next_actions/failure_reason)· idempotent 步驟 verify + 有限自動重試(max_action_retries,預設 1、上限 2;每個 loop attempt 一次 HTTP attempt;高風險 action 永不自動重試)· 操作紀錄operation_log。Browser Use 第三步:把 Observe → Act → Verify 收成可規劃的迴圈 - ✅ v1.4(Chrome Fallback Broker) — 明確可解釋的 fallback 決策(
challenge/js_app/no_actions/forced)· session idempotent 步驟自動升級一次有界 headless render,rendered DOM 重走同一條蒸餾管線(絕不回 raw DOM/截圖)· 確認後的非 GET 結果頁永不被瀏覽器重抓 ·session_start加js/js_wait。Browser Use 第四步:RB 解不了 → 才進 Chrome,而且說得出為什麼 - ✅ v1.5(Safety + Eval) — browser-use benchmark(
tests/benchmark.rs):六種任務原型(搜尋頁 / 文件站 / 分頁列表 / 表單提交 / 登入後頁面 / JS-heavy SPA)走真實 Session,量測 RB-only 率、fallback 率、request 數、token cost、unsafe-action block、延遲,並鎖定路線圖目標:一般查找/文件/搜尋型任務 ≥70% 不進 Chrome(固定評測集上 100%)、危險提交 100% 先擋。Browser Use 第五步:迴圈的行為從「斷言」變成「可量測」 - ✅ v1.7(從固定集走向真實世界) — nightly 真站 CI(
tests/live.rs形狀不變式測試 + 非阻塞 workflow,第一次跑就抓到 codex-manual.md 改回application/octet-stream的真實漂移)·Session::settle()原子性重構(計算&self/提交同步分離,cancel 不留不一致狀態)· Chrome fallback 帶 session cookie(隔離 single-use profile、只送該 URL 的 cookie、render 完即清,RUSTBROWSER_FALLBACK_NO_COOKIES=1可關——登入牆後的 JS 頁面自此能渲染出登入內容)· session 四工具補 wall-clock deadline(step_budget推導自既有參數,超時回乾淨錯誤且 session 可續用;非 GET 超時明示「可能已送出勿重試」) - ✅ v1.6(Robustness) — 架構稽核後補實戰缺口:MCP fetch handler 加整體 wall-clock deadline(修「等很久 → transport closed」的假死)·
text/markdown/text/plain內容直出、不進 HTML extractor(修乾淨 markdown 被跳脫膨脹:實測某.md頁 raw 127,767 → 舊 output 131,539 → 新 output 127,767 精確直出)· MCP 三工具預設max_output_tokens=20000(傳 0 解除)· CDP render 補kill_on_drop+ session timeout + temp dir Drop guard(修孤兒 Chrome / 無界 hang)· 暫時性錯誤(429/5xx)不再入 cache ·Retry-After支援 HTTP-date
Rust · tokio · reqwest(rustls) · scraper · dom_smoothie · htmd · tiktoken-rs · clap · rmcp · futures · sha2 · dirs · tokio-tungstenite(CDP) · texting_robots(robots.txt)
這個專案的本質:把「瀏覽網頁」這件事,縮減成 LLM 真正需要的最小資訊集。