Главная / Статьи

Почему агенты для программирования постоянно переосмысляют браузеры

Почему долгосрочно работающие агенты для программирования сходятся к инструментам в формате браузера: вспомогательные скрипты, куки в качестве памяти, компактное отображение страниц, альтернативы на основе HTTP и смещение в обучающих данных.

Издатель: REACTAPP.TOP12 мин чтения2722 слов

Источники: Why Do AI Agents Love Building Web Browsers?

Браузер, которого никто не просил

Программы-кодеры проявляют повторяющуюся тенденцию. Имея бесплатный доступ к Интернету, возможность писать и выполнять код, а также работу, продолжающуюся достаточно долго, они склонны создавать что-то, похожее на браузер. Желание иметь браузер не является мотивацией; им нужен дешевый, многократно используемый инструмент, способный открывать URL, нажимать кнопки, заполнять формы, ждать данных и извлекать их, хранить куки и сессии, а также делать скриншот при сбое. С такой точки зрения это просто обычная инженерная работа, какую выполнил бы человек-разработчик.

Chromium как продукт не является конечной целью. Эти программы стремятся к функции, которую выполняет браузер: преобразованию веб-протоколов и конвенций в операции.

Продукт против абстракции

Браузер в понимании Chrome или Firefox — это крупное приложение: вкладки, строка адреса, движок отрисовки, модель обработки задач. Ничто из этого не соответствует потребностям агента. Ему нужно преобразовать принципы работы веба в конкретные операции, которые можно выполнить.

Люди используют этот интерфейс, даже не замечая этого. На странице входа, естественно, просят ввести учетные данные, кнопку, естественно, можно нажать, вы нажимаете её, ждете следующей страницы и продолжаете. Агент не может опираться на это негласное понимание, поэтому ему приходится преобразовывать ту же работу в явные операции. Если попросить кодирующего агента работать с произвольными веб-сайтами, вы даёте ему задачу, естественная абстракция которой уже известна, поэтому он будет двигаться в направлении этой абстракции.

Современный веб также не создан для использования в виде упорядоченного API. Обычно имеется HTML-документ, обернутый в JavaScript, плюс сессии входа, куки, перенаправления, отрисовка на стороне клиента, бесконечное прокручивание, всплывающие окна, загрузка файлов и асинхронные запросы. Простой HTTP GET — это лишь начало. Реальные задачи в таких условиях в конечном итоге требуют выполнения набора операций подобных этим.

open(url)
click(selector)
fill(selector, text)
wait_for(selector)
extract(selector)
go_back()
screenshot()

Это не графический браузер, но, несомненно, это универсальный интерфейс для работы в Интернете.

Почему длительные задачи требуют вспомогательных инструментов

Короткие задачи можно выполнять спонтанно. Однократный поиск можно выполнить методом проб и ошибок без какой-либо инфраструктуры, поскольку он не будет повторяться и займет несколько секунд.

"Find the current exchange rate."
"Look up this company's homepage."
"Find the opening hours of this restaurant."

Работа с длительным циклом выполнения — это что-то другое. Представьте агента, который каждые несколько часов отслеживает сотни сайтов, постоянно выполняет сложные рабочие процессы, скармливает запросы страницам, оставаясь вошедшим в систему, собирает данные в течение нескольких дней или отправляет запросы к сервису до тех пор, пока что-то не изменится. Если модель обрабатывает каждый клик и каждую проверку, затраты растут экспоненциально. Простой вариант выполнения выглядит так:

  1. Открыть браузер, который служит инструментом для получения страницы.
  2. Проверить страницу, используя отрендеренную структуру DOM в качестве источника данных.
  3. Найти поле поиска, ввести запрос, нажать «Поиск» и дождаться результата.
  4. Извлечь данные.
  5. Проанализировать их.
  6. Повторить процедуру.

