Автоматизация браузера

Hermes Agent включает полный набор инструментов для автоматизации браузера с несколькими вариантами бэкендов:

Во всех режимах агент может перемещаться по сайтам, взаимодействовать с элементами страницы, заполнять формы и извлекать информацию.

Обзор

Страницы представлены в виде деревьев доступности (текстовых снимков), что делает их идеальными для LLM-агентов. Интерактивные элементы получают ref ID (например, @e1, @e2), которые агент использует для кликов и ввода текста.

Ключевые возможности:

Настройка

tip Подписчики Nous Если у вас есть платная подписка Nous Portal, вы можете использовать автоматизацию браузера через Tool Gateway без отдельных API-ключей. Выполните hermes model или hermes tools для включения.

Облачный режим Browserbase

Чтобы использовать облачные браузеры, управляемые Browserbase, добавьте:

# Add to ~/.hermes/.env
BROWSERBASE_API_KEY=***
BROWSERBASE_PROJECT_ID=your-project-id-here

Получите свои учетные данные на browserbase.com.

Облачный режим Browser Use

Чтобы использовать Browser Use в качестве облачного провайдера браузеров, добавьте:

# Add to ~/.hermes/.env
BROWSER_USE_API_KEY=***

Получите свой API-ключ на browser-use.com. Browser Use предоставляет облачный браузер через REST API. Если заданы учетные данные и Browserbase, и Browser Use, приоритет у Browserbase.

Облачный режим Firecrawl

Чтобы использовать Firecrawl в качестве облачного провайдера браузеров, добавьте:

# Add to ~/.hermes/.env
FIRECRAWL_API_KEY=fc-***

Получите свой API-ключ на firecrawl.dev. Затем выберите Firecrawl в качестве провайдера браузера:

hermes setup tools
# → Browser Automation → Firecrawl

Опциональные настройки:

# Self-hosted Firecrawl instance (default: https://api.firecrawl.dev)
FIRECRAWL_API_URL=http://localhost:3002

# Session TTL in seconds (default: 300)
FIRECRAWL_BROWSER_TTL=600

Гибридная маршрутизация: облако для публичных URL, локально для LAN/localhost

Если настроен облачный провайдер, Hermes автоматически запускает локальный Chromium sidecar для URL, которые разрешаются в частный/loopback/LAN-адрес (localhost, 127.0.0.1, 192.168.x.x, 10.x.x.x, 172.16-31.x.x, *.local, *.lan, *.internal, IPv6 loopback ::1, link-local 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 и другие не могут достичь вашей LAN).

Требования: локальный sidecar использует тот же CLI agent-browser, что и чистый локальный режим, поэтому он должен быть установлен (hermes setup tools → Browser Automation устанавливает его автоматически). Перенаправления после навигации с публичного URL на частный адрес по-прежнему блокируются (нельзя использовать трюк с редиректом на внутренний адрес для доступа к LAN через публичный путь).

Локальный режим Camofox

Camofox — это самостоятельно размещаемый Node.js сервер, оборачивающий Camoufox (форк Firefox со спуфингом отпечатков на C++). Он обеспечивает локальный анти-детект браузинг без облачных зависимостей.

# Clone the Camofox browser server first
git clone https://github.com/jo-inc/camofox-browser
cd camofox-browser

# Build and start with Docker using the default container settings
# (auto-detects arch: aarch64 on M1/M2, x86_64 on Intel)
make up

# Stop and remove the default container
make down

# Force a clean rebuild (for example, after upgrading VERSION/RELEASE)
make reset

# Just download binaries without building
make fetch

# Override arch or version explicitly
make up ARCH=x86_64
make up VERSION=135.0.1 RELEASE=beta.24

make up запускает контейнер по умолчанию немедленно. Если вам нужны пользовательские настройки выполнения, такие как увеличенная Node heap, VNC или постоянный каталог профиля, сначала соберите образ, а затем запустите его самостоятельно:

# Build the image without starting the default container
make build

# Start with persistence, VNC live view, and a larger Node heap
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 браузер работает в headed-режиме, и за ним можно наблюдать в реальном времени в вашем браузере по адресу http://localhost:6080 (noVNC). Вы также можете подключиться с помощью нативного VNC-клиента к localhost:5901.

Если вы уже запустили make up, остановите и удалите контейнер по умолчанию перед запуском пользовательского:

make down
# then run the custom docker run command above

Затем укажите в ~/.hermes/.env:

CAMOFOX_URL=http://localhost:9377

Или настройте через hermes tools → Browser Automation → Camofox.

