Перейти к содержимому

2.4 · OpenRouter: один API ко многим моделям

Неделя 2 · Основы LLM · ⏱ ~3 ч · Теория, Практика

В главе 2.3 · Обзор моделей и провайдеров мы собрали таблицу моделей, но выбирать по таблице нельзя: модель выбирают по своим evals. Чтобы прогнать один промпт через пять моделей пяти лабораторий, нужно пять аккаунтов, пять ключей и пять SDK. Или один агрегатор. OpenRouter — самый распространённый из них: один ключ, один OpenAI-совместимый API и сотни моделей. В работе он нужен для быстрых сравнений, фолбэков и доступа к open-weight моделям без своего GPU. На собеседовании спросят о другом: «чем агрегатор хуже прямого провайдера и куда при этом уходят данные?»

OpenRouter — прослойка между нашим кодом и провайдерами моделей:

наш код ──► https://openrouter.ai/api/v1 (один ключ OPENROUTER_API_KEY)
│ router: picks model + provider endpoint
┌──────────────┼───────────────┬─────────────────┐
▼ ▼ ▼ ▼
Anthropic OpenAI DeepSeek (сам) хостинги open-weight
(Claude) (GPT) и другие хосты (Llama, Qwen, Mistral...)

Три вещи, которые он делает:

  1. Единый протокол. OpenAI Chat Completions (/api/v1/chat/completions), а также Responses API. Код из главы 1.6 работает с OpenRouter после смены base_url и ключа.
  2. Единый биллинг. Покупаем кредиты, с них списывается стоимость запросов в любые модели.
  3. Маршрутизация. У одной модели может быть несколько провайдеров (endpoint’ов): у open-weight модели это разные хостинги, у DeepSeek — сам DeepSeek и сторонние хосты. OpenRouter выбирает провайдера сам (балансирует цену, скорость и надёжность) или по нашим правилам, а при сбое пробует следующий.

Аналогия из мира интернет-магазинов: это как платёжный агрегатор для LLM. Один интерфейс над десятками платёжных провайдеров, но под капотом у каждого свои лимиты, особенности и комиссии, и абстракция местами протекает.

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

Модель на OpenRouter называется <организация>/<модель>, например deepseek/deepseek-v4.1-flash (на 13.11.2026 в каталоге DeepSeek есть и такой slug). Точные имена берём только из каталога или из GET /api/v1/models, по памяти не пишем. Кроме обычных имён есть:

  • Алиасы «latest» с тильдой (~deepseek/deepseek-flash-latest) указывают на новейшую модель семейства. Это удобно для экспериментов и опасно для продукта (см. главу 2.3: модель меняется прямо под ногами).
  • Варианты-суффиксы (Model variants):
Суффикс Что делает
:free бесплатная версия модели, отдельная запись в каталоге со своими лимитами и провайдерами
:nitro сортирует провайдеров по скорости (throughput)
:floor сортирует провайдеров по цене
:exacto сортирует провайдеров по качеству вызова инструментов
:batch цена batch, через Batch API
:thinking, :online, :extended устарели; для рассуждения есть параметр reasoning, для поиска — серверный инструмент веб-поиска

:free и :batch — это отдельные позиции каталога. :nitro, :floor и :exacto годятся для любой модели и меняют только выбор провайдера.

Бесплатные модели: что дают и чем за них платим

Заголовок раздела «Бесплатные модели: что дают и чем за них платим»

Самый заметный из суффиксов — :free: с ним можно сравнивать модели, не потратив ни цента. Модели с суффиксом :free бесплатны, но с лимитами (по Limits, 13.11.2026):

Куплено кредитов за всё время Запросов в минуту Запросов в день к :free
меньше $10 20 50
от $10 20 1000

Остаток видно через GET https://openrouter.ai/api/v1/key (поле free_model_daily_requests). При отрицательном балансе даже бесплатные модели могут отвечать 402.

Есть ещё роутер openrouter/free, который сам выбирает бесплатную модель и при сбое переходит только на другие бесплатные. Набор бесплатных моделей постоянно меняется, поэтому смотрим каталог в день работы.

