2.4 · OpenRouter: один API ко многим моделям
Неделя 2 · Основы LLM · ⏱ ~3 ч · Теория, Практика
Зачем это AI-инженеру
Заголовок раздела «Зачем это AI-инженеру»В главе 2.3 · Обзор моделей и провайдеров мы собрали таблицу моделей, но выбирать по таблице нельзя: модель выбирают по своим evals. Чтобы прогнать один промпт через пять моделей пяти лабораторий, нужно пять аккаунтов, пять ключей и пять SDK. Или один агрегатор. OpenRouter — самый распространённый из них: один ключ, один OpenAI-совместимый API и сотни моделей. В работе он нужен для быстрых сравнений, фолбэков и доступа к open-weight моделям без своего GPU. На собеседовании спросят о другом: «чем агрегатор хуже прямого провайдера и куда при этом уходят данные?»
Что такое OpenRouter
Заголовок раздела «Что такое OpenRouter»OpenRouter — прослойка между нашим кодом и провайдерами моделей:
наш код ──► https://openrouter.ai/api/v1 (один ключ OPENROUTER_API_KEY) │ router: picks model + provider endpoint ┌──────────────┼───────────────┬─────────────────┐ ▼ ▼ ▼ ▼ Anthropic OpenAI DeepSeek (сам) хостинги open-weight (Claude) (GPT) и другие хосты (Llama, Qwen, Mistral...)Три вещи, которые он делает:
- Единый протокол. OpenAI Chat Completions (
/api/v1/chat/completions), а также Responses API. Код из главы 1.6 работает с OpenRouter после сменыbase_urlи ключа. - Единый биллинг. Покупаем кредиты, с них списывается стоимость запросов в любые модели.
- Маршрутизация. У одной модели может быть несколько провайдеров (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 не может включить ручку, которой нет у модели.
Приватность: два уровня
Заголовок раздела «Приватность: два уровня»Раз запрос может уйти к любому из провайдеров модели, вопрос «кто увидит данные» теперь решается в два шага:
- Сам OpenRouter по умолчанию не хранит промпты и ответы (Data collection). Логи запросов и скидка 1% за разрешение использовать наши данные включаются отдельно, по умолчанию выключены.
- Провайдер, к которому ушёл запрос, живёт по своей политике: одни не хранят ничего (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 и после проверки политик |
DeepSeek и Ollama: как это сделать у нас
Заголовок раздела «DeepSeek и Ollama: как это сделать у нас»Код: тот же клиент, третий base_url
Заголовок раздела «Код: тот же клиент, третий base_url»import os, timefrom 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 answeredprint(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 через OpenRouter и напрямую
Заголовок раздела «DeepSeek через OpenRouter и напрямую»| 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. - Данные: публичные сообщения поставщиков о товарах и учебные вопросы. Никаких данных покупателей, журналов событий и снимков базы магазина ни в одну облачную модель.
Маршрут изучения
Заголовок раздела «Маршрут изучения»- OpenRouter Quickstart (≈15 мин). Берём base URL, пример с OpenAI SDK и формат имени модели. Создаём аккаунт и ключ, сразу задаём ключу лимит трат и кладём ключ в
.env. - Каталог моделей (≈20 мин). Фильтруем по цене (free), по
supported_parameters(tools, structured outputs) и по контексту. Открываем страницу модели DeepSeek и вкладку Providers: сколько хостингов, какие цены, скорость, политика данных. Выбираем 4–5 моделей для практики и выписываем их точные slug. - Model variants и Limits (≈15 мин). Что берём: что значит каждый суффикс и лимиты
:freeдля нашего аккаунта. - Provider selection и Model fallbacks (≈25 мин). Что берём: поля объекта
provider,require_parameters, кто платит при фолбэке. - Data collection, Provider logging и свои Privacy settings (≈20 мин). Проверяем, что логирование и использование данных для обучения выключены, и решаем, разрешать ли бесплатные endpoint’ы, которые могут учиться на входах. Если разрешаем, то только для публичных текстов.
- Usage accounting, Prompt caching, Structured outputs (≈20 мин). Что берём: поле
cost, поля кэша, зачемrequire_parametersдля схем. - FAQ → разделы про оплату и BYOK (≈10 мин).
- Практика (≈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:Под таблицей 4–5 выводов: кто лучший по качеству, кто по цене за правильный ответ, кто быстрее, что дал бесплатный вариант и чего он стоил (лимиты, задержка, политика данных).| модель | ответила (r.model) | провайдер | качество (из N) | TTFT, с | всего, с | in/out токенов | $ за прогон | заметки | - 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 и какие у него лимиты для аккаунта, который ни разу не покупал кредиты?
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. Агрегатор хорош для широты: одного ключа хватает на много моделей. Специфичные функции провайдера надёжнее получать напрямую.
Вопрос 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, бюджеты, фолбэки.