浏览器自动化

Hermes Agent 包含完整的浏览器自动化工具集,支持多种后端选项:

  • Browserbase 云模式:通过 Browserbase 使用托管云浏览器和反机器人工具
  • Browser Use 云模式:通过 Browser Use 作为替代云浏览器提供商
  • Firecrawl 云模式:通过 Firecrawl 使用带有内置抓取功能的云浏览器
  • Camofox 本地模式:通过 Camofox 进行本地反检测浏览(基于 Firefox 的指纹伪装)
  • 本地 Chromium 系列 CDP:使用 /browser connect 将浏览器工具连接到你自己的 Chrome、Brave、Chromium 或 Edge 实例
  • 本地浏览器模式:通过 agent-browser CLI 和本地 Chromium 安装

在所有模式下,代理都可以导航网站、与页面元素交互、填写表单和提取信息。

概述

页面以无障碍树(基于文本的快照)的形式呈现,非常适合 LLM 代理。交互式元素会获得 ref ID(如 @e1@e2),代理使用这些 ID 进行点击和输入。

关键能力:

  • 多提供商云执行——Browserbase、Browser Use 或 Firecrawl——无需本地浏览器
  • 本地 Chromium 系列集成——通过 CDP 连接到正在运行的 Chrome、Brave、Chromium 或 Edge 浏览器,进行实际操作式浏览
  • 内置隐身功能——随机指纹、CAPTCHA 解决、住宅代理(Browserbase)
  • 会话隔离——每个任务获得自己的浏览器会话
  • 自动清理——不活跃的会话会在超时后关闭
  • 视觉分析——截图 + AI 分析用于视觉理解

设置

:::tip Nous 订阅用户 如果你拥有付费的 Nous Portal 订阅,可以通过 工具网关 使用浏览器自动化,无需单独的 API 密钥。运行 hermes modelhermes tools 来启用。 :::

Browserbase 云模式

要使用 Browserbase 管理的云浏览器,添加:

# 添加到 ~/.hermes/.env
BROWSERBASE_API_KEY=***
BROWSERBASE_PROJECT_ID=your-project-id-here

browserbase.com 获取凭证。

Browser Use 云模式

要将 Browser Use 作为云浏览器提供商使用,添加:

# 添加到 ~/.hermes/.env
BROWSER_USE_API_KEY=***

browser-use.com 获取 API 密钥。Browser Use 通过其 REST API 提供云浏览器。如果同时设置了 Browserbase 和 Browser Use 凭证,Browserbase 优先。

Firecrawl 云模式

要将 Firecrawl 作为云浏览器提供商使用,添加:

# 添加到 ~/.hermes/.env
FIRECRAWL_API_KEY=fc-***

firecrawl.dev 获取 API 密钥。然后选择 Firecrawl 作为你的浏览器提供商:

hermes setup tools
# → 浏览器自动化 → Firecrawl

可选设置:

# 自托管 Firecrawl 实例(默认:https://api.firecrawl.dev)
FIRECRAWL_API_URL=http://localhost:3002
 
# 会话 TTL,以秒为单位(默认:300)
FIRECRAWL_BROWSER_TTL=600

混合路由:公网 URL 用云服务,局域网/本地地址用本地浏览器

当配置了云提供商时,Hermes 会自动为解析为私有/回环/LAN 地址的 URL 启动本地 Chromium 侧车localhost127.0.0.1192.168.x.x10.x.x.x172.16-31.x.x*.local*.lan*.internal、IPv6 回环 ::1、链路本地 169.254.x.x)。公网 URL 则在同一次对话中继续使用云提供商。

这解决了常见的”我本地开发但使用 Browserbase”的工作流——代理可以截取 http://localhost:3000 仪表盘的屏幕截图,同时还能抓取 https://github.com,无需切换提供商或禁用 SSRF 防护。云提供商永远不会看到私有 URL。

此功能默认开启。要禁用它(所有 URL 都发送到配置的云提供商,和以前一样):

# ~/.hermes/config.yaml
browser:
  cloud_provider: browserbase
  auto_local_for_private_urls: false

