Учебник

OpenRouter и Together AI: fallback и экономия на AI-запросах

Ваш бизнес использует AI-модели, и вдруг один провайдер «лёг» - заявки не обрабатываются, клиенты не получают ответ. Разбираем OpenRouter и Together AI: как настроить fallback (запасной канал) и снизить расходы на AI-запросы. Всё без программиста - через готовый API или простую настройку за час.

Макс Космов··9 мин чтения

Представьте: ваш бизнес уже использует AI-модель для обработки заказов или ответов клиентам. И вдруг провайдер «падает» - запросы не уходят, клиенты ждут, деньги теряются. Или вы замечаете, что счёт за AI-запросы вырос в три раза, а качество не изменилось. Знакомая боль?

Эта статья - про то, как не зависеть от одного провайдера и не переплачивать. Разберём два инструмента: OpenRouter (агрегатор 500+ моделей с автоматическим запасным каналом) и Together AI (инфраструктурный провайдер с собственным железом). Никакой магии - только конкретные шаги, которые можно внедрить за вечер без программиста.

OpenRouter и Together AI: в чём разница для вашего бизнеса

Главное различие - в бизнес-модели.

OpenRouter - это маршрутизатор. У него нет своих GPU. Он принимает ваш запрос и перенаправляет его на один из 50+ партнёрских провайдеров (Together, Fireworks, Groq и другие). Вы получаете единый API для 500+ моделей, единый счёт и автоматический fallback (запасной провайдер, если основной не ответил).

Together AI - это инфраструктурный провайдер. У него собственные кластеры H100, H200 и B200. 200+ моделей работают на его железе. Нет посредника - платите напрямую за вычислительные ресурсы. Плюс можно дообучать модели под свои задачи (fine-tuning).

Разберём на примере стройфирмы. У вас есть прайс на работы и типовой договор подряда. Вы хотите, чтобы AI-модель отвечала клиентам на вопросы по ценам. Если провайдер «упадёт» - клиенты не получат ответ. OpenRouter автоматически переключит запрос на другого провайдера. Together AI даст более низкую цену, если вы стабильно используете одну модель. В боевая среда-архитектуре их часто используют вместе: Together как основной провайдер, OpenRouter как запасной.

OpenRouter: 500+ моделей и защита от пустых трат

OpenRouter собирает практически всё, что есть на рынке открытых моделей. Каталог включает все основные варианты Llama, Qwen, DeepSeek, Mistral, а также проприетарные модели Claude (Anthropic), GPT (OpenAI), Gemini (Google) - через тот же API.

Zero Completion Insurance: если провайдер не вернул ответ из-за своей ошибки - OpenRouter не списывает токены. Вы не платите за «ничего». Это защита от ситуации, когда запрос ушёл, провайдер упал на полпути, а деньги списались.

Автоматический fallback: если первый провайдер вернул ошибку - OpenRouter автоматически перепробует других провайдеров для той же модели. Ваш код даже не заметит сбоя.

Подключение через OpenAI-совместимый API:

import os
from openai import OpenAI

client = OpenAI(
 api_key=os.environ["OPENROUTER_API_KEY"],
 base_url="https://openrouter.ai/api/v1"
)

response = client.chat.completions.create(
 model="meta-llama/llama-4-maverick",
 messages=[{"role": "user", "content": "Привет"}],
 extra_headers={
 "HTTP-Referer": "https://your-app.com",
 "X-Title": "Your App Name"
 }
)

HTTP-Referer и X-Title - рекомендуемые заголовки для аналитики. Не обязательны, но хороший тон.

Together AI: дешевле, быстрее, с дообучением

Together AI в 2026 работает на кластерах NVIDIA B200 - новейшее железо. Почему Together без посредника иногда выгоднее, чем та же модель через OpenRouter:

  • Нет 5-10% наценки агрегатора
  • Прямой SLA с Together, не с посредником
  • Доступен fine-tuning (дообучение модели под ваши данные) - через OpenRouter это недоступно

Fine-tuning - ключевая возможность для серьёзных продуктов. Например, вы можете дообучить модель на своих типовых ответах клиентам, чтобы она точнее отвечала на вопросы по вашему бизнесу.

# Together AI fine-tuning через их нативный SDK
from together import Together

client = Together(api_key=os.environ["TOGETHER_API_KEY"])

# Создаём fine-tuning job
job = client.fine_tuning.create(
 training_file="file-abc123", # JSONL файл загруженный заранее
 model="meta-llama/Llama-3.3-70B-Instruct-Reference",
 n_epochs=3,
 learning_rate=2e-5,
 batch_size=8,
 suffix="my-domain-v1"
)

print(f"Job ID: {job.id}")

# Мониторинг обучения
status = client.fine_tuning.retrieve(job.id)
print(f"Статус: {status.status}")
# После завершения - модель доступна как 'account/model-suffix'