Главная плата за бесплатность — данные. Провайдеры бесплатных endpoint’ов часто живут за счёт того, что логируют запросы или учатся на них. OpenRouter показывает политику данных каждого endpoint’а и даёт отдельные настройки для платных и бесплатных моделей, но решение о том, что отправлять, остаётся за нами. Правило курса: в :free-модели уходят только учебные вопросы и публичные тексты, ровно как в DeepSeek и в любую другую облачную модель.

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

  • Цены моделей — как у провайдеров, без наценки (по FAQ). Наценка берётся при покупке кредитов: 5.5% (минимум $0.80), криптой 5%. Неиспользованные кредиты могут сгореть через год после покупки.
  • Стоимость каждого запроса приходит в ответе: в usage есть поле cost (в кредитах), плюс prompt_tokens_details.cached_tokens и completion_tokens_details.reasoning_tokens (Usage accounting). Включать ничего не надо. Это удобнее, чем вести таблицу PRICES, но сверять с ней полезно.
  • BYOK (bring your own key): можно подключить собственный ключ провайдера, тогда OpenRouter работает только как роутер. Условия меняются, их стоит сверять с FAQ.
  • Лимит на ключ. Ключу можно задать предел трат (поля limit и limit_remaining в /api/v1/key). Для учебного ключа ставим его обязательно: опечатка в цикле не должна стоить больше $5.

Вернёмся к третьей функции OpenRouter — маршрутизации: от неё зависят и цена, и скорость, и то, кто увидит наши данные. Фолбэк (fallback) — запасной вариант, к которому переходят, если основной не ответил. Поведение по умолчанию (Provider selection): OpenRouter взвешивает цену, скорость, задержку, надёжность и качество вызова инструментов, при ошибке пробует следующего провайдера, а продолжение диалога старается держать у того же провайдера, пока у него «тёплый» кэш. Управлять этим можно объектом provider в теле запроса:

Поле Зачем
order, only, ignore какие провайдеры и в каком порядке
allow_fallbacks можно ли уходить к другим провайдерам (по умолчанию да)
sort price / throughput / latency
require_parameters только провайдеры, которые поддерживают все параметры запроса; иначе, например, response_format может молча проигнорироваться
data_collection: "deny" только провайдеры, которые не собирают данные
zdr: true только endpoint’ы с нулевым хранением (Zero Data Retention)
quantizations фильтр по квантованию (int4, fp8…): одна и та же open-weight модель в разной точности отвечает по-разному
max_price потолок цены

Помимо фолбэка между провайдерами одной модели есть фолбэк между моделями: параметр models со списком по приоритету (Model fallbacks). Если первая модель упала (лимит, перегрузка, слишком длинный контекст, модерация), берётся следующая. Платим по цене модели, которая ответила, а кто ответил, видно по полю model в ответе. Ловушка: если бесплатная модель «упала» на платную, мы платим. Чтобы запрос остался бесплатным, перечисляем только :free-модели.

Возможности, которые зависят от провайдера

Заголовок раздела «Возможности, которые зависят от провайдера»

Маршрутизация удобна, пока все провайдеры умеют одно и то же. Это не так. OpenRouter унифицирует протокол, но не возможности. Structured outputs (response_format с json_schema), tool calling, кэш и reasoning поддерживаются не всеми endpoint’ами даже одной модели (Structured outputs). Поэтому:

  • для строгого JSON фильтруем модели по supported_parameters и ставим provider.require_parameters: true;
  • кэш работает так, как у провайдера (Prompt caching): у DeepSeek и OpenAI он автоматический, у Anthropic нужен cache_control (OpenRouter его пробрасывает), у Gemini неявный. Попадания видны в usage.prompt_tokens_details.cached_tokens;
  • параметры вроде temperature у reasoning-моделей и новых Claude так же не работают, как и напрямую (глава 1.7): OpenRouter не может включить ручку, которой нет у модели.

Раз запрос может уйти к любому из провайдеров модели, вопрос «кто увидит данные» теперь решается в два шага:

  1. Сам OpenRouter по умолчанию не хранит промпты и ответы (Data collection). Логи запросов и скидка 1% за разрешение использовать наши данные включаются отдельно, по умолчанию выключены.
  2. Провайдер, к которому ушёл запрос, живёт по своей политике: одни не хранят ничего (ZDR), другие хранят ради борьбы со злоупотреблениями, третьи могут учиться на данных (Provider logging). Настройки — в Privacy settings аккаунта и в provider.data_collection / provider.zdr в запросе.