禁用自动路由后,私有 URL 会被拒绝并显示 "Blocked: URL targets a private or internal address",除非你同时设置了 browser.allow_private_urls: true(这会让云提供商尝试访问它们——但通常不会成功,因为 Browserbase 等无法到达你的局域网)。

要求:本地侧车使用与纯本地模式相同的 agent-browser CLI,因此需要安装它(hermes setup tools → 浏览器自动化 会自动安装)。从公网 URL 重定向到私有地址的导航仍会被阻止(你无法通过公网路径使用重定向到内部地址的技巧来访问你的局域网)。

Camofox 本地模式

Camofox 是一个自托管的 Node.js 服务器,封装了 Camoufox(一个带有 C++ 指纹伪装的 Firefox 分支)。它提供本地反检测浏览,无需云依赖。

# 首先克隆 Camofox 浏览器服务器
git clone https://github.com/jo-inc/camofox-browser
cd camofox-browser
 
# 使用默认容器设置构建并启动 Docker
#(自动检测架构:M1/M2 上为 aarch64,Intel 上为 x86_64)
make up
 
# 停止并移除默认容器
make down
 
# 强制干净重建(例如升级 VERSION/RELEASE 后)
make reset
 
# 仅下载二进制文件而不构建
make fetch
 
# 显式覆盖架构或版本
make up ARCH=x86_64
make up VERSION=135.0.1 RELEASE=beta.24

make up 会立即启动默认容器。如果你想要自定义运行时设置,例如更大的 Node 堆、VNC 或持久化配置文件目录,请先构建镜像然后自行运行:

# 构建镜像而不启动默认容器
make build
 
# 启动,启用持久化、VNC 实时查看和更大的 Node 堆
mkdir -p ~/.camofox-docker
docker run -d \
  --name camofox-browser \
  --restart unless-stopped \
  -p 9377:9377 \
  -p 6080:6080 \
  -p 5901:5900 \
  -e CAMOFOX_PORT=9377 \
  -e ENABLE_VNC=1 \
  -e VNC_BIND=0.0.0.0 \
  -e VNC_RESOLUTION=1920x1080 \
  -e MAX_OLD_SPACE_SIZE=2048 \
  -v ~/.camofox-docker:/root/.camofox \
  camofox-browser:135.0.1-aarch64

启用 VNC 后,浏览器以有头模式运行,可以在浏览器中通过 http://localhost:6080(noVNC)实时观看。你也可以将原生 VNC 客户端连接到 localhost:5901

如果你已经运行了 make up,请在启动自定义容器前停止并移除该默认容器:

make down
# 然后运行上面的自定义 docker run 命令

然后在 ~/.hermes/.env 中设置:

CAMOFOX_URL=http://localhost:9377

或通过 hermes tools → 浏览器自动化 → Camofox 配置。

当设置了 CAMOFOX_URL 时,所有浏览器工具会自动通过 Camofox 路由,而不是 Browserbase 或 agent-browser。

持久化浏览器会话

默认情况下,每个 Camofox 会话都有一个随机身份——cookie 和登录状态在代理重启后不会保留。要启用持久化浏览器会话,在 ~/.hermes/config.yaml 中添加以下内容:

browser:
  camofox:
    managed_persistence: true

然后完全重启 Hermes 以使新配置生效。

:::warning 嵌套路径很重要 Hermes 读取 browser.camofox.managed_persistence而不是顶层的 managed_persistence。一个常见的错误是写成:

# ❌ 错误——Hermes 忽略此设置
managed_persistence: true

如果标记放在错误的路径下,Hermes 会静默回退到随机临时 userId,你的登录状态将在每次会话中丢失。 :::

Hermes 做了什么
  • 向 Camofox 发送确定性的配置文件作用域 userId,以便服务器可以在会话之间重用相同的 Firefox 配置文件。
  • 在清理时跳过服务器端上下文销毁,以便 cookie 和登录状态在代理任务之间得以保留。
  • userId 限定在活动 Hermes 配置文件范围内,因此不同的 Hermes 配置文件获得不同的浏览器配置文件(配置文件隔离)。