Fine-tuning через Together: загрузка данных, обучение, развёртывание - всё в одной экосистеме. Стоимость зависит от числа токенов в датасете и числа эпох.

Маршрутизация в OpenRouter: задаём приоритет провайдеров

OpenRouter позволяет явно управлять маршрутизацией через параметр provider. Например, вы хотите сначала пробовать Together, потом Fireworks, потом DeepInfra - и разрешить fallback.

response = client.chat.completions.create(
 model="meta-llama/llama-4-maverick",
 messages=[{"role": "user", "content": "Привет"}],
 extra_body={
 "provider": {
 "order": ["Together", "Fireworks", "DeepInfra"], # приоритет провайдеров
 "allow_fallbacks": True,
 "data_collection": "deny" # не разрешать обучение на данных
 }
 }
)

order - список провайдеров по приоритету. OpenRouter попробует первый, при ошибке перейдёт ко второму.

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

data_collection: "deny" - запрет на использование данных запроса для обучения моделей у провайдера.

Маршрутизация по цене: параметр sort: "price" заставляет OpenRouter выбирать самого дешёвого провайдера для данной модели автоматически.

extra_body={
 "provider": {
 "sort": "price" # автоматически выбирает дешёвейший провайдер
 }
}

LiteLLM как локальный роутер: единый config.yaml

LiteLLM - опенсорс-прослойка, которую можно запустить на своём сервере. Ценность: один config.yaml описывает все провайдеры, а ваш код обращается к единому LiteLLM-серверу через стандартный OpenAI-формат.

Установка и запуск (команды выполняются в терминале):

pip install litellm

# Создаём config.yaml
cat > litellm_config.yaml << 'EOF'
model_list:
 - model_name: llama-4-maverick
 litellm_params:
 model: together_ai/meta-llama/Llama-4-Maverick
 api_key: os.environ/TOGETHER_API_KEY

 - model_name: llama-4-maverick # тот же alias - fallback
 litellm_params:
 model: openrouter/meta-llama/llama-4-maverick
 api_key: os.environ/OPENROUTER_API_KEY

 - model_name: deepseek-flash
 litellm_params:
 model: deepseek/deepseek-v4-flash
 api_key: os.environ/DEEPSEEK_API_KEY

 - model_name: deepseek-flash # fallback через OpenRouter
 litellm_params:
 model: openrouter/deepseek/deepseek-v4-flash
 api_key: os.environ/OPENROUTER_API_KEY

litellm_settings:
 fallbacks:
 - {"llama-4-maverick": ["openrouter/meta-llama/llama-4-maverick"]}
 set_verbose: false
EOF

# Запуск прокси
litellm --config litellm_config.yaml --port 8000

Теперь ваш код обращается к localhost:8000 с OpenAI-форматом:

client = OpenAI(base_url="http://localhost:8000", api_key="anything")

response = client.chat.completions.create(
 model="llama-4-maverick", # LiteLLM роутит на Together
 messages=[{"role": "user", "content": "Привет"}]
)

LiteLLM автоматически переключится на OpenRouter, если Together недоступен. Код приложения не меняется.

Стратегия cost optimization: сначала дешёвый, потом fallback

Архитектурный паттерн для экономии. Сначала пробуем самого дешёвого провайдера, при ошибке переходим к более дорогому.

import os
from openai import OpenAI
from typing import Optional

class CostOptimizedRouter:
 """Роутер: дешёвый провайдер первым, fallback на качество при ошибке"""
 
 MODELS_BY_COST = [
 {
 "client_key": "DEEPSEEK_API_KEY",
 "base_url": "https://api.deepseek.com",
 "model": "deepseek-v4-flash",
 "cost_per_1m_input": 0.14
 },
 {
 "client_key": "TOGETHER_API_KEY",
 "base_url": "https://api.together.xyz/v1",
 "model": "meta-llama/Llama-4-Maverick",
 "cost_per_1m_input": 0.15
 },
 {
 "client_key": "OPENROUTER_API_KEY",
 "base_url": "https://openrouter.ai/api/v1",
 "model": "anthropic/claude-sonnet-4-5", # emergency fallback
 "cost_per_1m_input": 3.00
 }
 ]
 
 def complete(self, messages: list, max_tokens: int = 1000) -> Optional[str]:
 for provider in self.MODELS_BY_COST:
 try:
 client = OpenAI(
 api_key=os.environ[provider["client_key"]],
 base_url=provider["base_url"]
 )
 response = client.chat.completions.create(
 model=provider["model"],
 messages=messages,
 max_tokens=max_tokens,
 timeout=15
 )
 return response.choices[0].message.content
 except Exception as e:
 print(f"Провайдер {provider['base_url']} недоступен: {e}")
 continue
 
 return None # все провайдеры упали

