Как мы переработали маршрутизацию провайдеров для более качественного и быстрого инференса

Источник: OpenRouter Blog•

Как мы переработали маршрутизацию провайдеров для более качественного и быстрого инференса

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

Сегодня мы объявляем о самом крупном улучшении нашего алгоритма маршрутизации провайдеров с момента основания OpenRouter.

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

Это уже работает. Новый алгоритм обеспечил значительные улучшения в показателях времени до первого токена — TTFT (на 16,9%), пропускной способности (на 16,3%) и ошибок вместимости (замечательное сокращение на 67%!) при лишь незначительном росте стоимости (на 6,0%). И это до того, как провайдеры успели оптимизировать свою работу под новый алгоритм. Подробности см. в наших полных результатах экспериментов.

Как это работает:

  • Он измеряет то, что вы получаете на самом деле. Для каждой модели он отслеживает фактическую цену, задержку, пропускную способность и частоту ошибок каждой конечной точки, а также выбирает оптимальное сочетание стоимости и производительности для каждого запроса.
  • Он реагирует в реальном времени. Если у конечной точки возникают проблемы, трафик перенаправляется от нее до тех пор, пока она не восстановится.
  • Он вознаграждает лучший инференс. Провайдеры, которые внедряют инновации, автоматически вознаграждаются большим объемом трафика.

Маршрутизация по-прежнему учитывает кэш, поэтому, как только мы направили вас к провайдеру, ваша сессия остается там же, пока кэш остается актуальным.

Хотите маршрутизацию только по цене? Вы по-прежнему можете ее использовать. Подробнее см. в разделах «Закрепление и сортировка провайдеров» и «Что остается неизменным».

С чего мы начинали: ограничения маршрутизации только по цене

Большая часть трафика (~77% запросов) на OpenRouter приходится на модели, обслуживаемые несколькими провайдерами. Когда запрос не содержит явной сортировки или списка провайдеров, нам нужно выбрать провайдера для его отправки. До сих пор мы делали этот выбор практически полностью на основе цены входных токенов. Чем дешевле был провайдер, тем большую доля трафика он получал, а любые неудачные запросы перенаправлялись на следующий самый дешевый вариант.

Этот подход, основанный исключительно на цене, обеспечивал пользователям самые низкие цены в экосистеме, но он породил и непредвиденные последствия:

  • Дешевизна побеждала, даже если качество было плохим. Резервные механизмы перехватывали сбои, но пользователи были вынуждены ждать их завершения, а улучшения скорости никак не вознаграждались.
  • Статичные рейтинги. Алгоритм не учитывал колебания производительности в реальном времени, поэтому показатели провайдера должны были ухудшиться до полного исключения из рейтинга, прежде чем это отразилось бы на распределении трафика.
  • Исчезающая маржа. Единственным способом для провайдеров получить трафик было снижение цен, что заставляло их сокращать инвестиции в ту самую инфраструктуру, которая обеспечивает надежность и качество.
  • Ценовые игры. Цена, по которой мы ранжировали провайдеров, почти полностью состояла из стоимости входных токенов (промпта), поэтому провайдер мог сохранять долю трафика с помощью странных ценовых комбинаций — например, указывая искусственно заниженную цену входа, а затем компенсируя разницу за счет переоцененных кэшированных или выходных токенов.

Мы хотели создать рынок, на котором конкурирующие провайдеры получают трафик за счет более качественного инференса, а не только за счет более дешевого.

Новый алгоритм: оптимизация стоимости «хорошего ответа»

Новый алгоритм маршрутизации постоянно отслеживает производительность каждого провайдера, чтобы вычислять стоимость маршрутизации в реальном времени (Routing Cost), которая отражает то, сколько пользователь платит за качественный ответ. Стоимость маршрутизации включает в себя цену в реальных долларах и центах, стоимость времени ожидания ответа, а также стоимость повторных попыток в случае сбоя провайдера или выдачи непригодного ответа.

Проще говоря: какова цена одной попытки и как часто она срабатывает?

Во что обходится одна попытка: цена плюс ожидание

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

Эффективная цена

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

Маршрутизатор оценивает ваш запрос по эффективной цене каждого провайдера и отдает приоритет самым дешевым вариантам.

Пропускная способность

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

Время до получения первого токена

Время до получения первого токена (TTFT) — это время, которое вы ждете до начала потоковой передачи ответа. Оно увеличивает стоимость маршрутизации само по себе, даже если оно уже учитывается в пропускной способности, поскольку интерактивное использование зависит от него больше всего. В агентской сессии модель может делать много вызовов инструментов подряд, и каждый из них ожидает первый токен.

Лимиты запросов

Лимит запросов (ошибка HTTP 429) означает, что у провайдера закончилась емкость и он отклонил ваш запрос. Вам придется ждать отказа, после чего ваш запрос полностью уйдет к другому провайдеру. Маршрутизатор добавляет это время ожидания плюс штраф к стоимости маршрутизации провайдера с поправкой на то, как часто он ограничивает частоту запросов, поэтому эффект обычно невелик. Повторяющиеся лимиты запросов имеют большее значение через ограничения трафика и экспоненциальные задержки (backoff), описанные ниже.

