# RouterAI — документация --- # Обзор # Обзор RouterAI RouterAI — это мощная платформа для работы с AI-моделями через единый API. Мы предоставляем доступ к различным AI-моделям от разных провайдеров, позволяя вам выбирать лучшее решение для ваших задач. ## Основные возможности - **Единый API** - Единый интерфейс для доступа к различным AI-моделям - **Гибкое ценообразование** - Платите в рублях только за то, что используете - **Множество провайдеров** - Доступ к моделям от OpenAI, Anthropic, Google и других - **Простая интеграция** - Совместимость с OpenAI SDK и другими популярными библиотеками ## Начало работы 1. [Зарегистрируйте аккаунт](https://routerai.ru/users/sign_up) 2. Сгенерируйте [API-ключ](https://routerai.ru/settings/keys) 3. Пополните баланс [картой или по безналичному расчету](https://routerai.ru/settings/billing) 4. Начните делать API-запросы ## API Base URL ``` https://routerai.ru/api/v1 ``` Наш API совместим с форматом OpenAI API, что упрощает переключение между провайдерами. Пример API Endpoint Chat Completions: `https://routerai.ru/api/v1/chat/completions` --- # Быстрый старт # Быстрый старт Это руководство поможет вам начать работу с RouterAI API за несколько минут. ## Шаг 1: Получите API-ключ 1. Зарегистрируйтесь на [routerai.ru](https://routerai.ru/users/sign_up) 2. Перейдите в [Настройки → API-ключи](https://routerai.ru/settings/keys) 3. Нажмите "Создать новый ключ" 4. Скопируйте и сохраните ключ в безопасном месте ## Шаг 2: Пополните баланс Перейдите в раздел [Биллинг](https://routerai.ru/settings/billing) и пополните баланс удобным способом: - Банковской картой - По безналичному расчету ## Шаг 3: Сделайте первый запрос ### cURL ```bash curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{ "model": "openai/gpt-4o", "messages": [ { "role": "user", "content": "Привет!" } ] }' ``` ### Python ```python from openai import OpenAI client = OpenAI( api_key="YOUR_API_KEY", base_url="https://routerai.ru/api/v1" ) response = client.chat.completions.create( model="openai/gpt-4o", messages=[ {"role": "user", "content": "Привет!"} ] ) print(response.choices[0].message.content) ``` ### JavaScript ```javascript import OpenAI from 'openai'; const client = new OpenAI({ apiKey: 'YOUR_API_KEY', baseURL: 'https://routerai.ru/api/v1', }); async function main() { const response = await client.chat.completions.create({ model: 'openai/gpt-4o', messages: [{ role: 'user', content: 'Привет!' }], }); console.log(response.choices[0].message.content); } main(); ``` ## Что дальше? - Изучите [доступные модели](/models) - Настройте [интеграцию с VS Code](/docs/guides/integrations/vscode) - Узнайте больше об [аутентификации](/docs/guides/overview/authentication) --- # Аутентификация # Аутентификация RouterAI использует API-ключи для аутентификации запросов к API. ## Типы ключей ### API-ключ Используется для вызовов AI-моделей (chat completions, completions). **Создание:** 1. Перейдите в [Настройки → API-ключи](https://routerai.ru/settings/keys) 2. Нажмите "Создать новый ключ" 3. Скопируйте и сохраните ключ в безопасном месте **Использование:** ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ https://routerai.ru/api/v1/chat/completions ``` ### Мастер-ключ (Master Key) Используется для программного управления API-ключами (создание, просмотр, удаление). **Создание:** 1. Перейдите в [Настройки → Мастер-ключи](https://routerai.ru/settings/provisioning_keys) 2. Нажмите "Создать мастер-ключ" 3. Скопируйте и сохраните ключ в безопасном месте **Использование:** ```bash curl -H "Authorization: Bearer YOUR_MASTER_KEY" \ https://routerai.ru/api/v1/keys ``` ## Различия между типами ключей | Характеристика | API-ключ | Мастер-ключ | | ---------------- | ------------------------------- | ---------------------- | | Назначение | Вызовы AI-моделей | Управление API-ключами | | Создание | Через UI или API | Только через UI | | Используется для | /chat/completions, /completions | /keys/\* | ## Лучшие практики безопасности - **Никогда не делитесь своим API-ключом** - Храните его в секрете - **Используйте переменные окружения** - Не вставляйте ключи прямо в исходный код - **Регулярно обновляйте ключи** - Периодически создавайте новые ключи и удаляйте старые - **Отслеживайте использование** - Проверяйте статистику на предмет необычных паттернов - **Используйте отдельные ключи** - Создавайте разные ключи для разных приложений ## Примеры использования ### Python ```python import os from openai import OpenAI # Используйте переменные окружения api_key = os.getenv('ROUTERAI_API_KEY') client = OpenAI( api_key=api_key, base_url="https://routerai.ru/api/v1" ) ``` ### JavaScript ```javascript // Используйте переменные окружения const client = new OpenAI({ apiKey: process.env.ROUTERAI_API_KEY, baseURL: 'https://routerai.ru/api/v1', }); ``` ### cURL ```bash # Используйте переменные окружения curl -H "Authorization: Bearer $ROUTERAI_API_KEY" \ https://routerai.ru/api/v1/chat/completions ``` --- # Выбор провайдера # Выбор провайдера RouterAI маршрутизирует запросы к оптимальным провайдерам для вашей модели. По умолчанию выполняется балансировка нагрузки между топ-провайдерами для максимизации аптайма. ## Стратегия балансировки Для каждой модели RouterAI распределяет нагрузку между провайдерами, отдавая приоритет низкой цене. > Когда вы отправляете запрос с параметрами `tools` или `tool_choice`, RouterAI будет маршрутизировать его только к тем провайдерам, которые поддерживают использование инструментов. Аналогично, если вы установите `max_tokens`, RouterAI будет маршрутизировать запрос только к провайдерам, поддерживающим ответ такой длины. Стандартный алгоритм балансировки нагрузки RouterAI работает следующим образом: 1. **Приоритет стабильности:** В первую очередь выбираются провайдеры, у которых не наблюдалось значительных сбоев за последние 30 секунд. 2. **Выбор по цене:** Среди стабильных провайдеров рассматриваются кандидаты с наименьшей стоимостью. 3. **Резервные варианты:** Оставшиеся провайдеры используются в качестве запасных (fallbacks). ## Управление выбором через объект `provider` Если стандартное поведение вас не устраивает, передайте объект `provider` в теле запроса. Поддерживаемые поля: | Поле | Тип | По умолчанию | Описание | | --- | --- | --- | --- | | `order` | `Array` | — | Приоритетный список slug'ов провайдеров — подсказка маршрутизации, применяется когда запрос проходит через нашу мульти-провайдерную сеть. | | `only` | `Array` | — | Whitelist провайдеров для мульти-провайдерной маршрутизации. | | `ignore` | `Array` | — | Blacklist провайдеров для мульти-провайдерной маршрутизации. | | `allow_fallbacks` | `Boolean` | `true` | При `false` RouterAI не пытается использовать резервный провайдер, если выбранный провайдер вернул ошибку — клиент получит эту ошибку как есть. | | `country` | `String` | — | Двухбуквенный код страны для фильтрации провайдеров по гео-политике (например, `"ru"`). | Slug'и провайдеров пишутся в нижнем регистре, например `"openai"`, `"anthropic"`, `"google"`, `"deepseek"`. > **Примечание про область применения `order/only/ignore`.** Если для запрошенной модели у нас настроен прямой провайдер или специальный маршрут, мы используем его — поля `order/only/ignore` в этом случае на наш выбор не влияют. Они применяются, когда запрос идёт через гибкую мульти-провайдерную маршрутизацию. Для гарантированного ограничения по гео-политике используйте `country`, для отключения резервных попыток — `allow_fallbacks: false`. ## Примеры ### Выбор страны обработки данных Если вам критично, чтобы обработка данных происходила на территории России, укажите `country`: ```bash curl -X POST "https://routerai.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-oss-120b", "messages": [ {"role": "user", "content": "Привет!"} ], "provider": { "country": "ru" } }' ``` ### Приоритетный порядок провайдеров `order` указывает порядок предпочтения провайдеров. Применяется при маршрутизации через нашу мульти-провайдерную сеть. ```bash curl -X POST "https://routerai.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "anthropic/claude-sonnet-4.5", "messages": [{"role": "user", "content": "Привет!"}], "provider": { "order": ["anthropic", "google"] } }' ``` ### Только указанные провайдеры (`only`) Применяется при маршрутизации через мульти-провайдерную сеть: ```bash curl -X POST "https://routerai.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-4o", "messages": [{"role": "user", "content": "Привет!"}], "provider": { "only": ["openai"] } }' ``` ### Исключение провайдеров (`ignore`) ```bash curl -X POST "https://routerai.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "anthropic/claude-sonnet-4.5", "messages": [{"role": "user", "content": "Привет!"}], "provider": { "ignore": ["google"] } }' ``` ### Отключение fallback (`allow_fallbacks: false`) По умолчанию, если выбранный провайдер вернул ошибку, RouterAI повторяет запрос через резервный провайдер. Если это поведение нежелательно — например, вы хотите гарантированно получить ответ только от выбранного провайдера, либо предпочитаете увидеть его исходную ошибку: ```bash curl -X POST "https://routerai.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "anthropic/claude-sonnet-4.5", "messages": [{"role": "user", "content": "Привет!"}], "provider": { "allow_fallbacks": false } }' ``` ### Комбинации Поля можно комбинировать. Например, "обработать в России и без резервных попыток": ```json { "model": "openai/gpt-oss-120b", "messages": [{"role": "user", "content": "Привет!"}], "provider": { "country": "ru", "allow_fallbacks": false } } ``` Или "при мульти-провайдерной маршрутизации предпочитать DeepSeek, потом Yandex, и только в России": ```json { "model": "openai/gpt-4o", "messages": [{"role": "user", "content": "Привет!"}], "provider": { "order": ["deepseek", "yandex"], "country": "ru" } } ``` ## Тарификация при выборе провайдера Стоимость запроса считается по фактическому провайдеру, в которого ушёл запрос. Один и тот же запрос через разных провайдеров может стоить по-разному. Точная цена для каждого провайдера видна в личном кабинете и в детализации запросов. При ошибках (когда запрос не выполнен), а также при `allow_fallbacks: false`, если выбранный провайдер вернул ошибку, средства не списываются. ## Возможные ошибки | Код | Когда возникает | | --- | --- | | `503` | Для запрошенной модели нет ни одного доступного провайдера. | | `402` | Недостаточно средств на балансе. | | `500` / `502` / `503` | Ошибка провайдера. Если `allow_fallbacks: true` (default) — RouterAI попробовал резервный провайдер и тот тоже не отработал. При `allow_fallbacks: false` — клиент получает исходную ошибку выбранного провайдера, без повторных попыток. | --- # Параметры # Параметры Параметры сэмплирования управляют процессом генерации токенов моделью. Вы можете отправлять в RouterAI любые параметры из списка ниже, а также другие. RouterAI применит значения по умолчанию, указанные ниже, если соответствующие параметры отсутствуют в вашем запросе (например, `temperature` равно 1.0). Мы также передадим некоторые провайдер-специфичные параметры, такие как `safe_prompt` для Mistral или `raw_mode` для Hyperbolic, напрямую соответствующим провайдерам, если они указаны. ## Temperature * Ключ: `temperature` * Опционально, **float**, от 0.0 до 2.0 * По умолчанию: 1.0 Этот параметр влияет на разнообразие ответов модели. Меньшие значения приводят к более предсказуемым и типичным ответам, тогда как большие значения поощряют более разнообразные и менее распространённые ответы. При значении 0 модель всегда даёт один и тот же ответ на заданный ввод. ## Top P * Ключ: `top_p` * Опционально, **float**, от 0.0 до 1.0 * По умолчанию: 1.0 Этот параметр ограничивает выбор модели процентом наиболее вероятных токенов: только верхние токены, чьи вероятности в сумме дают P. Меньшее значение делает ответы модели более предсказуемыми, тогда как значение по умолчанию допускает полный диапазон выбора токенов. Думайте об этом как о динамическом Top-K. ## Top K * Ключ: `top_k` * Опционально, **integer**, 0 или больше * По умолчанию: 0 Это ограничивает выбор токенов моделью на каждом шаге, заставляя её выбирать из меньшего набора. Значение 1 означает, что модель всегда выбирает наиболее вероятный следующий токен, что приводит к предсказуемым результатам. По умолчанию этот параметр отключён, что позволяет модели рассматривать все варианты. ## Frequency Penalty * Ключ: `frequency_penalty` * Опционально, **float**, от -2.0 до 2.0 * По умолчанию: 0.0 Этот параметр направлен на контроль повторения токенов в зависимости от того, как часто они появляются на входе. Он стремится реже использовать токены, которые чаще встречаются во входных данных, пропорционально частоте их появления. Штраф за токен масштабируется с количеством вхождений. Отрицательные значения поощряют повторное использование токенов. ## Presence Penalty * Ключ: `presence_penalty` * Опционально, **float**, от -2.0 до 2.0 * По умолчанию: 0.0 Регулирует, как часто модель повторяет конкретные токены, уже использованные во входных данных. Большие значения делают такое повторение менее вероятным, тогда как отрицательные значения дают противоположный эффект. Штраф за токен не масштабируется с количеством вхождений. Отрицательные значения поощряют повторное использование токенов. ## Repetition Penalty * Ключ: `repetition_penalty` * Опционально, **float**, от 0.0 до 2.0 * По умолчанию: 1.0 Помогает уменьшить повторение токенов из входных данных. Большее значение делает менее вероятным повторение токенов моделью, но слишком высокое значение может сделать вывод менее связным (часто с длинными предложениями без коротких слов). Штраф за токен масштабируется на основе исходной вероятности токена. ## Min P * Ключ: `min_p` * Опционально, **float**, от 0.0 до 1.0 * По умолчанию: 0.0 Представляет минимальную вероятность для рассмотрения токена относительно вероятности наиболее вероятного токена. (Значение меняется в зависимости от уровня уверенности самого вероятного токена.) Если ваш Min-P установлен в 0.1, это означает, что будут допускаться только токены, которые как минимум в 10 раз менее вероятны, чем лучший вариант. ## Top A * Ключ: `top_a` * Опционально, **float**, от 0.0 до 1.0 * По умолчанию: 0.0 Рассматривает только верхние токены с «достаточно высокой» вероятностью на основе вероятности самого вероятного токена. Думайте об этом как о динамическом Top-P. Меньшее значение Top-A фокусирует выбор на основе самого вероятного токена, но с более узким охватом. Большее значение Top-A не обязательно влияет на креативность вывода, а скорее уточняет процесс фильтрации на основе максимальной вероятности. ## Seed * Ключ: `seed` * Опционально, **integer** Если указан, инференс будет сэмплировать детерминированно, так что повторные запросы с одинаковым seed и параметрами должны возвращать один и тот же результат. Детерминизм не гарантируется для некоторых моделей. ## Max Tokens * Ключ: `max_tokens` * Опционально, **integer**, 1 или больше Устанавливает верхний предел количества токенов, которые модель может сгенерировать в ответе. Она не выдаст больше этого предела. Максимальное значение — длина контекста минус длина промпта. ## Max Completion Tokens * Ключ: `max_completion_tokens` * Опционально, **integer**, 1 или больше Устанавливает верхний предел количества токенов, которые модель может сгенерировать в ответе. Она не выдаст больше этого предела. Максимальное значение — длина контекста минус длина промпта. ## Logit Bias * Ключ: `logit_bias` * Опционально, **map** Принимает JSON-объект, который сопоставляет токены (заданные их ID в токенизаторе) со значением смещения от -100 до 100. Математически смещение добавляется к логитам, генерируемым моделью, перед сэмплированием. Точный эффект варьируется в зависимости от модели, но значения от -1 до 1 должны уменьшать или увеличивать вероятность выбора; значения вроде -100 или 100 должны приводить к запрету или исключительному выбору соответствующего токена. ## Logprobs * Ключ: `logprobs` * Опционально, **boolean** Возвращать ли логарифмические вероятности выходных токенов. Если true, возвращаются логарифмические вероятности каждого возвращаемого выходного токена. ## Top Logprobs * Ключ: `top_logprobs` * Опционально, **integer** Целое число от 0 до 20, задающее количество наиболее вероятных токенов, возвращаемых на каждой позиции токена, с соответствующей логарифмической вероятностью. Параметр logprobs должен быть установлен в true, если используется этот параметр. ## Response Format * Ключ: `response_format` * Опционально, **map** Заставляет модель выдавать определённый формат вывода. Установка `{ "type": "json_object" }` включает режим JSON, который гарантирует, что сообщение, генерируемое моделью, является валидным JSON. **Примечание:** при использовании режима JSON следует также самостоятельно указать модели генерировать JSON через системное или пользовательское сообщение. ## Structured Outputs * Ключ: `structured_outputs` * Опционально, **boolean** Может ли модель возвращать структурированный вывод с помощью response\_format json\_schema. ## Stop * Ключ: `stop` * Опционально, **array** Немедленно останавливает генерацию, если модель встречает любой токен, указанный в массиве stop. ## Tools * Ключ: `tools` * Опционально, **array** Параметр для вызова инструментов, следующий формату запросов tool calling от OpenAI. Для не-OpenAI провайдеров он преобразуется соответствующим образом. ## Tool Choice * Ключ: `tool_choice` * Опционально, **string или object** Управляет тем, какой (если есть) инструмент вызывается моделью. 'none' означает, что модель не будет вызывать никакой инструмент и вместо этого сгенерирует сообщение. 'auto' означает, что модель может выбирать между генерацией сообщения или вызовом одного или нескольких инструментов. 'required' означает, что модель должна вызвать один или несколько инструментов. Указание конкретного инструмента через `{"type": "function", "function": {"name": "my_function"}}` заставляет модель вызвать именно этот инструмент. ## Parallel Tool Calls * Ключ: `parallel_tool_calls` * Опционально, **boolean** * По умолчанию: **true** Включать ли параллельный вызов функций при использовании инструментов. Если true, модель может вызывать несколько функций одновременно. Если false, функции будут вызываться последовательно. Применяется только при наличии инструментов. ## Verbosity * Ключ: `verbosity` * Опционально, **enum** (low, medium, high, xhigh, max) * По умолчанию: **medium** Ограничивает многословность ответа модели. Меньшие значения дают более лаконичные ответы, тогда как большие значения дают более подробные и развёрнутые ответы. Введён OpenAI для Responses API. Для моделей Anthropic этот параметр сопоставляется с `output_config.effort`. Уровень 'xhigh' поддерживается Anthropic Claude 4.7 Opus и более поздними моделями. Уровень 'max' поддерживается Anthropic Claude 4.6 Opus и более поздними моделями. --- # Обзор типов данных # Работа с различными типами данных > Отправляйте изображения, PDF, аудио и видео в модели RouterAI через наш унифицированный API. RouterAI поддерживает работу с различными типами входных данных помимо текста, позволяя отправлять изображения, PDF, аудио и видео файлы в совместимые модели через наш унифицированный API. Эта возможность (также называемая мультимодальностью) обеспечивает богатые взаимодействия для широкого спектра сценариев использования. ## Поддерживаемые модальности ### Изображения Отправляйте изображения в модели с возможностями компьютерного зрения для анализа, описания, OCR и многого другого. RouterAI поддерживает множество форматов изображений, как на основе URL, так и в кодировке base64. [Узнайте больше об отправке изображений →](/docs/guides/overview/multimodal/images) ### Генерация изображений Генерируйте изображения из текстовых запросов, используя AI модели с возможностями вывода изображений. RouterAI поддерживает различные модели генерации изображений, которые могут создавать высококачественные изображения на основе ваших описаний. [Узнайте больше о генерации изображений →](/docs/guides/overview/multimodal/image-generation) ### PDF Обрабатывайте PDF документы с любой моделью на RouterAI. Наша интеллектуальная система парсинга PDF извлекает текст и обрабатывает как текстовые, так и отсканированные документы. [Узнайте больше о работе с PDF →](/docs/guides/overview/multimodal/pdfs) ### Аудио Отправляйте аудио файлы в модели с возможностями обработки речи для транскрипции, анализа и обработки. RouterAI поддерживает распространенные аудио форматы с автоматической маршрутизацией к совместимым моделям. [Узнайте больше о работе с Аудио →](/docs/guides/overview/multimodal/audio) ### Преобразование речи в текст Расшифровывайте аудио в текст через выделенный эндпоинт `/api/v1/audio/transcriptions`. Отправьте аудио в кодировке base64 и получите структурированный JSON с распознанным текстом и статистикой использования. [Узнайте больше о преобразовании речи в текст →](/docs/guides/overview/multimodal/speech-to-text) ### Синтез речи Синтезируйте речь из текста через выделенный эндпоинт `/api/v1/audio/speech`, совместимый с OpenAI Audio Speech API. Отправьте текст и получите поток сырых байтов аудио в формате `mp3` или `pcm`. [Узнайте больше о синтезе речи →](/docs/guides/overview/multimodal/text-to-speech) ### Видео Отправляйте видео файлы в модели с возможностями обработки видео для анализа, описания, обнаружения объектов и распознавания действий. RouterAI поддерживает множество видео форматов для комплексных задач понимания видео. [Узнайте больше о работе с Видео →](/docs/guides/overview/multimodal/videos) ## Начало работы Все мультимодальные входные данные используют один и тот же эндпоинт `/api/v1/chat/completions` с параметром `messages`. Различные типы контента указываются в массиве содержимого сообщения: - **Изображения**: Используйте тип контента `image_url` - **PDF**: Используйте тип контента `file` с данными PDF - **Аудио**: Используйте тип контента `input_audio` - **Видео**: Используйте тип контента `video_url` Вы можете комбинировать несколько модальностей в одном запросе, и количество файлов, которые вы можете отправить, варьируется в зависимости от провайдера и модели. ## Совместимость моделей Не все модели поддерживают каждую модальность. RouterAI автоматически фильтрует доступные модели на основе содержимого вашего запроса: - **Модели компьютерного зрения**: Требуются для обработки изображений - **Модели, совместимые с файлами**: Могут обрабатывать PDF нативно или через нашу систему парсинга - **Модели с возможностями аудио**: Требуются для обработки аудио входных данных - **Модели с возможностями видео**: Требуются для обработки видео входных данных Используйте нашу [страницу моделей](https://routerai.ru/models), чтобы найти модели, поддерживающие желаемые входные модальности. ## Поддержка форматов входных данных RouterAI поддерживает как **прямые URL**, так и **данные в кодировке base64** для мультимодальных входных данных: ### URL (Рекомендуется для публичного контента) - **Изображения**: `https://example.com/image.jpg` - **PDF**: `https://example.com/document.pdf` - **Аудио**: Не поддерживается через URL (только base64) - **Видео**: Зависит от провайдера (например, ссылки YouTube для Gemini на AI Studio) ### Кодировка Base64 (Требуется для локальных файлов) - **Изображения**: `data:image/jpeg;base64,{base64_data}` - **PDF**: `data:application/pdf;base64,{base64_data}` - **Аудио**: Необработанная строка base64 с указанием формата - **Видео**: `data:video/mp4;base64,{base64_data}` --- # Изображения # Изображения > Как отправить изображения c помощью AI-моделей через RouterAI API. Запросы с изображениями к мультимодальным моделям доступны через API `/api/v1/chat/completions` с многокомпонентным параметром `messages`. Параметр `image_url` может быть либо URL-адресом, либо изображением в кодировке base64. Обратите внимание, что несколько изображений можно отправлять в отдельных элементах массива содержимого. Количество изображений, которые вы можете отправить в одном запросе, варьируется в зависимости от провайдера и модели. Из-за особенностей парсинга содержимого мы рекомендуем сначала отправлять текстовый запрос, а затем изображения. Если изображения должны идти первыми, рекомендуется поместить их в системный промпт. RouterAI поддерживает как **прямые URL-адреса**, так и **данные в кодировке base64** для изображений: - **URL-адреса**: Более эффективны для публично доступных изображений, так как не требуют локального кодирования - **Base64**: Требуется для локальных файлов или приватных изображений, которые не являются публично доступными ## Использование URL-адресов изображений Вот как отправить изображение, используя URL-адрес: ```bash curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "google/gemini-2.5-flash", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Что изображено на этой картинке?" }, { "type": "image_url", "image_url": { "url": "https://example.com/image.jpg" } } ] } ] }' ``` ## Использование изображений в кодировке Base64 Для локально хранящихся изображений вы можете отправлять их, используя кодировку base64. Вот как это сделать: **Шаг 1: Кодирование изображения в base64** ```bash # Кодирование изображения в base64 и сохранение в переменную BASE64_IMAGE=$(base64 -w 0 path/to/your/image.jpg) # Или создание data URL напрямую DATA_URL="data:image/jpeg;base64,$(base64 -w 0 path/to/your/image.jpg)" ``` **Шаг 2: Отправка запроса с base64 изображением** ```bash # Используя переменную DATA_URL из предыдущего шага curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "google/gemini-2.5-flash", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Что изображено на этой картинке?" }, { "type": "image_url", "image_url": { "url": "'"$DATA_URL"'" } } ] } ] }' ``` **Альтернативный способ (всё в одной команде):** ```bash curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "google/gemini-2.5-flash", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Что изображено на этой картинке?" }, { "type": "image_url", "image_url": { "url": "data:image/jpeg;base64,'"$(base64 -w 0 path/to/your/image.jpg)"'" } } ] } ] }' ``` ## Поддерживаемые типы содержимого изображений - `image/png` - `image/jpeg` - `image/webp` - `image/gif` --- # Генерация изображений # Генерация изображений > Генерируйте изображения с помощью AI-моделей через RouterAI API. RouterAI поддерживает генерацию изображений через модели, которые имеют `"image"` в своих `output_modalities`. Эти модели могут создавать изображения из текстовых промптов, когда вы указываете соответствующие модальности в запросе. ## Поиск моделей Вы можете найти модели для генерации изображений несколькими способами: ### На странице моделей Посетите [страницу моделей](/models) и отфильтруйте по выходным модальностям, чтобы найти модели, способные генерировать изображения. Ищите модели, которые содержат `"image"` в своих выходных модальностях. ### В Чате При использовании [чата](/chat) выберите ИИ модель для работы и изображениями ( Например, google/gemini-3-pro-image-preview), нажмите кнопку Прикрепить файл, выберите ваше изображение. ## Использование API Для генерации изображений отправьте запрос на эндпоинт `/api/v1/chat/completions` с параметром `modalities`, включающим `"image"` и `"text"`. ### Базовая генерация изображений ```bash # Базовый запрос на генерацию изображения curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "google/gemini-2.5-flash-image", "messages": [ { "role": "user", "content": "Создай красивый закат над горами" } ], "modalities": ["image", "text"] }' ``` ### Параметры конфигурации изображений Модели генерации изображений Gemini поддерживают дополнительную конфигурацию через параметр `image_config`. Подробнее об использовании моделей Gemini Image Gen: [https://ai.google.dev/gemini-api/docs/image-generation](https://ai.google.dev/gemini-api/docs/image-generation) #### Соотношение сторон Установите `image_config.aspect_ratio` для запроса определенных соотношений сторон генерируемых изображений. **Поддерживаемые соотношения сторон:** - `1:1` → 1024×1024 (по умолчанию) - `2:3` → 832×1248 - `3:2` → 1248×832 - `3:4` → 864×1184 - `4:3` → 1184×864 - `4:5` → 896×1152 - `5:4` → 1152×896 - `9:16` → 768×1344 - `16:9` → 1344×768 - `21:9` → 1536×672 #### Размер изображения (только Gemini) Установите `image_config.image_size` для управления разрешением генерируемых изображений. Этот параметр в настоящее время поддерживается только моделями Gemini. **Поддерживаемые размеры:** - `1K` → Стандартное разрешение (по умолчанию) - `2K` → Высокое разрешение - `4K` → Максимальное разрешение Вы можете комбинировать `aspect_ratio` и `image_size` в одном запросе: ```bash # Генерация изображения с настройками соотношения сторон и размера curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "google/gemini-2.5-flash-image", "messages": [ { "role": "user", "content": "Создай картину блюда из нано-банана в роскошном ресторане с темой Gemini" } ], "modalities": ["image", "text"], "image_config": { "aspect_ratio": "16:9", "image_size": "4K" } }' ``` ### Потоковая генерация изображений Генерация изображений также работает с потоковыми ответами: ```bash # Потоковая генерация изображения curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "google/gemini-2.5-flash-image", "messages": [ { "role": "user", "content": "Создай изображение футуристического города" } ], "modalities": ["image", "text"], "stream": true }' ``` ## Формат ответа При генерации изображений сообщение ассистента включает поле `images`, содержащее сгенерированные изображения: ```json { "choices": [ { "message": { "role": "assistant", "content": "Я создал для вас красивое изображение заката.", "images": [ { "type": "image_url", "image_url": { "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." } } ] } } ] } ``` ### Формат изображения - **Формат**: Изображения возвращаются как base64-кодированные data URL - **Типы**: Обычно формат PNG (`data:image/png;base64,`) - **Несколько изображений**: Некоторые модели могут генерировать несколько изображений в одном ответе - **Размер**: Размеры изображений зависят от возможностей модели ### Работа с base64 изображениями Для сохранения полученного base64 изображения в файл используйте следующую команду: ```bash # Извлечение base64 данных из JSON ответа и сохранение в файл # Предполагается, что ответ сохранен в response.json cat response.json | jq -r '.choices[0].message.images[0].image_url.url' | \ sed 's/data:image\/png;base64,//' | base64 -d > image.png ``` Для отправки изображения в base64 формате в запросе: ```bash # Кодирование изображения в base64 для использования в запросе IMAGE_BASE64=$(base64 -w 0 image.png) # Использование в запросе curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d "{ \"model\": \"google/gemini-2.5-flash-image\", \"messages\": [ { \"role\": \"user\", \"content\": [ { \"type\": \"text\", \"text\": \"Опиши это изображение\" }, { \"type\": \"image_url\", \"image_url\": { \"url\": \"data:image/png;base64,$IMAGE_BASE64\" } } ] } ] }" ``` ## Совместимость моделей Не все модели поддерживают генерацию изображений. Для использования этой функции: 1. **Проверьте выходные модальности**: Убедитесь, что модель имеет `"image"` в своих `output_modalities` 2. **Установите параметр модальностей**: Включите `"modalities": ["image", "text"]` в ваш запрос 3. **Используйте совместимые модели**: Примеры включают: - `google/gemini-3-pro-image-preview` - `google/gemini-2.5-flash-image` - `openai/gpt-5-image-mini` - `black-forest-labs/flux.2-pro` - Другие модели с возможностями генерации изображений ## Лучшие практики - **Четкие промпты**: Предоставляйте подробные описания для лучшего качества изображений - **Выбор модели**: Выбирайте модели, специально разработанные для генерации изображений - **Обработка ошибок**: Проверяйте наличие поля `images` в ответах перед обработкой - **Ограничения скорости**: Генерация изображений может иметь другие ограничения скорости, чем генерация текста - **Хранение**: Продумайте, как вы будете обрабатывать и хранить данные изображений в формате base64 ## Устранение неполадок **Нет изображений в ответе?** - Убедитесь, что модель поддерживает генерацию изображений (`output_modalities` включает `"image"`) - Проверьте, что вы включили `"modalities": ["image", "text"]` в ваш запрос - Убедитесь, что ваш промпт запрашивает генерацию изображения **Модель не найдена?** - Используйте [страницу моделей](/models) для поиска доступных моделей генерации изображений - Фильтруйте по выходным модальностям, чтобы увидеть совместимые модели --- # PDF документ # Работа с PDF > Отправляйте PDF-документы любой модели на RouterAI. RouterAI поддерживает обработку PDF через API `/api/v1/chat/completions`. PDF можно отправлять как **прямые URL** или **данные в формате base64** в массиве сообщений через тип контента file. Эта функция работает с **любой** моделью на RouterAI. **Поддержка URL**: Отправляйте публично доступные PDF напрямую без скачивания или кодирования **Поддержка Base64**: Требуется для локальных файлов или приватных документов, которые недоступны публично PDF также работают в чате для интерактивного тестирования. Когда модель изначально поддерживает ввод файлов, PDF передается напрямую в модель. Когда модель не поддерживает ввод файлов изначально, RouterAI разберет файл и передаст результаты разбора в запрошенную модель. Вы можете отправлять как PDF, так и другие типы файлов в одном запросе. ## Конфигурация плагина Для настройки обработки PDF используйте параметр `plugins` в вашем запросе. RouterAI предоставляет несколько движков обработки PDF с различными возможностями и ценами: ```json { "plugins": [ { "id": "file-parser", "pdf": { "engine": "cloudflare-ai" } } ] } ``` Доступные движки: - `cloudflare-ai` — для текстовых PDF (бесплатно) - `mistral-ocr` — для отсканированных документов и PDF с изображениями - `native` — для моделей с нативной поддержкой файлов Значение `"pdf-text"` устарело и автоматически интерпретируется как `"cloudflare-ai"`. Существующие запросы с `"pdf-text"` продолжат работать. ## Цены RouterAI предоставляет несколько движков обработки PDF: 1. `mistral-ocr`: лучше всего подходит для отсканированных документов или PDF с изображениями (~450 ₽ за 1 000 страниц). 2. `cloudflare-ai`: конвертирует PDF в markdown через Cloudflare Workers AI (бесплатно, без изображений). 3. `native`: доступен только для моделей, которые поддерживают ввод файлов нативно (оплачивается как входные токены). Если вы явно не указываете движок, RouterAI по умолчанию сначала использует нативные возможности обработки файлов модели, а если они недоступны — `cloudflare-ai`. ## Ограничения OCR на изображения Когда движок `mistral-ocr` извлекает изображения из PDF, RouterAI запрашивает у Mistral не более **8 изображений на PDF** и передаёт не более 8 изображений в нижестоящую модель. Избыточные изображения отбрасываются, при этом весь распознанный текст сохраняется в полном объёме. Это ограничение существует потому, что лимиты на количество изображений в одном запросе значительно различаются у разных провайдеров — некоторые отклоняют запросы с более чем 8 изображениями, а длинные PDF, которые выдают по одному изображению на страницу, часто упираются в лимит контекста. Ограничение в 8 изображений удерживает запросы в рамках лимитов всех поддерживаемых провайдеров. Если ваша нижестоящая модель вообще не принимает изображения на вход, OCR-извлечённые изображения полностью отбрасываются, а в модель передаётся только распознанный текст. ## Использование URL PDF Для публично доступных PDF вы можете отправить URL напрямую без необходимости скачивания и кодирования файла: ```bash curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "anthropic/claude-sonnet-4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Каковы основные моменты в этом документе?" }, { "type": "file", "file": { "filename": "document.pdf", "file_data": "https://bitcoin.org/bitcoin.pdf" } } ] } ], "plugins": [ { "id": "file-parser", "pdf": { "engine": "mistral-ocr" } } ] }' ``` URL PDF работают со всеми движками обработки. Для Mistral OCR URL передается напрямую в сервис. Для других движков RouterAI загружает PDF и обрабатывает его внутренне. ## Использование PDF в формате Base64 Для локальных PDF-файлов или когда вам нужно отправить содержимое PDF напрямую, вы можете закодировать файл в base64: ### Подготовка base64 в Linux ```bash # Кодируем PDF в base64 без переносов строк и сохраняем в файл base64 -w 0 path/to/your/document.pdf > document.b64 ``` Не подставляйте base64 PDF прямо в `curl -d '{...}'` через переменную (`-d '{"file_data":"'"$DATA_URL"'"}'`). У реальных PDF base64-строка занимает сотни килобайт и упирается в лимит длины аргументов командной строки (`ARG_MAX`), из-за чего bash выдаёт `/usr/bin/curl: Слишком длинный список аргументов`. Вместо этого собирайте тело запроса через `jq` (читает base64 из файла, а не из аргумента) и передавайте JSON в curl через stdin (`--data-binary @-`). Примеры ниже используют именно этот подход — он работает с PDF любого размера. Для них нужна утилита `jq`. ### Пример запроса с base64 ```bash # Кодируем PDF в файл (см. выше) base64 -w 0 path/to/your/document.pdf > document.b64 # Собираем тело запроса через jq и передаём в curl через stdin. # --rawfile читает base64 из файла, поэтому ARG_MAX не превышается. jq -n --rawfile pdf document.b64 '{ model: "google/gemma-3-27b-it", messages: [ { role: "user", content: [ { type: "text", text: "Каковы основные моменты в этом документе?" }, { type: "file", file: { filename: "document.pdf", file_data: ("data:application/pdf;base64," + ($pdf | gsub("\\s"; ""))) } } ] } ], plugins: [ { id: "file-parser", pdf: { engine: "cloudflare-ai" } } ] }' | curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ --data-binary @- ``` Разбор PDF будет работать, даже если плагин не указан явно. По умолчанию используется движок, оптимальный для выбранной модели. ## Пропуск затрат на разбор Когда вы отправляете PDF в API, ответ может включать аннотации файлов в сообщении ассистента. Эти аннотации содержат структурированную информацию о разобранном PDF-документе. Отправляя эти аннотации обратно в последующих запросах, вы можете избежать повторного разбора того же PDF-документа, что экономит время обработки и затраты. Вот как повторно использовать аннотации файлов: ### Первый запрос с PDF ```bash # Кодируем PDF в файл base64 -w 0 path/to/your/document.pdf > document.b64 # Первый запрос (тело собираем через jq, отправляем через stdin) RESPONSE=$(jq -n --rawfile pdf document.b64 '{ model: "google/gemma-3-27b-it", messages: [ { role: "user", content: [ { type: "text", text: "Каковы основные моменты в этом документе?" }, { type: "file", file: { filename: "document.pdf", file_data: ("data:application/pdf;base64," + ($pdf | gsub("\\s"; ""))) } } ] } ] }' | curl -s https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ --data-binary @-) # Сохраняем аннотации и ответ ассистента в файлы (используем их в следующем запросе) echo "$RESPONSE" | jq '.choices[0].message.annotations' > annotations.json echo "$RESPONSE" | jq -r '.choices[0].message.content' > assistant.txt ``` ### Последующий запрос с аннотациями ```bash # Последующий запрос. PDF отправляется повторно ВМЕСТЕ с аннотациями: RouterAI # сверяет SHA256 присланных байт с hash в аннотации и переиспользует уже # разобранное содержимое, не вызывая движок разбора заново. jq -n \ --rawfile pdf document.b64 \ --rawfile assistant assistant.txt \ --slurpfile annotations annotations.json '{ model: "google/gemma-3-27b-it", messages: [ { role: "user", content: [ { type: "text", text: "Каковы основные моменты в этом документе?" }, { type: "file", file: { filename: "document.pdf", file_data: ("data:application/pdf;base64," + ($pdf | gsub("\\s"; ""))) } } ] }, { role: "assistant", content: ($assistant | rtrimstr("\n")), annotations: $annotations[0] }, { role: "user", content: "Можете ли вы подробнее рассказать о втором пункте?" } ] }' | curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ --data-binary @- ``` Когда вы включаете аннотации файлов из предыдущего ответа в последующие запросы, RouterAI будет использовать эту предварительно разобранную информацию вместо повторного разбора PDF, что экономит время обработки и затраты. Это особенно полезно для больших документов или при использовании движка `mistral-ocr`, который влечет дополнительные расходы. ## Схема file-аннотаций Когда RouterAI разбирает PDF, ответ включает file-аннотации в сообщении ассистента. JSON Schema: ```json { "$schema": "https://json-schema.org/draft-07/schema", "$defs": { "FileAnnotation": { "type": "object", "required": ["type", "file"], "properties": { "type": { "const": "file" }, "file": { "type": "object", "required": ["hash", "content"], "properties": { "hash": { "type": "string", "description": "Уникальный SHA256 hash разобранного файла" }, "name": { "type": "string", "description": "Исходное имя файла (опционально)" }, "content": { "type": "array", "items": { "$ref": "#/$defs/ContentPart" } } } } } }, "ContentPart": { "oneOf": [ { "type": "object", "required": ["type", "text"], "properties": { "type": { "const": "text" }, "text": { "type": "string" } } }, { "type": "object", "required": ["type", "image_url"], "properties": { "type": { "const": "image_url" }, "image_url": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string", "description": "Data URL вида data:image/png;base64,..." } } } } } ] } } } ``` Массив `content` содержит распознанное содержимое PDF — текстовые блоки и изображения (как base64 data URL). Поле `hash` уникально идентифицирует разобранный файл и используется для пропуска повторного разбора, если вы включаете аннотацию в последующие запросы. ## Формат ответа API вернет ответ в следующем формате: ```json { "id": "gen-1234567890", "provider": "DeepInfra", "model": "google/gemma-3-27b-it", "object": "chat.completion", "created": 1234567890, "choices": [ { "message": { "role": "assistant", "content": "Документ обсуждает...", "annotations": [ { "type": "file", "file": { "hash": "abc123...", "name": "document.pdf", "content": [ { "type": "text", "text": "Распознанное содержимое..." }, { "type": "image_url", "image_url": { "url": "data:image/png;base64,..." } } ] } } ] } } ], "usage": { "prompt_tokens": 1000, "completion_tokens": 100, "total_tokens": 1100 } } ``` ## Ошибки с разобранными аннотациями Если RouterAI успешно разобрал PDF, но провайдер инференса затем вернул ошибку, аннотации всё равно возвращаются в поле `error.metadata.file_annotations` ответа с ошибкой. Структура совпадает с `FileAnnotation` из success-ответа, поэтому вы можете передать тот же массив обратно в RouterAI при повторной попытке и пропустить повторный разбор. Это применимо к движкам `mistral-ocr` и `cloudflare-ai`, которые разбирают PDF до отправки в модель. Движок `native` не выдаёт аннотации, поскольку файл передаётся напрямую в модель. ```json { "error": "Provider returned an error", "metadata": { "file_annotations": [ { "type": "file", "file": { "hash": "abc123...", "name": "document.pdf", "content": [ { "type": "text", "text": "Распознанное содержимое..." } ] } } ] } } ``` --- # Аудио # Аудио входные данные > Отправляйте аудиофайлы моделям с поддержкой речи через API RouterAI. RouterAI поддерживает отправку аудиофайлов совместимым моделям через API. Это руководство покажет вам, как работать с аудио, используя наш API. **Примечание**: Аудиофайлы должны быть **закодированы в base64** - прямые URL не поддерживаются для аудиоконтента. ## Аудио входные данные Запросы с аудиофайлами к совместимым моделям доступны через API [`/api/v1/chat/completions`](https://routerai.ru/docs/reference#tag/chat-completions) с типом контента `input_audio`. Аудиофайлы должны быть закодированы в base64 и включать спецификацию формата. Обратите внимание, что только модели с возможностями обработки аудио будут обрабатывать эти запросы. Вы можете найти модели с поддержкой аудио, отфильтровав по модальности аудио входа на нашей [странице моделей](/models?input_modalities[]=audio). ### Отправка аудиофайлов Чтобы отправить аудиофайл, закодируйте его в base64 и передайте в массиве `content` сообщения с типом `input_audio`. Вместе с аудио укажите текстовый блок с вашим вопросом или инструкцией. Структура запроса: 1. `type: "input_audio"` — тип блока контента для аудио 2. `input_audio.data` — содержимое файла, закодированное в base64 3. `input_audio.format` — формат файла (`wav`, `mp3`, `flac` и др.) #### Пример запроса cURL ```bash BASE64_AUDIO=$(base64 -w 0 ./audio.wav) curl -X POST https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d @- << EOF { "model": "openai/gpt-audio", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Пожалуйста, расшифруйте этот аудиофайл." }, { "type": "input_audio", "input_audio": { "data": "$BASE64_AUDIO", "format": "wav" } } ] } ] } EOF ``` ### Поддерживаемые форматы аудио Поддерживаемые форматы аудио различаются в зависимости от провайдера. Распространенные форматы включают: - `wav` - WAV аудио - `mp3` - MP3 аудио - `aiff` - AIFF аудио - `aac` - AAC аудио - `ogg` - OGG Vorbis аудио - `flac` - FLAC аудио - `m4a` - M4A аудио - `pcm16` - PCM16 аудио - `pcm24` - PCM24 аудио **Примечание:** Проверьте документацию вашей модели, чтобы подтвердить, какие форматы аудио она поддерживает. Не все модели поддерживают все форматы. --- # Генерация аудио # Генерация аудио > Генерируйте аудио ответ с помощью AI-моделей через RouterAI API. RouterAI поддерживает генерацию аудио через модели OpenAI с возможностями аудио выхода. Эти модели могут создавать **речевые ответы** из текстовых промптов в потоковом режиме. ## Доступные модели Для генерации аудио доступны следующие модели OpenAI: - `openai/gpt-audio` - GPT Audio - `openai/gpt-audio-mini` - GPT Audio Mini (оптимизированная версия) - `openai/gpt-4o-audio-preview` - GPT-4o Audio Preview Все модели поддерживают генерацию речи с различными голосами и работают только в потоковом режиме. ## Доступные голоса Модели генерации аудио поддерживают следующие голоса: - `alloy` - Нейтральный голос - `ash` - Выразительный голос - `ballad` - Мелодичный голос - `coral` - Теплый голос - `echo` - Резонирующий голос - `fable` - Повествовательный голос - `onyx` - Глубокий голос - `nova` - Энергичный голос - `sage` - Мудрый голос - `shimmer` - Яркий голос - `verse` - Ритмичный голос ## Использование API Для генерации аудио необходимо отправить запрос на эндпоинт [`/api/v1/chat/completions`](https://routerai.ru/docs/reference#tag/chat-completions) с обязательными параметрами: - `stream: true` - генерация поддерживается только в потоковом режиме - `modalities: ["text", "audio"]` - указание модальностей вывода - `audio` - конфигурация аудио с голосом и форматом ### Базовая генерация аудио ```bash # Базовый запрос на генерацию аудио curl -X POST "https://routerai.ru/api/v1/chat/completions" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-audio-mini", "modalities": ["text", "audio"], "messages": [ {"role": "user", "content": "Расскажи о зарождении вселенной"} ], "audio": { "voice": "alloy", "format": "pcm16" }, "stream": true }' ``` ### Параметры конфигурации аудио #### Выбор голоса Установите **voice** параметр для выбора голоса генерируемого аудио. Доступны 11 различных голосов с разными характеристиками. ```bash # Генерация аудио с конкретным голосом curl -X POST "https://routerai.ru/api/v1/chat/completions" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-audio-mini", "modalities": ["text", "audio"], "messages": [ {"role": "user", "content": "Объясни квантовую физику простыми словами"} ], "audio": { "voice": "nova", "format": "pcm16" }, "stream": true }' ``` #### Формат аудио В настоящее время поддерживается формат `pcm16` (PCM 16-bit, mono, 24kHz). ## Формат ответа При генерации аудио ответ приходит в виде потока Server-Sent Events (SSE). Каждое событие содержит chunk с аудио данными в формате base64: ```json { "choices": [ { "delta": { "audio": { "data": "base64_encoded_pcm_data..." } } } ] } ``` ### Обработка потокового ответа Аудио данные приходят в виде base64-кодированных PCM16 chunks, которые необходимо: 1. Декодировать из base64 2. Накопить все chunks 3. Сохранить как PCM файл 4. При необходимости конвертировать в другой формат (например, MP3) ## Пример: Генерация и сохранение в MP3 Полный пример на Python для генерации аудио и сохранения в MP3 формат: ```python import base64 import json import subprocess import requests url = "https://routerai.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "openai/gpt-audio-mini", "modalities": ["text", "audio"], "messages": [ { "role": "system", "content": "Ты математик, говори на русском языке, пользователь будет задавать вопрос, а ты отвечай очень кратко, 1-2 слова и без лишних рассуждений." }, { "role": "user", "content": "сколько будет один в квадрате?" } ], "audio": { "voice": "alloy", "format": "pcm16" }, "stream": True } # Накопление PCM chunks pcm_chunks = bytearray() with requests.post(url, headers=headers, json=payload, stream=True) as r: r.raise_for_status() for raw_line in r.iter_lines(decode_unicode=True): if not raw_line: continue # SSE: каждая строка вида "data: {...}" или "data: [DONE]" if not raw_line.startswith("data: "): continue data = raw_line[6:] if data == "[DONE]": break try: chunk = json.loads(data) except json.JSONDecodeError: continue # Извлекаем audio.data из delta choices = chunk.get("choices", []) if not choices: continue delta = choices[0].get("delta", {}) audio = delta.get("audio", {}) audio_b64 = audio.get("data") if audio_b64: # Декодируем base64 в байты PCM16 pcm_chunks += base64.b64decode(audio_b64) # Сохраняем сырой PCM pcm_path = "output.pcm" with open(pcm_path, "wb") as f: f.write(pcm_chunks) # Конвертация в MP3 через ffmpeg # PCM16: 16-bit, mono, 24kHz mp3_path = "output.mp3" subprocess.run([ "ffmpeg", "-y", "-f", "s16le", # PCM16 little-endian "-ar", "24000", # sample rate 24kHz "-ac", "1", # mono "-i", pcm_path, "-codec:a", "libmp3lame", "-q:a", "4", mp3_path ], check=True) print(f"Saved: {mp3_path}") ``` ### Конвертация PCM в другие форматы После получения PCM файла вы можете конвертировать его в различные форматы с помощью ffmpeg: ```bash # Конвертация в MP3 ffmpeg -y -f s16le -ar 24000 -ac 1 -i output.pcm -codec:a libmp3lame -q:a 4 output.mp3 # Конвертация в WAV ffmpeg -y -f s16le -ar 24000 -ac 1 -i output.pcm output.wav # Конвертация в OGG ffmpeg -y -f s16le -ar 24000 -ac 1 -i output.pcm -codec:a libvorbis output.ogg ``` ## Важные требования При работе с генерацией аудио необходимо соблюдать следующие требования: 1. **Потоковый режим обязателен**: Установите `"stream": true` в запросе 2. **Указание модальностей**: Обязательно укажите `"modalities": ["text", "audio"]` 3. **Конфигурация аудио**: Необходимо указать объект `audio` с параметрами `voice` и `format` 4. **Обработка потока**: Реализуйте корректную обработку SSE событий ## Лучшие практики - **Выбор модели**: Используйте [`openai/gpt-audio-mini`](https://routerai.ru/models/openai/gpt-audio-mini) для быстрой генерации, [`openai/gpt-audio`](https://routerai.ru/models/openai/gpt-audio) для более качественного результата - **Выбор голоса**: Тестируйте разные голоса для вашего use case - каждый голос имеет свои характеристики - **Обработка ошибок**: Проверяйте статус ответа и корректность JSON в SSE событиях - **Хранение**: Конвертируйте PCM в сжатые форматы (MP3, OGG) для экономии места - **Системные промпты**: Используйте системные промпты для управления стилем и длиной ответа - **Буферизация**: Накапливайте все chunks перед сохранением для получения полного аудио ## Устранение неполадок **Нет аудио данных в ответе?** - Убедитесь, что установлен `"stream": true` - Проверьте наличие `"modalities": ["text", "audio"]` в запросе - Убедитесь, что объект `audio` с параметрами `voice` и `format` указан корректно **Ошибка при обработке потока?** - Проверьте корректность парсинга SSE формата (строки начинаются с `"data: "`) - Убедитесь, что обрабатываете событие `"data: [DONE]"` для завершения потока - Проверьте корректность декодирования base64 данных **Проблемы с воспроизведением аудио?** - Убедитесь, что используете правильные параметры для PCM16: 16-bit, mono, 24kHz - Проверьте, что все chunks были корректно декодированы и объединены - Используйте ffmpeg для конвертации в стандартные форматы (MP3, WAV) ## Совместимость моделей Генерация аудио доступна только для моделей OpenAI с поддержкой аудио выхода: - [`openai/gpt-audio`](https://routerai.ru/models/openai/gpt-audio) - [`openai/gpt-audio-mini`](https://routerai.ru/models/openai/gpt-audio-mini) - [`openai/gpt-4o-audio-preview`](https://routerai.ru/models/openai/gpt-4o-audio-preview) Для работы с аудио входными данными см. руководство [Аудио входные данные](/docs/guides/overview/multimodal/audio). --- # Преобразование речи в текст # Преобразование речи в текст > Расшифровывайте аудио в текст через выделенный эндпоинт RouterAI API. RouterAI поддерживает преобразование речи в текст (STT, speech-to-text) через выделенный эндпоинт `/api/v1/audio/transcriptions`. Отправьте аудио в кодировке base64 и получите JSON-ответ с распознанным текстом и статистикой использования. **Примечание**: Аудио передаётся как **строка base64** (сырые байты, не data URI). Расшифровку выполняют только модели с поддержкой транскрибации. ## Поиск моделей Модели с поддержкой STT можно найти на нашей [странице моделей](https://routerai.ru/models?output_modalities[]=transcription), отфильтровав по модальности аудио. Примеры моделей: `openai/whisper-large-v3`, `openai/whisper-1`. ## Использование API Отправьте `POST` запрос на [`/api/v1/audio/transcriptions`](https://routerai.ru/docs/reference#tag/transcription) с JSON-телом, содержащим аудио в base64. В ответ придёт JSON с распознанным текстом и статистикой использования. ### Структура запроса 1. `model` — идентификатор STT-модели (например, `openai/whisper-large-v3`) 2. `input_audio.data` — содержимое аудиофайла в кодировке base64 3. `input_audio.format` — формат файла (`mp3`, `wav`, `flac`, `m4a`, `ogg`, `webm`, `aac`) ### Пример запроса cURL ```bash # Кодируем аудиофайл в base64 BASE64_AUDIO=$(base64 -w 0 ./audio.wav) curl -X POST https://routerai.ru/api/v1/audio/transcriptions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d @- << EOF { "model": "openai/whisper-large-v3", "input_audio": { "data": "$BASE64_AUDIO", "format": "wav" } } EOF ``` ### Пример на Python ```python import requests import base64 with open("audio.wav", "rb") as f: base64_audio = base64.b64encode(f.read()).decode("utf-8") response = requests.post( url="https://routerai.ru/api/v1/audio/transcriptions", headers={ "Authorization": "Bearer $ROUTERAI_API_KEY", "Content-Type": "application/json", }, json={ "model": "openai/whisper-large-v3", "input_audio": { "data": base64_audio, "format": "wav", }, }, ) result = response.json() print(result["text"]) ``` ### Пример на TypeScript (fetch) ```typescript import fs from 'fs'; const audioBuffer = await fs.promises.readFile('audio.wav'); const base64Audio = audioBuffer.toString('base64'); const response = await fetch('https://routerai.ru/api/v1/audio/transcriptions', { method: 'POST', headers: { Authorization: `Bearer ${process.env.ROUTERAI_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'openai/whisper-large-v3', input_audio: { data: base64Audio, format: 'wav', }, }), }); const result = await response.json(); console.log(result.text); ``` ### Параметры запроса | Параметр | Тип | Обязательный | Описание | | -------------------- | ------ | ------------ | --------------------------------------------------------------------------------- | | `model` | string | Да | STT-модель для запроса (например, `openai/whisper-large-v3`) | | `input_audio` | object | Да | Аудио для расшифровки | | `input_audio.data` | string | Да | Аудио в кодировке base64 (сырые байты, не data URI) | | `input_audio.format` | string | Да | Формат аудио (`mp3`, `wav`, `flac`, `m4a`, `ogg`, `webm`, `aac`) | | `language` | string | Нет | Язык в формате ISO-639-1 (например, `"ru"`, `"en"`). По умолчанию определяется автоматически | | `temperature` | number | Нет | Температура семплирования. Меньшие значения дают более детерминированный результат | ## Формат ответа Эндпоинт возвращает JSON-ответ с распознанным текстом: ```json { "text": "Привет, это тест преобразования речи в текст.", "usage": { "seconds": 9.2, "total_tokens": 113, "input_tokens": 83, "output_tokens": 30, "cost": 0.000508 } } ``` ### Поля ответа | Поле | Тип | Описание | | --------------------- | ------ | --------------------------------------------------- | | `text` | string | Распознанный текст | | `usage.seconds` | number | Длительность входного аудио в секундах | | `usage.total_tokens` | number | Всего использовано токенов (вход + выход) | | `usage.input_tokens` | number | Количество тарифицированных входных токенов | | `usage.output_tokens` | number | Количество сгенерированных выходных токенов | | `usage.cost` | number | Полная стоимость запроса в USD | ### Заголовки ответа | Заголовок | Описание | | ----------------- | ---------------------------------------------------------------------- | | `X-Generation-Id` | Уникальный ID генерации для запроса — полезен для отслеживания и отладки | ## Поддерживаемые форматы аудио Поддерживаемые форматы зависят от провайдера. Распространённые форматы: | Формат | MIME-тип | Описание | | ------ | ------------ | --------------------------------------- | | `wav` | `audio/wav` | Несжатое аудио, наивысшее качество | | `mp3` | `audio/mpeg` | Сжатое аудио, широкая совместимость | | `flac` | `audio/flac` | Сжатие без потерь | | `m4a` | `audio/mp4` | Аудио MPEG-4 | | `ogg` | `audio/ogg` | Аудио Ogg Vorbis | | `webm` | `audio/webm` | Аудио WebM, частое для записей в браузере | | `aac` | `audio/aac` | Advanced Audio Coding | **Примечание:** Проверьте документацию вашей модели, чтобы подтвердить поддерживаемые форматы. Не все модели поддерживают все форматы. ## Тарификация STT-модели используют разные схемы тарификации в зависимости от провайдера: - **По длительности** (например, OpenAI Whisper): оплата за секунду входного аудио - **По токенам** (например, новые модели OpenAI): оплата за входные/выходные токены, как у текстовых моделей Стоимость каждой модели можно посмотреть на [странице моделей](https://routerai.ru/models?output_modalities[]=transcription). Поле `usage.cost` в ответе показывает фактическую стоимость запроса. ## Отличия от аудио входных данных RouterAI предлагает два способа обработки аудио: 1. **Преобразование речи в текст** (эта страница): выделенный эндпоинт `/api/v1/audio/transcriptions`, оптимизированный под транскрибацию. Возвращает структурированный JSON с текстом и статистикой использования. Лучший выбор для перевода аудио в текст. 2. **Аудио во входных данных чата** ([Аудио входные данные](/docs/guides/overview/multimodal/audio)): аудио передаётся в составе запроса `/api/v1/chat/completions` через тип контента `input_audio`. Модель обрабатывает аудио вместе с текстом и отвечает в диалоговом формате. Лучший выбор для анализа аудио, ответов на вопросы по содержанию и комбинирования модальностей. ## Лучшие практики - **Выбор формата**: WAV даёт лучшее качество для транскрибации. MP3 и другие сжатые форматы работают хорошо, но могут немного снижать точность на пограничном аудио - **Размер файла**: Очень длинные записи разбивайте на сегменты покороче. Максимальный размер тела запроса — 32 МБ - **Кодирование base64**: Аудио передаётся как строка base64 (сырые байты, не data URI). В большинстве языков есть встроенные средства base64-кодирования - **Указание языка**: Если язык известен заранее, передайте `language` в формате ISO-639-1 — это повышает точность и скорость ## Устранение неполадок **Пустая или неверная расшифровка?** - Убедитесь, что формат аудио совпадает с полем `format` в запросе - Проверьте, что качество аудио достаточно для распознавания - При необходимости укажите параметр `language` **Запрос завершается с ошибкой размера?** - Тело запроса не должно превышать 32 МБ. Разбейте длинные записи на сегменты покороче - Сжатые форматы (MP3, AAC) дают меньший размер и передаются быстрее **Модель не найдена?** - Найдите доступные STT-модели на [странице моделей](https://routerai.ru/models?output_modalities[]=transcription) - Проверьте корректность идентификатора модели (например, `openai/whisper-large-v3`, а не `whisper-large-v3`) **Ошибка аутентификации?** - Убедитесь, что используете действительный API-ключ из [вашего дашборда](https://routerai.ru/settings/keys) - Эндпоинт STT использует ту же аутентификацию, что и Chat Completions API --- # Синтез речи # Синтез речи > Синтезируйте речь из текста через выделенный эндпоинт RouterAI API. RouterAI поддерживает синтез речи (TTS, text-to-speech) через выделенный эндпоинт `/api/v1/audio/speech`, совместимый с [OpenAI Audio Speech API](https://platform.openai.com/docs/api-reference/audio/createSpeech). Отправьте текст и получите в ответ поток сырых байтов аудио в выбранном формате. **Примечание**: Ответ эндпоинта — **бинарный поток аудио**, а не JSON. Его можно сразу записать в файл или передать аудиоплееру. ## Поиск моделей Модели с поддержкой TTS можно найти на нашей [странице моделей](https://routerai.ru/models?output_modalities[]=speech), отфильтровав по модальности аудио на выходе. Примеры моделей: `x-ai/grok-voice-tts-1.0`, `openai/gpt-4o-mini-tts`. ## Использование API Отправьте `POST` запрос на [`/api/v1/audio/speech`](https://routerai.ru/docs/reference#tag/speech) с текстом, который нужно озвучить. Ответ — поток сырых байтов аудио (не JSON), поэтому его можно направить напрямую в файл. ### Структура запроса 1. `model` — идентификатор TTS-модели (например, `x-ai/grok-voice-tts-1.0`) 2. `input` — текст для синтеза речи 3. `voice` — идентификатор голоса (набор голосов зависит от модели) 4. `response_format` — формат выходного аудио (`mp3` или `pcm`) ### Пример запроса cURL ```bash curl -X POST https://routerai.ru/api/v1/audio/speech \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ --output output.mp3 \ -d '{ "model": "x-ai/grok-voice-tts-1.0", "input": "Привет! Это пример синтеза речи.", "voice": "eve", "response_format": "mp3" }' ``` ### Пример на Python ```python import requests response = requests.post( url="https://routerai.ru/api/v1/audio/speech", headers={ "Authorization": "Bearer $ROUTERAI_API_KEY", "Content-Type": "application/json", }, json={ "model": "x-ai/grok-voice-tts-1.0", "input": "Привет! Это пример синтеза речи.", "voice": "eve", "response_format": "mp3", }, ) response.raise_for_status() with open("output.mp3", "wb") as f: f.write(response.content) generation_id = response.headers.get("X-Generation-Id") print(f"Аудио сохранено. ID генерации: {generation_id}") ``` ### Пример на TypeScript (fetch) ```typescript const response = await fetch('https://routerai.ru/api/v1/audio/speech', { method: 'POST', headers: { Authorization: `Bearer ${process.env.ROUTERAI_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'x-ai/grok-voice-tts-1.0', input: 'Привет! Это пример синтеза речи.', voice: 'eve', response_format: 'mp3', }), }); if (!response.ok) { const err = await response.json(); throw new Error(`Ошибка TTS ${response.status}: ${JSON.stringify(err)}`); } const audioBuffer = await response.arrayBuffer(); const generationId = response.headers.get('X-Generation-Id'); console.log(`ID генерации: ${generationId}`); // Сохраните audioBuffer в файл или воспроизведите напрямую ``` ### Параметры запроса | Параметр | Тип | Обязательный | Описание | | ----------------- | ------ | ------------ | ------------------------------------------------------------------------------------------------ | | `model` | string | Да | TTS-модель для запроса (например, `x-ai/grok-voice-tts-1.0`) | | `input` | string | Да | Текст для синтеза речи | | `voice` | string | Да | Идентификатор голоса. Набор голосов зависит от модели — смотрите страницу модели на [странице моделей](https://routerai.ru/models) | | `response_format` | string | Нет | Формат выходного аудио: `mp3` или `pcm` | | `speed` | number | Нет | Множитель скорости воспроизведения. Используется только моделями с его поддержкой (например, OpenAI TTS); остальными провайдерами игнорируется | ## Формат ответа Эндпоинт возвращает **поток сырых байтов аудио**, а не JSON. В ответе присутствуют следующие заголовки: | Заголовок | Описание | | ----------------- | ------------------------------------------------------------------------------ | | `Content-Type` | MIME-тип аудио: `audio/mpeg` для формата `mp3`, `audio/pcm` для формата `pcm` | | `X-Generation-Id` | Уникальный ID генерации для запроса — полезен для отслеживания и отладки | ### Форматы вывода | Формат | Content-Type | Описание | | ------ | ------------ | --------------------------------------------------------------------------------- | | `mp3` | `audio/mpeg` | Сжатое аудио, меньший размер файла. Подходит для хранения и воспроизведения | | `pcm` | `audio/pcm` | Несжатое сырое аудио. Низкая задержка, подходит для потоковых конвейеров реального времени | ## Тарификация TTS-модели тарифицируются **посимвольно** — за количество символов входного текста. Стоимость зависит от модели и провайдера. Стоимость за символ для каждой модели можно посмотреть на [странице моделей](https://routerai.ru/models). ## Совместимость с OpenAI SDK Эндпоинт TTS полностью совместим с OpenAI SDK. Достаточно указать клиентским библиотекам OpenAI базовый URL RouterAI: ```python from openai import OpenAI client = OpenAI( api_key="$ROUTERAI_API_KEY", base_url="https://routerai.ru/api/v1", ) # Без стриминга: получаем полный ответ с аудио response = client.audio.speech.create( model="x-ai/grok-voice-tts-1.0", input="На дворе трава, на траве дрова.", voice="eve", response_format="mp3", ) response.write_to_file("output.mp3") # Стриминг: обрабатываем аудио-чанки по мере поступления with client.audio.speech.with_streaming_response.create( model="x-ai/grok-voice-tts-1.0", input="На дворе трава, на траве дрова.", voice="eve", response_format="mp3", ) as response: response.stream_to_file("output.mp3") ``` ```typescript import OpenAI from 'openai'; import fs from 'fs'; const client = new OpenAI({ apiKey: process.env.ROUTERAI_API_KEY, baseURL: 'https://routerai.ru/api/v1', }); const response = await client.audio.speech.create({ model: 'x-ai/grok-voice-tts-1.0', input: 'На дворе трава, на траве дрова.', voice: 'eve', response_format: 'mp3', }); const buffer = Buffer.from(await response.arrayBuffer()); await fs.promises.writeFile('output.mp3', buffer); console.log('Аудио сохранено в output.mp3'); ``` ## Лучшие практики - **Выбор формата**: Используйте `mp3` для хранения и обычного воспроизведения. Используйте `pcm` для потоковых конвейеров реального времени, где важна задержка - **Выбор голоса**: Разные провайдеры предлагают разные голоса. Сверьтесь с документацией модели или поэкспериментируйте с доступными голосами, чтобы подобрать подходящий под ваш сценарий - **Длина текста**: Очень длинные тексты разбивайте на сегменты покороче и объединяйте получившееся аудио. Это повышает надёжность и снижает задержку до первого аудиофрагмента. Максимальный размер тела запроса — 32 МБ - **Параметр скорости**: `speed` поддерживается только некоторыми провайдерами (например, OpenAI) и молча игнорируется теми, кто его не поддерживает ## Устранение неполадок **Пустой или повреждённый аудиофайл?** - Убедитесь, что `response_format` совпадает с тем, как вы сохраняете файл (например, не сохраняйте вывод `pcm` с расширением `.mp3`) - Проверьте статус ответа — ответы со статусом не 200 возвращают JSON с ошибкой, а не аудио **Модель не найдена?** - Найдите доступные TTS-модели на [странице моделей](https://routerai.ru/models?output_modalities[]=speech) - Проверьте корректность идентификатора модели (например, `x-ai/grok-voice-tts-1.0`, а не `grok-voice-tts`) **Голос недоступен?** - Набор голосов зависит от провайдера. Сверьтесь с документацией провайдера на предмет поддерживаемых идентификаторов голосов - У каждой модели свой набор голосов — полный список смотрите на странице модели на [странице моделей](https://routerai.ru/models?output_modalities[]=speech) --- # Видео # Видео входные данные > Отправляйте видеофайлы моделям с поддержкой видео через API RouterAI. RouterAI поддерживает отправку видеофайлов совместимым моделям через API. Это руководство покажет вам, как работать с видео, используя наш API. RouterAI поддерживает как **прямые URL**, так и **base64-кодированные data URL** для видео: - **URL**: Эффективны для публично доступных видео, так как не требуют локального кодирования - **Base64 Data URL**: Требуются для локальных файлов или приватных видео, которые не являются публично доступными **Важно:** Поддержка видео URL различается у разных провайдеров. RouterAI отправляет видео URL только тем провайдерам, которые явно их поддерживают. Например, Google Gemini на AI Studio поддерживает только ссылки YouTube (не Vertex AI). **Только API:** Видео входные данные в настоящее время поддерживаются только через API. Загрузка видео недоступна в интерфейсе чата RouterAI в данный момент. ## Видео входные данные Запросы с видеофайлами к совместимым моделям доступны через API `/api/v1/chat/completions` с типом контента `video_url`. `url` может быть либо URL, либо base64-кодированным data URL. Обратите внимание, что только модели с возможностями обработки видео будут обрабатывать эти запросы. Вы можете искать модели с поддержкой видео, фильтруя по модальности видео входа на нашей [странице Моделей](/models?input_modalities[]=video). ### Использование видео URL Вот как отправить видео, используя URL. Обратите внимание, что для Google Gemini на AI Studio поддерживаются только ссылки YouTube: ```bash curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "google/gemini-2.5-flash", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Пожалуйста, опишите, что происходит в этом видео." }, { "type": "video_url", "video_url": { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" } } ] } ] }' ``` ### Использование Base64 кодированных видео Для локально хранящихся видео вы можете отправлять их, используя base64 кодирование как data URL: **Подготовка base64 кодированного видео в Linux:** ```bash # Кодирование видеофайла в base64 и сохранение в переменную VIDEO_BASE64=$(base64 -w 0 path/to/your/video.mp4) # Создание data URL VIDEO_DATA_URL="data:video/mp4;base64,$VIDEO_BASE64" ``` **Отправка запроса с base64 видео:** ```bash # Сначала кодируем видео VIDEO_BASE64=$(base64 -w 0 path/to/your/video.mp4) VIDEO_DATA_URL="data:video/mp4;base64,$VIDEO_BASE64" # Затем отправляем запрос curl https://routerai.ru/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "google/gemini-2.5-flash", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Что в этом видео?" }, { "type": "video_url", "video_url": { "url": "'"$VIDEO_DATA_URL"'" } } ] } ] }' ``` ## Поддерживаемые форматы видео RouterAI поддерживает следующие форматы видео: - `video/mp4` - `video/mpeg` - `video/mov` - `video/webm` ## Распространенные случаи использования Видео входы позволяют реализовать широкий спектр приложений: - **Суммаризация видео**: Генерация текстовых резюме видеоконтента - **Распознавание объектов и действий**: Идентификация объектов, людей и действий в видео - **Понимание сцены**: Описание обстановки, окружения и контекста - **Анализ спорта**: Анализ игрового процесса, движений и тактики - **Наблюдение**: Мониторинг и анализ записей с камер безопасности - **Образовательный контент**: Анализ обучающих видео и предоставление инсайтов ## Лучшие практики ### Соображения по размеру файла Видеофайлы могут быть большими, что влияет как на время загрузки, так и на стоимость обработки: - **Сжимайте видео**, когда это возможно, чтобы уменьшить размер файла без значительной потери качества - **Обрезайте видео**, чтобы включить только релевантные сегменты - **Учитывайте разрешение**: Более низкие разрешения (например, 720p вместо 4K) уменьшают размер файла, сохраняя при этом пригодность для большинства задач анализа - **Частота кадров**: Более низкая частота кадров может уменьшить размер файла для видео, где высокое временное разрешение не критично ### Оптимальная длина видео Разные модели могут иметь разные ограничения на продолжительность видео: - Проверьте документацию конкретной модели на максимальную длину видео - Для длинных видео рассмотрите разделение на более короткие сегменты - Сосредоточьтесь на ключевых моментах, а не отправляйте весь длинный контент ### Компромиссы между качеством и размером Балансируйте качество видео с практическими соображениями: - **Высокое качество** (1080p+, высокий битрейт): Лучше всего для детального визуального анализа, обнаружения объектов, распознавания текста - **Среднее качество** (720p, умеренный битрейт): Подходит для большинства общих задач анализа - **Низкое качество** (480p, низкий битрейт): Приемлемо для базового понимания сцены и распознавания действий ## Поддержка видео URL у конкретных провайдеров Поддержка видео URL значительно различается у разных провайдеров: - **Google Gemini (AI Studio)**: Поддерживает только ссылки YouTube (например, `https://www.youtube.com/watch?v=...`) - **Google Gemini (Vertex AI)**: Не поддерживает видео URL - используйте вместо этого base64-кодированные data URL - **Другие провайдеры**: Проверьте документацию конкретной модели на поддержку видео URL ## Устранение неполадок **Видео не обрабатывается?** - Убедитесь, что модель поддерживает видео вход (проверьте, что `input_modalities` включает `"video"`) - Если используете видео URL, подтвердите, что провайдер поддерживает видео URL (см. раздел "Поддержка видео URL у конкретных провайдеров" выше) - Для Gemini на AI Studio убедитесь, что используете ссылку YouTube, а не прямой URL видеофайла - Если видео URL не работает, попробуйте использовать base64-кодированный data URL вместо этого - Проверьте, что формат видео поддерживается - Убедитесь, что видеофайл не поврежден **Ошибки с большими файлами?** - Сжмите видео, чтобы уменьшить размер файла - Уменьшите разрешение видео или частоту кадров - Обрежьте видео до более короткой продолжительности - Проверьте ограничения на размер файла для конкретной модели - Рассмотрите использование видео URL (если поддерживается провайдером) вместо base64 кодирования для больших файлов **Плохие результаты анализа?** - Убедитесь, что качество видео достаточно для задачи - Предоставьте четкие, конкретные промпты о том, что нужно проанализировать - Рассмотрите, подходит ли продолжительность видео для модели - Проверьте, хорошо ли виден и освещен контент видео --- # Генерация видео # Генерация видео > Генерируйте видео из текстовых промптов через RouterAI API. RouterAI поддерживает генерацию видео через модели, у которых `"video"` указан в `output_modalities`. Генерация **асинхронная**: вы создаёте задачу, а готовое видео получаете позже — опросом статуса (polling) или через webhook на ваш `callback_url`. Полный жизненный цикл: 1. **Создание** — `POST /api/v1/videos` возвращает `id` задачи и `polling_url`. 2. **Ожидание** — опрашивайте статус (`GET /api/v1/videos/{id}`) **или** получите webhook, если указали `callback_url`. 3. **Скачивание** — когда статус `completed`, заберите mp4 через content-эндпоинт. ## Поиск моделей Модели для генерации видео — это модели с `"video"` в `output_modalities`. Найти их можно: - на [странице моделей](/models), отфильтровав по выходным модальностям; - запросом общего каталога моделей `GET /api/v1/models` — видео-модели отличаются значением `video` в `architecture.output_modalities`: ```bash curl https://routerai.ru/api/v1/models \ -H "Authorization: Bearer $ROUTERAI_API_KEY" ``` ## Шаг 1. Создание генерации Отправьте `POST /api/v1/videos` с обязательными `model` и `prompt`. Необязательное поле `callback_url` — HTTPS-адрес, на который придёт webhook о готовности (см. [Шаг 3](#шаг-3-webhook-о-готовности)). ```bash curl https://routerai.ru/api/v1/videos \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -d '{ "model": "x-ai/grok-imagine-video", "prompt": "Кот в скафандре медленно плывёт в невесомости на космической станции, кинематографичный свет", "aspect_ratio": "16:9", "duration": 4, "resolution": "480p", "callback_url": "https://example.com/hooks/routerai-video" }' ``` Ответ `202 Accepted` — задача принята: ```json { "id": "Cq4gNzomlZDrNyy72GHC", "status": "pending", "polling_url": "https://routerai.ru/api/v1/videos/Cq4gNzomlZDrNyy72GHC" } ``` - `id` — идентификатор задачи (используется во всех последующих запросах). - `status` — текущий статус (`pending` сразу после создания). - `polling_url` — URL для опроса статуса (указывает на домен RouterAI). ## Шаг 2. Поллинг статуса Опрашивайте статус задачи, пока он не станет терминальным: ```bash curl https://routerai.ru/api/v1/videos/Cq4gNzomlZDrNyy72GHC \ -H "Authorization: Bearer $ROUTERAI_API_KEY" ``` Статусы: | Статус | Тип | Значение | |---|---|---| | `pending` | промежуточный | задача создана | | `in_progress` | промежуточный | видео генерируется | | `completed` | успех | готово — можно скачивать | | `failed` | терминальная ошибка | ошибка генерации (см. поле `error`) | | `cancelled` | терминальная ошибка | задача отменена | | `expired` | терминальная ошибка | срок хранения результата истёк | Ответ для готовой задачи (`completed`): ```json { "id": "Cq4gNzomlZDrNyy72GHC", "status": "completed", "polling_url": "https://routerai.ru/api/v1/videos/Cq4gNzomlZDrNyy72GHC", "unsigned_urls": [ "https://routerai.ru/api/v1/videos/Cq4gNzomlZDrNyy72GHC/content?index=0" ], "usage": { "cost": 18.2 } } ``` `unsigned_urls` — ссылки на content-эндпоинт RouterAI; по ним скачивается готовое видео (см. [Шаг 4](#шаг-4-скачивание-видео)). Вместо опроса в цикле удобнее указать `callback_url` при создании — тогда RouterAI сам уведомит вас о готовности, и поллинг не нужен. ## Шаг 3. Webhook о готовности Если при создании указан `callback_url`, RouterAI отправит на него `POST` с JSON-телом, когда задача достигнет терминального статуса (`completed`, `failed`, `expired`, `cancelled`). Это избавляет от постоянного опроса статуса. ### Что приходит ```json { "type": "video.generation.completed", "created_at": "2026-01-01T00:00:00.000Z", "data": { "id": "Cq4gNzomlZDrNyy72GHC", "status": "completed", "generation_id": "gen-abc123", "model": "x-ai/grok-imagine-video", "unsigned_urls": [ "https://routerai.ru/api/v1/videos/Cq4gNzomlZDrNyy72GHC/content?index=0" ], "usage": { "cost": 18.2 } } } ``` - `type` — тип события, одно из: - `video.generation.completed` - `video.generation.failed` - `video.generation.expired` - `video.generation.cancelled` - `data.unsigned_urls` — ссылки на content-эндпоинт RouterAI (только при `completed`). - `data.usage.cost` — стоимость в рублях (только при `completed`). - `data.error` — текст ошибки (для `failed`/`expired`). Заголовки запроса: | Заголовок | Значение | |---|---| | `Content-Type` | `application/json` | | `X-RouterAI-Timestamp` | момент отправки, unix-секунды | | `X-RouterAI-Signature` | HMAC-SHA256 в hex (см. ниже) | ### Подпись Подпись считается над строкой `"."`, где `body` — **сырое тело запроса** (та же JSON-строка, что пришла): ``` signature = HMAC_SHA256(secret, ".") ``` Особенность RouterAI: **отдельный секрет не нужен** — секретом служит SHA-256-дайджест вашего API-ключа в hex. То есть вы вычисляете секрет прямо из своего ключа: ``` secret = sha256_hex(ROUTERAI_API_KEY) ``` Так подпись можно проверить, имея только свой API-ключ. Запрос подписывается ключом, которым была создана задача. Считайте HMAC именно по полученным байтам тела, а не по результату `JSON.parse` + повторной сериализации — иначе порядок ключей и пробелы изменят дайджест, и сверка ложно не сойдётся. ### Как проверить подпись 1. Прочитайте `X-RouterAI-Timestamp` и **сырое** тело запроса (до парсинга JSON). 2. Вычислите `secret = sha256_hex(api_key)`. 3. Пересчитайте `HMAC_SHA256(secret, ".")` и сравните с `X-RouterAI-Signature` **в постоянном времени** (constant-time), не обычным `==`. 4. Проверьте свежесть `timestamp` (например, ±5 минут) — защита от повторного воспроизведения (replay). #### Node.js (Express) ```js const crypto = require("crypto"); // важно получить сырое тело: app.use(express.raw({ type: "application/json" })) app.post("/hooks/routerai-video", (req, res) => { const apiKey = process.env.ROUTERAI_API_KEY; const ts = req.get("X-RouterAI-Timestamp"); const sig = req.get("X-RouterAI-Signature"); const rawBody = req.body; // Buffer // свежесть метки времени (анти-replay) if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) { return res.status(401).end(); } // секрет = sha256(api_key) в hex const secret = crypto.createHash("sha256").update(apiKey).digest("hex"); const expected = crypto .createHmac("sha256", secret) .update(`${ts}.${rawBody}`) .digest("hex"); const ok = sig && sig.length === expected.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected)); if (!ok) return res.status(401).end(); const event = JSON.parse(rawBody.toString("utf8")); // ... ваша логика: event.type, event.data.unsigned_urls ... res.status(200).end(); }); ``` #### Python (Flask) ```python import os, hmac, hashlib, time from flask import request, abort @app.post("/hooks/routerai-video") def routerai_video(): api_key = os.environ["ROUTERAI_API_KEY"] ts = request.headers.get("X-RouterAI-Timestamp", "") sig = request.headers.get("X-RouterAI-Signature", "") raw = request.get_data() # bytes, сырое тело if abs(time.time() - int(ts)) > 300: abort(401) # секрет = sha256(api_key) в hex secret = hashlib.sha256(api_key.encode()).hexdigest() expected = hmac.new(secret.encode(), f"{ts}.".encode() + raw, hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): abort(401) event = request.get_json() # ... ваша логика: event["type"], event["data"]["unsigned_urls"] ... return "", 200 ``` ### Доставка и ретраи - Доставка считается успешной при ответе **HTTP 2xx**. Любой другой код или таймаут — неуспех. - При неуспехе RouterAI повторяет отправку: до **10 попыток** с экспоненциальной задержкой (несколько часов суммарно). - Бюджет одной попытки — около **8 секунд** (на установку соединения и ответ). - Endpoint должен быть **публично доступен** — RouterAI не подключается к адресам внутри приватных сетей (защита от SSRF). ## Шаг 4. Скачивание видео Когда статус `completed`, скачайте готовое видео через content-эндпоинт. `index` — позиция ссылки в массиве `unsigned_urls` (по умолчанию `0`): ```bash curl "https://routerai.ru/api/v1/videos/Cq4gNzomlZDrNyy72GHC/content?index=0" \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -o video.mp4 ``` Эндпоинт отдаёт бинарный mp4. Если модель вернула несколько видео, в `unsigned_urls` будет несколько ссылок — скачайте каждую, меняя `index` (`?index=1`, `?index=2`, …). ## Устранение неполадок **Не приходит webhook?** - Убедитесь, что `callback_url` — валидный **HTTPS**-адрес и публично доступен (приватные сети блокируются). - Endpoint должен отвечать **2xx**; при ошибках/таймаутах RouterAI ретраит, но после исчерпания попыток перестаёт. - Webhook отправляется только при терминальном статусе (`completed`/`failed`/`expired`/`cancelled`). **Подпись не сходится?** - Считайте HMAC по **сырым байтам** тела, без `JSON.parse` + пересериализации. - Секрет — это `sha256_hex(api_key)` именно того ключа, которым создавалась задача, а не сам ключ и не отдельный секрет. - Подписываемая строка — `"."` (timestamp, точка, тело). **Статус `failed` или `expired`?** - Смотрите `data.error` (в webhook) или поле `error` в ответе поллинга. - `expired` означает, что срок хранения результата истёк — создайте задачу заново. --- # Обзор плагинов # Плагины > Расширяйте возможности AI-моделей с помощью плагинов: веб-поиск, обработка PDF, исправление JSON и сжатие контекста. Плагины RouterAI позволяют расширить стандартные возможности языковых моделей прямо в API-запросе. Их не нужно настраивать заранее — достаточно передать параметр `plugins` в запрос, и модель получит доступ к дополнительным инструментам. ## Доступные плагины | Плагин | ID | Описание | |--------|----|----------| | Веб-поиск | `web` | Дополняет ответы актуальными результатами из интернета | | Работа с PDF | `file-parser` | Анализ и извлечение содержимого из загруженных PDF-файлов. | ## Как подключить плагины Для активации плагина добавьте массив `plugins` в тело запроса: ```bash curl https://routerai.ru/api/v1/chat/completions \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-4o", "plugins": [{"id": "web"}], "messages": [ {"role": "user", "content": "Какие последние новости в области AI?"} ] }' ``` ## Быстрое включение веб-поиска Для удобного использования веб-поиска добавьте `:online` к идентификатору модели: ```json { "model": "openai/gpt-4o:online", "messages": [ {"role": "user", "content": "Последние новости о ChatGPT"} ] } ``` Это эквивалентно явному указанию плагина `web`. ## Разделы - [Веб-поиск →](/docs/guides/overview/plugins/web-search) - [Работа с PDF →](/docs/guides/overview/multimodal/pdfs) --- # Веб-поиск # Веб-поиск > Добавьте актуальные данные из интернета в ответы AI-моделей с помощью плагина веб-поиска. Плагин веб-поиска позволяет моделям получать актуальную информацию из интернета в режиме реального времени. Это особенно полезно для запросов о текущих событиях, свежих данных и информации, появившейся после даты обучения модели. ## Способы активации ### Суффикс `:online` (рекомендуется для простых случаев) Добавьте `:online` к идентификатору любой модели: ```json { "model": "openai/gpt-4o:online", "messages": [ {"role": "user", "content": "Какой курс доллара сейчас?"} ] } ``` ### Явное указание плагина Для расширенной настройки используйте массив `plugins`: ```bash curl https://routerai.ru/api/v1/chat/completions \ -H "Authorization: Bearer $ROUTERAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-4o", "plugins": [ { "id": "web", "max_results": 5, "search_prompt": "Ищи актуальные и достоверные источники" } ], "messages": [ {"role": "user", "content": "Какой курс доллара сейчас?"} ] }' ``` ## Поисковые движки RouterAI поддерживает несколько поисковых движков. Укажите предпочтительный через параметр `engine`: | Движок | Описание | |--------|----------| | `native` | Нативный поиск через инструменты провайдера (Anthropic, OpenAI, Perplexity, xAI) | | `exa` | Поиск Exa — комбинирует ключевые слова и семантические эмбеддинги | ```json { "plugins": [ { "id": "web", "engine": "exa", "max_results": 10 } ] } ``` ## Параметры настройки | Параметр | Тип | По умолчанию | Описание | |----------|-----|-------------|----------| | `max_results` | integer | 5 | Максимальное количество результатов поиска | | `search_prompt` | string | — | Системный промпт для поисковых запросов | | `engine` | string | `native` | Поисковый движок | | `include_domains` | string[] | — | Список разрешённых доменов | | `exclude_domains` | string[] | — | Список исключённых доменов | ## Фильтрация по доменам Ограничьте поиск определёнными сайтами или исключите нежелательные источники: ```json { "plugins": [ { "id": "web", "include_domains": ["wikipedia.org", "arxiv.org"], "exclude_domains": ["example.com"] } ] } ``` Поддерживаются шаблоны с подстановочными символами. Совместимость зависит от движка: у нативных провайдеров могут быть ограничения — например, у Anthropic фильтры `include_domains` и `exclude_domains` взаимоисключающие. ## Структура ответа Результаты поиска возвращаются в стандартном формате OpenAI Chat Completion с аннотациями `url_citation`: ```json { "role": "assistant", "content": "По данным на сегодня, курс рубля составляет...", "annotations": [ { "type": "url_citation", "url_citation": { "url": "https://example.com/article", "title": "Курс рубля сегодня", "content": "Актуальный курс по данным биржи...", "start_index": 25, "end_index": 80 } } ] } ``` ## Стоимость Стоимость веб-поиска добавляется к обычной стоимости генерации токенов: | Движок | Стоимость | |--------|-----------| | Exa | ~450₽ за 1 000 результатов (~2.2 ₽ за запрос при настройках по умолчанию) | | Native | Зависит от провайдера и объёма поискового контекста (low/medium/high) |