Способный агент реагирует так же, как человек-разработчик, пишет повторно используемый вспомогательный инструмент. Тогда последующее выполнение выглядит так:

  1. Запустить скрипт.
  2. Проверить, соответствуют ли результаты ожидаемым.
  • Звоните модели снова только в том случае, если она этого не делает, например, когда результат поиска пуст, структура страницы изменилась или извлеченные данные больше не соответствуют требованиям задачи.
  • Это значительное изменение в архитектуре. Модель прекращает выполнять все операции. Она становится той частью, которая определяет, какая процедура должна быть запущена, в то время как обычное программное обеспечение использует выбранный инструмент и собирает данные. Другими словами, агент преобразует свой собственный опыт в скрипт.

    Исследование в браузере, повторная реализация в коде

    Браузер — отличное место для исследований. Агент может исследовать окружающую среду, навигировать, просматривать результаты и определять, какая последовательность действий позволит достичь цели. После этого повторное рассмотрение каждого действия является расточительством ресурсов.

    Предположим, агент узнаёт, что для поиска товара на интернет-магазине всегда необходимо перейти на главную страницу, ввести запрос «USB-C cables», применить фильтры по оценке четыре звезды и выше, быстрой доставке и предельной цене, просмотреть результаты и извлечь названия, цены и идентификаторы товаров. У языковой модели нет причин заново выполнять эти пять операций при каждом запуске. Она может преобразовать их в процедуру и использовать её для аналогичных задач. Для этого требуется активная сессия с куки, поэтому агент выбирает Puppeteer, Playwright или подобные инструменты в качестве средства для получения страниц.

    async function getNewProducts(query) {
      const browser = await playwright.chromium.connectOverCDP(
        `wss://${AUTH}@brd.superproxy.io:9222`,
      );
      const page = await browser.newPage();
      await page.goto("https://example.com/products");
      await page.fill("input[name=q]", query);
      await page.click("button[type=submit]");
      await page.waitForSelector(".results");
      return extractResults(page);
    }
    

    Этот фрагмент подключает Playwright к удаленно размещенному браузеру через протокол Chrome DevTools Protocol. Использование удаленного браузера целесообразно, когда агент, работающий длительное время, должен поддерживать активность своей сессии каждые несколько часов без участия модели. Для этого требуются учетные данные в формате строки подключения, которые обозначаются местоположением ${AUTH}.

    Для структурированного извлечения данных с сайта, у которого нет заранее созданного скрейпера, даже не требуется локальный файл Playwright. Тот же рабочий процесс можно преобразовать в инструмент для скрейпинга, размещенный на сервере: достаточно описать нужные данные простым языком, получить генерированный сборщик данных и запустить его без использования модели в цикле кликов. Функции взаимодействия и парсинга остаются теми же — открытие страницы, клик, заполнение формы, ожидание, извлечение данных и сделка скриншота, только все это выполняется на удаленном сервере.

    Такой скрипт теряет эффективность при изменении CSS-селекторов, что вынуждает агента заново исследовать страницу и создавать новый скрипт. Если этот процесс находится внутри веб-инструмента, ИИ может его восстановить без необходимости переписывания селекторов.

    Люди-разработчики ведут себя аналогично: первый визит на веб-сайт помогает понять его работу, и после этого никто не задумывается о каждом клике. Когда сайт меняется, приходится снова учиться, хотя знания остаются в подсознании. У больших языковых моделей память гораздо дороже; если им приходится каждый раз воссоздавать процесс на основе контекста, они постоянно «открывают» одно и то же заново. Поэтому они сохраняют изученный алгоритм действий в скрипте и используют его до тех пор, пока страница больше не будет соответствовать заданным критериям.

    Куки как память вне модели

    Ни одна языковая модель не может сохранять длительную веб-сессию в своем контексте, по крайней мере сегодня. Запись файла .py всё равно запускает модель, в то время как хранение куки этого не делает. По мере развития сессии браузер сам накапливает память, поэтому она уже находится вне хранилища агента. Она состоит из трёх ключевых частей:

    • Хранилище куки, включающее HttpOnly-куки и те, которые устанавливаются JavaScript после входа в систему или проверки бота. Часто модель вообще не может их прочитать, однако браузер сохраняет их и присоединяет к следующему запросу.
    • Хранилище исходного домена, то есть localStorage, sessionStorage и IndexedDB, в которых почти полностью хранятся значения, заданные сайтом.
    • История сессии — стек «назад» и «вперёд», обеспечивающий работу функций back() или tabs.goBack().

    Некоторые состояния существуют вне хранилища браузера, например, сессия на стороне сервера или URL, который появляется только после выполнения JavaScript. Агенту не обязательно читать их самостоятельно; ему достаточно управлять слоем браузера, в котором уже хранится сессия.

    Риски безопасности при передаче браузера

    Когда агент может читать любую страницу и любые куки, а также управлять активной сессией, внедрение вводимого пользователя кода перестаёт быть проблемой качества интерфейса и превращается в архитектурную угрозу. С этой проблемой сталкиваются все системы, использующие активный браузер, но агенты, написанные с помощью кода, находятся в ещё более уязвимом положении, поскольку они обычно могут писать и запускать всё, с чем сталкиваются. Ограничьте возможности агента при отсутствии наблюдения человека, начав с использования песочницы.

    Хорошим примером шаблона является чек-лист для работы с компьютером от Anthropic: используйте специальную виртуальную машину или контейнер, избегайте входа в систему, если это не требуется задачей, ведите списки разрешенных доменов и требуйте подтверждения человеком любых действий, связанных с деньгами или получением согласия.

    Почему сырой HTML — плохой входной материал

    Сырые страницы представляют собой ужасный входной материал для языковой модели из-за огромного количества лишней информации. То, что нужно агенту, может быть скрыто среди тысяч токенов маркировки, стилизации и вспомогательных элементов. Поэтому хороший инструмент браузера возвращает более сжатый набор действий и наблюдений вместо полного HTML.

    На рисунке показана модель объектов документа HTML — дерево, которое должно быть сокращено в компактном представлении или дереве доступности. Полезный инструмент может преобразовать его в что-то гораздо более компактное. Вместо целого документа он может предоставить модели краткое описание, подобное этому.

    Title: Search results
    Links:
      [1] Home
      [2] Next page
    Forms:
      search: input[name=q]
    Buttons:
      submit: button[type=submit]
    Main content:
      ...
    

    Или это может вывести дерево доступности.

    - navigation
      - link "Home"
      - link "Search"
    - main
      - heading "Results"
      - list
        - listitem "Item 1"
        - listitem "Item 2"
    

    Такая форма гораздо ближе к тому, что может использовать модель рассуждений. Поэтому слой в форме браузера выполняет не только функцию взаимодействия: он сводит окружающую среду к компактному набору действий и наблюдений. Агент видит лишь те элементы веба, которые важны для его задачи, а не механизмы, отвечающие за отображение страниц. Контекст сохраняется, процесс вывода выводов становится более эффективным, а ошибки, хотя и не всегда, уменьшаются.

    Есть одно ограничение: полная копия информации об доступности со всеми ссылками может оказаться больше, чем сам видимый текст. Компрессия имеет смысл только тогда, когда обертка действительно возвращает короткий, удобный для работы список элементов управления. Степень короткости зависит от модели. Маленькая модель не может использовать необработанный DOM, а мощная может, но всё равно тратит ресурсы на обработку токенов. Ни одна из них не нуждается в полном HTML-коде.

    Когда достаточно обычного HTTP

    После того как агент разберётся, как работает сайт, самое дешёвое и надёжное решение может вообще не включать автоматизацию браузера. Иногда оказывается, что браузер выполняет на самом деле что-то довольно простое. Кнопка «Следующая страница» в конечном итоге может просто отправлять соответствующий сигнал.

    GET /api/products?page=2
    

    В таком случае отрисовка страницы бессмысленна, и агент может напрямую обратиться к конечной точке. В результате получается иерархия вариантов.

    human interface
          ↓
    browser automation
          ↓
    discovered workflow
          ↓
    direct HTTP/API calls   ← only if the site still allows it
    

    Его ценность заключалась в том, что он показывал, как ведет себя приложение. После того как это становится ясно, агент может убирать слои и иногда переходить на простой HTTP. Агент, который никогда не работает с страницами, насыщенными JavaScript, может полностью обойтись без автоматизации браузера и использовать только HTTP, желательно с сервисом для обхода блокировок на случай отклоненных запросов. Каким бы ни был путь, автономным агентам нужен запасной вариант, поскольку на открытом вебе практически неизбежны барьеры вроде Cloudflare или проверки на ботов. Без недорогих возможностей повторной попытки модель блуждает, тратит токены и увеличивает счета.

    Существуют две сложности.

    Во-первых, многие сайты невозможно свести к использованию только HTTP. Большинство из них не позволяют проводить обратную инженерию: они ограничивают трафик, не похожий на трафик браузера, меняют селекторы, фиксируют уникальные характеристики клиентов и добавляют проверки на ботов или CAPTCHи. В таких случаях необходимо использовать полноценный подход с браузером, будь то локальная установка или хостинг.

    Во-вторых, использование альтернативных решений не всегда оправдано. Документированный публичный JSON API имеет четкую структуру, ограничения и удобен для логирования. Внутренний эндпоинт без документации, который агент находит самостоятельно, — это уже другое: его действительно проще вызывать, но его сложнее проверить человеку по сравнению с скриптом, нажимающим видимую кнопку, при этом у такого решения меньше логов. Ответ 200 с большим количеством ненужных данных легко ускользнуть от внимания, тогда как неисправная страница бросается в глаза.

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

    • Если таким интерфейсом является JSON-эндпоинт и сайт его поддерживает, используйте JSON.
    • Если требуется выполнение JavaScript и сохранение состояния сессии, используйте настоящий браузер через Puppeteer или Playwright, либо хостинговый браузер.
    • Если нужен только загруженный HTML, используйте HTTP с прокси или средством для обхода блокировок, если запрос GET заблокирован.
  • Для повторяемой структурированной выгрузки на сайте, у которого нет готового скрапера, необходимо организовать работу в рамках хостингового процесса скрапинга, при котором кодовый рабочий обрабатывает HTTP-запросы, а браузерный рабочий — живую сессию.
  • Когда важна структура доступности, её следует передавать напрямую.
  • Долговечные веб-агенты обычно используют несколько из этих методов одновременно. Важным навыком является умение переключаться между уровнями иерархии по мере необходимости.

    Могут ли обучающие данные это объяснить?

    Ответ двойственный. Обучающие данные могут объяснить, почему модель выбирает Playwright или Puppeteer, но они не могут объяснить создание инструментов, похожих на браузеры, с самого начала.

    Исследование Oxford и Microsoft 2026 года под названием BiasBusters изучало вариант этого вопроса: влияет ли воздействие определенных данных в процессе обучения на выбор модели соответствующего инструмента. Исследователи продолжили обучение небольшой модели на корпусе данных, содержащем большое количество метаданных одного конкретного API для получения погодной информации, одного из нескольких аналогичных сервисов.

    • До обучения модель почти никогда не выбирала этот API — примерно в 0,6% случаев, что соответствует вероятности выбора при случайном подходе.
    • После обучения на этом смещенном корпусе данных модель выбирала его примерно в 12% случаев, то есть в двадцать раз чаще.

    Короче говоря, одни лишь тренировочные данные, независимо от задачи, оказывают заметное влияние на то, какой инструмент или продукт предпочитает модель. Однако речь идет лишь о выборе инструмента. Абстракция (открытие, клик, заполнение, ожидание, извлечение в форме фигуры — что бы ни предоставляла соответствующая библиотека) определяется средой. Модели, которые никогда не сталкивались с Playwright, все равно нуждаются в средствах для открытия страниц, ожидания загрузки контента и отчета о результатах, поскольку интерактивные страницы этого требуют.

    Здесь действуют два разных фактора:

    • Абстракция операций open, click, fill, wait и extract навязывается средой. Интерактивные страницы включают в себя навигацию, тайминг, элементы управления и отображаемый результат, независимо от того, присутствует ли Playwright в весах модели.
  • Инструмент Playwright по сравнению с разработанным внутри клиентом основан на том, что видел модель, как показали BiasBusters на примере взаимозаменяемых API.
  • Данные для обучения охватывают второй вариант, но не учитывают первый. Модель не может объяснить, почему проблема постоянно сводится к абстракциям, похожим на браузеры. Более основная причина заключается в том, что сеть уже организована именно таким образом.

    Адаптеры с наилучшими результатами

    Такие агенты, как Claude Code, на самом деле не создают браузеры. Они создают адаптеры между системой рассуждений и средой, которая случайно имеет форму браузера.

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

    Эти виды не пришли к выводу, что быть крабом — это разумный выбор. Их окружение постоянно вознаграждало примерно один и тот же ответ на примерно одни и те же проблемы. Агенты, занимающиеся программированием, возможно, следуют похожему пути: они замечают, что текущий подход медленный, пишут скрипт, добавляют попытки повтора при сбоях, обеспечивают сохранение состояния сессии после аутентификации и добавляют функции извлечения данных из DOM или для обеспечения доступности, когда страницы становятся слишком большими для анализа.

    The task requires the web.
            ↓
    The web exposes a browser-shaped interface.
            ↓
    The agent needs a way to operate that interface.
            ↓
    Repeated operations make ad-hoc reasoning expensive.
            ↓
    The agent writes reusable tools.
            ↓
    Those tools accumulate state, retries, and abstractions.
            ↓
    The tools start looking like a browser.
            ↓
    Known workflows get compiled into deterministic code.
            ↓
    The page changes so the agent re-explores.
            ↓
    If an API exists, use it to get the data.
    If not, and the site allows it, fall back to regular HTTP.
    If not, stay on the browser.
    

    При достаточном количестве итераций результат напоминает небольшой браузер. Это лучшая когнитивная модель для автономных агентов, чем представление о цифровых существах с странным интересом к браузерам. Они ведут себя как хорошие инженеры: изучают сложную среду, выявляют реально существующий интерфейс и создают абстракции для того, что повторяется, имеет состояние и требует значительных усилий. В сети уже существует старая и чрезвычайно эффективная абстракция для этой цели — браузер.