BrowserSkill for DeepSeek Harness:六个注入式浏览器工具域驱动的 Agent 浏览器自动化实战指南
【免费下载链接】BrowserSkillLet AI agents use your real, logged-in browser without interrupting your work. CLI + extension for browser automation across any shell-capable AI agent.项目地址: https://gitcode.com/GitHub_Trending/br/BrowserSkill
本篇技术指南以 BrowserSkill 为 DeepSeek Harness(dsh)发布的browser-skillAgent 技能(skill)为绝对核心,系统讲解 Agent 如何在拥有既有登录态的 Agent Window 中,通过browser_session、browser_page、browser_inspect、browser_interact、browser_tabs、browser_assist六个注入式浏览器工具完成“定义成功 → 建会话 → 导航 → 观察 → 交互 → 收尾”的闭环任务。读完本文,你将掌握会话/标签页的归属边界、@eNref 的失效与恢复策略、人工协助(request-help)的启用与降级规则、Canvas 截图点击协议,以及基于maxTokens/nextCursor的长页面续读方案,并能在源码层面理解这些规则背后的实现。
一、定位:dsh 插件中的浏览器技能与六个工具域
browser-skill是 dsh 插件@wxg-prc-cpg/browser-skill-dsh-plugin发布的 Agent 技能,其全部行为约束定义在 skill/SKILL.md 中。它有三条根本性前提:
- 所有浏览器操作必须直接使用注入的
browser_*工具,运行在拥有既有登录态的 Agent Window 内,绝不通过另一个进程间接控制浏览器; - 参数一律以已加载的动作 schema 为准,模型不能凭空发明参数或工具;
- 远程接入或配对场景,需先按 远程扩展连接指南 完成配置后再使用这些工具。
插件只向模型暴露六个“域工具”,每个工具内部按action字段分发到私有的操作处理器。从 browser-tools.ts 的BROWSER_TOOL_SPECS可以看到六个工具及其动作清单:
| 工具 | 动作 | 用途 |
|---|---|---|
browser_session | start、stop、list | 管理插件拥有的 Agent Window 会话 |
browser_page | navigate、back、forward、reload、wait | 导航活动标签页并等待页面生命周期事件 |
browser_inspect | observe、snapshot、html、screenshot、console、network | 读取语义化/诊断页面状态并截图 |
browser_interact | click、hover、wheel、scroll-to、focus、blur、fill、select、press | 使用新鲜 ref 或选择器与控件交互 |
browser_tabs | list、create、select、close、borrow、return | 管理 Agent Window 标签页并临时借用用户标签页 |
browser_assist | resize、emulate、request-help | 调整窗口/模拟设备并暂停等待人工步骤 |
值得注意的实现细节:六个 schema 之下,tools.ts 通过createBrowserOperationDefinitions构建私有操作定义集合,defineBrowserTool在运行时按action查表分发(browser-tools.ts),因此校验、取消、归属、观察上报、UI 呈现等横切逻辑可以复用在每个动作上,模型却只会看到六个精简的工具 schema。
二、环境准备与插件配置(前置条件)
技能本身不负责安装运行环境。使用前需要满足(详见 插件 README):
- 安装 DeepSeek Harness 与 pnpm;
- 安装
bskCLI 并连接 Chrome/Edge 中的 BrowserSkill 扩展,确保bsk位于启动 dsh 的PATH上; - 将插件安装进
webprofile 并启动:
dsh plugin --profile web add @wxg-prc-cpg/browser-skill-dsh-plugin dsh --profile web插件自带browser-skill技能,无需单独的bsk install-skill步骤。在会话中输入/browser-skill open example.com and summarize the page.即可触发。
安装后可在 profile 的cordis.patch.yml(默认~/.dsh/profiles/web/cordis.patch.yml,设置了DSH_HOME则用$DSH_HOME/profiles/web/cordis.patch.yml)中覆盖插件配置。参考配置与默认值如下(全部字段可选,来源 index.ts 的 Schemastery schema):
- id: browserskill config: bskPath: bsk defaultTimeoutMs: 120000 maxSessions: 5 observationEnabled: true thumbnailIntervalMs: 1500 idleIntervalMs: 8000 lazyTools: true| 选项 | 默认值 | 作用 |
|---|---|---|
bskPath | bsk | CLI 二进制路径,不在 PATH 时改为全路径 |
defaultTimeoutMs | 120000 | 默认命令超时(毫秒) |
maxSessions | 5 | 本插件可启动的最大并发会话数 |
observationEnabled | true | 是否开启实时浏览器观察 |
thumbnailIntervalMs | 1500 | 活动会话截图间隔(毫秒) |
idleIntervalMs | 8000 | 空闲会话截图间隔与近期活动窗口(毫秒) |
lazyTools | true | 是否在技能被调用后才注册browser_*工具 |
lazyTools: true时,模型起初只在<available_skills>里看到技能目录条目,六个工具 schema 在技能成功调用(模型自行调用或/browser-skill)后才加入系统提示词,注册一次、持续到插件卸载;设为false则在启动时立即注册(实现见 skill.ts 与 lazy-tools.ts)。补丁会整体替换该条目的config对象,因此需要保留的覆盖项要写在一起;配置热加载与否由 profile 的dsh.profile.patchReload决定(web默认live,保存即生效)。
三、强制工作流:会话、导航、观察与收尾
技能规定了一套不可跳过的执行顺序,核心是“先定义成功,再动手”:
场景 A:新页面。启动会话并保存返回的sessionId,随后在 Agent Window 中导航并观察:
browser_session({ action: "start" }) browser_page({ action: "navigate", session: "<id>", url: "https://example.com" }) browser_inspect({ action: "observe", session: "<id>" })场景 B:已有用户标签页。改用borrow借用,而不是新建页面;把示例 ID/ref 替换为实际返回结果。存在多个会话时显式传session,绝不使用外部(foreign)ID。
页面每次变化后都要重新observe;对歧义结果只检查一次。成功可见即停止动作。成功或失败后都应调用:
browser_session({ action: "stop", session: "<id>" })除非“保持会话开启”本身就是用户的请求。stop会归还借用的标签页——它们仍以打开状态留在用户的窗口里。
从实现看,start会先同步预留会话槽位(tools.ts 的registry.reserveStart()),避免并发启动突破maxSessions上限;若随后的navigate/emulate初始化失败,会走同一套幂等清理路径停掉半初始化会话,防止泄漏(tools.ts)。stop只允许停掉本插件创建的会话,list也只列出插件自有会话——这是多程序共享同一个 bsk daemon 时的归属边界(tools.ts 明确注释:registry-only,不触碰 daemon,外部会话连“被看到”都不可能)。
四、读取与交互:observe 优先与 ref 使用规则
技能给出了一套清晰的读取工具选择策略:
observe:首选,输出语义化的 VOM 观察(角色、状态、感知探针)并附带@eNref,只读、绝不提交输入;snapshot:需要静态无障碍树(aria-tree)时使用;html:需要精确标记时使用;screenshot:需要视觉证据时使用;console/network:有界的只读诊断,跟随序列游标读取,仅等待预期的导航。
ref 生命周期是交互正确性的关键:@eNref 在导航后失效,大范围 DOM 变更也可能使其过期——必须重新observe。对 iframe/shadow root 内的元素,ref 是首选寻址方式,CSS 选择器只搜索主文档。对普通控件一律用 observe 定位,包括在基于 HTML 或截图结论行动之前。select下拉框按 value 选值,而不是可见标签。
填充一个观察到的字段@e3的示例(源码侧动作定义见 tools.ts,noClear可追加而非清空):
browser_interact({ action: "fill", session: "<id>", target: "@e3", value: "text" })三个动作的特殊语义需要牢记(对应 docs/scroll-to.md 与 docs/wheel.md):
- Hover 标记:形如
[hover first: Shoes | Bags]的标记列出的是标签而非 ref。流程是:hover 触发器 → observe → 拿到具体条目 ref → 再用该 ref 行动。只有当触发器本身的动作正是你想要的,才直接点击它。 scroll-to:返回的是祖先裁剪后的边界框,单位是顶层视口 CSS 像素。部分可见即可成功,隐藏或完全被裁剪的目标会失败;它不做遮挡(occlusion)测试。wheel:使用带符号的deltaX/deltaY,至少一个非零。可选target会先滚动进入视野,否则以视口中心为准。它报告的是输入本身,而非滚动结果——之后必须 observe 验证。focus/blur会改变焦点状态。
五、借用标签页与人工协助(request-help)
借用原则:行动前先用browser_tabs(list)确认 ID;仅为当前步骤借用,用完立即return。浏览器自动化设置(Browser Automation 设置)管辖确认与帮助行为,绝不可为绕过某个提示或重复 pending/denied/expired 的借用而修改这些设置。未知结果必须 inspect 后再行动,并遵循版本错误提示。远程场景下,读取/操作只允许作用于任务创建或借用的标签页,弹出窗口(popup)无法获得控制权。Agent Window 内未被拥有的标签页,需用户先移到用户窗口才能被借用。
帮助开启时(request-help):用于登录、CAPTCHA、OTP、支付确认、同意授权等场景,或在连续两次尝试无进展后使用。用法要点:
- 提供精确的 prompt 和新鲜的 targets;
- 完成标准需要一个稳定的成功信号(completion criteria);
- 仅在收到
continued/completed后恢复行动,然后 observe; - 取消/超时会阻塞当前步骤,不要重复请求;
- 单纯的导航不算成功。
browser_assist除了request-help,还支持resize调整窗口、emulate对单个标签页做移动设备模拟(内置预设见 browser-tools.ts:iphone-14、iphone-14-pro-max、iphone-se、pixel-7、galaxy-s23、ipad-mini、galaxy-tab-s8;mobile标志必须与width+height同时给出,daemon 会拒绝单独使用--mobile,见 tools.ts)。
帮助关闭时:不请求帮助、不重新启用。disabled确认没有人工操作或新权限可用。此时应重新 observe,在任务/宿主规则内使用既有登录态、已授权输入和可行替代方案。视觉模型在授权范围内可尝试图形验证。以下情形可能保持受阻:仅限手机的扫码、人脸验证、缺失短信验证码、纯文本模型面对纯图片任务。应报告缺失的输入/能力或已穷尽的替代方案,继续独立工作;绝不重复未知副作用,也不切换后端来绕过限制。借用确认(borrow confirmation)在这些场景下依然适用。
六、恢复与容错:错误分类与处理动作
技能把常见故障归纳为五类,每类有明确的处理动作:
| 错误 | 处理 |
|---|---|
| 过期 ref(stale ref) | 重新 observe,然后重试预期动作一次 |
| 未知 tab/session | 列出自有资源或启动会话,绝不猜测 ID |
| 超时/未知效果 | 先 inspect 再重试——动作可能已经发生 |
| 未确认的 fill | 读字段值核对;若格式已满足目标,只修正剩余差异,不要盲目重填或请求帮助 |
| 其他错误 | 跟随提示;不可恢复时报告并停止自有会话 |
同时技能明确了两条能力红线:任意页面脚本求值(arbitrary page-script evaluation)与交互录制(interaction recording)是有意不支持的;不要发明工具或试图绕过这些限制。(这一点在插件 README 与 docs/development.md 中被多次重申,是 dsh 集成界面的刻意边界而非缺陷。)
七、Canvas 与长页面续读
Canvas 特例:@eN canvas [visual:screenshot]在观察结果中是文本而非图片。需要时对 ref 截图,绝不从邻近标签推断 Canvas 的名称/控件;若图像无法被理解,应请求具备图像能力的模型并继续使用可用语义继续。
Canvas 上的点击协议(对应 tools.ts 中interact.click的 capture 参数):
browser_inspect({ action: "screenshot", session: "<id>", ref: "@e3" }) browser_interact({ action: "click", session: "<id>", target: "@e3", captureId: "<capture-id>", imageX: 100, imageY: 50 })关键约束:
imageX/imageY必须是原始 PNG 像素中的真实坐标,不是缩放后的展示/视口坐标;- capture单次使用、有效期 2 分钟,ref 被替换或该 ref 出现新截图时立即过期;
captureUnavailable表示只读:先 observe 再截图,之后才能点击;- Canvas 点击支持次数 1/2、按钮与修饰键;Canvas 的 fill/IME/drag/hover/HTML 均不支持;
- 重绘是允许的,但要验证结果,并用 DOM ref 操作随后出现的控件;
- 若返回
effect_state=unknown,在获取新 capture 重试前先 inspect。
长页面续读:无默认 token 上限;设了maxTokens时,用 observe 返回的cursor跟随nextCursor读取剩余内容。每个页面都会替换 refs:必须在续读前使用当前 refs,绝不复用旧 ref。续读读取的是同一 capture,前提是没有刷新/深度变化;新的 observe/snapshot 或页面身份变化都会使其失效(对应 tools.ts 中 observe 的cursor/nextCursor/truncated输出契约)。
八、源码级支撑:多会话模型、执行与观察机制
技能文档描述的行为,在插件源码中都有对应实现:
- 多会话模型:一次对话可同时驱动多个浏览器会话。每个操作工具接受可选
session参数,省略时作用于当前会话(最近启动或使用的那个),显式传入则将其设为当前;每个工具结果都会回显实际作用的会话,模型无需猜测。所有会话的启动上限受maxSessions控制(index.ts 中SessionRegistry构造)。插件卸载时会终止所有它启动的会话并杀掉在途的 bsk 子进程(index.ts)。 - 命令执行:每个动作经
runBsk调用bsk <cmd> --json并解析结构化输出;命令按会话进入 per-session FIFO 队列(tools.ts),因为 daemon 同一时刻只接受每会话一条未完成命令;取消(abort)会杀掉对应 bsk 子进程,与 BrowserSkill 的协作式取消模型一致。bsk非零退出时透传 CLI 的 JSON 错误信封(code/message/hint),让模型拿到 daemon 的可执行建议(docs/development.md)。 - 技能注册:技能正文经构建期脚本内嵌为静态模块(
skill-content.generated),注册与目录快照均为纯内存读取;同名的~/.agentsCLI 技能会在预设层被发现并遮蔽全局注册,因此插件还会通过agent/session-start在每个精确 agent 作用域重新注册,使 dsh 协议文本对每个 agent 权威生效(skill.ts)。 - 实时观察视图:dsh Web UI 通过
GET /bsk-observation/events(SSE)同步会话快照与upsert/remove/reset事件,观察端点要求 loopback 地址(localhost、127.0.0.0/8、[::1]),并复刻 dsh 自身的浏览器信任栅栏——LAN 地址或非 loopback 反向代理会刻意失败(docs/development.md 的“Trust model”一节)。
九、常用排查速查
把技能文档中的规则收敛为一张可执行检查表,供模型在每步动作前自检:
- 行动前:这个会话/tab 是我拥有的吗?ref 是否来自最近一次 observe?
- 导航后:是否重新 observe 过了?还在复用旧 ref 吗?
- 借用后:用完是否立即 return 了?有没有为了绕过确认而改设置?
- 失败后:是先 inspect 再重试,还是盲目重试?超时/未知效果可能意味着动作已发生。
- 收尾时:成功可见了吗?该 stop 的会话 stop 了吗?是否在保持会话开启是用户需求时才不 stop?
- 红线检查:我是否在试图做任意脚本求值、交互录制、或发明不存在的工具?
参考资源
- 技能完整规则原文:packages/dsh-plugin-browserskill/skill/SKILL.md
- 插件安装、更新、配置与实时视图:packages/dsh-plugin-browserskill/README.md
- 插件开发与内部机制:packages/dsh-plugin-browserskill/docs/development.md
- 工具 schema 与动作分发:packages/dsh-plugin-browserskill/src/browser-tools.ts
- 操作实现与配置 schema:packages/dsh-plugin-browserskill/src/tools.ts、packages/dsh-plugin-browserskill/src/index.ts
- 共享参数定义:packages/dsh-plugin-browserskill/src/tool-params.ts
wheel与scroll-to的完整语义:docs/wheel.md、docs/scroll-to.md- 远程扩展连接:docs/remote-extension-connection.md
【免费下载链接】BrowserSkillLet AI agents use your real, logged-in browser without interrupting your work. CLI + extension for browser automation across any shell-capable AI agent.项目地址: https://gitcode.com/GitHub_Trending/br/BrowserSkill
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考