ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ZCode Browser Use 实战:control-browser Skill 的六步浏览器操作工作流(Snapshot→Locator→Act)

ZCode Browser Use 实战: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 为主体结合官方内置插件 browser-use-plugin 的 Skill 引导control-browser SKILL.md与 overview.md 中的 API 行为约定展开。读完本文你将掌握为什么每次 JS 调用都要重新引导bootstrap运行时、如何用「先列全量标签页、再按已验证事实绑定」的协议选择目标、如何以domSnapshot()的 AI/ARIA 树为唯一定位事实来源构建 Playwright 定位器以及动作之后如何用「组合观察」判断真实效果最终写出可稳定复现的浏览器自动化轨迹。ZCode 的浏览器自动化能力由官方内置插件zcode/browser-use-plugin提供。它并不把一个浏览器会话暴露给模型而是把每次js调用都放进一个全新的 JavaScript kernel由zcode/node-repl-host提供的node_replMCP 主机承载模型侧看到的是mcp__node_repl__js。因此跨调用连续性的唯一边界是BrowserControl 的标签页tabs而不是 JavaScript 变量、模块缓存或某个browser/tab绑定。workflow.md 正是在这一前提下为 Agent 定义了一套严格的六步操作协议。下面逐步展开并给出可直接复制运行的代码。一、先决条件每一段代码都从 Skill 引导开始workflow.md 的每一段代码都假设control-browserSkill 的引导已经在当前这个全新的 JS kernel中运行过。引导代码做两件事解析插件根目录并导入browser-client模块然后注册agent.browsers运行时。引导不选择后端真正的后端选择在引导之后的同一次调用里完成。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的实现很薄它从zcode/core/browser-client引入真正的setupBrowserRuntime并通过zcode/node-repl-host/runtime-bridge读取当前 kernel 的运行时桥见 src/browser-client.ts。核心约束是每次js调用都必须重新引导并重建同一个浏览器包装对象而不是因为kernel 是新的就去偷偷切换后端iab/extension/cdp也不是把上一个调用的tabid 直接拿来用。control-browserSkill 强调可用的后端必须来自await agent.browsers.list()的广告desktop 通常广告 IABCLI 以--browser-useheadless启动时广告托管 Chromium 为cdpheadless 是 CDP 的启动/显示模式不是第四种后端类型。未被广告的后端绝不可视为可用。在第一次浏览器调用中选择后端后应立即把完整的 API 文档发给模型一次nodeRepl.write(await browser.documentation())之后的每次新鲜调用只需重复相同的后端选择即可。二、六步工作流全解workflow.md 将一次浏览器自动化任务归纳为六个步骤。核心设计思想是模型必须在每个决策点拿到可验证的事实verified facts——包括标签页的 id、URL、标题、快照中的 role/accessible name——然后用下一个独立 JS 调用基于这些事实行动绝不凭猜测、绝不靠记忆。第 1 步目标选择协议——先列全量再按已验证事实绑定每一个「逻辑标签页操作批次」开始之前用一个专门的 JS 调用把所有受控标签页完整地返回给模型const browser await agent.browsers.getDefault(); const controlledTabs await browser.tabs.list(); controlledTabs;tabs.list()返回的是元数据数组TabInfo[]包含当前active标记与真实 CSSviewport: { width, height }不是可操作的Tab对象。模型查看这段输出后在下一个 JS 调用里按稳定 id 或经核实的 URL/标题事实匹配目标页再调用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();几条硬性规则值得注意绝不因为列表非空就选[0]。多标签页场景下按数组位置选目标是被明确禁止的at(-1)、凭记忆的 id 同样不行。列表空也不等于可以随便开新页。如果受控列表里没有匹配项先用下一次调用把await browser.user.openTabs()返回给模型——这是用户标签页浏览器已打开但尚未交给 Browser Use 控制的页面然后只认领claim核实的用户标签页事实。只有两轮观察都失败受控列表无匹配、用户标签页也无匹配时才创建新标签页。注意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是两个不同的协议不要混用。第 2 步任务给出新 URL 时——选择、打开、导航一次如果任务点名了一个新 URL优先考虑复用感知的入口agent.browsers.open(url)它会复用同站点同 hostname的受控标签页、激活到用户可见并原地导航而不是每次导航都堆一个新标签页。只有确实需要并行独立标签页时才显式创建并走如下导航序列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 之前必须显式调用waitForLoadState({ state: domcontentloaded })。这个显式确认必须保留在模型可见的轨迹trajectory里即使后端导航已经完成也不许省略不许用networkidle代替networkidle存在于共享类型中但被所有 ZCode 浏览器后端拒绝也不许用固定 sleep 代替。常规 URL/加载状态等待的预算被封顶在 3000ms。第 3 步用domSnapshot()读页面——AI/ARIA 树是唯一定位事实来源await tab.playwright.domSnapshot()是默认的页面观察与定位器事实来源ground truth。它返回的是紧凑的 AI/ARIA 树包含计算出的角色role、可访问名称accessible name、状态以及可用时的展开 iframe 内容——而不是页面的outerHTML。使用规则只从最新相关快照中出现的事实构造 Playwright 定位器。绝不猜测 label、可访问名称、placeholder、selector 或 URL 模式绝不用猜测的定位器去当探索性探针exploratory probe消耗超时预算。快照里已经有目标时直接基于快照事实行动不要写evaluate()代码去重新发现相关元素、枚举 input、dump HTML 或遍历 DOM。快照证实snapshot-proven的标题或可见文本不需要link或button角色也能点击不要用猜测的link角色去替换快照证实的heading。只要用户已授权导航、且该标题/文本定位器唯一就直接点击它——事件可以冒泡到祖先卡片上的 JavaScript 处理器。快照调用必须是 JS 单元格里的最后一个表达式或者把它传给nodeRepl.write(...)。仅仅把结果赋值给本地变量并不会把 DOM 观察结果返回给模型overview.md也有同样强调。第 4 步确认唯一性再执行真实浏览器动作当唯一性不明显时先确认定位器唯一然后通过真实浏览器动作执行。count()为 0 时不要等待也不要执行该定位器而是重新拍快照并重建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 内创建的RegExp。推荐的定位器事实优先级来自 docs/playwright.md依次是稳定 test id /data-*属性 → 稳定精确href→ 带快照证实可访问名称的语义角色 → 作用域化可见文本 → 基于已知 DOM 事实的 CSS selector → 作用域化 DOM/CUA 兜底。像Search、Menu、Close这类通用名称默认就是有歧义的行动前必须收窄作用域。第 5 步动作之后——取最廉价的观察组合标签页事实判断效果动作之后收集能回答下一个问题的最廉价观察优先做针对性的定位器状态检查需要新的定位器事实时才再拍一次domSnapshot()。每个观察周期最多执行一个改变状态的动作at most one state-changing action per observation cycle。判断动作成败的标准非常关键源标签页 URL 没变并不能证明点击失败了。判断依据是预期效果是否出现而不是browser.tabs.list()是否非空。已经存在的源标签页或无关的受控标签页不是动作效果。预期效果可以是源页面的状态变化也可以是URL/标题经核实与预期结果匹配的标签页。当动作可能打开弹窗/新标签页、而源标签页没显示预期效果时要在同一个观察单元格里无条件地同时读取受控标签页与用户标签页const [controlledTabs, userTabs] await Promise.all([ browser.tabs.list(), browser.user.openTabs(), ]); ({ controlledTabs, userTabs });把{ controlledTabs, userTabs }作为该单元格的最终结果返回让模型基于两张表做一次决策。不要先返回受控列表、再根据它的内容决定要不要查用户标签页。下一个单元格里按核实的 id/url/title 匹配激活受控页或认领用户页。如果源页面 组合标签页观察都没有预期效果就拍新快照、选新定位器而不是重放旧的点击。截图相关的纪律workflow.md 与 docs/screenshot.md 一致打开或导航一个普通页面不是截图理由默认不要把 DOM 快照和截图一起收集。只有用户明确要求截图、必须判断视觉布局/渲染/图像内容、或目标不在 DOM 快照里如 canvas / 自定义绘制 UI时才加载agent.documentation.get(screenshots)指引。一旦进入截图分支每张截图必须在同一个 JS 单元格里用nodeRepl.emitImage(await tab.screenshot())发出绝不把tab.screenshot()留作最终表达式也绝不直接返回它的Uint8Array字节内部返回 PNG 字节对模型不可见。截图超时不要立刻重试同一张截图——底层 Chromium 捕获可能仍在完成应等待后重试或按显式 in-flight 错误重开标签页。超时与失败恢复任何 Playwright 超时、strict-mode 失败或 selector 解析失败之后不要重试同一个定位器。拍一张新的domSnapshot()并从快照证实的事实重建。常规定位器/页面状态等待都在 3000ms 预算内失败只有无法观察到任何具体状态时才用更长的固定 sleeptab.playwright.waitForTimeout(ms)注意根级tab.waitForTimeout在这个运行时不存在。expectNavigation(action)若要证明确实发生了新导航应传入{ url: expectedUrl }否则已加载的旧页面也可能满足等待器。第 6 步标签页生命周期——默认跨轮次保持收尾用finalize标签页在当前 ZCode 进程的生命周期内默认跨轮次保持打开。只有需要把列出的页面标记为deliverable或handoff时才调用await browser.tabs.finalize({ keep });不在keep列表里的页面不会因此被关闭。关闭标签页只有一条路有意的await tab.close()用户手动关闭、关窗、进程退出也会移除标签页。不要因为轮次结束就关掉研究/源标签页相关约定见 docs/all-tabs-cleanup.md 与 overview.md。三、直接查找direct lookup的纪律workflow.md 最后给出了一条针对只读直接查找的规则至多做一次聚焦尝试且尝试必须来源于用户输入或经核实的页面事实。绝不迭代猜测的 URL 变体、路径、查询参数或数字 ID。如果这次聚焦尝试失败改用一张新的domSnapshot()站点自身的搜索/导航功能权威的连接器/API/CLI 查询。找到一个权威候选后直接验证它而不是继续收集更多候选。这条规则与control-browserSkill 的规则完全一致goto()只接受http:、https:与精确的about:blankfile:、其他about:*、data:、javascript:目标不可导航file:URL 仅可作为多后端场景下getForUrl()的后端选择提示。四、安全边界页面内容不可信浏览器自动化中页面内容必须被当作不可信输入处理docs/safety.md快照的 role/name/text、URL 只用于定位元素和理解页面状态绝不执行网页里的指令。evaluate()会在页面上下文执行 JavaScript 且可能改变页面状态因此除非用户明确意图不要把页面上的指令复制进 evaluate 脚本能用高层定位器/动作方法表达时优先用它们让交互与结果状态更可观察。优先使用快照引用而非坐标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 完整引导与规则skills/control-browser/SKILL.md插件入口源码src/browser-client.tsviewport 能力值得一提setViewportSize({ width, height })会自动打开 IAB 响应式画布宽高为 CSS 像素响应式模式使用 DPR 1截图像素与视口一致宽度须在 320–3840、高度在 320–2160 之间非法输入会直接失败而非被钳制退出响应式模式会清除覆盖并恢复宿主自然 DPR。它只应用于响应式/设备尺寸测试平时保持正常 IAB 视口即可。结语把六步流程内化为习惯回顾整个 workflow它的设计目标非常清晰让模型的每一步决策都建立在自己刚拿到的可验证事实之上。引导bootstrap解决kernel 是新的问题标签页列表解决目标在哪里的问题domSnapshot()解决页面是什么的问题count()确认解决定位器是否唯一的问题组合观察{ controlledTabs, userTabs }解决动作有没有生效的问题finalize/close解决标签页怎么收尾的问题。按这套协议执行浏览器自动化轨迹会稳定、可复现、且每一步都有据可查——这正是 ZCode Browser Use 在 workflow.md 中希望 Agent 内化的行为准则。赞分享人工智能大模型代码智能体AI Agent桌面应用后端前端CLI【免费下载链接】ZCodeZCode 是 AI 编程工作台提供桌面应用、浏览器界面和终端 Agent。本仓库包含客户端、后端服务、共享 UI以及 Agent CLI 与运行时源码。项目地址https://gitcode.com/zai-org/ZCode点击查看免费下载相关推荐ZCode Browser Use 工作流全解析基于 control-browser Skill 的浏览器自动化操作规范ZCode Browser Use 工作流全解析基于 control browser Skill 的浏览器自动化操作规范 本文以 ZCode 内置浏览器自动化ZCode Browser Use 浏览器自动化实战control-browser 技能完整指南ZCode Browser Use 浏览器自动化实战control browser 技能完整指南 本文以 control browser 技能文档 httpsNode.js v0.10.44 安全维护版本深度解析npm 凭据泄露修复与 OpenSSL 弱密码套件禁用Node.js v0.10.44 安全维护版本深度解析npm 凭据泄露修复与 OpenSSL 弱密码套件禁用 Node.js v0.10.44 是 v0.10人工智能大模型代码智能体AI Agent桌面应用后端前端CLI插件系统上一篇ElastAlert 自定义规则开发从 YAML 配置到 Python 插件编写下一篇twin.macro与Web Assembly交互样式创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表