Важная тонкость: запрос к модели DeepSeek через OpenRouter не обязательно попадёт на серверы DeepSeek в Китае. У open-weight моделей бывают и другие хостинги, и это видно во вкладке Providers на странице модели. Но правило курса от этого не меняется: персональные данные покупателей, журнал событий заказов, снимки базы магазина и рабочий код в облако не уходят никаким маршрутом. OpenRouter решает вопрос удобства, а не вопрос наших данных.

Ситуация Выбор
Сравнить 5 моделей разных лабораторий на одном промпте или eval OpenRouter
Фолбэк на другую модель или провайдера при сбое OpenRouter (models, provider) или своя логика (глава 11.2 · Prompt caching, бюджеты, фолбэки)
Повседневная учёба на одной дешёвой модели DeepSeek напрямую: свои фичи (продолжение начатого ответа через бета-prefix из главы 2.1, strict tools из главы 2.2, reasoning_content) документированы, без лишнего звена
Фичи конкретного провайдера (Batch API Anthropic, Files API, свежие беты) Напрямую у провайдера: агрегатор их часто не пробрасывает или отстаёт
Данные покупателей, журнал событий заказов, снимок базы, эмбеддинги своих данных Ollama локально, без вариантов
Попробовать большую open-weight модель, которая не влезает в память нашей машины OpenRouter (на публичных данных)
Продакшен с требованиями к данным Прямой договор с провайдером или облаком; OpenRouter только с ZDR и после проверки политик
import os, time
from openai import OpenAI
router = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"], # from .env, listed in .gitignore
)
r = router.chat.completions.create(
model="deepseek/deepseek-v4.1-flash", # copy exact slugs from openrouter.ai/models
messages=[{"role": "user", "content": "Explain gross margin in two sentences."}],
max_tokens=300,
extra_body={
"provider": {"data_collection": "deny", "sort": "price"}, # OpenRouter-specific
"models": ["deepseek/deepseek-v4.1-flash", "openrouter/free"], # fallback chain
},
)
print(r.model) # who actually answered
print(r.choices[0].message.content)
print(r.usage) # includes cost (credits) and token details

Заголовки HTTP-Referer и X-OpenRouter-Title необязательны: они нужны только для публичных рейтингов приложений на сайте OpenRouter, учебному скрипту не нужны. Поля provider, models и reasoning специфичны для OpenRouter, поэтому в OpenAI SDK они передаются через extra_body.

Это тот же клиент openai, которым мы ходили в DeepSeek и Ollama с главы 1.6. Сведём три адреса в одну таблицу:

PROVIDERS = {
"deepseek": {"base_url": "https://api.deepseek.com", "key_env": "DEEPSEEK_API_KEY"},
"ollama": {"base_url": "http://localhost:11434/v1", "key_env": None}, # any placeholder key
"openrouter": {"base_url": "https://openrouter.ai/api/v1", "key_env": "OPENROUTER_API_KEY"},
}

В обёртке llm_utils.py, которую соберём в главе 2.7 · Стриминг, ретраи, rate limits, prompt caching, OpenRouter станет просто ещё одной строкой такой конфигурации. В этом и смысл OpenAI-совместимого протокола.

DeepSeek напрямую DeepSeek через OpenRouter
Имя модели deepseek-flash (алиас) deepseek/deepseek-v4.1-flash (или алиас ~deepseek/deepseek-flash-latest)
Где выполняется серверы DeepSeek (КНР) зависит от выбранного провайдера, видно во вкладке Providers
Режим размышления extra_body={"thinking": {...}}, reasoning_content единый параметр reasoning от OpenRouter; формат рассуждения может отличаться, сверяемся с докой
Бета-функции (prefix, strict на /beta) есть не гарантированы
Кэш автоматический, поля prompt_cache_hit_tokens виден как cached_tokens; работает, если запрос попал к провайдеру с кэшем
Цена прайс DeepSeek, скидка вне пика цена конкретного провайдера + 5.5% при покупке кредитов

Сравнение четырёх «наших» провайдеров с точки зрения OpenRouter