Hermes 没有做什么
  • 它不强求 Camofox 服务器进行持久化。Hermes 仅发送稳定的 userId;服务器必须通过将该 userId 映射到持久化的 Firefox 配置文件目录来配合。
  • 如果你的 Camofox 服务器构建将所有请求视为临时(例如总是调用 browser.newContext() 而不加载存储的配置文件),Hermes 无法使这些会话持久化。请确保你运行的 Camofox 构建实现了基于 userId 的配置文件持久化。
验证是否生效
  1. 启动 Hermes 和你的 Camofox 服务器。
  2. 在浏览器任务中打开 Google(或任何登录站点)并手动登录。
  3. 正常结束浏览器任务。
  4. 启动新的浏览器任务。
  5. 再次打开同一站点——你应仍处于登录状态。

如果第 5 步要求你重新登录,则 Camofox 服务器没有识别稳定的 userId。请仔细检查你的配置路径,确认在编辑 config.yaml 后完全重启了 Hermes,并验证你的 Camofox 服务器版本支持持久化的每用户配置文件。

状态存储位置

Hermes 从配置文件作用域的目录 ~/.hermes/browser_auth/camofox/(或非默认配置文件的 $HERMES_HOME 对应目录)派生稳定的 userId。实际的浏览器配置文件数据存储在 Camofox 服务器端,以该 userId 为键。要完全重置持久化配置文件,请在 Camofox 服务器上清除它,并删除相应 Hermes 配置文件的状态目录。

外部管理的 Camofox 会话

当另一个应用程序驱动可见的 Camofox 浏览器时(桌面助手、自定义集成、另一个代理),配置 Hermes 在同一身份内操作,而不是生成自己独立的配置文件。

三个控制选项:

设置环境变量效果
browser.camofox.user_idCAMOFOX_USER_IDHermes 在创建标签页时使用的 Camofox userId。设置此选项会使会话进入”外部管理”模式。
browser.camofox.session_keyCAMOFOX_SESSION_KEY在标签页创建时发送的 sessionKey(也称为 listItemId)。用于在接管时匹配现有标签页。如果未设置,默认为每个任务的值。
browser.camofox.adopt_existing_tabCAMOFOX_ADOPT_EXISTING_TAB当为 true 时,Hermes 在首次使用时调用 GET /tabs?userId=<user_id> 并重用现有标签页,然后再创建新标签页。

环境变量优先于 config.yaml。两种形式都可使用:

browser:
  camofox:
    user_id: shared-camofox
    session_key: visible-tab
    adopt_existing_tab: true
CAMOFOX_USER_ID=shared-camofox
CAMOFOX_SESSION_KEY=visible-tab
CAMOFOX_ADOPT_EXISTING_TAB=true

设置 user_id 后的变化:

  • Hermes 在任务结束时跳过破坏性清理(与 managed_persistence: true 相同)。其他应用程序的标签页/cookie/配置文件得以保留。
  • Hermes 调用 DELETE /sessions/<user_id>——该端点会擦除所有用户数据,如果触发会破坏外部应用的会话。

标签页接管如何工作(当 adopt_existing_tab: true 时):

  1. 在进程启动后的第一个浏览器工具调用时,Hermes 发出 GET /tabs?userId=<user_id>(5 秒超时)。
  2. 如果响应中的任何标签页的 listItemId == session_key,Hermes 采用该组中最近创建的那个。
  3. 否则,Hermes 采用该用户最近创建的标签页(任何 listItemId)。
  4. 如果没有标签页存在或请求失败,Hermes 在下一次操作时回退到创建新标签页。

接管仅在 tab_id 被填充之前触发。如果外部应用在运行过程中关闭了已接管的标签页,下一次浏览器工具调用会显示 Camofox 错误——Hermes 不会在每次调用时重新轮询新标签页。

选择 session_key 如果你希望 Hermes 可靠地附加到特定现有标签页,请将 session_key 设置为外部应用创建该标签页时使用的 listItemId。如果你不设置 session_key,只设置 user_id,Hermes 会生成每个任务的 session_keytask_<id>)——Hermes 将与外部应用共享 cookie 和配置文件,但会打开自己的标签页而不是重用现有的标签页。

