Главная / Статьи / Как выбрать LLM-провайдера: ограничения, маршрутизация и обратимые решения

Как выбрать LLM-провайдера: ограничения, маршрутизация и обратимые решения

Пять ограничений, которые решают выбор между закрытыми, open-weight и self-hosted моделями, плюс код, не привязанный к провайдеру, уровни маршрутизации, расчёт стоимости и чек-лист по безопасности.

1597 слов

Команды всё спрашивают, какая модель лучшая, будто выбор — это дегустация. У такого вопроса короткий срок годности. Цены провайдеров за первую половину 2026 года менялись дважды, и все крупные лаборатории за то же время выпустили новые версии моделей. Компания, которая в январе намертво привязалась к одному вендору, уже увидела, как эта ставка устарела.

Вопрос получше состоит из трёх частей. Что требует эта нагрузка? Какой класс моделей эти требования закрывает? И насколько дёшево мы сможем переключиться через полгода? Если переезд к другому провайдеру означает переписывание, то вы сделали не архитектурный выбор. Вы обзавелись зависимостью.

Дальше — об ограничениях, которые на самом деле решают дело, и о структуре кода, которая сохраняет выбор обратимым.

Пять ограничений, которые всё решают

Пройдитесь по ним до того, как открывать любые таблицы бенчмарков.

Куда могут уходить ваши данные. Закрытые API-модели с каждым запросом пропускают данные через инфраструктуру вендора. Для регулируемых отраслей, медицинских карт или госконтрактов одного этого факта бывает достаточно, чтобы закрыть обсуждение. Тогда self-hosting или развёртывание в нужном регионе перестаёт быть вопросом денег и становится вопросом комплаенса.

Стоимость на продакшен-объёмах. Демо-трафик скрывает разброс. Бюджетные модели стоят около $0.10 за миллион входных токенов, а флагманские доходят до $25–30 за миллион выходных. При примерно миллионе диалогов в месяц хостинговые модели обходятся где-то в $15 000–75 000 ежемесячно. Небольшая дообученная модель на собственном железе может тянуть ту же нагрузку за несколько сотен долларов — при условии, что задача узкая и повторяющаяся.

Реальная сложность задачи. Большинство бизнес-нагрузок — это сортировка, извлечение, суммаризация и маршрутизация. Ни одной из них не нужно рассуждение флагманского уровня, так что дорогой уровень оставьте для сложного меньшинства.

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

Готовность к эксплуатации. Open-weight модели скачиваются бесплатно, но их запуск означает аренду GPU — примерно от $0.50 до $5.00 в час по мере роста моделей — и зарплаты инженерам, которые будут развёртывать, патчить и мониторить весь стек.

Шаг 1: сначала постройте шов

Определите абстракцию до того, как кого-то выбирать. Весь остальной код должен общаться с вашим интерфейсом и никогда — с SDK вендора.

class ModelProvider(Protocol):
    def complete(self, messages, *, max_tokens, tools=None) -> Completion: ...

class Router:
    def __init__(self, providers: dict[str, ModelProvider]):
        self.providers = providers
    def complete(self, messages, *, tier="standard", **kw):
        name = MODEL_FOR_TIER[tier]                # config, not code
        try:
            return self.providers[name].complete(messages, **kw)
        except (RateLimited, ProviderDown):
            fallback = FALLBACK_FOR_TIER[tier]     # different vendor entirely
            return self.providers[fallback].complete(messages, **kw)

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

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

Шаг 2: маршрутизируйте по задаче, а не по любимчику

Отправлять каждый запрос в одну модель — самая дорогая привычка в продакшен-AI. Разбейте работу на уровни.

MODEL_FOR_TIER = {
    "bulk":     "small_local",      # classification, extraction, tagging
    "standard": "mid_hosted",       # summaries, drafting, most chat
    "hard":     "frontier_hosted",  # multi-step reasoning, ambiguous cases
    "sensitive":"self_hosted",      # data that cannot leave your estate
}

def choose_tier(task, payload):
    if contains_regulated_data(payload):
        return "sensitive"                      # compliance overrides cost
    if task in {"classify", "extract", "tag", "route"}:
        return "bulk"
    if task == "reason" or payload.get("complexity") == "high":
        return "hard"
    return "standard"

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

Шаг 3: измеряйте на своей нагрузке

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

Устройте собственное сравнение на том же golden set, который защищает от регрессий.

def bake_off(candidates, cases):
    results = {}
    for name, provider in candidates.items():
        passed, cost, latencies = 0, 0.0, []

