Три с половиной секунды ожидания — это вечность в мире AI
Представьте: ваш AI-агент думает быстрее, чем успевает получить данные из интернета. Абсурд? Стандартная ситуация. Когда я начал измерять реальную латентность поиска в production-агентах, цифры шокировали: 3.5 секунды на простой запрос. Пользователь успевал отвлечься, чат-бот замирал, агент "простаивал" дорогое GPU-время.
Три секунды — это не просто цифра. Это разница между "интеллектуальным помощником" и "медленным поисковиком". Пользователи сносят головы, когда агент думает секунду, но терпеть три секунды ожидания на поиск — уже нет.
Почему поиск такой медленный? Разбираем по косточкам
Типичный стек AI-агента выглядит так: LLM -> поисковый инструмент -> API поисковика -> парсинг HTML -> возврат в LLM. В каждом звене накапливается латентность. Но главные убийцы скорости — не там, где вы думаете.
| Этап | Латентность (мс) | Проблема |
|---|---|---|
| Поиск через Google API | 800-1200 | Rate limiting, географическая задержка |
| Парсинг HTML | 500-800 | Избыточные данные, медленные библиотеки |
| Семантическая фильтрация | 700-1000 | Ненужная перепроверка релевантности |
| Сериализация/десериализация | 200-400 | JSON туда-обратно между микросервисами |
Самый большой обман — "семантическая фильтрация". Агенты часто перепроверяют релевантность найденных результатов через второй вызов LLM. Звучит умно, на практике — лишние 700 мс. Если вы используете архитектуру с суб-агентами, как в нашей статье про суб-агентов, эта проблема знакома.
Пять конкретных шагов от 3500 мс к 700 мс
Никакой теории. Только то, что работает в production прямо сейчас.
1 Убиваем парсинг HTML — переходим на Markdown-экстракцию
BeautifulSoup и lxml — прошлый век для AI-агентов. Они парсят ВЕСЬ HTML, включая скрипты, стили, метатеги. Агентам нужен только текст. Решение: кастомные экстракторы, которые превращают HTML в чистый Markdown за один проход.
2 Распределённые прокси — обходим rate limiting
Google API блокирует после 100 запросов в день. Платные тарифы — дорого. Решение: пул из 10-20 residential прокси в разных регионах. Когда один прокси получает блокировку, агент автоматически переключается на следующий.
- Используйте прокси с низкой задержкой (менее 100 мс)
- Ротация по географическому принципу: Европа -> США -> Азия
- Кэширование результатов на 5 минут — одинаковые запросы не идут в сеть
Это снижает латентность поиска с 1200 мс до 400-600 мс. Плюс убирает зависимость от одного провайдера.
3 Parallel scraping — качаем 10 страниц одновременно
Типичная ошибка: агент получает 10 ссылок из поиска и качает их последовательно. 10 страниц × 500 мс = 5 секунд ожидания. Решение: асинхронный пул запросов.
Не используйте asyncio.gather без ограничений. 100 одновременных запросов убьют и ваш сервер, и целевые сайты. Ограничивайте пул 10-15 параллельными запросами, используйте semaphore.
Результат: 10 страниц скачиваются за 600-800 мс вместо 5000 мс. Если вам интересна тема эффективной параллельной работы, посмотрите нашу статью про оркестрацию агентов Beads — те же принципы, другой контекст.
4 Умная семантическая фильтрация — без лишнего LLM
Забудьте про "проверим релевантность через GPT-4". Вместо этого:
- Фильтруйте по домену сразу (нет смысла проверять википедию на релевантность запросу про последние новости)
- Используйте эмбеддинги + косинусное сходство вместо полноценного LLM-запроса
- Кэшируйте эмбеддинги популярных страниц
Если нужна максимальная скорость — используйте бинарные индексы, как в нашем руководстве про ускорение семантического поиска в 20 раз. Разница: 700 мс против 30 мс на проверку релевантности.
5 MCP-сервер как единая точка входа
Model Context Protocol — стандарт от Anthropic, который решает проблему "каждому агенту — свой поиск". Вместо того чтобы каждый агент реализовывал поиск по-своему, вы поднимаете один MCP-сервер поиска.
Архитектура, которая не тормозит
Собираем всё вместе:
| Компонент | Латентность до | Латентность после | Техника |
|---|---|---|---|
| Поисковый запрос | 1200 мс | 400 мс | Распределённые прокси + кэш |
| Загрузка страниц | 5000 мс (10 стр.) | 700 мс | Parallel scraping (пул 10) |
| Парсинг контента | 800 мс | 50 мс | Кастомный Markdown-экстрактор |
| Фильтрация | 700 мс | 30 мс | Бинарные эмбеддинги + кэш |
| ИТОГО | ~3500 мс | ~700 мс | -80% латентности |
Типичные ошибки, которые сведут оптимизацию на нет
Видел десятки проектов, где после оптимизации снова всё замедлялось. Причины всегда одни и те же.
- Синхронные вызовы в асинхронном коде. Один блокирующий вызов — и весь event loop встаёт. Проверяйте все библиотеки на asyncio-совместимость
- Логирование каждого запроса в базу. INSERT после каждого поиска добавляет 50-100 мс. Используйте batch-вставку или выносите логирование в отдельный поток
- Валидация ответов через Pydantic. Каждый раз, когда вы делаете SearchResponse(**data) — это 10-20 мс на сериализацию. В высоконагруженных системах это складывается
- DNS-кэширование не настроено. Каждый запрос к google.com начинается с DNS-резолвинга. Кэшируйте DNS на уровне ОС или используйте статические IP
Как проверить свой поиск прямо сейчас
Не верите цифрам? Проверьте на готовом API:
Я выложил оптимизированный поисковый endpoint на search.keiro-labs.com. Отправьте POST запрос с {"query": "последние новости про ИИ"} и замерьте время ответа. Средняя латентность — 650-750 мс с полным пайплайном (поиск + загрузка 5 страниц + экстракция). Код архитектуры открыт на GitHub.
Что делать, если 700 мс всё ещё много?
Для некоторых use-cases (high-frequency trading agents, real-time аналитика) даже 700 мс — неприемлемо. Тогда идём дальше:
- Pre-fetching. Если агент обсуждает определённую тему, заранее подгружаем связанные данные. Похоже на принцип из статьи про research agent от Tavily, но для латентности
- Edge-кэширование. Размещайте поисковые прокси в тех же регионах, что и пользователи. Европейский пользователь -> европейский прокси -> 200 мс вместо 400 мс
- Стриминг результатов. Не ждите, пока загрузятся все 10 страниц. Отправляйте результаты по мере готовности. Пользователь видит первый результат через 300 мс, остальные "догружаются"
Самое главное — измеряйте. Каждый день. Латентность имеет свойство "поползти вверх" при росте нагрузки. Настройте мониторинг с percentiles (p95, p99), а не только average. Если p99 латентности растёт — ищите новый bottleneck.
Не оптимизируйте то, что не измеряете. Типичная ошибка: команда месяц оптимизирует парсинг HTML, а потом выясняется, что основная задержка — в DNS. Используйте distributed tracing (Jaeger, Zipkin) или хотя бы детальное логирование с таймингами каждого этапа.
Будущее: поиск, который успевает за мыслью
Через год-два стандартом станет латентность 200-300 мс. Как этого добиться?
- Векторный поиск по предзагруженному интернету. Вместо live-поиска — семантический поиск по snapshot всего интернета (как у Perplexity). Латенция: 50 мс
- Специализированные ASIC для семантического поиска. Аналогично тому, как TPU ускорили inference, появятся чипы для эмбеддингов и поиска
- Локальные поисковые индексы. Зачем ходить в Google, если можно скачать компактный индекс Википедии и новостей (10-20 GB) и искать локально
Пока это звучит как фантастика, но помните: ещё два года назад RAG с латентностью 2 секунды считался "быстрым". Если вы проектируете AI-агентов сегодня, закладывайте архитектуру, которая выдержит переход на 200 мс. Это значит: асинхронность везде, минимальная сериализация, умное кэширование.
И последнее: не пытайтесь оптимизировать всё сразу. Начните с самого медленного этапа (подсказка: это почти всегда загрузка страниц). Снизили его латентность в 5 раз? Переходите к следующему bottleneck. Такой итеративный подход даёт видимый результат уже через неделю, а не через месяц теоретических оптимизаций.