嵌入式浏览器
每个工作区都自带一个网页浏览器:一个完整的 Chromium,它会作为一个窗格在终端旁边打开。它的存在是为了让代理能够看到网络 —— 打开它刚刚构建的应用、阅读文档页面、复现 bug、点击走完某个流程 —— 同时也让你能够观看(并驾驭)它所使用的同一个浏览器。该浏览器运行在自己独立的、可丢弃的边车虚拟机中,与工作区虚拟机分离,因此恶意页面永远无法触及代理的文件或你的 Mac。
本章是使用它的完整指南:如何打开它、如何手动驾驭它、如何让代理通过内置的浏览器 MCP 服务器驾驭它、如何保持登录状态,以及隐私模型。它与会话中介绍的是同一个窗格;这里的一切在远程代理通过富客户端连接驾驭它时同样适用。
打开浏览器
用 ⌃⌘B 切换浏览器窗格,或点击会话窗口工具栏中的地球仪按钮。它会作为一个分栏在舞台的右侧边缘打开,与终端共享同一个窗口。
第一次打开它时 —— 按每台 Mac 计,而非按每个工作区 —— 会弹出一张许可卡片,询问安装浏览器?,并提供下载并安装和暂不两个选项。浏览器镜像是一次性下载,大约 500 MB,由每个工作区共享。在它安装完成之前,窗格显示的是安装提示而非页面;你也可以在工作区的浏览器设置中通过立即下载预先获取它。
安装完成后,浏览器虚拟机会在任何工作区首次打开该窗格时(或代理首次调用浏览器工具时)惰性启动,这需要一两秒。你不必直接管理这个虚拟机 —— 它会为你创建、挂起并销毁(参见生命周期与资源占用)。
注意: 浏览器运行在与你的代理 shell 所在虚拟机不同的虚拟机中。二者共享一个专用网络(参见加载开发服务器),但它们不是同一台机器 —— 代理写入其主目录的文件并不在浏览器的磁盘上,浏览器中的
localhost也不是代理的localhost。
自己驾驭它
该窗格是一个无边框的浏览器视图,位于一个紧凑的、类似 Safari 风格的标签栏之下:
| 控件 | 功能 |
|---|---|
| 后退 / 前进 | 箭头按钮,或 ⌘[ 和 ⌘]。 |
| 标签胶囊 | 每个打开的标签页一个胶囊。活动胶囊同时兼作地址栏(“搜索或输入网址”):键入纯主机名会自动加上 https://;键入任何非网址的内容则会变成一次 Google 搜索。 |
| + | 新建标签页(窗格获得焦点时按 ⌘T)。 |
| DevTools | 切换 Chromium 的开发者工具(F12)—— 完整的元素检查器、控制台和网络面板。 |
| 站点信息 | 点击网站图标可弹出站点信息浮层,在 HTTPS 页面上还包括证书链。 |
| 共享 | 针对当前页面的标准 macOS 共享菜单。 |
拖动窗格的左边缘可调整其大小(默认 640 点,可在 380 到 1400 之间调整;终端始终至少保留 240 点)。将其拖到最小宽度以下即可关闭窗格。
注意: 当浏览器视图拥有键盘焦点时,⌘Q 和 ⌘Tab 会被客户机捕获,以便页面内的快捷键生效 —— 它们不会退出应用或切换 macOS 应用。点击终端或侧边栏可将这些快捷键交还给 macOS。
加载代理启动的开发服务器
打开浏览器最常见的原因是查看代理正在构建的某个东西。由于浏览器虚拟机与工作区虚拟机共享同一个 NAT 子网,它可以直接访问代理启动的开发服务器 —— 但不能通过 localhost,因为浏览器是一台独立的机器。
请通过工作区虚拟机的 IP 地址访问开发服务器:
- 像往常一样在代理的终端中启动服务器(例如在端口 3000 上启动一个开发服务器)。
- 从工具栏中的 IP 胶囊复制工作区的 IP(或在代理的终端中运行
hostname -I)。 - 在浏览器中导航到
http://<workspace-ip>:3000。
代理在自己驾驭浏览器时,被指示要精确地这样做 —— 通过局域网 IP 访问开发服务器,而绝不使用 localhost —— 这样它的截图和检查才能命中正确的服务器。
让代理驾驭它
该浏览器是代理式的:每个工作区代理都会自动获得一个内置的 browser MCP 服务器,无需任何配置。它的工具让代理能够打开页面、点击、输入、读取 DOM、截图,以及检查控制台和网络 —— 驾驭的正是你所看到的那个窗格。你和代理共享一个浏览器:代理打开的页面会出现在你的窗格中,而你打开的标签页也能被代理的 browser_list_tabs 看到。
你不需要开启这个功能。只需让代理去做某件需要用到浏览器的事 —— 例如:
Open http://<workspace-ip>:3000, click "Sign up", fill the form with a test
account, and tell me if the confirmation page renders. Screenshot it.
代理的工具调用可以为所选的工作区自动启动并显示浏览器;如果窗格已关闭,工具调用会打开它并等待冷启动。(在一个会话内,你手动关闭窗格后它永远不会自行重新打开,所以你始终掌控它是否可见。)
触发浏览器的提示词
并不存在“使用浏览器”这样的命令 —— 每当你的请求只能通过加载、查看或操作真实页面来回答时,代理就会去调用 browser_* 工具。实践中,任何指明某个 URL、要求代理查看或点击某个已渲染内容、或要求截图、控制台日志或网络活动的请求,都会把浏览器牵引进来。以下几种形式能可靠地做到这一点:
- 查看你构建的东西 ——“打开我在
http://<workspace-ip>:3000上的开发服务器,告诉我仪表板是否渲染出来了。” / “给落地页拍一张全宽截图。” / “我把标题改成蓝色了 —— 重新加载页面并确认它看起来正常。” - 复现或测试某个流程 ——“进入注册页面,用一个测试账户填写它,提交,并告诉我确认页面是否出现。” / “点击走完结账流程,在第一个出错的步骤停下。”
- 从页面读取或提取内容 ——“打开
<docs URL>并总结身份验证部分。” / “列出此页面上的每一个出站链接。” / “把定价表抓取为 Markdown。” - 调试客户端问题 ——“购买按钮没有任何反应 —— 打开页面、点击它,并检查控制台和网络日志中失败的请求。”(代理使用
browser_console和browser_network来读取你在 DevTools 中会看到的完全相同的内容,无需你复制任何东西出来。)
你越具体地指向某个页面或某个屏幕上的操作,代理就越直接地走向浏览器。如果你只是描述一个结果(“注册功能能用吗?”),代理通常仍会打开浏览器去检查 —— 但指明 URL 或按钮能省去一次来回。请记得为开发服务器给它工作区的局域网 IP,而非 localhost(参见加载开发服务器)。
浏览器工具
该服务器暴露了 23 个工具,按其功能分组:
| 分组 | 工具 |
|---|---|
| 导航 | browser_navigate、browser_back、browser_forward、browser_reload、browser_wait_for |
| 标签页 | browser_new_tab、browser_list_tabs、browser_activate_tab、browser_close_tab |
| 读取页面 | browser_get_text、browser_get_html、browser_get_links、browser_screenshot(带全页选项)、browser_evaluate(运行 JavaScript) |
| 交互 | browser_click、browser_fill、browser_type、browser_press_key、browser_pick_element |
| 诊断 | browser_console、browser_network、browser_network_summary、browser_clear_network |
browser_evaluate 在页面中运行任意 JavaScript 并返回结果,而 browser_network / browser_console 则为代理提供你会在 DevTools 中读取的相同请求日志和控制台输出 —— 这正是代理在你无需手动复制任何内容的情况下调试失败的 fetch 或客户端错误的方式。browser_pick_element 是唯一会直接把你牵涉进来的工具,它在下文有自己独立的小节。
指向某个元素
在一个繁忙的页面上,用文字来标识某一个元素是很笨拙的方式 ——“第二张卡片”、“那个坏掉的按钮”、“错位的标签”。当代理弄不清你指的是哪个元素时,让它把控制权交给你去指向,它就会把控制权交给你而不是猜测:
One card in this grid is misaligned — let me point at it. Then read that
element's classes and tell me why it's off.
在其背后,代理会调用 browser_pick_element,它会直接在浏览器窗格中激活一个交互式选取器:当你把鼠标移到元素上时,元素会高亮显示,顶部还会出现一条“点击一个元素”的横幅。点击你所指的元素,代理便会立即收到它精确的 CSS 选择器 —— 无需描述、复制或粘贴任何东西。你大约有 60 秒的时间去点击,超过后选取器会超时,代理什么也得不到。
你永远不必按什么“启用选取器”按钮或打开任何菜单 —— 激活选取器就是代理的工具调用,所以它在你一开口的那一刻就会发生。能可靠触发它的措辞有:“让我指给你看”、“我来点我指的那个”、“哪个元素?我指给你看”,或者干脆**“point-and-pick”**。一旦代理拿到选择器,它就可以对该元素做任何事 —— 点击它、读取它的文本或类、观察它,或以它为锚点来解释某个布局 bug —— 所以一个好的后续做法是,在提出要指向它的同一口气里说清你想对这个元素做什么。
提示: 选取器是弥合“我能看到问题,你看不到”的最快方式。与其描述一个视觉故障,不如指向那个有问题的元素,让代理去检查真实的 DOM 节点。
在底层,这些工具通过一个生成的 Python stdio 垫片 bromure-browser-mcp.py 访问浏览器,该垫片以只读方式被暂存到代理虚拟机的 /mnt/bromure-meta/ 中。它通过 vsock 端口 5830 拨号连接宿主机并永久重连,因此即使在浏览器被销毁后,这些工具也永远不会从代理的工具列表中消失。完整的工具参考见 CLI、自动化与 MCP。
注意: 在富客户端上,远程代理的浏览器 MCP 流可以通过 SSH 连接进行拼接,使远程代理驾驭你在本地观看的浏览器窗格。同一时间只有一个这样的中继处于活动状态。
保持登录 vs. 保持可丢弃
默认情况下,浏览器是可丢弃的:它的磁盘是一个短暂的克隆,会在浏览器被销毁时删除,因此 cookie、登录信息和历史记录都会随之消失。每次全新打开都从干净状态开始。这是安全的默认设置 —— 代理在浏览器中所做的任何事都不会持久保留或泄漏到后续工作中。
当你需要让登录状态存续时 —— 登录代理稍后会重访的暂存站点、跨重启保持一个会话 —— 请在工作区的浏览器设置中启用保持网站登录状态。此后,Chromium 的配置文件会存放在 ~/Library/Application Support/BromureAC/browser-profiles/ 下一个加密的、按每个工作区独立的磁盘上,并在销毁后存续。切换该设置会重启工作区的浏览器,因此在更改被存储之前会向你发出警告。
警告: 开启保持登录状态是以牺牲可丢弃性来换取便利。保存的 cookie 和登录信息正是遭到提示注入的代理会试图窃取的那类东西。对于任何指向不受信任代码的工作区,请优先使用可丢弃的默认设置,只在那些永远只访问你信任的站点的浏览器上启用持久化。
生命周期与资源占用
浏览器虚拟机会为你托管,并在空闲时保持低成本:
- 它在首次打开时(或代理首次调用工具时)惰性创建,并从共享的 500 MB 镜像以写时复制克隆的方式启动。
- 隐藏的浏览器会在约 10 秒后挂起,并在折叠 5 分钟后被完全销毁,从而释放其内存和磁盘。
- 窗格的打开/关闭状态在应用运行期间按每个工作区记住,但有意不跨应用重启保留 —— 反正一个可丢弃的浏览器也无法在重启后存续。
与工作区虚拟机不同,边车浏览器虚拟机确实由一个预热池提供,这就是为什么在第一次之后打开窗格通常感觉是即时的。
键盘快捷键
以下快捷键在浏览器窗格拥有键盘焦点时生效:
| 快捷键 | 操作 |
|---|---|
| ⌃⌘B | 切换浏览器窗格 |
| ⌘T / ⌘W | 新建 / 关闭浏览器标签页 |
| ⌘[ / ⌘] | 后退 / 前进 |
| ⌘R | 重新加载 |
| ⌘L | 聚焦地址栏(活动标签胶囊) |
| F12 | 切换 DevTools |
故障排除
窗格显示的是安装提示而非页面。 浏览器镜像尚未下载。点击下载并安装,或从浏览器设置 → 立即下载预先获取它(约 500 MB)。
代理的页面无法加载 / 显示连接被拒绝。 代理几乎肯定是在使用 localhost。浏览器是一台独立的虚拟机 —— 它必须通过工作区虚拟机的局域网 IP(在代理的终端中运行 hostname -I,或使用工具栏的 IP 胶囊)访问开发服务器,如加载开发服务器中所述。
⌘Q 或 ⌘Tab 没有任何反应。 浏览器视图拥有焦点,正在为页面内使用捕获它们。点击终端或侧边栏可将这些快捷键交还给 macOS。
登录状态在会话之间消失。 这是可丢弃的默认设置。请在浏览器设置中启用保持网站登录状态以保留一个持久的配置文件。
代理使用浏览器后,浏览器窗格不会自行重新打开。 这是设计使然:一旦你手动关闭窗格,它就会保持关闭,直到你重新打开它,即使代理继续发出浏览器工具调用(这些调用仍然会运行 —— 只是你看不到窗格而已)。按 ⌃⌘B 即可将其唤回。
相关设置与工具
- 浏览器设置 —— 保持网站登录状态开关以及浏览器镜像管理。
- 会话 —— 在整个会话窗口的语境中看浏览器窗格。
- CLI、自动化与 MCP —— 完整的
browser_*工具参考以及 vsock 传输。