# OpenRouter меняет провайдера сам — как это ломает продакшен и что с этим делать
Каноническая страница: https://plainews.ru/posts/openrouter-provider-routing-problem
Опубликовано: 2026-09-13T07:01:14.813Z

OpenRouter автоматически выбирает провайдера под капотом, и один и тот же запрос может вести себя по-разному. Разбираем, где ломается, и как зафиксировать провайдера через provider.only.
OpenRouter продаёт себя как один API для сотен моделей: указал model ID, а сервис сам подберёт самого дешёвого и доступного провайдера. Звучит удобно, пока в один прекрасный день ответы модели не начинают вести себя иначе — без изменений в вашем коде. Разработчик Мохамед Мустафа собрал список причин, почему так происходит, и что с этим делать до того, как это сломает ваш продакшен.

## Зачем вообще нужен этот автоматический роутинг

Идея OpenRouter в том, чтобы дать разработчику один эндпоинт вместо десятка SDK разных провайдеров. Вы меняете base_url на https://openrouter.ai/api/v1, подставляете свой ключ OpenRouter — и получаете доступ к моделям OpenAI, Anthropic, Google, Meta и других через единый интерфейс, максимально похожий на OpenAI SDK.

Под капотом сервис сам решает, к какому бэкенд-провайдеру отправить запрос: он «handles fallbacks automatically and picks the most cost-effective option for each request» — то есть автоматически переключается между провайдерами при сбоях и выбирает самый выгодный вариант по цене. Для многих сценариев это плюс: меньше даунтайма, ниже счета.

Проблема в том, что за одним model ID у OpenRouter могут стоять несколько разных провайдеров, которые физически хостят одну и ту же модель на разном софте для инференса (serving software — программный стек, который запускает модель и обрабатывает запросы). А разный софт — это разные оптимизации, разные настройки по умолчанию и разное поведение на одних и тех же входных данных.

## Что именно ломается на практике

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

Во-первых, не все провайдеры одной и той же модели поддерживают одинаковый набор возможностей. Например, у некоторых провайдеров может отсутствовать поддержка vision (обработка изображений) даже для модели, которая формально заявлена как vision-capable — то есть умеющая работать с картинками. Если ваш роутинг случайно попадёт на такого провайдера, запрос с картинкой либо упадёт с ошибкой, либо будет обработан не так, как вы ожидали.

Во-вторых, по-разному обрабатывается параметр reasoning effort (степень усилий на рассуждение — настройка, которая управляет тем, сколько «размышлений» модель тратит перед финальным ответом у reasoning-моделей вроде o1/o3 или похожих). Один провайдер может честно передавать это значение в модель, другой — интерпретировать его иначе или вовсе игнорировать. В итоге одна и та же настройка в вашем коде даёт разное качество и разную скорость ответа в зависимости от того, куда вас в этот раз направил роутер.

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

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

## Как зафиксировать конкретного провайдера

Хорошая новость: OpenRouter даёт способ обойти автоматический выбор — параметр provider.only, который явно ограничивает список провайдеров, куда может уйти запрос.

Пример через прямой HTTP-запрос:

```bash
curl https://openrouter.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $OPENROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-3.5-sonnet",
    "provider": {
      "only": ["anthropic"]
    },
    "messages": [
      {"role": "user", "content": "Проверь этот запрос на конкретном провайдере"}
    ]
  }'
```

Тот же принцип работает и через OpenAI-совместимый Python SDK — вы просто передаёте дополнительное поле provider в теле запроса:

```python
from openai import OpenAI

client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="ВАШ_OPENROUTER_API_KEY",
)

response = client.chat.completions.create(
    model="anthropic/claude-3.5-sonnet",
    extra_body={
        "provider": {
            "only": ["anthropic"]
        }
    },
    messages=[
        {"role": "user", "content": "Тестовый запрос с фиксированным провайдером"}
    ],
)

print(response.choices[0].message.content)
```

Если провайдер, который вы указали в only, недоступен в момент запроса, вы получите явную ошибку вместо тихого переключения на альтернативу — это и есть цель: лучше упасть предсказуемо, чем незаметно получить другое поведение модели.

## Как узнать, какие провайдеры вообще доступны для модели

Прежде чем фиксировать провайдера, нужно понять, кто вообще стоит за конкретным model ID. Для этого у OpenRouter есть метод /endpoints, который возвращает список всех доступных провайдеров для указанной модели.

```bash
curl https://openrouter.ai/api/v1/models/anthropic/claude-3.5-sonnet/endpoints \
  -H "Authorization: Bearer $OPENROUTER_API_KEY"
```

Ответ придёт в JSON и будет содержать список провайдеров с их параметрами — включая поддерживаемые возможности, лимиты по контексту и цены за токен:

```json
{
  "data": {
    "id": "anthropic/claude-3.5-sonnet",
    "endpoints": [
      {
        "provider_name": "anthropic",
        "context_length": 200000,
        "supports_vision": true
      },
      {
        "provider_name": "another-provider",
        "context_length": 128000,
        "supports_vision": false
      }
    ]
  }
}
```

Этот список стоит сверять перед тем, как выбирать модель для vision-задач или reasoning-сценариев — иначе легко наткнуться на провайдера, у которого нужной вам возможности просто нет.

## Где ломается и что с этим делать

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

Вторая типичная проблема — тестировать интеграцию один раз и считать её стабильной навсегда. Роутинг OpenRouter динамический: провайдер, который отвечал вчера, может быть недоступен сегодня из-за перегрузки или изменения цен, и запрос уйдёт к другому. Если у вас нет мониторинга того, какой провайдер реально обработал запрос (это видно в ответе API в поле provider), отладка странного поведения превращается в гадание.

Третье — reasoning effort и другие тонкие параметры лучше явно тестировать на каждом провайдере из списка /endpoints, а не полагаться на то, что все они интерпретируют параметр одинаково.

## Что попробовать дальше

Для критичных продакшен-сценариев имеет смысл держать provider.only с конкретным провайдером как значение по умолчанию, а автоматический роутинг оставлять только для некритичных или экспериментальных запросов, где важна цена, а не стабильность поведения. Периодически проверяйте /endpoints для используемых моделей — список провайдеров и их возможностей меняется, и то, что работало вчера, может выглядеть иначе через месяц.

## FAQ

### Что такое provider.only в OpenRouter?

Это параметр в теле запроса, который ограничивает список провайдеров, куда OpenRouter может направить ваш запрос. Указав конкретного провайдера, вы отключаете автоматический выбор и получаете предсказуемое поведение модели.

### Почему один и тот же промпт даёт разные ответы через OpenRouter?

Потому что за одним model ID может стоять несколько провайдеров с разным serving-софтом, оптимизациями и обработкой параметров вроде reasoning effort. Роутер может выбирать разного провайдера от запроса к запросу.

### Как узнать, какие провайдеры доступны для модели?

Через метод /endpoints, например GET /api/v1/models/{model}/endpoints. Ответ содержит список провайдеров с их возможностями — включая поддержку vision, лимит контекста и цены.

### Замедлит ли фиксация провайдера мои запросы?

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

### Стоит ли вообще использовать OpenRouter, если есть такие подводные камни?

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

## Источники

- Simon Willison: So you want to use OpenRouter?