Как часто это работает: надежность и качество

Неудачная попытка все равно стоит своей цены и времени ожидания, поэтому стоимость маршрутизации рассчитывает ожидаемые затраты на повторные попытки до тех пор, пока одна из них не увенчается успехом. Если 1 попытка из 5 терпит неудачу, вы платите за 1,25 попытки на один хороший ответ.

Надежность

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

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

Качество

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

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

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

Поверх этого работают три защитных механизма:

  • Минимум: каждый провайдер получает небольшой поток трафика, чтобы мы могли заметить, когда испытывающие трудности эндпоинты улучшают свои показатели. Новые эндпоинты начинают со стандартных для модели показателей, поэтому им не требуется история трафика.
  • Откат: провайдер, у которого начинают возникать сбои или ограничения частоты запросов (rate limiting), получает меньше трафика до своего восстановления.
  • Ограничение: маршрутизатор определяет, какую нагрузку может выдержать каждый провайдер до выдачи ошибок 429, и перенаправляет излишки остальным. При увеличении емкости лимит возрастает автоматически.

Что остается прежним

  • Запросы, в которых задан параметр provider.order, обходят новую логику маршрутизации, а провайдеры упорядочиваются указанным образом (по умолчанию, как и раньше, используется сортировка по цене). Установка параметров provider.only или provider.ignore задействует новый алгоритм для выбора среди оставшихся провайдеров, если их больше одного.
  • Явное указание provider.sort (цена, пропускная способность или задержка) использует эту сортировку вместо нового алгоритма.
  • Только для первого запроса в диалоге провайдер будет выбран алгоритмически. Текущий диалог закрепляется за исходным провайдером для сохранения кэша промптов. Если этот провайдер становится недоступным, диалог автоматически переключается на другого провайдера.
  • Если попытка завершается неудачей, запрос повторяется со следующим по рейтингу провайдером.

Как мы это измерили

Чтобы оценить влияние нового алгоритма маршрутизации, нам пришлось выйти за рамки стандартного A/B-тестирования, поскольку изменения в поведении маршрутизации непросто изолировать от контрольной группы. Например, если новый алгоритм эффективнее перенаправлял трафик от проблемного провайдера, запросы старого алгоритма к этому провайдеру обнаруживали бы больше доступной емкости и выполнялись быстрее, искажая результаты. Дополнительную сложность создает колоссальная вариативность формы запросов и паттернов объема. Один пользователь-«кит», запускающий автоматизированный шквал ресурсоемких запросов к одному провайдеру, может искусственно завысить показатели этого провайдера независимо от того, какой алгоритм мы использовали для маршрутизации его запросов.

Поэтому мы провели перекрестный эксперимент (switchback experiment): мы разделили каждый день на 3-часовые блоки и чередовали каждую подобранную пару блоков между новым и старым маршрутизатором, отбрасывая данные первого часа работы в качестве периода прогрева при каждом переключении, и измерили влияние на каждую модель на репрезентативной выборке моделей с открытым исходным кодом в течение полной недели.

Результаты

За неделю эксперимента мы распределили более 24 миллионов запросов со 103 миллиардами токенов ввода поровну между старым и новым алгоритмами маршрутизации, измерив влияние на ключевые показатели производительности.

Начало работы

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

Чтобы сохранить старую маршрутизацию исключительно по цене, установите для provider.sort значение "price", добавьте :floor к идентификатору (slug) модели или установите сортировку по цене по умолчанию в настройках аккаунта. Чтобы самостоятельно выбирать провайдеров, используйте provider.order или provider.only. См. руководство по маршрутизации провайдеров.

Часто задаваемые вопросы

Нужно ли мне менять свой код для использования новой маршрутизации?

Нет. Запросы без явной сортировки провайдеров и без списков provider.order, only или ignore автоматически используют новый маршрутизатор для тех моделей, где он включен. Ваш ключ API, тело запроса и идентификаторы моделей остаются прежними.

Как сохранить маршрутизацию только по цене?

Установите provider.sort в значение price в теле запроса, добавьте :floor к идентификатору модели или задайте сортировку провайдеров по умолчанию по цене в настройках аккаунта. Любая явная сортировка обходит новый маршрутизатор.

Переопределяет ли новая маршрутизация мой порядок провайдеров или список only?

provider.order обходит новый маршрутизатор и выполняет маршрутизацию в указанном вами порядке. provider.only и provider.ignore по-прежнему фильтруют набор кандидатов, но новый алгоритм выбирает среди оставшихся провайдеров.

Будет ли новая маршрутизация стоить дороже, чем маршрутизация только по цене?

Это возможно, так как иногда она выбирает более быстрый или надежный провайдер вместо самого дешевого. В нашем реальном эксперименте стоимость одного запроса выросла на 6,0%, при этом было достигнуто улучшение TTFT на 16,9%, улучшение пропускной способности на 16,3% и снижение частоты ошибок 429 на 67%.

Как провайдер может получить больше трафика при новой маршрутизации?

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

О чём эта статья

Ещё в разделе «AI и машинное обучение»

Все →

Ещё от OpenRouter