router = CostOptimizedRouter()
result = router.complete([{"role": "user", "content": "Что такое RAG?"}])

Мониторинг: Helicone поверх OpenRouter

Helicone - SaaS-прослойка для логирования и аналитики. Не требует изменения кода - только смена base_url.

client = OpenAI(
 api_key=os.environ["OPENROUTER_API_KEY"],
 base_url="https://oai.helicone.ai/v1" # Helicone как прокси
)

# Добавляем заголовки Helicone
response = client.chat.completions.create(
 model="meta-llama/llama-4-maverick",
 messages=[{"role": "user", "content": "Привет"}],
 extra_headers={
 "Helicone-Auth": f"Bearer {os.environ['HELICONE_API_KEY']}",
 "Helicone-Target-URL": "https://openrouter.ai",
 "Helicone-Property-Session": "user-123", # кастомные теги
 "Helicone-Property-Version": "prompt-v2.1"
 }
)

Helicone-дашборд показывает:

  • Стоимость по моделям и провайдерам
  • Задержку (TTFT, генерация)
  • Ошибки и повторные попытки
  • Версионирование промптов с A/B сравнением
  • Стоимость на пользователя/сессию через Property теги

Бесплатный план: 10 000 запросов/месяц. Хватит для малых проектов.

Архитектурный паттерн: primary / fallback / emergency

Проверенный подход для боевой среды:

Первичный провайдер (primary):
 - Оптимальная цена/качество для вашей задачи
 - Например: DeepSeek V4 Flash для простых задач
 - SLA: best-effort

fallback провайдер:
 - Тот же класс качества, другой провайдер
 - Например: Together AI Llama 4 Maverick
 - Активируется при ошибках от primary

Emergency провайдер:
 - Гарантированная доступность (OpenAI, Anthropic)
 - Дороже, но с SLA
 - Активируется при падении primary + fallback
 - Желательно иметь бюджетный алерт

LiteLLM реализует этот паттерн через config с несколькими алиасами на одну модель-имя. OpenRouter - через provider.order. Для крупного боевая среда LiteLLM даёт больше контроля, OpenRouter проще для старта.

Бюджетные алерты: установите alert при превышении $X/день через LiteLLM (max_budget) или Helicone (budget alerts) - это спасёт от неожиданных счетов при петлях или DDoS.

Сравнение моделей через единый API: A/B тестирование

Один из сильных паттернов OpenRouter - сравнивать разные модели на одних данных через единый API:

import asyncio
from openai import AsyncOpenAI
from typing import List, Tuple
import time

client = AsyncOpenAI(
 api_key=os.environ["OPENROUTER_API_KEY"],
 base_url="https://openrouter.ai/api/v1"
)

MODELS_TO_COMPARE = [
 "deepseek/deepseek-v4-flash",
 "meta-llama/llama-4-maverick",
 "qwen/qwen3.7-max",
 "mistralai/mistral-large-2407"
]

async def test_one_model(model: str, prompt: str) -> dict:
 start = time.time()
 try:
 response = await client.chat.completions.create(
 model=model,
 messages=[{"role": "user", "content": prompt}],
 max_tokens=500,
 temperature=0.3,
 extra_headers={
 "HTTP-Referer": "https://your-eval.com",
 "X-Title": "Model Benchmark"
 }
 )
 elapsed = time.time() - start
 return {
 "model": model,
 "response": response.choices[0].message.content,
 "input_tokens": response.usage.prompt_tokens,
 "output_tokens": response.usage.completion_tokens,
 "elapsed_sec": round(elapsed, 2),
 "error": None
 }
 except Exception as e:
 return {"model": model, "response": None, "error": str(e)}

async def benchmark_models(test_prompts: List[str]):
 results = []
 for prompt in test_prompts:
 print(f"\nТест: {prompt[:60]}...")
 tasks = [test_one_model(m, prompt) for m in MODELS_TO_COMPARE]
 prompt_results = await asyncio.gather(*tasks)
 results.append({"prompt": prompt, "results": prompt_results})
 
 # Вывод сравнения
 for r in prompt_results:
 if r["error"]:
 print(f" {r['model']}: ОШИБКА - {r['error']}")
 else:
 tok_per_sec = r["output_tokens"] / r["elapsed_sec"]
 print(f" {r['model']}: {r['elapsed_sec']}с, {tok_per_sec:.0f} tok/s")
 
 return results

test_cases = [
 "Напиши функцию бинарного поиска на Python с тестами",
 "Объясни принцип работы BERT в 3 абзацах",
 "Переведи на русский: The attention mechanism allows models to focus on relevant parts of the input"
]

results = asyncio.run(benchmark_models(test_cases))

Такой benchmark за 5-10 минут даёт конкретные цифры по скорости и качеству для вашей задачи - лучше, чем полагаться на общие leaderboard.

