为什么做共享真实浏览器

August 21, 2026 · View on GitHub

问题

LLM agent 需要"上网"。传统做法是给 agent 一个无头浏览器(Playwright/Puppeteer 等)或网页抓取工具:

  • 无头浏览器:agent 在看不见的页面里操作,用户无法确认它在做什么,也无法中途接管;遇到登录、验证码、人机检测时寸步难行。
  • 网页抓取:只能读不能交互,且大量现代网站依赖 JS 渲染,抓到的内容失真。

这两条路都绕开了"用户"——浏览器成了 agent 的私有工具,而不是用户和 agent 共用的工具。

方案:共享真实浏览器

dsh-browser-plus 的思路很朴素:让 agent 驱动用户眼前那个真实的浏览器窗口

  • 浏览器是原生 WebContentsView,用户直接看到 agent 的每一步操作(打开页面、填写表单、点击、滚动);
  • 用户随时可以上手接管:输入、点击、登录、过验证码——做完之后 agent 继续;
  • agent 通过 CDP 在同一个页面里执行 JS,拿到的是与用户所见完全一致的真实 DOM。

一句话:浏览器不是 agent 的"黑盒工具",而是用户与 agent 之间的共享工作台

与无头方案的能力对比

能力无头浏览器网页抓取本插件(共享真实浏览器)
真实页面渲染部分
复杂交互(填表/点击/拖拽)
用户可见、可接管
保留登录态需手动管理✅(browser_auth + cookie 落盘)
人工处理验证码❌ 卡死✅ 请用户点一下即可
多任务并行需多实例✅ 任务级会话隔离

设计取舍

  • 登录态共享:所有任务共享同一份 cookie(符合"用户登录一次,agent 到处可用");需要隔离时用 browser_auth 手动导出/恢复。
  • 任务级会话隔离:每个 DSH 会话(任务)拥有独立的浏览器会话(标签页与历史),并发任务互不抢页面;但窗口只有一个,当前活动的任务视图可见。
  • 装好即用:不依赖桌面外壳。有外壳时嵌入外壳视图;纯 dsh web 时插件自托管——自己拉起 Electron 窗口,通过本机 TCP JSON-RPC 驱动。
  • 边界清晰:可见视图、浏览器列布局属于宿主外壳;插件只负责 seam、provider 与工具,不含任何 UI。
  • 人机验证不硬刚:检测到 Cloudflare/reCAPTCHA/hCaptcha/Turnstile 时停下,请用户在共享窗口人工完成,而不是盲目重试。

什么场景不适合

  • 需要无头批量抓取(成千上万页面):请用专门的抓取工具/服务,不必开窗口。
  • 需要每个任务完全独立的登录态(互不可见):本插件默认共享 cookie;如需强隔离,可用多个 DSH 实例或 browser_auth 手动管理。
  • 需要浏览器列 UI / 布局管理:那是宿主外壳的配套,本插件不包含。