Когда CAMOFOX_URL установлен, все инструменты браузера автоматически маршрутизируются через Camofox вместо Browserbase или agent-browser.

Постоянные сессии браузера

По умолчанию каждая сессия Camofox получает случайную идентичность — cookies и логины не сохраняются между перезапусками агента. Чтобы включить постоянные сессии браузера, добавьте следующее в ~/.hermes/config.yaml:

browser:
  camofox:
    managed_persistence: true

Затем полностью перезапустите Hermes, чтобы новая конфигурация вступила в силу.

warning Важен правильный путь Hermes читает browser.camofox.managed_persistence, а не managed_persistence верхнего уровня. Частая ошибка — написать:

# ❌ Wrong — Hermes ignores this
managed_persistence: true

Если флаг размещен по неправильному пути, Hermes молча возвращается к случайному временному userId, и ваше состояние входа будет теряться при каждой сессии.

Что делает Hermes
Что Hermes не делает
Проверка работы
  1. Запустите Hermes и ваш сервер Camofox.

  2. Откройте Google (или любой сайт с входом) в задаче браузера и войдите вручную.

  3. Завершите задачу браузера обычным образом.

  4. Запустите новую задачу браузера.

  5. Снова откройте тот же сайт — вы все еще должны быть в системе.

Если на шаге 5 вас выкинуло из системы, сервер Camofox не учитывает стабильный userId. Перепроверьте путь в конфиге, убедитесь, что вы полностью перезапустили Hermes после редактирования config.yaml, и проверьте, что ваша версия сервера Camofox поддерживает постоянные профили для каждого пользователя.

Где хранится состояние

Hermes получает стабильный userId из каталога профиля ~/.hermes/browser_auth/camofox/ (или эквивалентного в $HERMES_HOME для нестандартных профилей). Фактические данные профиля браузера хранятся на стороне сервера Camofox, привязанные к этому userId. Чтобы полностью сбросить постоянный профиль, очистите его на сервере Camofox и удалите соответствующий каталог состояния профиля Hermes.

Просмотр VNC в реальном времени

Когда Camofox работает в headed-режиме (с видимым окном браузера), он открывает VNC-порт в ответе на health check. Hermes автоматически обнаруживает это и включает VNC URL в ответы навигации, чтобы агент мог поделиться ссылкой для просмотра браузера в реальном времени.

Локальный Chrome через CDP (/browser connect)

Вместо облачного провайдера вы можете подключить инструменты браузера Hermes к вашему запущенному экземпляру Chrome через Chrome DevTools Protocol (CDP). Это полезно, когда вы хотите видеть, что агент делает в реальном времени, взаимодействовать со страницами, требующими ваших собственных cookies/сессий, или избежать затрат на облачные браузеры.

`/browser connect` — это **слэш-команда интерактивного CLI** — она не отправляется через gateway. Если вы попытаетесь выполнить ее в WebUI, Telegram, Discord или другом gateway-чате, сообщение будет отправлено агенту как обычный текст, и команда не выполнится. Запустите Hermes из терминала (`hermes` или `hermes chat`) и выполните `/browser connect` там.

В CLI используйте:

/browser connect              # Connect to Chrome at ws://localhost:9222
/browser connect ws://host:port  # Connect to a specific CDP endpoint
/browser status               # Check current connection
/browser disconnect            # Detach and return to cloud/local mode

Если Chrome еще не запущен с удаленной отладкой, Hermes попытается автоматически запустить его с флагом --remote-debugging-port=9222.

Чтобы запустить Chrome вручную с включенным CDP, используйте выделенный user-data-dir, чтобы порт отладки действительно открылся, даже если Chrome уже запущен с вашим обычным профилем:
# Linux
google-chrome \
  --remote-debugging-port=9222 \
  --user-data-dir=$HOME/.hermes/chrome-debug \
  --no-first-run \
  --no-default-browser-check &

# macOS
"/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`?** Без него запуск Chrome, когда обычный экземпляр Chrome уже работает, обычно открывает новое окно в существующем процессе — а этот процесс не был запущен с `--remote-debugging-port`, поэтому порт 9222 никогда не открывается. Выделенный user-data-dir заставляет создать новый процесс Chrome, где порт отладки действительно слушает. `--no-first-run --no-default-browser-check` пропускает мастер первого запуска для нового профиля.

При подключении через CDP все инструменты браузера (browser_navigate, browser_click и т.д.) работают на вашем живом экземпляре Chrome вместо запуска облачной сессии.

WSL2 + Windows Chrome: предпочитайте MCP вместо /browser connect

