Инфраструктурное проектирование для снижения затрат на прокси и токены при развертывании Agent-Reach в продакшене
19. Juni 2026
0
Computing/SoftwareComments (0)
Log in to leave a comment
No posts yet
Log in to leave a comment
No posts yet
Даже те агенты на базе Agent-Reach, которые отлично работали в локальной CLI, сталкиваются с препятствиями, как только их переносят на сервер. Стоит прийти десяткам тысяч запросов на скрапинг, как они попадают под защитные сети CDN вроде Cloudflare, и IP-адреса начинают массово блокироваться. Однако, если полагаться только на платные резидентские прокси, расходы на трафик становятся неподъемными. А если подавать «сырой» HTML прямо в LLM, можно выйти за рамки контекста и получить огромный счет за токены. Чтобы решить эту проблему, необходимы архитектура динамической маршрутизации и конвейер предварительной обработки данных.
Если использовать Agent-Reach без защиты, расходы только на платные резидентские прокси могут достигать тысяч долларов. В системе, обрабатывающей 100 000 запросов в день со средним размером страницы 150 КБ, при уровне отказов в 50% ежемесячный объем передачи данных достигает 675 ГБ. Премиальные резидентские прокси, такие как Bright Data или Oxylabs, стоят от 4 до 8 долларов за ГБ. Если пропускать весь трафик через них, ежемесячные расходы взлетят до 5400 долларов.
Развертывание Scrapoxy, агрегатора прокси с открытым исходным кодом, в качестве супер-прокси на базе Docker-контейнера позволяет контролировать инфраструктурные расходы, сохраняя единую точку доступа. Сначала создайте файл docker-compose.yml в корне проекта и определите в нем образы valkey/valkey:7.2-alpine и fabienvauchelles/scrapoxy:latest. В контейнере Valkey укажите команду --appendonly yes --requirepass [пароль], чтобы обеспечить постоянство кэширования учетных данных. После настройки имени пользователя и пароля в переменных окружения Scrapoxy запустите контейнеры командой docker compose up -d. Эта конфигурация поможет сэкономить более 200 долларов в месяц на подписках на платные сервисы.
Чтобы сессии не обрывались, периодичность смены IP должна варьироваться в зависимости от политики безопасности целевой платформы. Для публичных запросов с правами только на чтение (Read-Only), не требующих авторизации, установите агрессивный TTL от 30 секунд до 3 минут, принудительно назначая каждый раз новый IP в режиме round-robin. Это мера для обхода блокировок по порогу запросов. С другой стороны, для авторизованных платформ, таких как X или Reddit, где необходимо поддержание сессионных cookie, включите функцию инъекции cookie в Scrapoxy и закрепляйте один и тот же резидентский IP-узел на 5–10 минут. Это предотвратит истечение срока действия сессии из-за внезапной смены географического местоположения IP.
Чтобы еще больше сократить расходы, необходимо оптимизировать маршрутизацию трафика на уровне API-шлюза NGINX. В блоке upstream файла конфигурации NGINX (/etc/nginx/nginx.conf) определите пул дешевых дата-центровых прокси (например, DataImpulse, где цена составляет около 1 доллара за ГБ) и пул резидентских прокси Scrapoxy. Внутри блока server создайте location /fetch/generic/ для перенаправления публичного HTML-трафика с низким уровнем защиты (RSS-ленты, поиск GitHub и т. д.) на дата-центровые прокси. Затем создайте location /fetch/social/ для маршрутизации запросов к социальным сетям с высокой степенью защиты на бэкенд Scrapoxy с внедрением соответствующих заголовков. Применение этой двухканальной маршрутизации предотвращает перерасход трафика через дорогие резидентские прокси и сокращает общие расходы на прокси до 90%.
«Сырые» HTML-данные — это нагромождение дублирующихся DOM-элементов, таблиц стилей и встроенных скриптов. Если подавать их в LLM напрямую, это приводит к потреблению лишних токенов и снижению качества результатов логического вывода. Преобразование веб-страницы в Markdown вместо подачи необработанного содержимого в окно контекста позволяет уменьшить объем данных на 75–90%. Выполнение очистки на основе регулярных выражений и сериализация в Markdown на этапе предварительной обработки конвейера позволяют сократить расход токенов API LLM более чем на 40% и предотвратить ошибки превышения окна контекста.
Реализуйте Python-функцию для предварительной обработки входных данных, комбинируя парсеры Trafilatura и html2text. При вызове trafilatura.extract() установите опцию favor_recall=False, чтобы исключить боковые панели и рекламу, оставив только основной текст. На случай сбоя извлечения основного контента добавьте Fallback-код, который создает объект html2text.HTML2Text() с параметрами ignore_images=True и body_width=0. Запуск регулярных выражений (re.sub) для удаления оставшихся тегов типа <script>, <style> и процедура очистки для сокращения последовательных пустых строк из извлеченного Markdown-текста сократят время отклика агента.
При разделении длинных документов вместо простого чанкинга по количеству символов следует внедрить алгоритм сегментации, сохраняющий контекст на основе семантического сходства. Вычисляйте косинусное сходство между векторами эмбеддингов предложений, чтобы зафиксировать точки, где происходит семантический разрыв.
Similarity(u, v) = rac{u cdot v}{\|u\| \|v\|}После вычисления расстояния между соседними предложениями установите в качестве точек семантического разделения границы, где разница в расстоянии превышает 95-й процентиль для всего документа, и сформируйте список чанков. Применение семантического чанкинга вместо фиксированного предотвращает потерю информации из-за того, что связанные данные оказываются в разных фрагментах, и улучшает точность поиска информации для LLM.
Платформы вроде X или LinkedIn имеют строгие ограничения скорости (rate limits). Часто возникают ошибки HTTP 429 или 403. Если синхронный процесс приложения будет немедленно повторять запрос в таких условиях, ресурсы сервера исчерпаются, а уровень блокировки IP только вырастет. Для обеспечения устойчивости системы необходимо асинхронное middleware обработки исключений, которое классифицирует ошибки и динамически регулирует нагрузку на целевой сервер.
При проектировании класса обработчика ошибок важно четко разделять временные и постоянные ошибки. Если код состояния HTTP равен 429, 502, 503, 504 или сообщение об ошибке содержит 'timeout' или 'connection refused', классифицируйте это как временную ошибку и поставьте в очередь на повтор. Напротив, ошибки типа 401 или 400 следует считать постоянными и немедленно отправлять в очередь недоставленных сообщений (Dead Letter Queue, DLQ). В случае временной ошибки применяйте алгоритм экспоненциальной отсрочки с добавлением случайного «джиттера» (jitter) в миллисекундах, чтобы избежать эффекта «громоподобного стада» (Thundering Herd), когда множество запросов отправляется одновременно. Формула для расчета времени ожидания выглядит так:
Если установить базовое время задержки () на 30 секунд, а максимальный предел () на 600 секунд, то при третьей попытке будет обеспечено распределенное время ожидания около 240 секунд, что позволит обойти политику блокировки целевой платформы.
Для предотвращения каскадных сбоев, когда проблемы или усиление безопасности на одной платформе парализуют весь рабочий процесс, реализуйте в middleware-слое паттерн переборки (bulkhead) на основе Redis. Вместо единой глобальной очереди создайте независимые списки Redis, разделенные по целевым доменам (queue:bulkhead:twitter, queue:bulkhead:reddit, queue:bulkhead:general). Назначьте максимальные лимиты одновременного выполнения (concurrency) для пула воркеров, обслуживающего каждую очередь: например, 3 для Twitter и 25 для General Web. Для управления графиком повторных попыток используйте Sorted Set в Redis, регистрируя временную метку возобновления в качестве оценки (score). Применение такой структуры «переборки» гарантирует, что даже если API какой-то соцсети будет заблокировано, в режим ожидания уйдут только соответствующие воркеры, а общая эффективность завершения исследовательских задач агента останется на уровне более 95%.
Сырые данные, случайно собранные из различных веб-источников, могут содержать несовпадения в датах или ложные факты, что легко может привести к искаженным выводам LLM. Перед подачей контекста в генеративную ИИ-модель необходимо интегрировать в конец конвейера дискретный уровень проверки, который вычисляет достоверность содержимого Markdown-файлов и проверяет числовую непротиворечивость; это поможет блокировать галлюцинации.
Разработайте класс детерминированного фильтра, который вычисляет временную актуальность собранных метаданных и вес источника. Документы, содержащие временные метки из будущего относительно системного времени или даты в неверном формате ISO, следует немедленно исключать из набора данных. Также объявите словарь, отображающий веса доверия для каждого источника платформы: например, 0.95 для GitHub, 0.90 для Wikipedia, и более низкие базовые оценки для социальных сетей, таких как Reddit (0.50) или Twitter (0.40). Реализуйте логику, добавляющую бонус веса метаданных 0.05 только в том случае, если имя автора и заголовок внутри документа полностью сохранены; на основе этого формируется итоговая оценка доверия. Информационные активы, оценка которых ниже пороговой, исключаются на этапе сборки промпта для LLM.
Для окончательного подтверждения качества выходных данных запустите скрипт оценки, который сопоставляет сгенерированные ответы с исходным контекстом.
\b\d+(?:\.\d+)?%?\b), вычислите пересечение наборов числовых символов в исходном наборе данных и в сгенерированном предложении. Если обнаружены произвольные числа или денежные единицы, отсутствующие в источнике, установите флаг числового несоответствия и немедленно запросите повторное выполнение через middleware маршрутизации.Благодаря интеграции такого многослойного уровня проверки, проблемы манипуляции цифрами и ложных цитат, совершаемые агентами на основе краулинга, блокируются на архитектурном уровне, а конечный пользователь получает только полностью проверенные результаты исследований.