ИИ-функция через OpenRouter — главная функция сервиса
Тема 4/5: День 4. Доходный ИИ-сервис — собираем с нуля → Урок 5/7
Пользователь регистрируется, попадает в /dashboard и видит форму «Сгенерировать посты». Он жмёт кнопку — и получает готовые посты. Это и есть та ценность, ради которой к сервису приходят. В уроке разбираем, как собрать эту функцию через OpenRouter.
Почему OpenRouter
Прямой API Anthropic, OpenAI или Google создаёт две сложности. Во-первых, привязку к одной модели: чтобы переключиться, например, с Claude на GPT, придётся переписывать код. Во-вторых, оплату: Anthropic API из РФ напрямую без западной карты оплатить не получится.
OpenRouter снимает обе. Он даёт один API-эндпоинт сразу для всех моделей, так что переключение между ними — это буквально одна строка кода. Он часто принимает российские карты (Visa и Mastercard от Тинькофф, Сбера и других банков) — не всегда, но во многих случаях. И работает по схеме pay-as-you-go: вы платите только за реально потраченные токены.
Установка и настройка
Подключение OpenRouter — это четыре коротких шага:
- Регистрация на openrouter.ai (через GitHub или email)
- Settings → Credits → Add Credits → пополняете $5-10
- Keys → Create API Key → копируете ключ (начинается с
sk-or-...) - В вашем Next.js проекте в
.env.localдобавляете:OPENROUTER_API_KEY=sk-or-...
Промпт для ИИ-функции
Создай ИИ-функцию генерации постов:
Интерфейс (src/app/dashboard/page.tsx):
- Форма с полями: тема поста (textarea), стиль (select: экспертный/лёгкий/продающий), количество (1-10)
- Кнопка «Сгенерировать»
- После нажатия — показывает спиннер
- По окончании — выводит N сгенерированных постов, каждый в отдельной карточке с кнопкой «Скопировать»
Серверная часть (src/app/api/generate/route.ts):
- POST endpoint
- Проверяет авторизацию через Auth.js server client
- Проверяет лимит пользователя: если credits_used >= credits_limit — возвращает 402 (Payment Required)
- Шлёт запрос в OpenRouter на модель anthropic/claude-sonnet-4.6 с промптом «Напиши N постов на тему [тема] в стиле [стиль]. Каждый пост — 2-3 абзаца. Раздели посты строкой ---»
- Получает ответ, парсит на N постов
- Списывает 1 credit у пользователя (UPDATE profiles SET credits_used = credits_used + 1)
- Возвращает массив постов
OPENROUTER_API_KEY в .env.local.
Пример вызова OpenRouter из Node.js
Claude Code напишет примерно такой код в API-route:
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.OPENROUTER_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'anthropic/claude-sonnet-4.6',
messages: [{ role: 'user', content: prompt }],
})
});
Это стандартный fetch — никаких специальных SDK. Простой HTTP-запрос.
Списание кредитов и защита от гонки запросов
Здесь есть важный нюанс. Если пользователь очень быстро нажмёт «Сгенерировать» несколько раз подряд, то без защиты уйдёт столько же запросов в OpenRouter, а кредит спишется только один — то есть пользователь потратит ваши деньги в обход лимита. Решает это атомарное списание через Postgres row-locking:
Сделай списание кредита атомарно через PostgreSQL row lock:
BEGIN;
SELECT credits_used, credits_limit FROM profiles WHERE id = $1 FOR UPDATE;
-- проверка credits_used < credits_limit
UPDATE profiles SET credits_used = credits_used + 1 WHERE id = $1;
COMMIT;
Если параллельные запросы — второй будет ждать первого, лимит соблюдается.
Без такой защиты сервис рано или поздно начнут эксплуатировать. Это стандартный приём для боевых сервисов, и закладывать его лучше сразу.
Какую модель выбрать
На OpenRouter доступно много моделей. Вот ориентир по самым ходовым — с примерными ценами и тем, когда какую брать:
| Модель | Цена за 1М токенов | Когда брать |
|---|---|---|
| Claude Sonnet 4.6 | ~$3 input / $15 output | Универсальный выбор. Лучшее качество текстов |
| Claude Haiku 4.5 | ~$1 / $5 | Простые задачи, экономия |
| GPT-5.5 | ~$2.5 / $10 | Альтернатива Claude |
| Gemini 2.5 Pro | ~$1.25 / $5 | Дешёвый универсал, для длинных контекстов |
| GigaChat от Сбера | ~₽5-15 | Российские задачи (законы, налоги, локальная специфика) |
Для ИИ-генератора постов универсально подходит Claude Sonnet или Haiku, и переключение между ними — это всё та же одна строка model: '...' в коде.
Как считать экономику
Поскольку оплата идёт по факту — за реально потраченные токены, себестоимость одной генерации зависит от выбранной модели и длины ответа. Чтобы тариф был устойчивым, считать экономику нужно от реальных цифр: сколько токенов уходит на одну генерацию у вашей модели, сколько генераций укладывается в тариф и какую долю лимита пользователи действительно используют. Эти данные легко собрать после первых запусков — по логам OpenRouter и реальному поведению пользователей. Подбирать цену и лимит вслепую не стоит: лучше зафиксировать стартовые значения, посмотреть на фактическое потребление и скорректировать.
Streaming-ответ (опционально)
Если хочется, чтобы пользователь видел текст постов «в реальном времени», как в ChatGPT, — используйте streaming. OpenRouter поддерживает Server-Sent Events, и Claude Code настроит его за вас: достаточно сказать «добавь streaming-режим для ИИ-генерации». Стриминг улучшает восприятие, но усложняет код, поэтому первая рабочая версия вполне может обойтись без него — простой спиннер, а затем готовый текст. Добавить streaming можно позже, когда сервис подрастёт.
Что в следующем уроке
ИИ-функция работает, пользователи регистрируются — но платить пока некому. На уроке 25 подключаем T-Банк эквайринг и получаем первый тестовый платёж.