Если Hermes работает внутри WSL2, но окно Chrome, которым вы хотите управлять, работает на хосте Windows, /browser connect часто не является лучшим путем.

Почему:

Для такой настройки предпочитайте chrome-devtools-mcp через поддержку MCP в Hermes.

Смотрите руководство по MCP для практической настройки:

Local browser mode

Если вы не установили никаких облачных учетных данных и не используете /browser connect, Hermes все равно может использовать инструменты браузера через локальную установку Chromium, управляемую agent-browser.

Опциональные переменные окружения

# Residential proxies for better CAPTCHA solving (default: "true")
BROWSERBASE_PROXIES=true

# Advanced stealth with custom Chromium — requires Scale Plan (default: "false")
BROWSERBASE_ADVANCED_STEALTH=false

# Session reconnection after disconnects — requires paid plan (default: "true")
BROWSERBASE_KEEP_ALIVE=true

# Custom session timeout in milliseconds (default: project default)
# Examples: 600000 (10min), 1800000 (30min)
BROWSERBASE_SESSION_TIMEOUT=600000

# Inactivity timeout before auto-cleanup in seconds (default: 120)
BROWSER_INACTIVITY_TIMEOUT=120

Установка CLI agent-browser

npm install -g agent-browser
# Or install locally in the repo:
npm install
Набор инструментов `browser` должен быть включен в список `toolsets` вашей конфигурации или активирован через `hermes config set toolsets '["hermes-cli", "browser"]'`.

Доступные инструменты

browser_navigate

Перейти по URL. Должен быть вызван перед любым другим инструментом браузера. Инициализирует сессию Browserbase.

Navigate to https://github.com/NousResearch
Для простого получения информации предпочитайте `web_search` или `web_extract` — они быстрее и дешевле. Используйте инструменты браузера, когда нужно **взаимодействовать** со страницей (нажимать кнопки, заполнять формы, работать с динамическим контентом).

browser_snapshot

Получить текстовый снимок дерева доступности текущей страницы. Возвращает интерактивные элементы с ref ID (например, @e1, @e2) для использования с browser_click и browser_type.

Снимки длиннее 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

Поддерживаемые клавиши: Enter, Tab, Escape, ArrowDown, ArrowUp и другие.

browser_back

Вернуться на предыдущую страницу в истории браузера.

browser_get_images

Список всех изображений на текущей странице с их URL и alt-текстом. Полезно для поиска изображений для анализа.

browser_vision

Сделать скриншот и проанализировать его с помощью 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 также выполняет JavaScript при вызове с аргументом expression — так же, как консоль DevTools, результат возвращается в разобранном виде (JSON-сериализованные объекты становятся словарями, примитивные значения остаются примитивами).

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

Когда для текущей сессии активен CDP supervisor (обычно для любой сессии, запустившей browser_navigate для CDP-совместимого бэкенда), выполнение происходит через постоянный WebSocket supervisor — без затрат на запуск подпроцесса. В противном случае используется стандартный путь CLI agent-browser. Поведение идентично в обоих случаях — различается только задержка.

browser_cdp

Прямой проход к Chrome DevTools Protocol — запасной выход для операций в браузере, не охваченных другими инструментами. Используйте для работы с нативными диалогами, выполнения кода в iframe, управления cookies/сетью или любых команд CDP, которые нужны агенту.

Доступен только когда CDP-эндпоинт достижим при старте сессии — то есть когда /browser connect подключен к запущенному Chrome или в config.yaml установлен browser.cdp_url. Стандартный локальный режим agent-browser, Camofox и облачные провайдеры (Browserbase, Browser Use, Firecrawl) в настоящее время не предоставляют CDP этому инструменту — у облачных провайдеров есть CDP URL для каждой сессии, но маршрутизация в реальном времени — в разработке.

Справочник по методам CDP: https://chromedevtools.github.io/devtools-protocol/ — агент может использовать web_extract для страницы конкретного метода, чтобы посмотреть параметры и возвращаемые значения.

Типичные примеры:

# List tabs (browser-level, no target_id)
browser_cdp(method="Target.getTargets")

# Handle a native JS dialog on a tab
browser_cdp(method="Page.handleJavaScriptDialog",
            params={"accept": true, "promptText": ""},
            target_id="<tabId>")

# Evaluate JS in a specific tab
browser_cdp(method="Runtime.evaluate",
            params={"expression": "document.title", "returnByValue": true},
            target_id="<tabId>")

# Get all cookies
browser_cdp(method="Network.getAllCookies")