Заголовок раздела «Сравнение четырёх «наших» провайдеров с точки зрения OpenRouter»
Claude OpenAI DeepSeek Ollama
Доступен через OpenRouter да да да, плюс сторонние хосты нет: локальная модель, роутер не нужен
Что теряем через OpenRouter часть бета-функций, Batch API по своим правилам часть специфичных функций Responses бета-эндпоинт и его функции —
Кэш через OpenRouter нужен cache_control автоматический автоматический —
Бесплатный вариант см. каталог см. каталог на 13.11.2026 в разделе DeepSeek :free не было, см. каталог всегда бесплатно
Данные Anthropic OpenAI DeepSeek или другой хост наш компьютер
  • Сравнение 4–5 моделей: OpenRouter (это его главная учебная роль).
  • Базовая точка сравнения: DeepSeek напрямую (deepseek-flash) и Ollama (qwen3:4b). Размер локальной модели зависит от памяти: при 8 ГБ RAM — модели класса 3–4B, при 16 ГБ — 7–8B, при 32 ГБ и больше — 14B и крупнее.
  • LLM-судья, если оцениваем ответы моделью, должен быть сильнее оцениваемых: например, deepseek-v4-pro или модель Claude/OpenAI через OpenRouter.
  • Данные: публичные сообщения поставщиков о товарах и учебные вопросы. Никаких данных покупателей, журналов событий и снимков базы магазина ни в одну облачную модель.
  1. OpenRouter Quickstart (≈15 мин). Берём base URL, пример с OpenAI SDK и формат имени модели. Создаём аккаунт и ключ, сразу задаём ключу лимит трат и кладём ключ в .env.
  2. Каталог моделей (≈20 мин). Фильтруем по цене (free), по supported_parameters (tools, structured outputs) и по контексту. Открываем страницу модели DeepSeek и вкладку Providers: сколько хостингов, какие цены, скорость, политика данных. Выбираем 4–5 моделей для практики и выписываем их точные slug.
  3. Model variants и Limits (≈15 мин). Что берём: что значит каждый суффикс и лимиты :free для нашего аккаунта.
  4. Provider selection и Model fallbacks (≈25 мин). Что берём: поля объекта provider, require_parameters, кто платит при фолбэке.
  5. Data collection, Provider logging и свои Privacy settings (≈20 мин). Проверяем, что логирование и использование данных для обучения выключены, и решаем, разрешать ли бесплатные endpoint’ы, которые могут учиться на входах. Если разрешаем, то только для публичных текстов.
  6. Usage accounting, Prompt caching, Structured outputs (≈20 мин). Что берём: поле cost, поля кэша, зачем require_parameters для схем.
  7. FAQ → разделы про оплату и BYOK (≈10 мин).
  8. Практика (≈1.5 ч).
  • Бесплатное ≠ безопасное. :free-модель может учиться на наших данных. Это та же категория, что DeepSeek и бесплатный тариф Gemini: только публичное и учебное.
  • Фолбэк на платную модель. В models после :free стоит платная модель, и счёт растёт незаметно. Логируем r.model и usage.cost на каждом вызове.
  • Молча проигнорированные параметры. Провайдер без поддержки response_format вернёт обычный текст. Для схем и инструментов ставим require_parameters: true и валидируем ответ Pydantic’ом как обычно.
  • Разные провайдеры дают разное качество одной модели. Квантование, версии шаблона, ограничения контекста. Если результат «плавает» между прогонами, стоит проверить, не менялся ли провайдер (Activity в аккаунте), и зафиксировать его через provider.order/only для эксперимента.
  • Задержка. Лишнее звено добавляет время, а бесплатные endpoint’ы часто перегружены. Замеряем TTFT и общее время, ощущениям не верим.
  • 429 на :free при 20 запросах в минуту наступает быстро. Пока достаточно запускать задачи последовательно с паузой; семафор и backoff разберём в главе 2.7.
  • Алиасы с ~ удобны в ноутбуке и опасны в коде проекта. В eval-прогонах пишем точный slug и сохраняем r.model.
  • Кредиты не возвращаются и могут сгореть через год. Пополняем маленькими суммами.
  • Это не замена прямым интеграциям. Batch API Anthropic, бета-функции DeepSeek и свежие возможности провайдеров могут быть недоступны через агрегатор.

