Stagehand 托管 Deep Agents 浏览器代理指令:理解 snapshot / run / screenshot 三工具契约
发布时间:2026/9/12 11:13:39来源:尧图企业网站定制
Stagehand 托管 Deep Agents 浏览器代理指令理解 snapshot / run / screenshot 三工具契约【免费下载链接】stagehandThe SDK For Browser Agents项目地址: https://gitcode.com/GitHub_Trending/stag/stagehand在 Stagehand 的 Deep Agents 集成中examples/managed演示了一种托管运行模式LangChain Deep Agents 通过三个手工编写的 LangChain 工具直接驱动 Python Stagehand SDK为浏览器代理Browser Agent暴露一个严格受限、状态持久的工作面。本文以该示例的系统指令文档 instructions.md 为主线逐条解析一个持久浏览器、三个工具的契约设计、快照 ID 的水合与失效规则、run的两种执行模式及其 Playwright 兼容层原理。读完你既能看懂这份指令的每一句话为什么存在也能直接把它改造成自己 Deep Agent 的浏览器指令模板。这份 instructions 文档在项目中扮演什么角色examples/managed/instructions.md是托管示例发给 Deep Agent 的系统提示system instruction全文只有三层信息工具面三个工具、工具语义snapshot 水合 ID、run 双模式、以及一条硬约束绝不启动第二个浏览器。它与示例的装配代码一一对应。agent.py 中import os from managed_deepagents import define_deep_agent from tools.stagehand import run, screenshot, snapshot agent define_deep_agent( namestagehand-browser-agent, modelos.environ.get(DEEPAGENTS_MODEL, openai:gpt-5.6-luna), tools[run, snapshot, screenshot], )工具实现位于 tools/stagehand.py模型默认值、工具列表与指令文档完全一致。也就是说指令文档是给模型读的用户手册工具代码是给运行时执行的实现两者必须保持同步——这是编写浏览器 Agent 指令时最容易踩的坑。核心契约一个持久浏览器三个工具指令开篇即声明You control one persistent Browserbase browser through exactly three tools.一个持久浏览器不是修辞而是架构事实。托管模式下_BrowserRegistry以 Deep Agents 的线程 IDToolRuntime.execution_info.thread_id或run_id为键缓存_BrowserRuntime见 tools/stagehand.py同一线程内的多次工具调用共享同一个浏览器实例。三个工具的契约如下工具入参要点用途返回snapshotincludeIframes: bool True观察当前活动页水合hydrate方括号元素 ID格式化可访问性树formatted treeruncodeJavaScript或actions快照动作批二选一执行交互或多步工作流JSON 序列化结果screenshotfullPage、typepng/jpeg、quality视觉观察渲染结果base64 data URL 图片内容对应实现为 tools/stagehand.py 中三个tool装饰的异步函数。指令随后给出的使用原则是简单交互用 snapshot actions多步工作流用run代码快照 ID 只对活动页的最新一次快照有效导航后或 ID 过期时必须重新 snapshot绝不尝试启动另一个浏览器。snapshot可访问性树与方括号 ID 水合snapshot的职责是把页面翻译成模型可读、可引用的形式。其实现tools/stagehand.pyasync def snapshot(self, include_iframes: bool) - str: async with self.lock: page await self.active_page() snapshot await page.snapshot(include_iframesinclude_iframes) self.snapshots[page.page_id] _Snapshot( urlawait page.url(), xpath_by_iddict(snapshot.xpath_map), ) return snapshot.formatted_tree关键点有三水合发生在服务端snapshot同时返回两样东西——给模型看的formatted_tree其中元素以[ID]方括号形式标注和给运行时用的xpath_mapID → XPath 的映射。模型看到的 ID 只是句柄真正定位靠 XPath。快照按页隔离映射以page.page_id为键存储不同标签页的快照互不串扰。快照会整体替换每次调用都以当前活动页的最新快照覆盖旧映射MCP 版 server 的工具描述也明确写了 Every call replaces the active page ID map见 server.py。run动作批处理与 JavaScript 工作流run是三个工具中唯一能做事的其约束为必须且只能提供code或actions中的一个。源码中通过异或校验强制if (code is None) (actions is None): raise ValueError(run requires exactly one of code or actions)tools/stagehand.py模式一snapshot actions——适合简单交互动作是 Pydantic 模型校验的结构化对象合法操作共六种tools/stagehand.pyop必填字段说明clickid点击元素hoverid悬停fillid,value填入值一次替换typeid,text逐键输入可选delay毫秒≥0pressid,key先点击目标再按按键selectid,values下拉选择values可为字符串或字符串数组一个典型动作批[ {op: click, id: 1-42}, {op: fill, id: 2-14, value: Miami}, {op: select, id: 3-9, values: Lowest price} ]执行时tools/stagehand.py运行时先把 ID 从xpath_map解析成xpath...选择器再交给_ACTION_SOURCE这段内嵌 JavaScript 在浏览器侧逐个执行async (stagehand, input) { let completed 0; for (const action of input.actions) { const locator stagehand.page.locator(action.selector); switch (action.op) { case click: await locator.click(); break; case hover: await locator.hover(); break; case fill: await locator.fill(action.value); break; case type: await locator.type( action.text, action.delay undefined ? undefined : { delay: action.delay }, ); break; case press: await locator.click(); await stagehand.page.keyPress(action.key); break; case select: await locator.selectOption(action.values); break; default: throw new Error(Unsupported ref action: String(action.op)); } completed 1; } return { completed }; }tools/stagehand.py模式二JavaScript code——适合多步工作流run的code参数接收一段异步函数体执行时被包装进浏览器侧运行环境作用域内已有page、context、browser三个 Playwright 形状的对象source fasync (batchStagehand, input) {{ use strict; ... {facade} const runtime await createPlaywrightCompatRuntime(batchStagehand); const page runtime.page; const context runtime.context; const browser runtime.browser; return await (async () {{ {code} }})(); }} return await self.stagehand.experimental_batch( source, {}, pagepage, timeout_positive_int_env(STAGEHAND_RUN_TIMEOUT_MS, 60_000), )tools/stagehand.py所谓 Playwright-shaped来自 playwright_facade.js 这个约 1689 行的兼容层。它把 Stagehand 的页面 API 翻译成模型更熟悉的 Playwright 形态支持定位器page.locator(...)、getByText、getByRole、getByLabel、getByPlaceholder、getByAltText、getByTitle、getByTestId以及filter、first/last/nth、all()等动作click、fill、type、press、hover、selectOption、setInputFiles、check/uncheck、clear读取textContent、innerText、inputValue、getAttribute、count、boundingBox等页面与上下文goto/reload/goBack/goForward、waitForTimeout、waitForNavigation、waitForResponse、waitForSelector、事件订阅download、console、request/response、pageerror、route/unroute网络拦截、newCDPSession。未被实现的方法会被guard代理拦截并抛出统一错误Playwright compatibility facade does not implement ...见 playwright_facade.js避免模型在看似可用实则不存在的 API 上做无谓尝试。兼容层还会统计每次调用的命中与未命中calls/misses并通过telemetry()暴露便于评估 facade 覆盖面。二选一背后的工程考量run的 schema 刻意不做顶层oneOf校验因为 AI-SDK 系 MCP 客户端如 Eve、Vercel AI SDK会拒绝含顶层oneOf的工具输入 schema互斥性改由工具描述声明、并在运行时由ValueError兜底这一决策也同步体现在 TS 侧契约中见 server.py 的注释。screenshot视觉观察通道snapshot提供结构信息可访问性树screenshot则提供像素级视觉信息二者互补。其参数与约束tools/stagehand.pyfullPage是否截整页长图typepng默认或jpegquality0–100仅对 jpeg 有效png 下传该参数直接报错。截图以data:{mime};base64,...的图片内容块返回模型可以看图办事——这在验证布局、识别验证码类 UI 或检查渲染结果时不可或缺。ID 生命周期与失效规则指令中最重要的一句话指令特别强调Snapshot IDs are valid only for the latest snapshot of the active page. Snapshot again after navigation or when an ID is stale.这句话背后是两层运行时校验tools/stagehand.pysnapshot self.snapshots.get(page.page_id) if snapshot is None or snapshot.url ! await page.url(): raise ValueError(No current hydrated snapshot exists; call snapshot again) ... xpath snapshot.xpath_by_id.get(action.id) if xpath is None: raise ValueError(fSnapshot ID {action.id} is stale or not actionable)URL 变了快照记录的目标 URL 与当前页 URL 不一致 → 提示先重新 snapshotID 不在映射里→ 提示该 ID 已过期或不可操作。也就是说导航含单页应用内跳转导致 URL 变化后旧快照的 ID 全部作废。好的 Agent 工作流应该是导航 → snapshot → 用 ID 操作 → 再导航 → 再 snapshot的循环而不是把 ID 当作跨页面持久句柄。为什么绝不尝试启动另一个浏览器这条硬约束对应运行时里的两件事会话是按线程复用的_BrowserRegistry以thread_id为键命中缓存直接返回既有浏览器即使句柄因 socket 断开失效也会先尝试用session_id重连 Browserbase 的 keep-alive 会话tools/stagehand.py。浏览器由框架统一管理模型没有也不应该有开新浏览器的权限。会话是有生命周期与成本的keep-alive 会话在close()后依然存活运行时会在关闭时显式调用 Browserbase 的REQUEST_RELEASE释放空闲超过STAGEHAND_SESSION_TTL_SECONDS默认 1800 秒的会话会被定期回收见 tools/stagehand.py。若模型擅自另起炉灶等于绕开这套复用/回收机制造成会话泄漏与额外计费。配置与部署托管 Agent 的运行环境托管示例的运行配置写在其 pyproject.toml 中依赖managed-deepagents、stagehand4.0.0、langchain1,2等。部署时先复制.env.example为.env该文件在仓库中为模板需自行填充真实密钥需要配置的环境变量如下变量用途DEEPAGENTS_MODELDeep Agent 的模型标识如openai:gpt-5.6-luna未设置时 agent.py 使用默认值OPENAI_API_KEY或其他 provider key与DEEPAGENTS_MODEL匹配的模型密钥BROWSERBASE_API_KEY托管浏览器必填缺失时_BrowserRuntime.start直接抛RuntimeErrorSTAGEHAND_API_URL走 Browserbase Model Gateway零额外密钥的 Stagehand 路径STAGEHAND_MODELSTAGEHAND_MODEL_API_KEY直接向 provider BYOKMODEL_API_KEY必须与MODEL成对出现否则报错STAGEHAND_EXTENSION_ID复用预上传扩展时设置缺省时发布的stagehandwheel 自带扩展browserbase.launch自动装配然后依次执行uv sync uv run mda dev . uv run mda deploy .完整说明见 README.md 的 Managed Deep Agents 一节。另需注意依赖版本约束Stagehand 要求websockets16.1.1而当前 LangGraph SDK 要求websockets16因此托管示例通过override-dependencies [websockets15.0.1]临时对齐见 pyproject.toml待两个 SDK 的版本区间收敛后即可移除该覆盖。Managed Deep Agents 会把非保留的.env项作为部署密钥转发其中 Agent 模型密钥与 Stagehand 模型密钥相互独立用户可各自 BYOK。安全与错误处理设计代码在浏览器侧执行run的 JavaScript 运行于 Stagehand 浏览器扩展的 service worker 内浏览器进程而非宿主进程天然与本地环境隔离凭据脱敏工具返回的任何错误消息都会经过_sanitize_error处理把 URL 查询参数中的signingKey、apiKey、api_key、token、key以及sk-开头的密钥片段替换为[redacted]tools/stagehand.py防止密钥经模型回显泄漏环境变量白名单只有STAGEHAND_*与BROWSERBASE_*变量会随浏览器会话转发Deep Agent 的模型密钥等宿主机密不会进入浏览器会话。可直接复用的指令模板原指令全文本身就是一份精简的系统提示模板。基于上文分析可以把它扩展为更利于模型执行、且与实现严格对齐的版本You control one persistent Browserbase browser through exactly three tools: - snapshot inspects the active page and hydrates bracketed element IDs. Call it after every navigation; its IDs are valid only for the latest snapshot of the active page. - run accepts either snapshot actions or JavaScript using the Playwright- shaped page API (page / context / browser). Provide exactly one of code or actions. - screenshot inspects the rendered page visually; use type: jpeg with quality between 0 and 100, and fullPage for full-page captures. Workflow rules: 1. Use snapshot actions for simple interactions, and run code for multi-step workflows. 2. Re-snapshot after navigation or whenever an ID is stale — never reuse IDs across navigations. 3. Never attempt to launch another browser; the session is managed for you.编写浏览器 Agent 指令的核心原则由此可总结为三条工具面越小越好让模型少做选择、ID 语义必须讲清生命周期减少无效调用、约束必须与运行时强一致防止模型做出实现不支持的动作。Stagehand 托管示例正是这三条原则的可运行范本——指令、工具实现与运行时策略三者彼此印证值得作为同类 Agent 的参照起点。【免费下载链接】stagehandThe SDK For Browser Agents项目地址: https://gitcode.com/GitHub_Trending/stag/stagehand创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考