Together AI Custom Models: дообучение и развёртывание

Дообучение через Together - полный цикл от данных до развёртывания:

from together import Together
import json

client = Together(api_key=os.environ["TOGETHER_API_KEY"])

# Шаг 1: подготовка данных в формате JSONL
training_data = [
 {
 "messages": [
 {"role": "user", "content": "Как исправить ошибку KeyError в Python?"},
 {"role": "assistant", "content": "KeyError возникает когда ключ не найден в словаре. Проверьте наличие ключа через `if key in dict` или используйте `dict.get(key, default)`"}
 ]
 },
 # ... ещё сотни примеров
]

with open("/tmp/train.jsonl", "w") as f:
 for item in training_data:
 f.write(json.dumps(item, ensure_ascii=False) + "\n")

# Шаг 2: загрузка файла
with open("/tmp/train.jsonl", "rb") as f:
 uploaded = client.files.upload(file=("train.jsonl", f))
print(f"Файл загружен: {uploaded.id}")

# Шаг 3: запуск обучения
job = client.fine_tuning.create(
 training_file=uploaded.id,
 model="meta-llama/Llama-3.3-70B-Instruct-Reference",
 n_epochs=3,
 learning_rate=2e-5,
 lora=True, # LoRA для экономии ресурсов
 lora_r=16,
 suffix="python-support-v1"
)
print(f"Job: {job.id}, статус: {job.status}")

# Шаг 4: после обучения - использование
# Модель доступна как f"YOUR_ACCOUNT/{model_name}-python-support-v1"
custom_client = OpenAI(
 api_key=os.environ["TOGETHER_API_KEY"],
 base_url="https://api.together.xyz/v1"
)

response = custom_client.chat.completions.create(
 model="your-account/llama-3.3-70b-python-support-v1",
 messages=[{"role": "user", "content": "Как работает декоратор @property?"}],
 max_tokens=500
)

Дообученные модели развёртываются как обычные конечные точки Together - те же цены за токены, та же скорость.

Частые вопросы

OpenRouter берёт комиссию поверх цены провайдера?

На большинстве моделей - нет наценки или наценка минимальна (~0-5%). OpenRouter зарабатывает на платных фичах (OpenRouter API Pro) и на мелких моделях. Для популярных опенсорс-моделей цена через OpenRouter обычно совпадает или незначительно выше прямого провайдера. Точные цены - на openrouter.ai/models с разбивкой по провайдерам.

Как настроить автоматический fallback если один провайдер недоступен?

Три способа: (1) OpenRouter с allow_fallbacks: true в provider параметре - работает «из коробки»; (2) LiteLLM с несколькими записями с одним model_name - автоматический failover; (3) собственная логика retry с несколькими клиентами. Для быстрого старта - OpenRouter, для полного контроля - LiteLLM.

LiteLLM - это то же самое что OpenRouter?

Нет. LiteLLM - это SDK/прокси, который вы запускаете сами (self-hosted). OpenRouter - облачный сервис. LiteLLM объединяет ваши API-ключи разных провайдеров в единый интерфейс без передачи запросов через третью сторону. OpenRouter - посредник, который направляет ваши запросы через свои серверы. LiteLLM лучше для privacy и полного контроля, OpenRouter - для быстрого старта без своей инфраструктуры.

Together AI поддерживает дообучение опенсорс-моделей?

Да, это одно из ключевых преимуществ Together. Поддерживаются Llama 3.x, Mistral, Mixtral и ряд других. Формат: JSONL с парами prompt/completion, загрузка через API, обучение на кластерах Together, развёртывание в ваш private конечная точка API. Дообучение через OpenRouter недоступно - нужен прямой Together API.

Как выбрать между OpenRouter и прямыми API провайдеров для продакшна?

OpenRouter - правильный выбор, когда: нужны 5+ разных моделей, важен fallback без своего кода, нет времени на настройку LiteLLM. Прямые API (Together, DeepSeek, Moonshot) - когда: максимальная экономия критична, нужно дообучение, используете 1-2 модели стабильно. Для большинства боевая среда систем: начать с OpenRouter, перейти на прямой API для высоконагруженных маршрутов, когда наценка станет ощутимой.

Что дальше

Ваш следующий шаг: зарегистрироваться на OpenRouter (openrouter.ai), получить API-ключ и подключить его к вашему текущему AI-решению. Это займёт 15 минут. Если используете Together - заведите аккаунт и попробуйте дообучить модель на 50-100 примерах ваших ответов. Бесплатного плана Together хватит для теста.

AI Компас (t.me/kosmoslab_ai) - канал для предпринимателей в РФ и СНГ, которые применяют AI в своём бизнесе без программиста. Разбираем инструменты и схемы - без курсов и теории.