:control-browser Skill 的六步瀏覽器操作工作流(Snapshot→Locator→Act))
人工智能大模型代碼智能體AI Agent桌面應用后端前端CLI【免費下載鏈接】ZCodeZCode 是 AI 編程工作臺提供桌面應用、瀏覽器界面和終端 Agent。本倉庫包含客戶端、后端服務、共享 UI以及 Agent CLI 與運行時源碼。項目地址https://gitcode.com/zai-org/ZCode點擊查看免費下載本指南以 apps/zcode-cli/packages/browser-use-plugin/docs/workflow.md 為主體結(jié)合官方內(nèi)置插件 browser-use-plugin 的 Skill 引導control-browser SKILL.md與 overview.md 中的 API 行為約定展開。讀完本文你將掌握為什么每次 JS 調(diào)用都要重新引導bootstrap運行時、如何用「先列全量標簽頁、再按已驗證事實綁定」的協(xié)議選擇目標、如何以domSnapshot()的 AI/ARIA 樹為唯一定位事實來源構(gòu)建 Playwright 定位器以及動作之后如何用「組合觀察」判斷真實效果最終寫出可穩(wěn)定復現(xiàn)的瀏覽器自動化軌跡。ZCode 的瀏覽器自動化能力由官方內(nèi)置插件zcode/browser-use-plugin提供。它并不把一個瀏覽器會話暴露給模型而是把每次js調(diào)用都放進一個全新的 JavaScript kernel由zcode/node-repl-host提供的node_replMCP 主機承載模型側(cè)看到的是mcp__node_repl__js。因此跨調(diào)用連續(xù)性的唯一邊界是BrowserControl 的標簽頁tabs而不是 JavaScript 變量、模塊緩存或某個browser/tab綁定。workflow.md 正是在這一前提下為 Agent 定義了一套嚴格的六步操作協(xié)議。下面逐步展開并給出可直接復制運行的代碼。一、先決條件每一段代碼都從 Skill 引導開始workflow.md 的每一段代碼都假設control-browserSkill 的引導已經(jīng)在當前這個全新的 JS kernel中運行過。引導代碼做兩件事解析插件根目錄并導入browser-client模塊然后注冊agent.browsers運行時。引導不選擇后端真正的后端選擇在引導之后的同一次調(diào)用里完成。const browserPluginRoot process.env.ZCODE_PLUGIN_ROOT; if (!browserPluginRoot) { throw new Error(Browser plugin root is unavailable in the node_repl host); } const { join } await import(node:path); const { pathToFileURL } await import(node:url); const browserClientUrl pathToFileURL( join(browserPluginRoot, scripts, browser-client.mjs), ).href; const { setupBrowserRuntime } await import(browserClientUrl); await setupBrowserRuntime({ globals: globalThis });從源碼看browser-client的實現(xiàn)很薄它從zcode/core/browser-client引入真正的setupBrowserRuntime并通過zcode/node-repl-host/runtime-bridge讀取當前 kernel 的運行時橋見 src/browser-client.ts。核心約束是每次js調(diào)用都必須重新引導并重建同一個瀏覽器包裝對象而不是因為kernel 是新的就去偷偷切換后端iab/extension/cdp也不是把上一個調(diào)用的tabid 直接拿來用。control-browserSkill 強調(diào)可用的后端必須來自await agent.browsers.list()的廣告desktop 通常廣告 IABCLI 以--browser-useheadless啟動時廣告托管 Chromium 為cdpheadless 是 CDP 的啟動/顯示模式不是第四種后端類型。未被廣告的后端絕不可視為可用。在第一次瀏覽器調(diào)用中選擇后端后應立即把完整的 API 文檔發(fā)給模型一次nodeRepl.write(await browser.documentation())之后的每次新鮮調(diào)用只需重復相同的后端選擇即可。二、六步工作流全解workflow.md 將一次瀏覽器自動化任務歸納為六個步驟。核心設計思想是模型必須在每個決策點拿到可驗證的事實verified facts——包括標簽頁的 id、URL、標題、快照中的 role/accessible name——然后用下一個獨立 JS 調(diào)用基于這些事實行動絕不憑猜測、絕不靠記憶。第 1 步目標選擇協(xié)議——先列全量再按已驗證事實綁定每一個「邏輯標簽頁操作批次」開始之前用一個專門的 JS 調(diào)用把所有受控標簽頁完整地返回給模型const browser await agent.browsers.getDefault(); const controlledTabs await browser.tabs.list(); controlledTabs;tabs.list()返回的是元數(shù)據(jù)數(shù)組TabInfo[]包含當前active標記與真實 CSSviewport: { width, height }不是可操作的Tab對象。模型查看這段輸出后在下一個 JS 調(diào)用里按穩(wěn)定 id 或經(jīng)核實的 URL/標題事實匹配目標頁再調(diào)用tabs.get(id)激活它const browser await agent.browsers.getDefault(); const tab await browser.tabs.get(verified-tab-id-from-the-prior-list); await tab.playwright.domSnapshot();幾條硬性規(guī)則值得注意絕不因為列表非空就選[0]。多標簽頁場景下按數(shù)組位置選目標是被明確禁止的at(-1)、憑記憶的 id 同樣不行。列表空也不等于可以隨便開新頁。如果受控列表里沒有匹配項先用下一次調(diào)用把await browser.user.openTabs()返回給模型——這是用戶標簽頁瀏覽器已打開但尚未交給 Browser Use 控制的頁面然后只認領claim核實的用戶標簽頁事實。只有兩輪觀察都失敗受控列表無匹配、用戶標簽頁也無匹配時才創(chuàng)建新標簽頁。注意tabs.get()只綁定當前會話已受控的標簽頁openTabs()返回的 id 不能直接傳給tabs.get()必須先browser.user.claimTab(info)參見 docs/tab-claiming-iab.md。這套先列全量 → 核對 → 綁定的流程在 SKILL.md 里被稱為 pre-action target-selection protocol與后面第 5 步的 post-action 組合觀察combined observation是兩個不同的協(xié)議不要混用。第 2 步任務給出新 URL 時——選擇、打開、導航一次如果任務點名了一個新 URL優(yōu)先考慮復用感知的入口agent.browsers.open(url)它會復用同站點同 hostname的受控標簽頁、激活到用戶可見并原地導航而不是每次導航都堆一個新標簽頁。只有確實需要并行獨立標簽頁時才顯式創(chuàng)建并走如下導航序列const browser await agent.browsers.getForUrl(https://example.com); const tab await browser.tabs.new(); await tab.goto(https://example.com); await tab.playwright.waitForLoadState({ state: domcontentloaded }); await tab.playwright.domSnapshot();getForUrl(url)用于「有目標 URL 但用戶沒有顯式選擇瀏覽器」的場景會按 URL 選擇合適后端。workflow.md 對導航后觀察有一個非常嚴格的強制約束每次tab.goto(url)成功之后、第一次讀取 title/URL/DOM 之前必須顯式調(diào)用waitForLoadState({ state: domcontentloaded })。這個顯式確認必須保留在模型可見的軌跡trajectory里即使后端導航已經(jīng)完成也不許省略不許用networkidle代替networkidle存在于共享類型中但被所有 ZCode 瀏覽器后端拒絕也不許用固定 sleep 代替。常規(guī) URL/加載狀態(tài)等待的預算被封頂在 3000ms。第 3 步用domSnapshot()讀頁面——AI/ARIA 樹是唯一定位事實來源await tab.playwright.domSnapshot()是默認的頁面觀察與定位器事實來源ground truth。它返回的是緊湊的 AI/ARIA 樹包含計算出的角色role、可訪問名稱accessible name、狀態(tài)以及可用時的展開 iframe 內(nèi)容——而不是頁面的outerHTML。使用規(guī)則只從最新相關快照中出現(xiàn)的事實構(gòu)造 Playwright 定位器。絕不猜測 label、可訪問名稱、placeholder、selector 或 URL 模式絕不用猜測的定位器去當探索性探針exploratory probe消耗超時預算。快照里已經(jīng)有目標時直接基于快照事實行動不要寫evaluate()代碼去重新發(fā)現(xiàn)相關元素、枚舉 input、dump HTML 或遍歷 DOM??煺兆C實snapshot-proven的標題或可見文本不需要link或button角色也能點擊不要用猜測的link角色去替換快照證實的heading。只要用戶已授權導航、且該標題/文本定位器唯一就直接點擊它——事件可以冒泡到祖先卡片上的 JavaScript 處理器??煺照{(diào)用必須是 JS 單元格里的最后一個表達式或者把它傳給nodeRepl.write(...)。僅僅把結(jié)果賦值給本地變量并不會把 DOM 觀察結(jié)果返回給模型overview.md也有同樣強調(diào)。第 4 步確認唯一性再執(zhí)行真實瀏覽器動作當唯一性不明顯時先確認定位器唯一然后通過真實瀏覽器動作執(zhí)行。count()為 0 時不要等待也不要執(zhí)行該定位器而是重新拍快照并重建count()大于 1 時收緊作用域而不是用位置快捷方式first()/last()/nth()都是被禁止的歧義捷徑。const input tab.playwright.getByRole(textbox, { name: Search }); if ((await input.count()) ! 1) throw new Error(Search locator is not unique); await input.fill(hello); await input.press(Enter);getByRole(..., { name })的name選項接受普通字符串或RegExp包括在 Node REPL VM 內(nèi)創(chuàng)建的RegExp。推薦的定位器事實優(yōu)先級來自 docs/playwright.md依次是穩(wěn)定 test id /data-*屬性 → 穩(wěn)定精確href→ 帶快照證實可訪問名稱的語義角色 → 作用域化可見文本 → 基于已知 DOM 事實的 CSS selector → 作用域化 DOM/CUA 兜底。像Search、Menu、Close這類通用名稱默認就是有歧義的行動前必須收窄作用域。第 5 步動作之后——取最廉價的觀察組合標簽頁事實判斷效果動作之后收集能回答下一個問題的最廉價觀察優(yōu)先做針對性的定位器狀態(tài)檢查需要新的定位器事實時才再拍一次domSnapshot()。每個觀察周期最多執(zhí)行一個改變狀態(tài)的動作at most one state-changing action per observation cycle。判斷動作成敗的標準非常關鍵源標簽頁 URL 沒變并不能證明點擊失敗了。判斷依據(jù)是預期效果是否出現(xiàn)而不是browser.tabs.list()是否非空。已經(jīng)存在的源標簽頁或無關的受控標簽頁不是動作效果。預期效果可以是源頁面的狀態(tài)變化也可以是URL/標題經(jīng)核實與預期結(jié)果匹配的標簽頁。當動作可能打開彈窗/新標簽頁、而源標簽頁沒顯示預期效果時要在同一個觀察單元格里無條件地同時讀取受控標簽頁與用戶標簽頁const [controlledTabs, userTabs] await Promise.all([ browser.tabs.list(), browser.user.openTabs(), ]); ({ controlledTabs, userTabs });把{ controlledTabs, userTabs }作為該單元格的最終結(jié)果返回讓模型基于兩張表做一次決策。不要先返回受控列表、再根據(jù)它的內(nèi)容決定要不要查用戶標簽頁。下一個單元格里按核實的 id/url/title 匹配激活受控頁或認領用戶頁。如果源頁面 組合標簽頁觀察都沒有預期效果就拍新快照、選新定位器而不是重放舊的點擊。截圖相關的紀律workflow.md 與 docs/screenshot.md 一致打開或?qū)Ш揭粋€普通頁面不是截圖理由默認不要把 DOM 快照和截圖一起收集。只有用戶明確要求截圖、必須判斷視覺布局/渲染/圖像內(nèi)容、或目標不在 DOM 快照里如 canvas / 自定義繪制 UI時才加載agent.documentation.get(screenshots)指引。一旦進入截圖分支每張截圖必須在同一個 JS 單元格里用nodeRepl.emitImage(await tab.screenshot())發(fā)出絕不把tab.screenshot()留作最終表達式也絕不直接返回它的Uint8Array字節(jié)內(nèi)部返回 PNG 字節(jié)對模型不可見。截圖超時不要立刻重試同一張截圖——底層 Chromium 捕獲可能仍在完成應等待后重試或按顯式 in-flight 錯誤重開標簽頁。超時與失敗恢復任何 Playwright 超時、strict-mode 失敗或 selector 解析失敗之后不要重試同一個定位器。拍一張新的domSnapshot()并從快照證實的事實重建。常規(guī)定位器/頁面狀態(tài)等待都在 3000ms 預算內(nèi)失敗只有無法觀察到任何具體狀態(tài)時才用更長的固定 sleeptab.playwright.waitForTimeout(ms)注意根級tab.waitForTimeout在這個運行時不存在。expectNavigation(action)若要證明確實發(fā)生了新導航應傳入{ url: expectedUrl }否則已加載的舊頁面也可能滿足等待器。第 6 步標簽頁生命周期——默認跨輪次保持收尾用finalize標簽頁在當前 ZCode 進程的生命周期內(nèi)默認跨輪次保持打開。只有需要把列出的頁面標記為deliverable或handoff時才調(diào)用await browser.tabs.finalize({ keep });不在keep列表里的頁面不會因此被關閉。關閉標簽頁只有一條路有意的await tab.close()用戶手動關閉、關窗、進程退出也會移除標簽頁。不要因為輪次結(jié)束就關掉研究/源標簽頁相關約定見 docs/all-tabs-cleanup.md 與 overview.md。三、直接查找direct lookup的紀律workflow.md 最后給出了一條針對只讀直接查找的規(guī)則至多做一次聚焦嘗試且嘗試必須來源于用戶輸入或經(jīng)核實的頁面事實。絕不迭代猜測的 URL 變體、路徑、查詢參數(shù)或數(shù)字 ID。如果這次聚焦嘗試失敗改用一張新的domSnapshot()站點自身的搜索/導航功能權威的連接器/API/CLI 查詢。找到一個權威候選后直接驗證它而不是繼續(xù)收集更多候選。這條規(guī)則與control-browserSkill 的規(guī)則完全一致goto()只接受http:、https:與精確的about:blankfile:、其他about:*、data:、javascript:目標不可導航file:URL 僅可作為多后端場景下getForUrl()的后端選擇提示。四、安全邊界頁面內(nèi)容不可信瀏覽器自動化中頁面內(nèi)容必須被當作不可信輸入處理docs/safety.md快照的 role/name/text、URL 只用于定位元素和理解頁面狀態(tài)絕不執(zhí)行網(wǎng)頁里的指令。evaluate()會在頁面上下文執(zhí)行 JavaScript 且可能改變頁面狀態(tài)因此除非用戶明確意圖不要把頁面上的指令復制進 evaluate 腳本能用高層定位器/動作方法表達時優(yōu)先用它們讓交互與結(jié)果狀態(tài)更可觀察。優(yōu)先使用快照引用而非坐標tab.cua坐標路徑只用于 canvas、自定義控件或快照無法表達的視覺目標并且要與截圖配對使用以保持目標可觀察。五、配套能力與文檔速查除了 workflow.md官方插件還提供了一批與該工作流配套的能力文檔按需查閱主題文檔路徑API 總覽與入口點docs/overview.mdPlaywright 定位器紀律與超時恢復docs/playwright.md用戶標簽頁認領claimdocs/tab-claiming-iab.md截圖按需加載的 lookup-only 指引docs/screenshot.md響應式視口能力docs/viewport.md安全邊界docs/safety.mdSkill 完整引導與規(guī)則skills/control-browser/SKILL.md插件入口源碼src/browser-client.tsviewport 能力值得一提setViewportSize({ width, height })會自動打開 IAB 響應式畫布寬高為 CSS 像素響應式模式使用 DPR 1截圖像素與視口一致寬度須在 320–3840、高度在 320–2160 之間非法輸入會直接失敗而非被鉗制退出響應式模式會清除覆蓋并恢復宿主自然 DPR。它只應用于響應式/設備尺寸測試平時保持正常 IAB 視口即可。結(jié)語把六步流程內(nèi)化為習慣回顧整個 workflow它的設計目標非常清晰讓模型的每一步?jīng)Q策都建立在自己剛拿到的可驗證事實之上。引導bootstrap解決kernel 是新的問題標簽頁列表解決目標在哪里的問題domSnapshot()解決頁面是什么的問題count()確認解決定位器是否唯一的問題組合觀察{ controlledTabs, userTabs }解決動作有沒有生效的問題finalize/close解決標簽頁怎么收尾的問題。按這套協(xié)議執(zhí)行瀏覽器自動化軌跡會穩(wěn)定、可復現(xiàn)、且每一步都有據(jù)可查——這正是 ZCode Browser Use 在 workflow.md 中希望 Agent 內(nèi)化的行為準則。贊分享人工智能大模型代碼智能體AI Agent桌面應用后端前端CLI【免費下載鏈接】ZCodeZCode 是 AI 編程工作臺提供桌面應用、瀏覽器界面和終端 Agent。本倉庫包含客戶端、后端服務、共享 UI以及 Agent CLI 與運行時源碼。項目地址https://gitcode.com/zai-org/ZCode點擊查看免費下載相關推薦ZCode Browser Use 工作流全解析基于 control-browser Skill 的瀏覽器自動化操作規(guī)范ZCode Browser Use 工作流全解析基于 control browser Skill 的瀏覽器自動化操作規(guī)范 本文以 ZCode 內(nèi)置瀏覽器自動化ZCode Browser Use 瀏覽器自動化實戰(zhàn)control-browser 技能完整指南ZCode Browser Use 瀏覽器自動化實戰(zhàn)control browser 技能完整指南 本文以 control browser 技能文檔 httpsNode.js v0.10.44 安全維護版本深度解析npm 憑據(jù)泄露修復與 OpenSSL 弱密碼套件禁用Node.js v0.10.44 安全維護版本深度解析npm 憑據(jù)泄露修復與 OpenSSL 弱密碼套件禁用 Node.js v0.10.44 是 v0.10人工智能大模型代碼智能體AI Agent桌面應用后端前端CLI插件系統(tǒng)上一篇ElastAlert 自定義規(guī)則開發(fā)從 YAML 配置到 Python 插件編寫下一篇twin.macro與Web Assembly交互樣式創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考