Методы уровня браузера (Target.*, Browser.*, Storage.*) не требуют target_id. Методы уровня страницы (Page.*, Runtime.*, DOM.*, Emulation.*) требуют target_id из Target.getTargets. Каждый вызов без состояния независим — сессии не сохраняются между вызовами.

Кросс-доменные iframe: передайте frame_id (из browser_snapshot.frame_tree.children[] где is_oopif=true), чтобы направить CDP-вызов через живую сессию supervisor для этого iframe. Так работает Runtime.evaluate внутри кросс-доменного iframe на Browserbase, где соединения CDP без состояния столкнулись бы с истечением подписанных URL. Пример:

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

Одно-доменные iframe не нуждаются в frame_id — используйте document.querySelector('iframe').contentDocument из Runtime.evaluate верхнего уровня.

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 supervisor — один WebSocket на задачу, подписанный на события Page/Runtime/Target. Supervisor также заполняет поле frame_tree в снимке, чтобы агент видел структуру iframe текущей страницы, включая кросс-доменные (OOPIF) iframe.

Матрица доступности:

Бэкенд Обнаружение через pending_dialogs Ответ (инструмент browser_dialog)
Локальный Chrome через /browser connect или browser.cdp_url ✓ полный workflow
Browserbase ✓ полный workflow (через встроенный XHR-мост)
Camofox / стандартный локальный agent-browser ✗ (нет CDP-эндпоинта)

Как это работает на Browserbase. Прокси CDP от Browserbase автоматически отклоняет реальные нативные диалоги на стороне сервера в течение ~10 мс, поэтому мы не можем использовать Page.handleJavaScriptDialog. Supervisor внедряет небольшой скрипт через Page.addScriptToEvaluateOnNewDocument, который переопределяет window.alert/confirm/prompt синхронным XHR. Мы перехватываем эти XHR через Fetch.enable — поток JS страницы остается заблокированным на XHR, пока мы не вызовем Fetch.fulfillRequest с ответом агента. Возвращаемые значения prompt() передаются обратно в JS страницы без изменений.

Политика диалогов настраивается в config.yaml через browser.dialog_policy:

Политика Поведение
must_respond (по умолчанию) Захватить, показать в снимке, ждать явного вызова browser_dialog(). Автоматическое отклонение по безопасности после browser.dialog_timeout_s (по умолчанию 300 с), чтобы зависший агент не заблокировал все навсегда.
auto_dismiss Захватить, немедленно отклонить. Агент все еще видит диалог в истории browser_state, но не должен на него реагировать.
auto_accept Захватить, немедленно принять. Полезно при навигации по страницам с агрессивными подсказками beforeunload.

Frame tree внутри browser_snapshot.frame_tree ограничен 30 фреймами и глубиной OOPIF 2, чтобы размер данных оставался приемлемым на страницах с большим количеством рекламы. Флаг truncated: true появляется, когда лимиты были превышены; агентам, которым нужно полное дерево, следует использовать browser_cdp с Page.getFrameTree.

Практические примеры

Заполнение веб-формы

User: Sign up for an account on example.com with my email john@example.com

Agent workflow:

1. browser_navigate("https://example.com/signup")

2. browser_snapshot()   sees form fields with refs

3. browser_type(ref="@e3", text="john@example.com")

4. browser_type(ref="@e5", text="SecurePass123")

5. browser_click(ref="@e8")   clicks "Create Account"

6. browser_snapshot()   confirms success

Исследование динамического контента

User: What are the top trending repos on GitHub right now?

Agent workflow:

1. browser_navigate("https://github.com/trending")

2. browser_snapshot(full=true)   reads trending repo list

3. Returns formatted results

Запись сессий

Автоматически записывать сессии браузера в видеофайлы WebM:

browser:
  record_sessions: true  # default: false

Когда включено, запись начинается автоматически при первом browser_navigate и сохраняется в ~/.hermes/browser_recordings/ при закрытии сессии. Работает как в локальном, так и в облачном режиме (Browserbase). Записи старше 72 часов автоматически очищаются.

Стелс-функции

Browserbase предоставляет автоматические стелс-возможности:

Функция По умолчанию Примечания
Basic Stealth Всегда включено Случайные отпечатки, рандомизация viewport, решение CAPTCHA
Residential Proxies Включено Маршрутизация через резидентные IP для лучшего доступа
Advanced Stealth Выключено Пользовательская сборка Chromium, требуется Scale Plan
Keep Alive Включено Переподключение сессии после сетевых сбоев
Если платные функции недоступны в вашем тарифе, Hermes автоматически выполняет откат — сначала отключая `keepAlive`, затем прокси — так что браузинг все еще работает на бесплатных тарифах.

Управление сессиями

Ограничения