- Дата публикации
AI Subroutines: как rtrvr учит веб‑агентов работать в вашем браузере без токенов и сбоев авторизации
Что нового
rtrvr.ai запустила Subroutines — механизм «подпрограмм» для браузерного агента, который превращает разовый сценарий в масштабируемый инструмент без постоянных вызовов LLM.
Ключевые новинки:
-
Subroutines — записываемые и переиспользуемые сценарии внутри вкладки браузера
- Вы один раз выполняете действие в веб‑интерфейсе (например, отправляете DM в Instagram).
- Расширение rtrvr перехватывает сетевые запросы и DOM‑действия.
- На основе записи генерируется JavaScript‑функция (Subroutine), которую агент вызывает как обычный tool.
- На горячем пути больше нет LLM‑инференса: каждый запуск — это
fetchвнутри страницы, а не новый запрос к GPT или Claude.
-
Запись и воспроизведение происходят прямо внутри страницы
- rtrvr ставит патч
fetch/XHR в MAIN‑контексте до загрузки скриптов сайта и дублирует его через ChromewebRequestдля путей, которые не видны из страницы (CORS, service workers). - Все запросы при воспроизведении идут из того же контекста: тот же origin, те же cookies, тот же TLS‑сеанс, тот же JS, который считает подписи заголовков.
- За счёт этого авторизация, CSRF, подписи и fingerprint‑механизмы «приезжают» автоматически.
- rtrvr ставит патч
-
Агрессивная фильтрация сетевого шума перед LLM
- Обычная минута серфинга даёт десятки–сотни запросов, интересных — 2–5.
- rtrvr ранжирует запросы по набору сигналов и обрезает всё лишнее до топ‑5 кандидатов, плюс контекст DOM‑действий.
- Эти данные упаковываются в контекст примерно 12 000 символов для генератора. Если не помещается, rtrvr по шагам выкидывает сначала URL‑историю, потом лишние кандидаты, затем подсказки по DOM — пока всё не влезет.
-
Защита от «ломких» API по volatile‑идентификаторам
- Если в запросе есть
queryId,doc_id,operationHashили другой build‑зависимый хеш, планировщик принудительно выбирает DOM‑сценарий, а не сетевой. - Генератор получает прямую инструкцию: «Do NOT expose or discover queryId/doc_id/operationHash values».
- Это снижает риск сценария, который красиво работает неделю и тихо умирает после деплоя сайта.
- Если в запросе есть
-
Subroutines как полноценные tool‑вызовы агента
Примеры интерфейса:Sheet of Instagram URLs → sendInstagramDirectMessage({ url, message }) Daily content queue → createXPost({ text, mediaUrl }) List of profiles → sendLinkedInConnectionRequest({ url, note })- Агент работает с Subroutine так же, как с
searchилиfetch. - Для каждого ряда в таблице LLM вызывается один раз — только чтобы подобрать параметры.
- Само действие — это детерминированный скрипт без токенов на горячем пути.
- Агент работает с Subroutine так же, как с
-
Набор вспомогательных rtrvr.*‑хелперов внутри вкладки
Subroutine — этоasync‑функция, которая запускается в контексте вкладки и получает namespacertrvr:rtrvr.find({ role, name, text, placeholder })— поиск цели на странице по семантике, с поддержкой открытых shadow‑root.rtrvr.click(handleOrTarget)— клик по найденному элементу или семантическому описанию.rtrvr.type(handleOrTarget, value, { clear, submit })— ввод текста в поля и rich‑редакторы.rtrvr.waitFor(targetOrFn, { timeoutMs })— ожидание следующего состояния UI, модалки, формы.rtrvr.waitForUrl(match, { timeoutMs })— ожидание навигации или смены маршрута.rtrvr.request(url, init)— аутентифицированныйfetchиз контекста страницы.rtrvr.requestJson(url, init)— то же, но с разбором JSON‑ответа.rtrvr.getCsrfToken()— чтение CSRF‑токена с текущей страницы.rtrvr.getCookie(name)— чтение cookie.
-
Готовые Subroutines и общий каталог
- В расширении уже есть готовые Subroutines для Instagram, X и LinkedIn.
- Команда rtrvr строит публичную библиотеку сценариев: от LinkedIn DM до создания черновика заказа в Shopify или обновления контакта в HubSpot.
- Пользователи могут записывать свои Subroutines и делиться ими.
-
Сопутствующие обновления rtrvr
Вместе с Subroutines вышёл крупный релиз экосистемы:- BYO ChatGPT / Claude — авторизация через OAuth в OpenAI или Anthropic из расширения. Агент работает на уже оплаченном тарифе, без отдельного API‑ключа.
- Управление через WhatsApp — можно сохранить любой выполненный workflow как shortcut и запускать его из чата командами
/run,/schedule,/trigger,/check_schedule_results, пока браузер включён дома. - Knowledge Base + MCP — облачный скрейпинг и индексация, новые MCP‑инструменты для баз знаний, записей, расписаний и Subroutines, плюс готовые API‑сниппеты на каждой панели в облаке (любой запуск, чат по KB или tool‑вызов — в один
curl). - Rover + RoverBook — скрипт, который владелец сайта встраивает как
<script>: он даёт агенту структурированное представление сайта и PostHog‑подобную аналитику (визиты, траектории, AX Score 0–100, отзывы агентов, память о прошлых сессиях). - Плюс: загрузка
.docx / .xlsx / .pptxв чат, логин по email+паролю, клиппинг по accessibility‑дереву (⌘Ctrl+Cснимает более богатое дерево, чем текстовый парсер), голосовой ввод на устройстве, динамические шаблоны, завязанные на URL, и апгрейд UI и производительности.
Как это работает
Главная идея: решать не UI, а авторизацию
Большинство веб‑агентов сегодня делают одну вещь: кликают по DOM или шлют разовый запрос к API. Пока вам нужно отправить один пост в X или одно приглашение в LinkedIn — это терпимо. Как только вы хотите сделать это 1000 раз, всё ломается:
- каждый шаг требует отдельного вызова LLM;
- вы платите токенами за каждую итерацию;
- добавляется задержка на каждый запрос;
- поведение агента нестабильно: «в этот раз кликнул не туда».
Интуитивное решение — не трогать UI, а бить прямо по внутреннему API сайта. Но реальная проблема не в URL эндпоинта, а в авторизации.
Почему auth — узкое место
Аутентифицированные HTTP‑запросы в браузере несут на себе целый «зоопарк»:
- cookies;
- вращающиеся CSRF‑токены;
- session‑токены;
- bearer‑заголовки;
- одноразовые nonces;
- параметры, привязанные к device‑fingerprint;
- подписи запросов, которые считает JS сайта на лету.
Часть этих данных приходит от сервера, часть — вычисляется в браузере, часть — обновляется на каждый запрос.
Если вы запускаете скрейпер или агент вне вкладки (Node‑воркер, Playwright, cloud function), вам приходится вручную восстанавливать все эти механизмы. Любое изменение схемы заголовков или подписи на стороне сайта ломает ваш код. Большинство инструментов, которые «просто реплеят HAR», умирают на этом месте.
Фокус rtrvr: запись и воспроизведение внутри страницы
rtrvr решает это за счёт архитектуры:
-
Запись:
- Расширение ставит патч на
fetchи XHR в MAIN‑контекст вкладки ещё до того, как запустился JS сайта. - Параллельно расширение использует
chrome.webRequestкак резерв для запросов, которые не видны из страницы (например, через service worker). - rtrvr перехватывает все сетевые запросы, которые происходят, пока вы вручную выполняете задачу.
- Сохраняются не только JSON‑тела, но и
FormData,Blob, сырые байты.
- Расширение ставит патч на
-
Ранжирование:
- За минуту работы вкладка может отправить сотни запросов: аналитика, пиксели, prefetch, RUM, HMR, медиа‑чанки.
- rtrvr оценивает каждый запрос по набору весов и отбирает только кандидатов, которые с высокой вероятностью являются «настоящим действием».
-
Генерация Subroutine:
- В LLM уходит уже не сырая простыня HAR, а компактный контекст: топ‑5 сетевых кандидатов + DOM‑действия рядом с ними, упакованные в ~12 000 символов.
- Модель генерирует
async‑функцию на JavaScript, которая используетrtrvr.*‑хелперы и/или прямойrtrvr.request.
-
Воспроизведение:
- Когда агент вызывает Subroutine, код выполняется внутри вкладки.
- Запросы уходят из того же контекста, что и ручное действие: браузер сам подставляет cookies, считает CSRF и подписи, использует тот же TLS‑сеанс.
- Агент не трогает секреты и не восстанавливает сессию вручную.
Результат: авторизация, CSRF и подписи «приезжают» в Subroutine автоматически. Никакой экстракции ключей, пересборки сессий или прокси‑ротации.
Как rtrvr отфильтровывает сетевой шум
Если просто сохранить все запросы, получается слишком много данных для LLM. rtrvr решает это через скоринг с конкретными весами:
-
Происхождение:
- Первый домен (сам сайт):
+20. - Третьи стороны:
−15. - Известные хосты телеметрии (Sentry, Segment, Hotjar, RUM и т.д.):
−80безоговорочно — даже если они сильно коррелируют с кликом.
- Первый домен (сам сайт):
-
Временная корреляция с DOM‑событием:
- Запрос в пределах 800 мс после клика:
+28. - В пределах 2,5 с:
+16. - POST, который уходит через 40 мс после нажатия «Send», почти наверняка и есть отправка.
- Запрос в пределах 800 мс после клика:
-
Метод и форма запроса:
- Мутирующие методы
POST/PUT/PATCH/DELETE:+35. GET:+5.- Наличие тела запроса:
+8. OPTIONS/HEADи записи производительности:−40.
- Мутирующие методы
-
Качество ответа:
- Код 2xx:
+12. - 4xx и выше:
−25. - Непустое тело ответа:
+4.
- Код 2xx:
-
Volatile‑идентификаторы:
- Наличие
queryId,doc_id,operationHashили другого build‑зависимого хеша:−18.
- Наличие
Пример: первый домен + мутирующий POST + отправка через 80 мс после клика + ответ 200 с телом дадут суммарно около +83. Типичный аналитический beacon получит −80. rtrvr сортирует все запросы по сумме и оставляет топ‑5.
Эти пять, плюс DOM‑интеракции вокруг них, рендерятся в контекст для генерации Subroutine. Если объём превышает лимит, rtrvr по очереди выкидывает:
- историю посещённых URL;
- часть сетевых кандидатов;
- подсказки по DOM.
После этого контекст отправляется в LLM.
DOM, сеть или гибрид — как выбирается стратегия
Даже если лучший сетевой кандидат набрал высокий балл, rtrvr не всегда разрешает сетевой replay. Критический случай — volatile‑идентификаторы:
- Если запрос использует
queryId,doc_id,operationHashили аналогичный хеш, завязанный на текущий билд, планировщик принудительно выбирает DOM‑only‑сценарий. - Генератор получает явный запрет на использование и даже поиск этих значений.
Причина проста: сетевой replay с такими параметрами хорошо выглядит в демо и быстро ломается после первого же деплоя сайта.
В остальных случаях генератор может строить гибрид: часть действий через DOM (поиск и клик по кнопке, ожидание модалки), часть — через rtrvr.request к стабильному эндпоинту.
Как устроен код Subroutine
Subroutine — это небольшая async‑функция на JavaScript, которая запускается в контексте вкладки. Параметры, которые передаёт агент (строка из таблицы, URL профиля, текст сообщения), объявляются как const над телом функции.
Внутри функции доступен namespace rtrvr. Пример минимального Subroutine для кнопки «Connect» в LinkedIn:
const button = await rtrvr.find({
role: "button",
name: /Connect/i,
});
if (!button) {
return { success: false, error: "Connect button not found." };
}
await rtrvr.click(button);
const csrfToken = rtrvr.getCsrfToken();
return await rtrvr.requestJson("/voyager/api/example", {
method: "POST",
headers: {
"content-type": "application/json",
"x-csrf-token": csrfToken,
},
body: JSON.stringify({ ok: true }),
});
Пара важных деталей реализации:
-
Параметры — это аргументы функции, а не конкатенация строк.
Subroutine исполняется какAsyncFunction, где параметры — это объявленные аргументы плюсrtrvr. Код обращается кurl,messageи другим параметрам напрямую. Это убирает риск инъекций через шаблонные строки, а имена параметров не конфликтуют с локальными переменными. -
rtrvr.findумеет ходить в открытые shadow‑root.
LinkedIn‑чат и многие компоненты Material 3 рендерят интерактивные элементы внутри открытых shadow‑root. Обычныйdocument.querySelectorих не видит. Еслиfindне находит цель, он возвращает ещё и три ближайших кандидата с их ролями и именами — это помогает быстро понять, почему сценарий перестал работать. -
rtrvr.requestсам разбирается с CSRF и «грязными» заголовками.
Хелпер читает распространённые имена CSRF‑cookie (ct0,XSRF-TOKEN,csrftoken) и метатеги, подставляетx-csrf-token, если он отсутствует, и вычищает заголовки, вредные для реплея (set-cookie,x-client-transaction-id,livepipeline-session). Это не даёт одноразовым nonces сломать следующий запуск.
Ограничения
Subroutines работают на уровне HTTP. Если сайт опирается на WebSocket, WebRTC или тяжёлую клиентскую логику «посередине», сценарий придётся строить через DOM‑действия с ожиданиями состояний. Такой путь медленнее и менее надёжен, поэтому rtrvr использует его как запасной.
Кроме того, Subroutines требуют перезаписи, когда сайт серьёзно меняет API. Это цена отказа от LLM на горячем пути. На практике API меняются реже, чем DOM, и rtrvr делает ставку именно на это.
Что это значит для вас
Когда Subroutines дают максимальный эффект
Если вы:
- массово рассылаете сообщения и приглашения в соцсетях;
- обновляете CRM‑записи по спискам;
- создаёте посты, тикеты, заявки по шаблону;
- уже пробовали Puppeteer/Playwright и устали чинить авторизацию,
Subroutines закрывают сразу несколько болей.
1. Масштабирование без взрыва по токенам
Обычный агент вызывает LLM на каждом шаге сценария. При 500–1000 элементов в списке это превращается в заметный счёт за токены и задержки в десятки секунд или минуты.
С Subroutines LLM нужен только для выбора параметров по каждой строке (например, сформировать текст сообщения). Само действие — это JavaScript в вкладке, без токенов. Если текст у вас уже готов в таблице, агент вообще может не вызывать LLM на горячем пути.
2. Детерминированность вместо «агент иногда ошибся»
Subroutine — это код. При одинаковых входных данных вы получаете одинаковый результат. Никаких случайных кликов «не по той кнопке» из‑за дрейфа поведения модели.
3. Меньше риска банов и фильтров
Запросы уходят из того же браузера, где вы руками выполняли действие: тот же origin, те же заголовки, та же сессия. Для антибот‑систем это выглядит как обычная активность пользователя, а не как headless‑кластер.
4. Работа с «капризными» схемами авторизации
Если вы сталкивались с SSO‑редиректами, вращающимися refresh‑токенами, выдачей токенов через service worker, DPoP или mTLS, вы знаете, насколько тяжело это воспроизвести вне браузера. rtrvr просто не выходит за пределы вкладки и отдаёт всё это на откуп нативному стеку браузера.
Конкретные сценарии применения
-
Маркетинг и аутрич:
- Отправка 500+ личных сообщений в LinkedIn с персонализированными заметками.
- Массовые DM в Instagram по списку профилей.
- Планирование очереди постов в X по списку текстов и медиа.
-
Продажи и аккаунт‑менеджмент:
- Обновление статусов сделок в CRM по выгрузке из Google Sheets.
- Создание черновиков заказов в Shopify для списка клиентов.
- Массовое обновление контактов в HubSpot.
-
Саппорт и внутренние процессы:
- Создание тикетов в Zendesk по входящим запросам из таблицы.
- Регулярное бронирование слотов в календарях по шаблону.
- Заполнение форм внутренних порталов, которые не имеют публичного API.
Где Subroutines не подойдут
- Если вам нужен полностью автономный агент в облаке, который сам открывает браузер на сервере и работает без пользовательской сессии, Subroutines не закроют все потребности: они завязаны на локальный браузер и вашу сессию.
- Если сайт делает почти всю работу через WebSocket или WebRTC без явных HTTP‑эндпоинтов, сценарий придётся строить через DOM‑действия. Это медленнее и менее стабильно, чем чистый сетевой replay.
- Если вы хотите, чтобы агент сам «додумывал» сложную логику на каждом шаге (а не исполнял заранее записанный сценарий), вам всё равно понадобится LLM на горячем пути — Subroutines оптимизируют именно часть «действие», а не «мышление».
Доступность и возможные ограничения
rtrvr распространяется как расширение для Chrome. Для работы с Instagram, X, LinkedIn и другими зарубежными сервисами может потребоваться VPN, если доступ к этим сайтам ограничен с вашей сети или региона. Сам rtrvr не вшивает обход блокировок, поэтому условия доступа зависят от вашей среды.
Место на рынке
По сравнению с Browser-Use и Stagehand
Browser-Use и Stagehand держат LLM внутри цикла выполнения действий:
- агент регулярно описывает состояние страницы модели;
- модель принимает решение, что делать дальше;
- цикл повторяется до завершения задачи.
Плюсы такого подхода — гибкость и удобство для одноразовых задач. Минусы для масштабных сценариев:
- каждый шаг — отдельный вызов GPT или Claude;
- стоимость растёт линейно с числом действий;
- поведение остаётся вероятностным, сценарии могут вести себя по‑разному на одинаковых входных данных.
rtrvr с Subroutines переносит LLM в момент генерации кода. На горячем пути остаётся детерминированный JavaScript, который не требует токенов и не меняет поведение от запуска к запуску.
По сравнению с Libretto + Playwright
Libretto, вышедший недавно, использует очень похожую идею: LLM генерирует скрипты заранее, а не управляет браузером в реальном времени. Но есть важное отличие:
- Libretto исполняет сценарии через Playwright вне пользовательского браузера.
- Вы наследуете сессию Playwright, а не реального пользователя.
- Любая схема авторизации, которую браузер решает «сам» (SSO, refresh‑токены, сервис‑воркеры, DPoP, mTLS), превращается в задачу для разработчика.
rtrvr делает ставку именно на то, что скрипт работает в том же контексте, где вы уже авторизованы руками. Из‑за этого авторизация вообще не становится отдельной задачей: всё, что умеет ваш браузер, автоматически умеет и Subroutine.
Чётких цифр по сравнению скорости выполнения или стоимости токенов между rtrvr, Browser-Use, Stagehand и Libretto авторы не приводят. Но архитектура rtrvr очевидно убирает повторные вызовы LLM на горячем пути и даёт детерминированный результат при одинаковых входных данных.
Установка / Как запустить
1. Установка расширения rtrvr
- Откройте Chrome Web Store.
- Найдите расширение rtrvr.ai и установите его.
- Авторизуйтесь в rtrvr через интерфейс расширения.
2. Привязка ChatGPT или Claude
В настройках расширения можно подключить свой аккаунт OpenAI или Anthropic:
- Вы проходите OAuth‑авторизацию в OpenAI или Anthropic.
- Агент rtrvr начинает использовать ваш оплаченный план GPT или Claude.
- Дополнительный API‑ключ не нужен.
3. Запись первого Subroutine
- Откройте нужный сайт (например, LinkedIn, Instagram или X) в Chrome и убедитесь, что вы авторизованы.
- Запустите rtrvr из панели расширений и нажмите Record.
- Выполните задачу руками один раз: отправьте сообщение, создайте пост, обновите запись.
- Остановите запись и сохраните сценарий как Subroutine, задав имя и параметры (например,
url,message).
4. Применение Subroutine к списку
- Откройте таблицу с данными — например, Google Sheets со столбцами
urlиmessage. - Укажите rtrvr, какую Subroutine использовать и какие столбцы связать с параметрами.
- Агент пройдётся по строкам:
- для каждой строки подберёт параметры (при необходимости спросит LLM);
- запустит Subroutine во вкладке;
- выполнит сетевые запросы или DOM‑действия в соответствии с кодом.
5. Пример кода Subroutine
Ниже — полный пример Subroutine для кнопки «Connect» в LinkedIn, приведённый авторами rtrvr:
const button = await rtrvr.find({
role: "button",
name: /Connect/i,
});
if (!button) {
return { success: false, error: "Connect button not found." };
}
await rtrvr.click(button);
const csrfToken = rtrvr.getCsrfToken();
return await rtrvr.requestJson("/voyager/api/example", {
method: "POST",
headers: {
"content-type": "application/json",
"x-csrf-token": csrfToken,
},
body: JSON.stringify({ ok: true }),
});
6. Управление через WhatsApp
После того как вы настроили и запустили workflow в rtrvr, вы можете:
- сохранить его как shortcut;
- управлять им из WhatsApp‑чата командами:
/run— запустить;/schedule— поставить в расписание;/trigger— инициировать выполнение;/check_schedule_results— посмотреть результаты по расписанию.
Браузер при этом должен быть запущен на вашем компьютере: rtrvr использует ваш локальный контекст вкладки.
rtrvr.ai с Subroutines делает ставку на простую идею: всё, что вы однажды сделали руками в браузере и что ломалось из‑за auth и нестабильных DOM‑скриптов, можно записать один раз и превратить в детерминированный сценарий без токенов на горячем пути. Для тех, кто уже упёрся в лимиты Puppeteer, Playwright и «агентов, которые иногда кликают не туда», это может быть заметным шагом вперёд.