ЭкспериментЭксперименты

Куда исчезли 18 секунд: раскладываю задержку AI-агента по карманам

Интерактивный калькулятор показывает, сколько времени съедают модель, токены, инструменты и повторные проходы агента. Можно покрутить параметры и сразу увидеть узкое место.

21 июля 2026 г.2 минут чтения

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

Потом разложил один запуск на части и обнаружил, что модель честно работала меньше половины времени. Остальное съели три похода в инструменты, повторное чтение контекста и один особенно задумчивый API.

Из чего складывается ожидание

Для грубой оценки мне хватило пяти величин:

  1. Время до первого токена. Модель принимает контекст и готовит начало ответа.
  2. Скорость генерации. Количество выходных токенов делю на токены в секунду.
  3. Вызовы инструментов. База данных, браузер, shell или внешний API отвечают со своей задержкой.
  4. Повторные проходы. После результата инструмента модель снова читает контекст и принимает решение.
  5. Служебный запас. Сеть, сериализация и очередь редко спрашивают разрешения перед тем, как откусить ещё полсекунды.

Упрощённая формула выглядит так:

total = rounds × (first_token + output_tokens / tokens_per_second)
      + tool_calls × tool_latency
      + network_overhead

Она не заменяет трассировку. Зато быстро показывает порядок величин и помогает выбрать первый замер.

Если полоса инструментов длиннее полосы модели, смена LLM почти ничего не ускорит. Проверено способом «потратил вечер и вернулся к тому же API» :D

Покрутить задержку руками

Ниже живёт небольшой калькулятор. Я добавил несколько пресетов: чат без инструментов, RAG-поиск и многошаговый агент. Ползунки пересчитывают диаграмму сразу в браузере.

Что измерять в настоящем сервисе

Калькулятор даёт гипотезу. В рабочем агенте я отдельно записываю четыре времени:

  • запрос ушёл к модели;
  • появился первый токен;
  • начался и закончился каждый инструмент;
  • завершился весь запуск.

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

Самый дешёвый способ ускориться

Сначала убираю лишний проход агента. Потом параллелю независимые инструменты и кеширую стабильные ответы. Модель меняю уже после этих двух шагов.

Иногда результат получается немного обидным: самая дорогая оптимизация была открыта в соседней вкладке, а самая полезная помещалась в один Promise.all.

Живой экспериментНа весь экран ↗