exercises/week-02/openrouter/: compare.py, tasks.jsonl, results/. Ключ в .env (OPENROUTER_API_KEY), у ключа лимит трат $2–5.

  • 1. Ключ и проверка. Создаём ключ с лимитом, проверяем GET https://openrouter.ai/api/v1/key (через httpx с Authorization: Bearer): limit_remaining, is_free_tier, free_model_daily_requests. В Privacy settings выключаем логирование и обучение на своих данных.
  • 2. Выбор моделей. 4–5 моделей из каталога: DeepSeek (deepseek/deepseek-v4.1-flash или актуальный slug), одна модель Claude и одна OpenAI (дешёвые), одна open-weight другого семейства (Qwen/Llama/Mistral), одна бесплатная (openrouter/free или конкретная :free). Записываем slug, цену и провайдеров в notes/openrouter.md.
  • 3. Задачи. tasks.jsonl, 3–4 задачи на публичных данных с проверяемым ответом:
    • извлечение ProductUpdate из двух сообщений поставщиков из главы 2.2 (эталон у нас уже есть);
    • классификация двух текстов из главы 2.1;
    • один вопрос «на рассуждение», например: кружка стоит 1200 ₽, себестоимость 700 ₽, скидка 10%, комиссия платёжного провайдера 2.5% от оплаченной суммы — какая прибыль с заказа до расходов на доставку? (ответ проверяем сами: 1080 − 700 − 27 = 353 ₽).
  • 4. Скрипт сравнения. compare.py для каждой модели и задачи делает стриминговый запрос (как в chat.py из главы 1.6: TTFT можно замерить только на стриме — это момент прихода первого кусочка текста) и пишет в results/run_<дата>.jsonl поля requested_model, answered_model (r.model), текст, TTFT, общее время, prompt_tokens, completion_tokens, cached_tokens, reasoning_tokens, cost. Каркас:
def run_one(model: str, messages: list[dict]) -> dict:
t0 = time.perf_counter()
ttft, parts, usage, answered = None, [], None, None
stream = router.chat.completions.create(
model=model, messages=messages, max_tokens=800, stream=True,
extra_body={"provider": {"data_collection": "deny"}},
)
for chunk in stream:
answered = answered or chunk.model
if chunk.choices and chunk.choices[0].delta.content:
ttft = ttft or time.perf_counter() - t0
parts.append(chunk.choices[0].delta.content)
if getattr(chunk, "usage", None):
usage = chunk.usage # arrives with the last chunk
# TODO: total time, cost = getattr(usage, "cost", None), token details
...
  • 5. Базовые точки. Те же задачи напрямую через DeepSeek (deepseek-flash, размышление выключено) и через Ollama (qwen3:4b). Это ещё две строки в таблице: «тот же DeepSeek напрямую против OpenRouter» и «локальная модель».
  • 6. Оценка качества. Для извлечения сравниваем поля с эталоном вручную (автоматическое сравнение по полям — функция compare — появится в следующей главе, тогда к этому прогону можно вернуться). Классификацию сравниваем с меткой. Задачу на рассуждение оцениваем сами по правильности числа.
  • 7. Таблица в notes/openrouter.md:
    | модель | ответила (r.model) | провайдер | качество (из N) | TTFT, с | всего, с | in/out токенов | $ за прогон | заметки |
    Под таблицей 4–5 выводов: кто лучший по качеству, кто по цене за правильный ответ, кто быстрее, что дал бесплатный вариант и чего он стоил (лимиты, задержка, политика данных).
  • 8. Фолбэк и роутинг. Запрос с models=[<несуществующий или заведомо недоступный slug>, "openrouter/free"]: смотрим, кто ответил. Затем один и тот же запрос с provider.sort = "price" и "throughput" к open-weight модели: изменился ли провайдер, время и цена?
  • 9. Structured output через OpenRouter. Извлечение ProductUpdate с response_format типа json_schema и provider.require_parameters: true для 2 моделей из списка. Сравниваем с главой 2.2: сколько валидных ответов.
  • Один промпт-набор прогнан через 4–5 моделей на OpenRouter, плюс DeepSeek напрямую и Ollama. Таблица с качеством, задержкой (TTFT и общее время), токенами и стоимостью лежит в notes/openrouter.md.
  • У ключа OpenRouter есть лимит трат, логирование и обучение на данных выключены, в облако не ушло ничего, кроме публичных текстов.
  • Можем объяснить, когда брать OpenRouter, когда прямого провайдера, а когда Ollama, и что происходит с данными на каждом пути.

Вопрос 1

Что в коде меняется при переходе с DeepSeek напрямую на OpenRouter, если используется пакет openai?