并发注意: 外部应用和 Hermes 可以同时驱动相同的 Camofox userId,但 Camofox 不协调客户端之间的每个标签页焦点。请在应用层协调所有权(例如外部应用在 Hermes 运行时暂停)。

VNC 实时查看

当 Camofox 以有头模式运行(带有可见的浏览器窗口)时,它会在健康检查响应中暴露 VNC 端口。Hermes 会自动发现此信息,并将 VNC URL 包含在导航响应中,因此代理可以分享链接供你实时观看浏览器。

通过 CDP 使用本地 Chromium 系列浏览器(/browser connect

除了云提供商,你可以通过 Chrome DevTools 协议(CDP)将 Hermes 浏览器工具附加到你正在运行的 Chrome、Brave、Chromium 或 Edge 实例。这在你想实时查看代理的操作、与需要你自己 cookie/会话的页面交互,或避免云浏览器费用时非常有用。

:::note /browser connect 是一个交互式 CLI 斜杠命令——它不由网关分发。如果你尝试在 WebUI、Telegram、Discord 或其他网关聊天中运行它,该消息将作为纯文本发送给代理,命令不会执行。请从终端启动 Hermes(hermeshermes chat),然后在那里运行 /browser connect。 :::

在 CLI 中,使用:

/browser connect                 # 自动启动/连接到 http://127.0.0.1:9222 的本地 Chromium 系列浏览器
/browser connect ws://host:port  # 连接到特定的 CDP 端点
/browser status                  # 检查当前连接状态
/browser disconnect              # 断开连接并返回云/本地模式

如果浏览器尚未启用远程调试运行,Hermes 会尝试自动启动受支持的 Chromium 系列浏览器,并设置 --remote-debugging-port=9222。检测范围包括 Brave、Google Chrome、Chromium 和 Microsoft Edge,常见的 Linux 安装路径如 /opt/brave-bin/brave/snap/bin/brave

:::tip 要手动启动启用了 CDP 的 Chromium 系列浏览器,请使用专门的数据目录,这样即使浏览器已使用你的正常配置文件运行,调试端口也能正常启动:

# Linux — Brave
brave-browser \
  --remote-debugging-port=9222 \
  --user-data-dir=$HOME/.hermes/chrome-debug \
  --no-first-run \
  --no-default-browser-check &
 
# Linux — Google Chrome
google-chrome \
  --remote-debugging-port=9222 \
  --user-data-dir=$HOME/.hermes/chrome-debug \
  --no-first-run \
  --no-default-browser-check &
 
# macOS — Brave
"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser" \
  --remote-debugging-port=9222 \
  --user-data-dir="$HOME/.hermes/chrome-debug" \
  --no-first-run \
  --no-default-browser-check &
 
# macOS — Google Chrome
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
  --remote-debugging-port=9222 \
  --user-data-dir="$HOME/.hermes/chrome-debug" \
  --no-first-run \
  --no-default-browser-check &

然后启动 Hermes CLI 并运行 /browser connect

为什么需要 --user-data-dir 如果不使用它,在常规实例已经在运行时启动 Chromium 系列浏览器通常会在现有进程上打开新窗口——而该现有进程没有以 --remote-debugging-port 启动,因此端口 9222 永远不会打开。专门的数据目录会强制启动一个新的浏览器进程,使调试端口真正开始监听。--no-first-run --no-default-browser-check 跳过了新配置文件的首屏向导。 :::

通过 CDP 连接后,所有浏览器工具(browser_navigatebrowser_click 等)将在你的实时浏览器实例上操作,而不是启动云会话。

WSL2 + Windows Chrome:优先选择 MCP 而非 /browser connect

如果 Hermes 在 WSL2 内部运行,但你想控制的 Chrome 窗口在 Windows 主机上运行,/browser connect 通常不是最佳路径。

原因:

  • /browser connect 期望 Hermes 自身能到达一个可用的 CDP 端点
  • 现代 Chrome 实时调试会话通常暴露一个主机本地端点,该端点不能像经典的 9222 端口那样直接从 WSL 访问
  • 即使 Windows Chrome 可调试,最干净的集成方式通常是让 Windows 端的浏览器 MCP 服务器附加到 Chrome,然后让 Hermes 与该 MCP 服务器通信

对于这种设置,推荐通过 Hermes MCP 支持使用 chrome-devtools-mcp

请查看 MCP 指南了解实际设置:

本地浏览器模式

如果你没有设置任何云凭证,也没有使用 /browser connect,Hermes 仍然可以通过由 agent-browser 驱动的本地 Chromium 安装使用浏览器工具。

可选环境变量

# 用于更好 CAPTCHA 解决的住宅代理(默认:"true")
BROWSERBASE_PROXIES=true
 
# 使用自定义 Chromium 的高级隐身——需要 Scale Plan(默认:"false")
BROWSERBASE_ADVANCED_STEALTH=false
 
# 断开连接后的会话重连——需要付费计划(默认:"true")
BROWSERBASE_KEEP_ALIVE=true
 
# 自定义会话超时时间,以毫秒为单位(默认:项目默认)
# 示例:600000(10 分钟),1800000(30 分钟)
BROWSERBASE_SESSION_TIMEOUT=600000
 
# 自动清理前的非活动超时时间,以秒为单位(默认:120)
BROWSER_INACTIVITY_TIMEOUT=120
 
# 额外的 Chromium 启动标志(逗号或换行分隔)。Hermes 在检测到 root 或
# AppArmor 限制的非特权用户命名空间(Ubuntu 23.10+、DGX Spark、许多容器镜像)时
# 会自动注入 `--no-sandbox,--disable-dev-shm-usage`,因此大多数用户无需设置此选项。
# 仅当你需要 Hermes 不会自动添加的标志时手动设置;设置后会禁用自动注入。
AGENT_BROWSER_ARGS=--no-sandbox

安装 agent-browser CLI

npm install -g agent-browser
# 或在仓库中本地安装:
npm install

:::info browser 工具集必须包含在你的配置的 toolsets 列表中,或通过 hermes config set toolsets '["hermes-cli", "browser"]' 启用。 :::

可用工具

browser_navigate

导航到指定 URL。必须在任何其他浏览器工具之前调用。会初始化 Browserbase 会话。

Navigate to https://github.com/NousResearch

:::tip 对于简单的信息检索,优先使用 web_searchweb_extract——它们更快、更便宜。当你需要与页面交互(点击按钮、填写表单、处理动态内容)时,再使用浏览器工具。 :::

browser_snapshot

获取当前页面无障碍树的基于文本的快照。返回带有 ref ID(如 @e1@e2)的交互式元素,供 browser_clickbrowser_type 使用。

  • full=false(默认):紧凑视图,仅显示交互式元素
  • full=true:完整页面内容

超过 8000 个字符的快照会被 LLM 自动汇总。

browser_click

点击由快照中的 ref ID 标识的元素。

Click @e5 to press the "Sign In" button

browser_type

在输入字段中输入文本。会先清除字段,然后输入新文本。

Type "hermes agent" into the search field @e3

browser_scroll

向上或向下滚动页面以显示更多内容。

Scroll down to see more results

browser_press

按下键盘键。适用于提交表单或导航。

Press Enter to submit the form

支持的按键:EnterTabEscapeArrowDownArrowUp 等。

browser_back

在浏览器历史中导航回上一页。

browser_get_images

列出当前页面上的所有图像及其 URL 和替代文本。适用于查找要分析的图像。

browser_vision

拍摄屏幕截图并使用视觉 AI 进行分析。当文本快照无法捕获重要的视觉信息时使用——特别适用于 CAPTCHA、复杂布局或视觉验证挑战。

屏幕截图会持久保存,文件路径会与 AI 分析一起返回。在消息平台(Telegram、Discord、Slack、WhatsApp)上,你可以要求代理分享屏幕截图——它将通过 MEDIA: 机制以原生照片附件的形式发送。

What does the chart on this page show?

屏幕截图存储在 ~/.hermes/cache/screenshots/ 中,24 小时后自动清理。

browser_console

获取当前页面的浏览器控制台输出(log/warn/error 消息)和未捕获的 JavaScript 异常。对于检测不在无障碍树中出现的静默 JS 错误至关重要。

Check the browser console for any JavaScript errors

使用 clear=True 在读取后清除控制台,以便后续调用仅显示新消息。

browser_console 在使用 expression 参数调用时还会执行 JavaScript——与 DevTools 控制台类似,结果会被解析返回(JSON 序列化的对象变为字典;原始值保持原始类型)。

browser_console(expression="document.querySelector('h1').textContent")
browser_console(expression="JSON.stringify(performance.timing)")

当当前会话存在 CDP 主管时(对于已对支持 CDP 的后端运行 browser_navigate 的会话这是典型情况),评估通过主管的持久 WebSocket 运行——无需子进程启动开销。否则回退到标准的 agent-browser CLI 路径。两种方式的行为相同;仅延迟有所变化。

browser_cdp

原始 Chrome DevTools 协议直通——用于其他工具未涵盖的浏览器操作的逃生舱。适用于原生对话框处理、iframe 作用域评估、cookie/网络控制,或代理需要的任何 CDP 命令。

仅当会话启动时可到达 CDP 端点时才可用——意味着已通过 /browser connect 附加到正在运行的 Chrome、Brave、Chromium 或 Edge 浏览器,或在 config.yaml 中设置了 browser.cdp_url。默认的本地 agent-browser 模式、Camofox 和云提供商(Browserbase、Browser Use、Firecrawl)当前不向此工具暴露 CDP——云提供商有每会话的 CDP URL,但实时会话路由是后续功能。

CDP 方法参考: https://chromedevtools.github.io/devtools-protocol/——代理可以使用 web_extract 获取特定方法的页面以查阅参数和返回格式。

常见模式:

# 列出标签页(浏览器级别,无需 target_id)
browser_cdp(method="Target.getTargets")

# 处理标签页上的原生 JS 对话框
browser_cdp(method="Page.handleJavaScriptDialog",
            params={"accept": true, "promptText": ""},
            target_id="<tabId>")

# 在特定标签页中执行 JS
browser_cdp(method="Runtime.evaluate",
            params={"expression": "document.title", "returnByValue": true},
            target_id="<tabId>")

# 获取所有 cookie
browser_cdp(method="Network.getAllCookies")

浏览器级别的方法(Target.*Browser.*Storage.*)省略 target_id。页面级别的方法(Page.*Runtime.*DOM.*Emulation.*)需要来自 Target.getTargetstarget_id。每个无状态调用都是独立的——会话不会在调用之间持久化。

跨域 iframe: 传递 frame_id(来自 browser_snapshot.frame_tree.children[],其中 is_oopif=true)以将 CDP 调用路由到该 iframe 的主管实时会话。这是跨域 iframe 内部 Runtime.evaluate 在 Browserbase 上工作的方式,因为无状态 CDP 连接会遇到签名 URL 过期。示例:

browser_cdp(
  method="Runtime.evaluate",
  params={"expression": "document.title", "returnByValue": True},
  frame_id="<frame_id from browser_snapshot>",
)

同源 iframe 不需要 frame_id——可以从顶层的 Runtime.evaluate 中使用 document.querySelector('iframe').contentDocument 代替。

browser_dialog

响应原生 JS 对话框(alert / confirm / prompt / beforeunload)。在此工具出现之前,对话框会静默阻塞页面的 JavaScript 线程,后续的 browser_* 调用会挂起或抛出;现在代理可以在 browser_snapshot 输出中看到待处理的对话框并显式响应。

工作流程:

  1. 调用 browser_snapshot。如果有对话框阻塞页面,它会显示为 pending_dialogs: [{"id": "d-1", "type": "alert", "message": "..."}]
  2. 调用 browser_dialog(action="accept")browser_dialog(action="dismiss")。对于 prompt() 对话框,传入 prompt_text="..." 以提供响应。
  3. 重新截图——pending_dialogs 为空;页面的 JS 线程已恢复。

自动检测通过持久的 CDP 主管进行——每个任务一个 WebSocket,订阅 Page/Runtime/Target 事件。主管还在快照中填充 frame_tree 字段,以便代理可以看到当前页面的 iframe 结构,包括跨域(OOPIF)iframe。

可用性矩阵:

后端通过 pending_dialogs 检测响应(browser_dialog 工具)
通过 /browser connectbrowser.cdp_url 的本地 Chrome✓ 完整工作流
Browserbase✓ 完整工作流(通过注入的 XHR 桥)
Camofox / 默认本地 agent-browser✗(无 CDP 端点)

在 Browserbase 上的工作原理。 Browserbase 的 CDP 代理在服务器端约 10ms 内自动解除真实原生对话框,因此我们不能使用 Page.handleJavaScriptDialog。主管通过 Page.addScriptToEvaluateOnNewDocument 注入一个小型脚本,覆盖 window.alert/confirm/prompt 为同步 XHR。我们通过 Fetch.enable 拦截这些 XHR——页面的 JS 线程在 XHR 上保持阻塞,直到我们调用 Fetch.fulfillRequest 并带上代理的响应。prompt() 的返回值会原样返回给页面 JS。

对话框策略config.yamlbrowser.dialog_policy 下配置:

策略行为
must_respond(默认)捕获、在快照中显示、等待显式的 browser_dialog() 调用。安全自动解除在 browser.dialog_timeout_s(默认 300 秒)后触发,防止有 bug 的代理永远阻塞。
auto_dismiss捕获、立即解除。代理仍会在 browser_state 历史中看到对话框,但不需采取行动。
auto_accept捕获、立即接受。在浏览带有攻击性 beforeunload 提示的页面时有用。

帧树browser_snapshot.frame_tree 中被限制为 30 帧和 OOPIF 深度 2,以在广告繁重的页面上保持负载可控。当达到限制时会显示 truncated: true 标志;需要完整树的代理可以使用 browser_cdp 配合 Page.getFrameTree

实际示例

填写网页表单

用户:使用我的邮箱 john@example.com 在 example.com 上注册账户

代理工作流:
1. browser_navigate("https://example.com/signup")
2. browser_snapshot()  → 看到带 ref 的表单字段
3. browser_type(ref="@e3", text="john@example.com")
4. browser_type(ref="@e5", text="SecurePass123")
5. browser_click(ref="@e8")  → 点击"创建账户"
6. browser_snapshot()  → 确认成功

研究动态内容

用户:GitHub 上当前的热门仓库有哪些?

代理工作流:
1. browser_navigate("https://github.com/trending")
2. browser_snapshot(full=true)  → 读取趋势仓库列表
3. 返回格式化结果

会话录制

自动将浏览器会话录制为 WebM 视频文件:

browser:
  record_sessions: true  # 默认:false

启用后,录制在首次 browser_navigate 时自动开始,并在会话关闭时保存到 ~/.hermes/browser_recordings/。超过 72 小时的录制会自动清理。

隐身功能

Browserbase 提供自动隐身能力:

功能默认说明
基本隐身始终开启随机指纹、视口随机化、CAPTCHA 解决
住宅代理开启通过住宅 IP 路由以获得更好的访问
高级隐身关闭自定义 Chromium 构建,需要 Scale Plan
保活开启网络中断后会话重连

:::note 如果你的计划中没有付费功能,Hermes 会自动降级——首先禁用 keepAlive,然后是代理——因此即使在免费计划上浏览也能工作。 :::

会话管理

  • 每个任务通过 Browserbase 获得独立的浏览器会话
  • 会话在非活动后自动清理(默认:2 分钟)
  • 后台线程每 30 秒检查一次过期会话
  • 进程退出时执行紧急清理以防止孤儿会话
  • 会话通过 Browserbase API(REQUEST_RELEASE 状态)释放

限制

  • 基于文本的交互——依赖无障碍树,而非像素坐标
  • 快照大小——大页面可能被截断或由 LLM 在 8000 字符处汇总
  • 会话超时——云会话根据你提供商的计划设置过期
  • 成本——云会话消耗提供商积分;会话在对话结束或非活动后自动清理。使用 /browser connect 进行免费的本地浏览。
  • 不支持文件下载——无法从浏览器下载文件