for case in cases:
            t0 = time.monotonic()
            out = provider.complete(case["messages"], max_tokens=800)
            latencies.append((time.monotonic() - t0) * 1000)
            passed += grade(out.text, case["expected"])
            cost += price(name, out.usage)
        results[name] = {
            "accuracy": passed / len(cases),
            "cost_per_1k_calls": (cost / len(cases)) * 1000,
            "p95_latency_ms": percentile(latencies, 95),
        }
    return results

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

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

Шаг 4: посчитайте цену до того, как связывать себя

def monthly_estimate(name, calls_per_month, avg_in, avg_out, cache_hit_rate=0.0):
    p = PRICING[name]                              # per million tokens
    billable_in = avg_in * (1 - cache_hit_rate) + avg_in * cache_hit_rate * p["cache_ratio"]

return calls_per_month * (
        (billable_in / 1_000_000) * p["input"]
        + (avg_out / 1_000_000) * p["output"]
    )
# Always run it at 10x expected volume before signing anything.

Два рычага сильно меняют итог, и о них часто забывают. Пакетная обработка обычно вдвое снижает тариф для несрочной работы. Кэширование промптов может сократить стоимость повторяющегося входа примерно на 90 процентов, а это огромная разница, когда каждый вызов несёт один и тот же длинный контекст.

Три семейства моделей

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

Open-weight модели через хостинг-провайдера стоят дешевле, легче переносятся и быстро улучшаются. Медианная стартовая цена флагманских открытых моделей выросла примерно с $0.48 в 2024 году до $1.35 в 2026-м, но это всё равно намного ниже закрытых тарифов. Одна оговорка: сторонние хостинги часто запускают модели с пониженной числовой точностью ради экономии, что может немного срезать качество, а их обещания по надёжности отличаются от обещаний исходной лаборатории.

Self-hosting даёт полный контроль над данными и никакой платы за токены. Платите вы мощностями GPU и временем инженеров, а патчи, масштабирование и аптайм — на вас. Это оправдано требованиями суверенитета данных или узкими задачами с большим объёмом, где небольшая дообученная модель обходит универсальную и по цене, и по точности.

Большинство зрелых систем используют все три, и это не нерешительность. Так и задумано.

Безопасность

  • Считайте требования к размещению данных входными данными для проектирования. Решите, какие типы данных где можно обрабатывать, ещё до выбора провайдера. Если добавить это в конце, проект умирает на проверке комплаенса.
  • Внимательно читайте условия обработки данных: сроки хранения, используются ли входные данные для обучения будущих моделей, список субпроцессоров и какой регион на самом деле отвечает на ваши запросы. Корпоративные договоры обычно отличаются от условий по умолчанию, а условия по умолчанию — это то, что вы получите, если никто не спросит.
  • Промпт — это исходящий поток данных. Всё, что в нём есть, уже покинуло ваш периметр, так что вычищайте лишнее до отправки, а не после.
  • Self-hosting перемещает риск, а не устраняет его. Теперь защищать веса — ваша забота, каждый эндпоинт инференса открыт для атак, а обновления становятся вашей работой. Внутренний эндпоинт инференса без аутентификации — частая и серьёзная находка.
  • Обращайтесь с API-ключами как с продакшен-учётными данными: отдельный ключ на каждое окружение и сервис, ротация, узкие права и лимиты расходов. Утёкший ключ — это риск для данных плюс счёт без потолка.
  • Фиксируйте версии моделей. Провайдеры тихо выводят модели из эксплуатации и обновляют их, и модель, изменившаяся у вас под ногами, может сломать поведение, которое вы проверили несколько месяцев назад. Зафиксируйте версию и прогоняйте golden set перед тем, как принять любое изменение.

Чек-лист

  • Один интерфейс, не привязанный к провайдеру, а детали вендоров — только в адаптерах
  • Выбор модели живёт в конфиге и меняется без деплоя
  • Фолбэк на другого вендора на случай сбоев и лимитов
  • Работа распределяется по уровням, вопрос комплаенса — раньше вопроса цены
  • Golden set прогоняется на каждом кандидате: точность, стоимость и задержка p95
  • Вызов инструментов и следование инструкциям оцениваются наравне с качеством ответов
  • Стоимость просчитана для объёма в десять раз выше ожидаемого
  • Пакетная обработка и кэширование везде, где позволяет нагрузка
  • Размещение данных определено для каждого класса данных до выбора провайдера
  • Версии зафиксированы и перепроверяются перед обновлением
  • Ключи ограничены по сервисам и имеют лимиты расходов

Напоследок

Кто говорит, что ответ — одна конкретная модель, описывает текущий месяц, а не вашу систему.

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

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

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