base_url (https://openrouter.ai/api/v1), ключ (OPENROUTER_API_KEY) и имя модели (deepseek/...). Специфичные параметры OpenRouter (provider, models, reasoning) передаются через extra_body.

Вопрос 2

Что означает суффикс :free и какие у него лимиты для аккаунта, который ни разу не покупал кредиты?

  • a) безлимитно
  • b) 20 запросов в минуту и 50 в день
  • c) 1000 в день без ограничения в минуту
  • d) только 10 запросов всего

b. 20 запросов в минуту и 50 в день к :free-моделям. После покупки кредитов на $10 и больше дневной лимит становится 1000.

Вопрос 3

Чем :nitro и :floor отличаются от :free?

:free — отдельная бесплатная позиция каталога со своими лимитами. :nitro и :floor — варианты маршрутизации для любой модели: сортировка провайдеров по скорости или по цене.

Вопрос 4

В запросе передан models=["some/model:free", "anthropic/<paid-model>"]. Бесплатная модель упала по rate limit. Что произойдёт и кто за это платит?

OpenRouter перейдёт к следующей модели из models, к платной Anthropic, и платить придётся по её цене. Чтобы запрос остался бесплатным, перечисляем только :free-модели.

Вопрос 5

Почему для structured outputs через OpenRouter нужен provider.require_parameters: true?

Поддержка response_format/json_schema зависит от endpoint’а. Без флага запрос может уйти к провайдеру, который параметр молча проигнорирует. С флагом он попадёт только к тем, кто его поддерживает.

Вопрос 6

Что не так в этом коде?

client = OpenAI(base_url="https://openrouter.ai/api/v1", api_key="sk-or-v1-3f9a...")
for line in open("exports/order_events_2026-11-12.log"):
client.chat.completions.create(model="openrouter/free",
messages=[{"role": "user", "content": f"Explain this order event: {line}"}])

Ключ зашит в коде. Журнал событий заказов (в нём бывают данные покупателей) отправляется в бесплатную облачную модель, которая может учиться на входах (нарушение правила курса: такие данные только в Ollama). Нет лимита запросов, семафора и обработки 429. Строка журнала не обёрнута в теги. Результат не сохраняется.

Вопрос 7

OpenRouter не хранит промпты по умолчанию. Значит ли это, что наши данные никто не сохранит?

Нет. OpenRouter может не хранить, но провайдер, к которому ушёл запрос, живёт по своей политике: может хранить для борьбы со злоупотреблениями или учиться на данных. Нужны data_collection: "deny", zdr и настройки приватности, а для реальных данных только локальная модель.

Вопрос 8

Зачем записывать r.model в результаты сравнения, если модель указана в запросе?

Из-за фолбэков и алиасов ответить могла другая модель. Без r.model сравнение может оказаться сравнением не тех моделей.

Вопрос 9

Какую задачу лучше решать через OpenRouter, а какую напрямую через DeepSeek?

  • a) сравнение 5 моделей — OpenRouter; использование бета-prefix DeepSeek — напрямую
  • b) всё только через OpenRouter
  • c) всё только напрямую
  • d) сравнение моделей — напрямую у каждого провайдера с пятью ключами

a. Агрегатор хорош для широты: одного ключа хватает на много моделей. Специфичные функции провайдера надёжнее получать напрямую.

Вопрос 10

Где на OpenRouter видна стоимость конкретного запроса?

В usage.cost ответа (в кредитах), а также в Activity аккаунта и через эндпоинт generation по id ответа.

Вопрос 11

Одна и та же open-weight модель через OpenRouter вчера отвечала лучше, чем сегодня. Каковы две вероятные причины, связанные с маршрутизацией?

Запрос ушёл к другому провайдеру (балансировка или фолбэк), у которого другое квантование или другие настройки. Или алиас указал на новую версию модели. Для экспериментов фиксируем провайдера (order/only) и точный slug.

Вопрос 12

Почему Ollama не нужна в OpenRouter, и в какой ситуации OpenRouter может заменить её для учёбы, а в какой нет?

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

Дальше [2.5 · Упражнение: JSON из 20 текстов (гл. 2.5)](/week-02/2-5/): измерим качество извлечения по полям, и compare.py из этой главы позволит прогнать тот же eval через несколько моделей. Фолбэки и бюджеты на уровне продакшена вернутся в главе 11.2 · Prompt caching, бюджеты, фолбэки.