# Обзор AllTokens > Единый API для доступа к 400+ моделям через совместимый с OpenAI интерфейс. AllTokens — это единый API для доступа к большим языковым моделям. Вы подключаете один адрес API, один ключ и сразу получаете доступ к сотням моделей от разных поставщиков. **Адрес API:** `https://api.alltokens.ru/api/v1` **Check.** Если у вас уже есть код на библиотеках OpenAI, чаще всего достаточно заменить адрес API, вставить ключ AllTokens и выбрать модель вроде `alltokens/auto`. ## Почему разработчики начинают с AllTokens - Один API вместо десятков: Один метод доступа для текстовых моделей, эмбеддингов и генерации изображений без отдельной интеграции под каждого провайдера. - Работает без VPN: Удобно для российских команд, локальных продуктов и рабочих сервисов, которым нужен стабильный доступ к LLM. - Маршрутизация и переключение: Модели `alltokens/auto` и `alltokens/free`, фильтры по моделям и ограничения помогают быстро выбрать рабочий маршрут. ## С чего начать - [Быстрый старт](https://docs.alltokens.ru/quickstart.md): Пройдите путь от регистрации до первого ответа за 5 минут. - [Авторизация](https://docs.alltokens.ru/authentication.md): Узнайте, где взять API-ключ и как передавать его в совместимые клиенты. - [Чат с моделью](https://docs.alltokens.ru/api/chat-completions.md): Основной метод для работы с сообщениями, потоковым ответом и маршрутизацией. ## Как устроена документация - [Основы](https://docs.alltokens.ru/concepts/models.md): Сначала поймите, как выбирать модели, провайдеров и роутинг под свою задачу. - [Справочник API](https://docs.alltokens.ru/api/chat-completions.md): Затем переходите к точным описаниям методов и рабочим примерам запросов и ответов. - [Интеграции](https://docs.alltokens.ru/guides/openai-sdk.md): Готовые инструкции для библиотек OpenAI, Cursor, Claude Code, n8n и LangChain. - [Вопросы и ошибки](https://docs.alltokens.ru/guides/faq.md): Быстрые ответы на типовые вопросы по ключам, моделям и потоковому режиму. ## Что вы можете сделать уже сегодня #### Запустить первый запрос Используйте `model: "alltokens/auto"` и отправьте стандартный `POST /chat/completions`. Это самый короткий путь к рабочему ответу без ручного выбора конкретной модели. #### Подобрать модель Откройте [`/api/models`](https://docs.alltokens.ru/api/models.md), посмотрите `context_length` и `supported_parameters`, а затем зафиксируйте конкретную модель в коде. #### Отладить маршрут Если вам важно понимать, что именно выбрал маршрутизатор, используйте [`/api/route-preview`](https://docs.alltokens.ru/api/route-preview.md), [`/api/generation`](https://docs.alltokens.ru/api/generation.md) и [`/api/route-explain`](https://docs.alltokens.ru/api/route-explain.md). ## Что читать дальше - [Быстрый старт](https://docs.alltokens.ru/quickstart.md): Первый рабочий запрос и ответ. - [Модели](https://docs.alltokens.ru/concepts/models.md): Когда брать `alltokens/auto`, а когда фиксированную модель. - [Библиотеки OpenAI](https://docs.alltokens.ru/guides/openai-sdk.md): Подключение существующего приложения без переписывания клиента. # Быстрый старт > Первый запрос к AllTokens за 5 минут: регистрация, ключ, curl и библиотеки OpenAI. ## Что понадобится - Аккаунт AllTokens - API-ключ из [личного кабинета](https://alltokens.ru/dashboard) - Любой HTTP-клиент или библиотека OpenAI **Info.** Все примеры в этой документации используют рабочий адрес `https://api.alltokens.ru/api/v1`. ## От регистрации до первого ответа #### Создайте аккаунт и откройте личный кабинет Зарегистрируйтесь в AllTokens и перейдите в раздел с ключами API. Если вы только что создали аккаунт, это будет ваша первая основная страница. #### Создайте API-ключ Выпустите новый ключ и сохраните его. Дальше вы будете передавать его в заголовке `Authorization` или в настройках совместимого клиента. #### Сделайте первый запрос с model=alltokens/auto Начните с `alltokens/auto`. Эта routing-модель снимает с вас выбор конкретной модели и помогает быстро проверить интеграцию. #### Проверьте ответ и ID генерации В успешном ответе вы увидите `choices[0].message.content` и `id`. Этот `id` пригодится, если потом захотите посмотреть сведения о выполненном запросе и выбранном маршруте. ## Первый запрос ```bash curl curl -X POST "https://api.alltokens.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "alltokens/auto", "messages": [ {"role": "system", "content": "Отвечай кратко и по делу."}, {"role": "user", "content": "Скажи привет в одном слове"} ] }' ``` ```python Python (библиотека OpenAI) from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="alltokens/auto", messages=[{"role": "user", "content": "Скажи привет в одном слове"}], ) print(response.choices[0].message.content) ``` ```typescript TypeScript (библиотека OpenAI) import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.alltokens.ru/api/v1", apiKey: "YOUR_API_KEY", }); const response = await client.chat.completions.create({ model: "alltokens/auto", messages: [{ role: "user", content: "Скажи привет в одном слове" }], }); console.log(response.choices[0].message.content); ``` ## Что вы увидите в ответе ```json response.json { "id": "gen-...", "object": "chat.completion", "model": "openai/gpt-4.1-mini", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Привет!" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 18, "completion_tokens": 2, "total_tokens": 20, "cost": 0.34 } } ``` **Check.** Если вы получили `choices[0].message.content`, значит интеграция уже работает. Дальше можно выбрать конкретную модель, включить потоковый режим или задать ограничения маршрутизации. ## Когда переходить от `alltokens/auto` к конкретной модели На старте используйте `alltokens/auto`. Когда появится понятная задача, переходите на фиксированную модель: ```json "model": "anthropic/claude-sonnet-4" ``` Полный список смотрите в [`GET /api/models`](https://docs.alltokens.ru/api/models.md) и в разделе [Модели](https://docs.alltokens.ru/concepts/models.md). ## Потоковый ответ Добавьте `"stream": true` в тело запроса. Ответ придёт фрагментами в формате серверных событий. ```bash curl -X POST "https://api.alltokens.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "alltokens/auto", "messages": [{"role": "user", "content": "Посчитай от 1 до 5"}], "stream": true }' ``` **Note.** После потокового запроса используйте `id` из ответа и вызовите [`GET /api/route/explain`](https://docs.alltokens.ru/api/route-explain.md) или [`GET /api/generation`](https://docs.alltokens.ru/api/generation.md), если хотите узнать, какая модель и какой провайдер сработали фактически. ## Частые вопросы #### Когда оставаться на model: "alltokens/auto", а когда фиксировать модель? Оставайтесь на `alltokens/auto`, пока проверяете интеграцию или не определились с рабочим профилем. Фиксируйте модель, когда вам уже важны повторяемость поведения, конкретные возможности модели или предсказуемый результат. #### Почему ответ пришёл не от той модели, которую я ожидал? Если вы используете `alltokens/auto` или `alltokens/free`, платформе разрешено выбирать фактическую модель сама. Чтобы увидеть итоговый выбор, сохраните `id` ответа и проверьте [`/api/route/explain`](https://docs.alltokens.ru/api/route-explain.md) или [`/api/generation`](https://docs.alltokens.ru/api/generation.md). #### Нужно ли сразу включать stream? Нет. Для первого успешного запроса проще начать без `stream`, убедиться, что интеграция работает, и только потом добавлять потоковый режим для UI, где важна выдача по мере генерации. #### Что проверить, если первый запрос не сработал? Сначала проверьте `Authorization`, `base_url`, JSON-тело и то, что вы используете `POST /api/v1/chat/completions`. После этого уже имеет смысл разбирать коды ответа и ограничения клиента. ## Что читать дальше - [Авторизация](https://docs.alltokens.ru/authentication.md): Где взять ключ и как передавать его в библиотеках и HTTP-клиентах. - [Чат с моделью](https://docs.alltokens.ru/api/chat-completions.md): Полное описание главного метода. - [Маршрутизация](https://docs.alltokens.ru/concepts/routing.md): Модели `alltokens/auto` и `alltokens/free`, цели и ограничения. - [Интеграции](https://docs.alltokens.ru/guides/openai-sdk.md): Готовые настройки для библиотек OpenAI, Cursor, Claude Code, n8n и LangChain. # Авторизация > Как получить API-ключ AllTokens и авторизовать запросы. AllTokens использует API-ключи в стиле OpenAI: вы получаете ключ в личном кабинете и передаёте его в заголовке `Authorization: Bearer`. ## Где взять ключ 1. Откройте [личный кабинет](https://alltokens.ru/dashboard) 2. Перейдите в раздел с ключами API 3. Создайте новый ключ 4. Сохраните его сразу после выпуска **Warning.** Полное значение ключа обычно показывается только в момент создания. Если вы его потеряли, безопаснее выпустить новый ключ, а старый отозвать. ## Основной способ авторизации ```http request Authorization: Bearer ``` Это рекомендуемый способ для `curl`, библиотек OpenAI, серверных приложений и интеграций. ## Пример запроса ```bash curl -X POST "https://api.alltokens.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "alltokens/auto", "messages": [{"role": "user", "content": "Hi"}]}' ``` ## Библиотеки OpenAI ```python Python from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) ``` ```typescript TypeScript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.alltokens.ru/api/v1", apiKey: "YOUR_API_KEY", }); ``` ## Что важно помнить **Info.** Для production-окружения храните ключ только на сервере и не встраивайте его в публичный фронтенд-код. ## Типовые ошибки - `401 Unauthorized` — ключ не передан, передан в неверном заголовке или был отозван. - `429 Too Many Requests` — вы превысили допустимую частоту запросов. ## Частые вопросы #### Где безопасно хранить API-ключ? Храните ключ в серверных переменных окружения, секретах CI/CD или в backend-конфиге. Не кладите его в публичный репозиторий, фронтенд-бандл или клиентское приложение без серверной прослойки. #### Можно ли использовать ключ во фронтенде? Для production-сценариев лучше не использовать. Если ключ попадает в браузер, его намного проще утечь, скопировать или использовать вне вашего приложения. #### Что делать, если ключ потерян или мог утечь? Безопаснее всего отозвать старый ключ и выпустить новый. Если есть сомнения, лучше считать ключ скомпрометированным и не продолжать им пользоваться. ## Что читать дальше - [Авторизация в API](https://docs.alltokens.ru/api/authentication.md): Та же тема в справочном разделе API. - [Быстрый старт](https://docs.alltokens.ru/quickstart.md): Минимальный рабочий запрос и базовая интеграция за пару минут. # Выбор модели > Как выбирать модели в AllTokens: когда использовать alltokens/auto, а когда фиксировать конкретную модель. В AllTokens выбор модели обычно начинается не с каталога, а с ответа на простой вопрос: вам нужен быстрый старт или предсказуемое рабочее поведение. ## Самое короткое правило #### Я только интегрируюсь Начните с `model: "alltokens/auto"`. Это самый быстрый способ проверить, что ключ, сеть и формат запросов уже работают. #### Мне нужна рабочая схема Переходите на фиксированную модель, когда вам важны стабильное качество, повторяемость цены, совместимость с tools или конкретный контекст. #### Мне нужен бесплатный режим Используйте `model: "alltokens/free"`, если хотите запускать запросы по бесплатному пулу и готовы к ограничениям по доступности и качеству. ## Какие варианты есть - alltokens/auto: Routing-модель для автоматического выбора. Удобно для старта, рабочих сервисов и быстрых экспериментов. - Конкретная модель: Прямой вызов вроде `anthropic/claude-sonnet-4` или `openai/gpt-4.1-mini`. Подходит для стабильной рабочей схемы. - alltokens/free: Бесплатная routing-модель для тестов и недорогих сценариев. ## На что смотреть в каталоге Когда вы открываете [`GET /api/models`](https://docs.alltokens.ru/api/models.md), в первую очередь смотрите на: - `context_length` — сколько контекста реально помещается - `supported_parameters` — какие параметры и функции модель понимает - `architecture.input_modalities` и `output_modalities` — умеет ли модель работать с изображениями, аудио и так далее ## Практический выбор #### Начните с задачи Для поддержки чатов чаще всего достаточно текстовой модели с хорошим качеством и умеренной ценой. Для поиска по смыслу понадобятся эмбеддинги. #### Проверьте поддерживаемые параметры Если вам нужны инструменты, потоковый режим или большой контекст, убедитесь, что модель это поддерживает. #### Зафиксируйте модель в коде После успешного теста замените `alltokens/auto` на конкретный `model`, если важна предсказуемость. ## Частые вопросы #### Когда alltokens/auto лучше фиксированной модели? `alltokens/auto` лучше на старте, для быстрых экспериментов и для сценариев, где вы хотите делегировать платформе выбор подходящей модели без ручного подбора. #### Когда фиксированная модель лучше alltokens/auto? Когда вам нужны повторяемое поведение, конкретные возможности модели, согласованный quality bar или жёсткий контроль над тем, какая модель используется в продакшене. #### Как выбрать первую рабочую модель для продакшена? Возьмите рабочий пользовательский сценарий, проверьте 2-3 кандидата на реальных запросах, сравните качество, скорость и совместимость с нужными параметрами, затем зафиксируйте лучший вариант в коде. #### Что важнее при выборе: цена, скорость или качество? Это зависит от продукта. Для первого выбора полезно определить один главный приоритет, а не пытаться оптимизировать всё сразу: UX чаще чувствителен к скорости, production-контент к качеству, массовые фоны и батчи к стоимости. ## Полезные страницы - [Каталог моделей](https://docs.alltokens.ru/api/models.md): Полная справка по каталогу моделей. - [Провайдеры](https://docs.alltokens.ru/concepts/providers.md): Чем отличается модель от провайдера и как работает переключение между ними. # Каталог моделей > Единый каталог моделей AllTokens: список, фильтрация и схема ответа GET /api/v1/models. `GET /api/v1/models` возвращает каталог доступных моделей и их свойства. Здесь можно посмотреть список моделей, сравнить возможности и выбрать подходящий вариант для поля `model`. ## Параметры запроса Каталог моделей поддерживает параметры запроса для фильтрации списка. ### `output_modalities` Фильтр по типу результата, который умеет отдавать модель. Принимает список значений через запятую или значение `"all"`, если нужно получить все модели без фильтрации по типу результата. | Значение | Что означает | | --- | --- | | `text` | Модели, которые возвращают текст | | `image` | Модели, которые создают изображения | | `audio` | Модели, которые возвращают звук | | `embeddings` | Модели эмбеддингов | | `all` | Все модели без фильтрации по типу результата | Примеры: ```bash # По умолчанию — текстовые модели curl "https://api.alltokens.ru/api/v1/models" # Только модели для изображений curl "https://api.alltokens.ru/api/v1/models?output_modalities=image" # Текстовые и графические модели curl "https://api.alltokens.ru/api/v1/models?output_modalities=text,image" # Все модели без фильтрации curl "https://api.alltokens.ru/api/v1/models?output_modalities=all" ``` ### `supported_parameters` Фильтр по параметрам API, которые понимает модель. Например, так можно найти модели с поддержкой `tools`: ```bash curl "https://api.alltokens.ru/api/v1/models?supported_parameters=tools" ``` ## Стандарт каталога моделей Справочник моделей AllTokens отдаёт самые важные сведения о каждой доступной модели в едином формате. Это позволяет не разбирать ответ отдельно под каждого поставщика и использовать один и тот же формат в рабочем коде. ## Схема ответа API `GET /api/v1/models` возвращает JSON-объект со списком моделей в поле `data`. ### Корневой объект ответа ```json { "data": [ /* Массив объектов модели */ ] } ``` ### Объект модели Каждый элемент массива `data` содержит стандартизированные поля: | Поле | Тип | Что означает | | --- | --- | --- | | `id` | `string` | Уникальный идентификатор модели для запросов API, например `"openai/gpt-4.1-mini"` | | `canonical_slug` | `string` | Постоянный символьный идентификатор модели | | `name` | `string` | Человекочитаемое название модели | | `created` | `number` | Время добавления модели в каталог в формате Unix-времени | | `description` | `string` | Подробное описание возможностей модели | | `context_length` | `number` | Максимальный размер контекстного окна в токенах | | `architecture` | `object` | Технические возможности модели | | `pricing` | `object` | Структура стоимости для этой модели | | `top_provider` | `object` | Основные сведения о базовом поставщике | | `per_request_limits` | `object \| null` | Ограничения на один запрос, если они есть | | `supported_parameters` | `string[]` | Список поддерживаемых параметров API | | `default_parameters` | `object \| null` | Значения параметров по умолчанию, если они заданы | | `expiration_date` | `string \| null` | Дата вывода из эксплуатации, если модель помечена к отключению | ### Объект `architecture` ```typescript { "input_modalities": string[], // Поддерживаемые типы входа: ["file", "image", "text"] "output_modalities": string[], // Поддерживаемые типы результата: ["text"] "tokenizer": string, // Способ разбиения текста на токены "instruct_type": string | null // Формат инструкций, если применимо } ``` ### Объект `pricing` Все значения стоимости передаются строками. ```typescript { "prompt": string, // Стоимость входных токенов "completion": string, // Стоимость выходных токенов "request": string, // Фиксированная стоимость запроса "image": string, // Стоимость входного изображения "web_search": string, // Стоимость веб-поиска "internal_reasoning": string, // Стоимость внутренних токенов рассуждения "input_cache_read": string, // Стоимость чтения из входного кэша "input_cache_write": string // Стоимость записи во входной кэш } ``` ### Объект `top_provider` ```typescript { "context_length": number, // Ограничение контекста у основного поставщика "max_completion_tokens": number, // Максимальный размер ответа "is_moderated": boolean // Применяется ли модерация содержимого } ``` ## Поддерживаемые параметры Поле `supported_parameters` показывает, какие OpenAI-совместимые параметры реально работают у конкретной модели: - `tools` — вызов инструментов - `tool_choice` — управление выбором инструмента - `max_tokens` — ограничение длины ответа - `temperature` — управление вариативностью - `top_p` — ядерная выборка - `reasoning` — внутренний режим рассуждения - `include_reasoning` — возврат рассуждений в ответе - `structured_outputs` — строгий вывод по схеме JSON - `response_format` — формат результата - `stop` — пользовательские стоп-последовательности - `frequency_penalty` — снижение повторов - `presence_penalty` — повышение тематического разнообразия - `seed` — воспроизводимый результат **Note.** Разные модели по-разному считают токены Разные модели используют разные токенизаторы. Поэтому даже при одинаковом входе и одинаковом ответе число токенов может отличаться. Фактические значения смотрите в `usage` у конкретного ответа. ## Как использовать каталог на практике #### Сначала отфильтруйте модели по типу результата Если вам нужен текст, изображения, звук или эмбеддинги, начните с `output_modalities`. #### Потом проверьте поддерживаемые параметры Если вам нужны `tools`, `response_format`, `reasoning` или другие функции, смотрите `supported_parameters`. #### После этого сравните контекст и свойства Проверьте `context_length`, `architecture`, `pricing` и `top_provider`, чтобы выбрать рабочий вариант под вашу задачу. # Мультимодальность > Как работать с изображениями, PDF и аудио в AllTokens через совместимый API. AllTokens поддерживает не только текстовые запросы. Если выбранная модель умеет работать с другими типами входа, вы можете передавать изображения, PDF и аудио через тот же совместимый API. ## Какие типы данных поддерживаются ### Изображения Изображения можно отправлять в модели с поддержкой зрения для разбора, описания, извлечения текста и других сценариев. [Подробнее о вводе изображений →](https://docs.alltokens.ru/concepts/image-inputs.md) ### Генерация изображений Если модель умеет возвращать изображения, через AllTokens можно не только анализировать картинки, но и создавать их по текстовому описанию. [Подробнее о генерации изображений →](https://docs.alltokens.ru/concepts/image-generation.md) ### PDF PDF-документы можно передавать моделям, которые умеют работать с файловым вводом. Это удобно для разбора документов, инструкций, отчётов и договоров. [Подробнее о PDF →](https://docs.alltokens.ru/concepts/pdf-inputs.md) ### Аудио Аудио можно использовать там, где модель поддерживает звуковой ввод или звуковой результат. Такие сценарии подходят для расшифровки, разбора речи и голосовых интерфейсов. [Подробнее об аудио →](https://docs.alltokens.ru/concepts/audio.md) ## С чего начать Большинство мультимодальных сценариев используют тот же `POST /api/v1/chat/completions` и параметр `messages`. Тип содержимого указывается внутри массива `content`. - изображения: `image_url` - PDF: `file` - аудио: `input_audio` В одном запросе можно сочетать несколько типов данных, если это поддерживает выбранная модель. ## Совместимость моделей Не каждая модель поддерживает все типы ввода и вывода. Перед интеграцией проверьте: - `architecture.input_modalities` — какие типы данных модель принимает - `architecture.output_modalities` — что модель умеет возвращать - `supported_parameters` — какие параметры действительно работают с этой моделью Для этого откройте [Каталог моделей](https://docs.alltokens.ru/api/models.md) и подберите подходящий вариант под ваш сценарий. ## Форматы передачи Для мультимодального ввода обычно используются два подхода: ### URL Подходит для общедоступных файлов, когда модель или поставщик умеет забирать содержимое по ссылке. - изображения: `https://example.com/image.jpg` - PDF: `https://example.com/document.pdf` ### Base64 Подходит для локальных файлов и закрытого содержимого, когда нужно передать данные прямо в запросе. - изображения: `data:image/jpeg;base64,...` - PDF: `data:application/pdf;base64,...` - аудио: base64-данные с указанием формата **Info.** URL обычно удобнее для крупных файлов, потому что не раздувает тело запроса. Base64 полезен для локальных файлов и закрытого содержимого, которое нельзя отдать по публичной ссылке. ## Частые вопросы #### Можно ли смешивать разные типы данных в одном запросе? Да, если выбранная модель это поддерживает. В одном запросе можно сочетать текст, изображения, PDF, аудио и другие типы входа. #### Как понять, поддерживает ли модель аудио? Смотрите `architecture.input_modalities` и `architecture.output_modalities` в [Каталоге моделей](https://docs.alltokens.ru/api/models.md). Это главный ориентир при выборе модели под мультимодальный сценарий. #### Как считается стоимость мультимодального запроса? Это зависит от модели, поставщика и типа данных. Ориентируйтесь на `pricing` в каталоге моделей и на фактические поля `usage` в ответе конкретного запроса. # Изображения > Как передавать изображения в мультимодальные модели AllTokens через /api/v1/chat/completions. Запросы с изображениями отправляются через `POST /api/v1/chat/completions` с массивом `messages`. Внутри `content` используется элемент типа `image_url`, а само изображение можно передать либо по URL, либо в виде base64-строки. Если вы передаёте несколько изображений, добавляйте их отдельными элементами массива `content`. Обычно удобнее сначала передать текстовую инструкцию, а затем изображения. AllTokens поддерживает два основных способа передачи изображений: - URL: удобнее для публично доступных файлов - base64: нужен для локальных файлов и закрытых изображений ## Передача изображения по URL Вот пример запроса, где изображение передаётся по ссылке: ```python Python import requests url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "google/gemini-3.1-flash", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Что изображено на этой картинке?" }, { "type": "image_url", "image_url": { "url": "https://upload.wikimedia.org/wikipedia/commons/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg" } } ] } ] } response = requests.post(url, headers=headers, json=payload) print(response.json()) ``` ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'google/gemini-3.1-flash', messages: [ { role: 'user', content: [ { type: 'text', text: 'Что изображено на этой картинке?', }, { type: 'image_url', image_url: { url: 'https://upload.wikimedia.org/wikipedia/commons/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg', }, }, ], }, ], }), }); const data = await response.json(); console.log(data); ``` ```python Python (библиотека OpenAI) from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="google/gemini-3.1-flash", messages=[ { "role": "user", "content": [ {"type": "text", "text": "Что изображено на этой картинке?"}, { "type": "image_url", "image_url": { "url": "https://upload.wikimedia.org/wikipedia/commons/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg" }, }, ], } ], ) print(response) ``` ## Передача изображения в base64 Для локальных изображений и непубличных файлов используйте base64. В этом случае в `image_url.url` передаётся `data:`-строка. ```python Python import base64 import requests def encode_image_to_base64(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode("utf-8") base64_image = encode_image_to_base64("path/to/your/image.jpg") data_url = f"data:image/jpeg;base64,{base64_image}" url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "google/gemini-3.1-flash", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Что изображено на этой картинке?" }, { "type": "image_url", "image_url": { "url": data_url } } ] } ] } response = requests.post(url, headers=headers, json=payload) print(response.json()) ``` ```typescript TypeScript (fetch) import { readFile } from 'node:fs/promises'; async function encodeImageToBase64(imagePath: string): Promise { const imageBuffer = await readFile(imagePath); const base64Image = imageBuffer.toString('base64'); return `data:image/jpeg;base64,${base64Image}`; } const base64Image = await encodeImageToBase64('path/to/your/image.jpg'); const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'google/gemini-3.1-flash', messages: [ { role: 'user', content: [ { type: 'text', text: 'Что изображено на этой картинке?', }, { type: 'image_url', image_url: { url: base64Image, }, }, ], }, ], }), }); const data = await response.json(); console.log(data); ``` ```python Python (библиотека OpenAI) import base64 from openai import OpenAI def encode_image_to_base64(image_path): with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode("utf-8") base64_image = encode_image_to_base64("path/to/your/image.jpg") data_url = f"data:image/jpeg;base64,{base64_image}" client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="google/gemini-3.1-flash", messages=[ { "role": "user", "content": [ {"type": "text", "text": "Что изображено на этой картинке?"}, { "type": "image_url", "image_url": { "url": data_url }, }, ], } ], ) print(response) ``` ## Поддерживаемые типы изображений - `image/png` - `image/jpeg` - `image/webp` - `image/gif` ## Что важно помнить **Info.** URL удобнее для публичных изображений и крупных файлов: тело запроса получается меньше, а код проще. Base64 нужен, если файл лежит локально или недоступен по публичной ссылке. ## Частые вопросы #### Можно ли передать несколько изображений в одном запросе? Да. Для этого добавьте несколько элементов `image_url` в массив `content`. Допустимое число изображений зависит от модели и поставщика. #### Текст должен идти до изображения или после? Обычно лучше сначала передать текстовую инструкцию, а затем изображение. Так модель проще понимает задачу. Если картинка должна идти первой, лучше объяснить контекст в `system`-сообщении. #### Как понять, поддерживает ли модель изображения? Смотрите `architecture.input_modalities` в [Каталоге моделей](https://docs.alltokens.ru/api/models.md). Если там есть нужный тип ввода, модель подходит для такого сценария. # Генерация изображений > Как создавать изображения через AllTokens и какие параметры для этого использовать. Генерация изображений доступна у моделей, которые умеют возвращать `image` в `output_modalities`. Такие модели создают изображения по текстовому описанию и, в зависимости от модели, могут одновременно возвращать и текстовый ответ. ## Как найти подходящую модель Подобрать модели для генерации изображений можно несколькими способами. ### Через каталог моделей В [Каталоге моделей](https://alltokens.ru/models) можно отфильтровать модели по `output_modalities` и оставить только те, которые умеют возвращать изображения. ```bash # Только модели для генерации изображений curl "https://api.alltokens.ru/api/v1/models?output_modalities=image" # Модели, которые умеют возвращать и текст, и изображения curl "https://api.alltokens.ru/api/v1/models?output_modalities=text,image" ``` ### По полям модели Если вы уже получили список моделей, смотрите в первую очередь на: - `architecture.output_modalities` — умеет ли модель возвращать изображения - `supported_parameters` — поддерживает ли модель нужные параметры - `default_parameters` — есть ли значения по умолчанию, которые влияют на результат ## Как отправить запрос Для генерации изображений используйте `POST /api/v1/chat/completions`. В запросе передаётся обычный `messages`, а тип результата задаётся через `modalities`. - если модель умеет возвращать и текст, и изображение: `["image", "text"]` - если модель возвращает только изображение: `["image"]` ## Базовый пример В примерах ниже используется модель [`google/gemini-3.1-flash-image-preview`](https://alltokens.ru/models/google/gemini-3.1-flash-image-preview). ```python Python import requests url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "google/gemini-3.1-flash-image-preview", "messages": [ { "role": "user", "content": "Нарисуй красивый закат над горами" } ], "modalities": ["image", "text"] } response = requests.post(url, headers=headers, json=payload) result = response.json() if result.get("choices"): message = result["choices"][0]["message"] if message.get("images"): for image in message["images"]: image_url = image["image_url"]["url"] print(image_url[:80]) ``` ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'google/gemini-3.1-flash-image-preview', messages: [ { role: 'user', content: 'Нарисуй красивый закат над горами', }, ], modalities: ['image', 'text'], }), }); const result = await response.json(); if (result.choices) { const message = result.choices[0].message; if (message.images) { message.images.forEach((image) => { console.log(image.image_url.url.slice(0, 80)); }); } } ``` ```python Python (библиотека OpenAI) from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="google/gemini-3.1-flash-image-preview", messages=[ { "role": "user", "content": "Нарисуй красивый закат над горами" } ], modalities=["image", "text"], ) print(response) ``` ## Настройки изображения Некоторые модели поддерживают дополнительные параметры через `image_config`. ### Соотношение сторон Параметр `image_config.aspect_ratio` задаёт формат изображения. Поддерживаемые значения: - `1:1` - `2:3` - `3:2` - `3:4` - `4:3` - `4:5` - `5:4` - `9:16` - `16:9` - `21:9` Точный список зависит от модели. Если нужен нестандартный формат, проверьте документацию конкретной модели в каталоге. ### Размер изображения Параметр `image_config.image_size` задаёт разрешение результата. Часто встречающиеся значения: - `1K` - `2K` - `4K` Конкретные размеры и доступные варианты тоже зависят от модели. ### Пример с настройками ```python Python import requests url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "google/gemini-3.1-flash-image-preview", "messages": [ { "role": "user", "content": "Создай кинематографичный постер футуристического города" } ], "modalities": ["image", "text"], "image_config": { "aspect_ratio": "16:9", "image_size": "2K" } } response = requests.post(url, headers=headers, json=payload) print(response.json()) ``` ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'google/gemini-3.1-flash-image-preview', messages: [ { role: 'user', content: 'Создай кинематографичный постер футуристического города', }, ], modalities: ['image', 'text'], image_config: { aspect_ratio: '16:9', image_size: '2K', }, }), }); const result = await response.json(); console.log(result); ``` ## Потоковая выдача Генерация изображений может работать и со `stream: true`, если это поддерживает выбранная модель. ```python Python import json import requests url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "google/gemini-3.1-flash-image-preview", "messages": [ { "role": "user", "content": "Создай изображение футуристического города" } ], "modalities": ["image", "text"], "stream": True } response = requests.post(url, headers=headers, json=payload, stream=True) for line in response.iter_lines(): if line: line = line.decode("utf-8") if line.startswith("data: "): data = line[6:] if data != "[DONE]": try: chunk = json.loads(data) if chunk.get("choices"): delta = chunk["choices"][0].get("delta", {}) if delta.get("images"): for image in delta["images"]: print(image["image_url"]["url"][:80]) except json.JSONDecodeError: continue ``` ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'google/gemini-3.1-flash-image-preview', messages: [ { role: 'user', content: 'Создай изображение футуристического города', }, ], modalities: ['image', 'text'], stream: true, }), }); const reader = response.body?.getReader(); const decoder = new TextDecoder(); while (reader) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value); const lines = chunk.split('\n'); for (const line of lines) { if (line.startsWith('data: ')) { const data = line.slice(6); if (data !== '[DONE]') { try { const parsed = JSON.parse(data); const delta = parsed.choices?.[0]?.delta; if (delta?.images) { delta.images.forEach((image) => { console.log(image.image_url.url.slice(0, 80)); }); } } catch (error) { } } } } } ``` ## Как выглядит ответ Сгенерированные изображения приходят в поле `images` внутри сообщения ассистента. ```json { "choices": [ { "message": { "role": "assistant", "content": "Готово, изображение создано.", "images": [ { "type": "image_url", "image_url": { "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." } } ] } } ] } ``` Что важно: - изображения обычно возвращаются как base64 data URL - некоторые модели могут вернуть сразу несколько изображений - итоговый размер и формат зависят от модели ## Практические рекомендации - формулируйте запрос максимально конкретно: стиль, композиция, освещение, формат кадра - заранее проверяйте `output_modalities`, чтобы не отправлять запрос в неподходящую модель - перед обработкой результата всегда проверяйте наличие поля `images` - если нужен низкоуровневый совместимый метод OpenAI, используйте [справку по /api/v1/images/generations](https://docs.alltokens.ru/api/images.md) ## Частые вопросы #### Почему в ответе нет изображения? Проверьте три вещи: модель действительно умеет возвращать `image`, в запросе указан правильный `modalities`, и сам запрос явно просит создать изображение, а не только описать его. #### Можно ли получить и текст, и картинку одновременно? Да, если модель это поддерживает. Для этого обычно используется `modalities: ["image", "text"]`. #### Нужно ли использовать /api/v1/images/generations или достаточно chat/completions? Для многих сценариев достаточно `chat/completions`, особенно если вы хотите единый интерфейс для текста и изображений. Если нужен отдельный совместимый метод генерации изображений, используйте [POST /api/v1/images/generations](https://docs.alltokens.ru/api/images.md). # PDF > Как передавать PDF-документы в AllTokens через /api/v1/chat/completions. PDF-документы можно отправлять через `POST /api/v1/chat/completions`. PDF передаётся внутри массива `messages` через элемент `file`. Документ можно передать как по прямой ссылке, так и в виде base64-строки. Для большинства сценариев удобнее использовать URL для публичных документов и base64 для локальных или закрытых файлов. **Info.** Если выбранная модель умеет принимать файлы напрямую, PDF будет обработан как файловый ввод. Если нет, платформа постарается передать модели содержимое документа в совместимом формате. **Tip.** В одном запросе можно сочетать PDF, текст и другие поддерживаемые типы входа. ## Как найти подходящую модель Ищите модели в [каталоге AllTokens](https://alltokens.ru/models), которые поддерживают файловый ввод. В первую очередь смотрите на: - `architecture.input_modalities` - `supported_parameters` - `context_length` В примерах ниже используется модель [`anthropic/claude-sonnet-4`](https://alltokens.ru/models/anthropic/claude-sonnet-4). ## PDF по URL Для публично доступных документов можно передать ссылку напрямую, без скачивания и кодирования файла. ```python Python import requests url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "anthropic/claude-sonnet-4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Кратко перечисли главные мысли из этого документа." }, { "type": "file", "file": { "filename": "bitcoin.pdf", "file_data": "https://bitcoin.org/bitcoin.pdf" } } ] } ] } response = requests.post(url, headers=headers, json=payload) print(response.json()) ``` ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'anthropic/claude-sonnet-4', messages: [ { role: 'user', content: [ { type: 'text', text: 'Кратко перечисли главные мысли из этого документа.', }, { type: 'file', file: { filename: 'bitcoin.pdf', file_data: 'https://bitcoin.org/bitcoin.pdf', }, }, ], }, ], }), }); const data = await response.json(); console.log(data); ``` ```python Python (библиотека OpenAI) from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=[ { "role": "user", "content": [ { "type": "text", "text": "Кратко перечисли главные мысли из этого документа." }, { "type": "file", "file": { "filename": "bitcoin.pdf", "file_data": "https://bitcoin.org/bitcoin.pdf" } } ] } ], ) print(response) ``` ## PDF в base64 Если PDF лежит локально или его нельзя отдать по публичной ссылке, передайте его как `data:application/pdf;base64,...`. ```python Python import base64 import requests def encode_pdf_to_base64(pdf_path): with open(pdf_path, "rb") as pdf_file: return base64.b64encode(pdf_file.read()).decode("utf-8") base64_pdf = encode_pdf_to_base64("path/to/your/document.pdf") data_url = f"data:application/pdf;base64,{base64_pdf}" url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "anthropic/claude-sonnet-4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "О чем этот документ и какие у него ключевые выводы?" }, { "type": "file", "file": { "filename": "document.pdf", "file_data": data_url } } ] } ] } response = requests.post(url, headers=headers, json=payload) print(response.json()) ``` ```typescript TypeScript (fetch) import { readFile } from 'node:fs/promises'; async function encodePdfToBase64(pdfPath: string): Promise { const pdfBuffer = await readFile(pdfPath); const base64Pdf = pdfBuffer.toString('base64'); return `data:application/pdf;base64,${base64Pdf}`; } const base64Pdf = await encodePdfToBase64('path/to/your/document.pdf'); const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'anthropic/claude-sonnet-4', messages: [ { role: 'user', content: [ { type: 'text', text: 'О чем этот документ и какие у него ключевые выводы?', }, { type: 'file', file: { filename: 'document.pdf', file_data: base64Pdf, }, }, ], }, ], }), }); const data = await response.json(); console.log(data); ``` ## Повторное использование разбора документа После первого запроса ответ может содержать `annotations` внутри сообщения ассистента. Если передать эти данные в следующем запросе, платформе не придётся заново разбирать тот же документ. Это полезно, если вы: - задаёте несколько вопросов по одному и тому же PDF - работаете с длинными документами - строите чат поверх одного документа ### Пример повторного использования `annotations` ```python Python import base64 import requests def encode_pdf_to_base64(pdf_path): with open(pdf_path, "rb") as pdf_file: return base64.b64encode(pdf_file.read()).decode("utf-8") url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } base64_pdf = encode_pdf_to_base64("path/to/your/document.pdf") data_url = f"data:application/pdf;base64,{base64_pdf}" first_payload = { "model": "anthropic/claude-sonnet-4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Сделай краткое резюме документа." }, { "type": "file", "file": { "filename": "document.pdf", "file_data": data_url } } ] } ] } first_response = requests.post(url, headers=headers, json=first_payload) first_data = first_response.json() annotations = None if first_data.get("choices"): annotations = first_data["choices"][0]["message"].get("annotations") if annotations: follow_up_payload = { "model": "anthropic/claude-sonnet-4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Сделай краткое резюме документа." }, { "type": "file", "file": { "filename": "document.pdf", "file_data": data_url } } ] }, { "role": "assistant", "content": "Вот краткое резюме документа.", "annotations": annotations }, { "role": "user", "content": "Теперь отдельно перечисли риски и ограничения." } ] } follow_up_response = requests.post(url, headers=headers, json=follow_up_payload) print(follow_up_response.json()) ``` ```typescript TypeScript (fetch) import { readFile } from 'node:fs/promises'; async function encodePdfToBase64(pdfPath: string): Promise { const pdfBuffer = await readFile(pdfPath); const base64Pdf = pdfBuffer.toString('base64'); return `data:application/pdf;base64,${base64Pdf}`; } const base64Pdf = await encodePdfToBase64('path/to/your/document.pdf'); const firstResponse = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'anthropic/claude-sonnet-4', messages: [ { role: 'user', content: [ { type: 'text', text: 'Сделай краткое резюме документа.', }, { type: 'file', file: { filename: 'document.pdf', file_data: base64Pdf, }, }, ], }, ], }), }); const firstData = await firstResponse.json(); const annotations = firstData.choices?.[0]?.message?.annotations; if (annotations) { const followUpResponse = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'anthropic/claude-sonnet-4', messages: [ { role: 'user', content: [ { type: 'text', text: 'Сделай краткое резюме документа.', }, { type: 'file', file: { filename: 'document.pdf', file_data: base64Pdf, }, }, ], }, { role: 'assistant', content: 'Вот краткое резюме документа.', annotations, }, { role: 'user', content: 'Теперь отдельно перечисли риски и ограничения.', }, ], }), }); const followUpData = await followUpResponse.json(); console.log(followUpData); } ``` **Info.** Если вы передаёте `annotations` из предыдущего ответа, платформа может использовать уже подготовленный разбор документа вместо повторной обработки PDF. ## Формат `annotations` Если PDF был разобран, в ответе может появиться структура примерно такого вида: ```typescript type FileAnnotation = { type: 'file'; file: { hash: string; name?: string; content: ContentPart[]; }; }; type ContentPart = | { type: 'text'; text: string } | { type: 'image_url'; image_url: { url: string } }; ``` Поле `content` содержит разобранное содержимое документа: текстовые блоки, а в некоторых случаях и изображения. ## Пример ответа ```json { "id": "gen-1234567890", "model": "anthropic/claude-sonnet-4", "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 } } ``` ## Частые вопросы #### Что лучше использовать: URL или base64? Для публичных PDF обычно удобнее URL: запрос короче и не нужно кодировать файл. Для локальных и закрытых документов нужен base64. #### Можно ли задавать несколько вопросов по одному PDF? Да. Для этого удобно использовать `annotations` из предыдущего ответа, чтобы не разбирать документ заново. #### Можно ли передавать PDF вместе с обычным текстом? Да. Текстовая инструкция и PDF обычно передаются вместе в одном массиве `content`. # Аудио > Как передавать аудио в модели и получать звуковой ответ через AllTokens. Через AllTokens можно и отправлять аудиофайлы в совместимые модели, и получать от некоторых моделей звуковой ответ. Ниже собраны оба сценария: звуковой ввод и звуковой результат. ## Звуковой ввод Аудио можно отправлять в модели для расшифровки, анализа речи и других сценариев обработки звука. Для этого используется `POST /api/v1/chat/completions` и тип содержимого `input_audio` внутри `messages`. Аудио передаётся только в base64. Прямая ссылка на файл для этого сценария не используется. Ищите подходящие модели в [каталоге AllTokens](https://alltokens.ru/models) по поддержке аудиоввода. В первую очередь смотрите на `architecture.input_modalities`. В примерах ниже используется модель [`google/gemini-2.5-flash`](https://alltokens.ru/models/google/gemini-2.5-flash). ### Как отправить аудиофайл ```python Python import base64 import requests def encode_audio_to_base64(audio_path): with open(audio_path, "rb") as audio_file: return base64.b64encode(audio_file.read()).decode("utf-8") base64_audio = encode_audio_to_base64("path/to/your/audio.wav") url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "google/gemini-2.5-flash", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Расшифруй этот аудиофайл." }, { "type": "input_audio", "input_audio": { "data": base64_audio, "format": "wav" } } ] } ] } response = requests.post(url, headers=headers, json=payload) print(response.json()) ``` ```typescript TypeScript (fetch) import { readFile } from 'node:fs/promises'; async function encodeAudioToBase64(audioPath: string): Promise { const audioBuffer = await readFile(audioPath); return audioBuffer.toString('base64'); } const base64Audio = await encodeAudioToBase64('path/to/your/audio.wav'); const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'google/gemini-2.5-flash', messages: [ { role: 'user', content: [ { type: 'text', text: 'Расшифруй этот аудиофайл.', }, { type: 'input_audio', input_audio: { data: base64Audio, format: 'wav', }, }, ], }, ], }), }); const data = await response.json(); console.log(data); ``` ```python Python (библиотека OpenAI) import base64 from openai import OpenAI def encode_audio_to_base64(audio_path): with open(audio_path, "rb") as audio_file: return base64.b64encode(audio_file.read()).decode("utf-8") base64_audio = encode_audio_to_base64("path/to/your/audio.wav") client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="google/gemini-2.5-flash", messages=[ { "role": "user", "content": [ { "type": "text", "text": "Расшифруй этот аудиофайл." }, { "type": "input_audio", "input_audio": { "data": base64_audio, "format": "wav" } } ] } ], ) print(response) ``` ### Поддерживаемые форматы аудиоввода Поддерживаемые форматы зависят от модели и поставщика. Часто встречаются: - `wav` - `mp3` - `aiff` - `aac` - `ogg` - `flac` - `m4a` - `pcm16` - `pcm24` **Note.** Точный набор форматов зависит от модели. Если формат важен, проверьте страницу модели в каталоге AllTokens перед интеграцией. ## Генерация аудио Некоторые модели умеют не только возвращать текст, но и синтезировать звук. Для этого в запросе нужно указать `modalities` и объект `audio`. В примерах ниже используется модель [`openai/gpt-4o-audio-preview`](https://alltokens.ru/models/openai/gpt-4o-audio-preview). ### Как запросить генерацию аудио Чтобы получить аудиоответ, используйте: - `modalities: ["text", "audio"]` - `audio.voice` — голос - `audio.format` — формат звука - `stream: true` — аудио приходит потоково ```python Python import base64 import json import requests url = "https://api.alltokens.ru/api/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } payload = { "model": "openai/gpt-4o-audio-preview", "messages": [ { "role": "user", "content": "Скажи привет дружелюбным тоном." } ], "modalities": ["text", "audio"], "audio": { "voice": "alloy", "format": "wav" }, "stream": True } response = requests.post(url, headers=headers, json=payload, stream=True) audio_data_chunks = [] transcript_chunks = [] for line in response.iter_lines(): if not line: continue decoded = line.decode("utf-8") if not decoded.startswith("data: "): continue data = decoded[len("data: "):] if data.strip() == "[DONE]": break chunk = json.loads(data) delta = chunk["choices"][0].get("delta", {}) audio = delta.get("audio", {}) if audio.get("data"): audio_data_chunks.append(audio["data"]) if audio.get("transcript"): transcript_chunks.append(audio["transcript"]) transcript = "".join(transcript_chunks) print(f"Transcript: {transcript}") full_audio_b64 = "".join(audio_data_chunks) audio_bytes = base64.b64decode(full_audio_b64) with open("output.wav", "wb") as f: f.write(audio_bytes) ``` ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'openai/gpt-4o-audio-preview', messages: [ { role: 'user', content: 'Скажи привет дружелюбным тоном.', }, ], modalities: ['text', 'audio'], audio: { voice: 'alloy', format: 'wav', }, stream: true, }), }); const reader = response.body!.getReader(); const decoder = new TextDecoder(); const audioDataChunks: string[] = []; const transcriptChunks: string[] = []; let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop() ?? ''; for (const line of lines) { if (!line.startsWith('data: ')) continue; const data = line.slice('data: '.length).trim(); if (data === '[DONE]') break; const chunk = JSON.parse(data); const audio = chunk.choices?.[0]?.delta?.audio; if (audio?.data) audioDataChunks.push(audio.data); if (audio?.transcript) transcriptChunks.push(audio.transcript); } } const transcript = transcriptChunks.join(''); console.log(`Transcript: ${transcript}`); const fullAudioB64 = audioDataChunks.join(''); console.log(fullAudioB64); ``` ### Формат потокового чанка При звуковом результате аудиоданные и текст расшифровки приходят по частям в `delta.audio`: ```json { "choices": [ { "delta": { "audio": { "data": "", "transcript": "Привет" } } } ] } ``` ### Настройки `audio` | Поле | Что означает | | --- | --- | | `voice` | Голос для синтеза речи, например `alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer` | | `format` | Формат выходного звука, например `wav`, `mp3`, `flac`, `opus`, `pcm16` | **Note.** Набор голосов и форматов зависит от выбранной модели. Если нужна конкретная связка, проверьте страницу модели в каталоге AllTokens. ## Частые вопросы #### Можно ли передать аудио по URL? Нет, для звукового ввода аудио передаётся только в base64. #### Почему для звукового ответа нужен stream? Потому что аудиоданные приходят по частям через SSE, в `delta.audio`. #### Можно ли получить и текст, и звук одновременно? Да, для этого обычно используют `modalities: ["text", "audio"]`. # Маршрутизация > Как в AllTokens работают alltokens/auto, alltokens/free и ограничения по маршрутизации. Маршрутизация в AllTokens позволяет не только вызвать модель, но и управлять тем, как именно она выбирается. ## Алиасы моделей - alltokens/auto: Основная routing-модель по умолчанию. Хороший старт для большинства интеграций. - alltokens/free: Бесплатная routing-модель для тестовых сценариев. ## Где передавать параметры маршрутизации Параметры маршрутизации можно передавать в `metadata` или `extra_body`. ```json request.json { "model": "alltokens/auto", "messages": [{"role": "user", "content": "Выбери самую дешёвую подходящую модель"}], "metadata": { "objective": "cheapest", "allowed_models": ["openai/*", "anthropic/*"] } } ``` ## Что можно контролировать #### Objective `objective` принимает значения `cheapest`, `fastest`, `reliable`, `balanced`. #### Model filters `allowed_models` и `blocked_models` помогают ограничить пул моделей по точным ID или паттернам вроде `anthropic/*`. #### Provider policy `provider_policy` позволяет выбрать только нужных провайдеров или исключить часть из них. ## Как разбирать маршрутизацию #### Сначала вызовите route preview Используйте [`POST /api/route/preview`](https://docs.alltokens.ru/api/route-preview.md), чтобы увидеть кандидатов без реального вызова модели. #### Потом отправьте боевой запрос Запустите обычный `POST /api/chat/completions` с теми же `metadata`. #### Сохраните generation id В ответе или в части потока вы получите `id`. #### Проверьте фактическое объяснение Вызовите [`GET /api/route/explain`](https://docs.alltokens.ru/api/route-explain.md) и посмотрите модель, провайдера и текстовое объяснение выбора. **Tip.** Для начала достаточно знать три вещи: `alltokens/auto` для старта, `objective` для управления приоритетом и `route/explain` для проверки выбора. ## Частые вопросы #### Чем отличаются alltokens/auto и alltokens/free на практике? `alltokens/auto` подходит для обычного автоматического выбора модели, а `alltokens/free` нужен для бесплатного пула. Для обычного первого запуска почти всегда достаточно `alltokens/auto`. #### Когда вообще не трогать metadata? Пока вы просто проверяете интеграцию или делаете базовый запрос, `metadata` можно не передавать. Добавляйте её только тогда, когда уже понимаете, что именно хотите контролировать: скорость, надёжность, допустимые модели или провайдеров. #### Как ограничить выбор моделей без жёсткой фиксации одной? Используйте `allowed_models` и `blocked_models`. Так вы сохраняете автоматический выбор, но сужаете пул до нужного семейства, провайдера или набора моделей. #### Как понять, почему роутер принял именно такое решение? Для предварительной проверки используйте [`/api/route/preview`](https://docs.alltokens.ru/api/route-preview.md), а для фактического выполненного запроса сохраняйте `id` и смотрите [`/api/route/explain`](https://docs.alltokens.ru/api/route-explain.md). # Автовыбор модели > Как работает alltokens/auto и как автоматически подбирать лучшую модель под запрос. [`alltokens/auto`](https://alltokens.ru/models/alltokens/auto) автоматически выбирает подходящую модель под ваш запрос. Это самый простой способ начать работу с AllTokens, если вы не хотите фиксировать конкретную модель вручную. ## Как это работает Вместо того чтобы заранее выбирать модель самостоятельно, вы отправляете запрос в `alltokens/auto`, а платформа подбирает подходящий вариант из доступного пула моделей. При выборе учитываются: - тип задачи - сложность запроса - доступные модели и их возможности - ваши ограничения в `metadata`, если они заданы ## Когда использовать `alltokens/auto` подходит, если вы: - только запускаете интеграцию - не знаете заранее, какие типы запросов будут у пользователей - хотите сохранить автоматический выбор, а не жёстко фиксировать одну модель - хотите управлять приоритетом через правила, а не через ручной выбор модели ## Базовый пример Укажите в `model` значение `alltokens/auto`: ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'alltokens/auto', messages: [ { role: 'user', content: 'Объясни квантовую запутанность простыми словами', }, ], }), }); const data = await response.json(); console.log(data.choices[0].message.content); console.log('Фактическая модель:', data.model); ``` ```python Python import requests response = requests.post( "https://api.alltokens.ru/api/v1/chat/completions", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, json={ "model": "alltokens/auto", "messages": [ { "role": "user", "content": "Объясни квантовую запутанность простыми словами" } ] }, ) data = response.json() print(data["choices"][0]["message"]["content"]) print("Фактическая модель:", data["model"]) ``` ```python Python (библиотека OpenAI) from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="alltokens/auto", messages=[ { "role": "user", "content": "Объясни квантовую запутанность простыми словами" } ], ) print(response.choices[0].message.content) print("Фактическая модель:", response.model) ``` ## Что приходит в ответе В ответе поле `model` показывает, какая модель была выбрана фактически: ```json { "id": "gen-...", "model": "anthropic/claude-sonnet-4", "choices": [ { "message": { "role": "assistant", "content": "..." } } ], "usage": { "prompt_tokens": 15, "completion_tokens": 150, "total_tokens": 165 } } ``` ## Как управлять выбором Если вы хотите оставить автоматический выбор, но сузить правила, передавайте ограничения в `metadata`. ### Приоритет выбора Параметр `objective` помогает подсказать платформе, что для вас важнее: - `cheapest` - `fastest` - `reliable` - `balanced` Пример: ```json { "model": "alltokens/auto", "messages": [ { "role": "user", "content": "Сделай краткое резюме документа" } ], "metadata": { "objective": "fastest" } } ``` ### Разрешённые модели Параметр `allowed_models` позволяет ограничить автоматический выбор нужным семейством моделей или конкретными ID. Пример: ```json { "model": "alltokens/auto", "messages": [ { "role": "user", "content": "Объясни квантовую запутанность" } ], "metadata": { "allowed_models": ["anthropic/*", "openai/gpt-5.1"] } } ``` ### Исключённые модели Если часть моделей не подходит под ваш сценарий, используйте `blocked_models`. ```json { "model": "alltokens/auto", "messages": [ { "role": "user", "content": "Сгенерируй аккуратный деловой ответ клиенту" } ], "metadata": { "blocked_models": ["provider-x/*"] } } ``` ### Ограничения по поставщикам Для более точного контроля можно использовать `provider_policy`, если вам нужно работать только с определёнными поставщиками или исключить часть из них. ## Как проверить выбор заранее Если вы хотите понять, какую модель выберет `alltokens/auto`, не отправляя боевой запрос, используйте: - [`POST /api/route/preview`](https://docs.alltokens.ru/api/route-preview.md) — показывает кандидатов заранее - [`GET /api/route/explain`](https://docs.alltokens.ru/api/route-explain.md) — объясняет уже выполненный выбор #### Посмотрите кандидатов Сначала вызовите [`POST /api/route/preview`](https://docs.alltokens.ru/api/route-preview.md) с тем же `model` и теми же `metadata`, которые вы будете использовать в реальном запросе. #### Отправьте реальный запрос После этого отправьте обычный `POST /api/v1/chat/completions` с `model: "alltokens/auto"`. #### Проверьте итоговое решение Сохраните `id` выполненного запроса и затем вызовите [`GET /api/route/explain`](https://docs.alltokens.ru/api/route-explain.md), чтобы увидеть фактическую модель и объяснение выбора. ## Сколько это стоит Отдельной наценки за `alltokens/auto` нет. Вы оплачиваете ту модель, которая была выбрана фактически. ## Ограничения - `alltokens/auto` работает через формат `messages` - потоковая выдача поддерживается - стандартные совместимые возможности вроде обычных параметров запроса продолжают работать - итоговый пул моделей может меняться со временем ## Когда лучше не использовать `alltokens/auto` Лучше зафиксировать конкретную модель, если: - вам нужна строго воспроизводимая конфигурация - у вас уже есть проверенная модель под конкретную задачу - вы хотите жёстко контролировать поведение и не зависеть от пула маршрутизации ## Частые вопросы #### Когда выбирать alltokens/auto, а когда фиксировать модель вручную? `alltokens/auto` лучше подходит для старта, широких пользовательских сценариев и случаев, когда тип запросов заранее не ясен. Фиксированная модель лучше, когда вам нужна стабильность и предсказуемость под конкретную задачу. #### Можно ли ограничить автоподбор только несколькими моделями? Да. Для этого передавайте `allowed_models` и при необходимости `blocked_models` в `metadata`. #### Как понять, какая модель была выбрана на самом деле? Смотрите поле `model` в ответе. Для более подробного разбора используйте [`/api/route/explain`](https://docs.alltokens.ru/api/route-explain.md). #### Поддерживается ли stream? Да, `alltokens/auto` можно использовать и с потоковой выдачей. # Бесплатный роутер > Как работает alltokens/free и как отправлять запросы в бесплатный пул моделей. [`alltokens/free`](https://alltokens.ru/models/alltokens/free) автоматически отправляет запрос в бесплатный пул моделей. Это удобный вариант для тестов, обучения, демо и других сценариев, где важна нулевая стоимость запроса. ## Как это работает Вместо ручного выбора конкретной бесплатной модели вы отправляете запрос в `alltokens/free`, а платформа подбирает подходящую модель из доступного бесплатного пула. При выборе учитываются: - требования самого запроса - доступность бесплатных моделей в текущий момент - поддержка нужных возможностей, если они следуют из тела запроса ## Когда использовать `alltokens/free` подходит, если вы: - проверяете интеграцию без затрат - делаете демо или внутренний прототип - изучаете API и хотите быстро попробовать разные сценарии - запускаете низконагруженный личный или учебный проект ## Базовый пример Укажите в `model` значение `alltokens/free`: ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'alltokens/free', messages: [ { role: 'user', content: 'Привет! Чем ты можешь помочь?', }, ], }), }); const data = await response.json(); console.log(data.choices[0].message.content); console.log('Фактическая модель:', data.model); ``` ```python Python import requests response = requests.post( "https://api.alltokens.ru/api/v1/chat/completions", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, json={ "model": "alltokens/free", "messages": [ { "role": "user", "content": "Привет! Чем ты можешь помочь?" } ] }, ) data = response.json() print(data["choices"][0]["message"]["content"]) print("Фактическая модель:", data["model"]) ``` ```python Python (библиотека OpenAI) from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="alltokens/free", messages=[ { "role": "user", "content": "Привет! Чем ты можешь помочь?" } ], ) print(response.choices[0].message.content) print("Фактическая модель:", response.model) ``` ```bash cURL curl https://api.alltokens.ru/api/v1/chat/completions \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "alltokens/free", "messages": [{"role": "user", "content": "Привет!"}] }' ``` ## Что приходит в ответе В ответе поле `model` показывает, какая бесплатная модель была выбрана фактически: ```json { "id": "gen-...", "model": "some-provider/some-free-model", "choices": [ { "message": { "role": "assistant", "content": "..." } } ], "usage": { "prompt_tokens": 12, "completion_tokens": 85, "total_tokens": 97 } } ``` ## Что важно понимать Бесплатный пул может меняться. Это влияет на: - доступные модели - стабильность времени ответа - итоговое качество - доступность некоторых возможностей в конкретный момент **Warning.** `alltokens/free` удобен для старта и тестов, но не всегда подходит для критичных продакшен-сценариев, где важны стабильность, скорость и повторяемость. ## Стоимость Запросы через `alltokens/free` не тарифицируются как платные вызовы модели. ## Ограничения - бесплатные модели могут быть временно недоступны - задержка может быть выше, чем у платных маршрутов - поведение и качество могут сильнее меняться со временем - вы не контролируете конкретную модель, если используете именно `alltokens/free` ## Когда лучше выбрать не `alltokens/free` Лучше использовать `alltokens/auto` или фиксированную модель, если: - вам нужна предсказуемая производительность - важна стабильность результата - вы строите продакшен-функцию с понятными SLA - вы уже знаете, какая модель лучше подходит под вашу задачу ## Как выбрать конкретную модель вместо free-роутера Если вам уже не нужен бесплатный роутер, вы можете: 1. Перейти на [`alltokens/auto`](https://docs.alltokens.ru/concepts/auto-router.md), если всё ещё хотите автоматический выбор. 2. Открыть [каталог AllTokens](https://alltokens.ru/models) и зафиксировать конкретную модель вручную. ## Частые вопросы #### Чем alltokens/free отличается от alltokens/auto? `alltokens/free` ограничен бесплатным пулом. `alltokens/auto` выбирает модель из более широкого пула и обычно лучше подходит для рабочих сценариев. #### Можно ли узнать, какая модель была выбрана? Да. Смотрите поле `model` в ответе. #### Подходит ли alltokens/free для продакшена? Обычно нет, если вам нужна стабильность. Для продакшена чаще выбирают `alltokens/auto` или конкретную фиксированную модель. #### Поддерживается ли stream? Да, если выбранная фактическая модель поддерживает потоковую выдачу. # Конструктор запросов > Как использовать bodybuilder для генерации нескольких параллельных запросов под разные модели. `bodybuilder` превращает текстовую инструкцию в готовые JSON-тела запросов для нескольких моделей. Это удобно, если вы хотите быстро запустить одну и ту же задачу параллельно на разных моделях и сравнить результат. ## Что это делает Вместо того чтобы вручную собирать несколько тел запросов, вы отправляете одну инструкцию в `bodybuilder`, а в ответ получаете набор готовых запросов, которые можно сразу выполнить параллельно. Это полезно для: - сравнения моделей - параллельного прогона одной задачи - быстрых экспериментов - подбора лучшей модели под конкретный тип задачи **Info.** Сам `bodybuilder` только генерирует тела запросов. Основная нагрузка и тарификация начинаются уже на этапе выполнения сгенерированных запросов. ## Базовый пример Используйте `model: "bodybuilder"`: ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'bodybuilder', messages: [ { role: 'user', content: 'Посчитай до 10 с помощью Claude Sonnet и GPT-5', }, ], }), }); const data = await response.json(); const generatedRequests = JSON.parse(data.choices[0].message.content); console.log(generatedRequests); ``` ```python Python import json import requests response = requests.post( "https://api.alltokens.ru/api/v1/chat/completions", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, json={ "model": "bodybuilder", "messages": [ { "role": "user", "content": "Посчитай до 10 с помощью Claude Sonnet и GPT-5" } ] }, ) data = response.json() generated_requests = json.loads(data["choices"][0]["message"]["content"]) print(json.dumps(generated_requests, indent=2, ensure_ascii=False)) ``` ```python Python (библиотека OpenAI) import json from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="bodybuilder", messages=[ { "role": "user", "content": "Посчитай до 10 с помощью Claude Sonnet и GPT-5" } ], ) generated_requests = json.loads(response.choices[0].message.content) print(json.dumps(generated_requests, indent=2, ensure_ascii=False)) ``` ## Формат ответа Обычно `bodybuilder` возвращает JSON-объект с массивом `requests`: ```json { "requests": [ { "model": "anthropic/claude-sonnet-4", "messages": [ { "role": "user", "content": "Посчитай до 10" } ] }, { "model": "openai/gpt-5.1", "messages": [ { "role": "user", "content": "Посчитай до 10" } ] } ] } ``` Каждый элемент в `requests` — это обычное тело запроса, которое потом можно отправить в `POST /api/v1/chat/completions`. ## Как выполнить сгенерированные запросы После генерации вы можете выполнить все запросы параллельно. ```typescript TypeScript const builderResponse = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'bodybuilder', messages: [ { role: 'user', content: 'Объясни гравитацию с помощью Gemini и Claude', }, ], }), }); const builderData = await builderResponse.json(); const { requests } = JSON.parse(builderData.choices[0].message.content); const results = await Promise.all( requests.map((requestBody) => fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify(requestBody), }).then((response) => response.json()), ), ); results.forEach((result, index) => { console.log(requests[index].model); console.log(result.choices[0].message.content); }); ``` ```python Python import asyncio import aiohttp import json async def execute_request(session, request_body): async with session.post( "https://api.alltokens.ru/api/v1/chat/completions", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, json=request_body ) as response: return await response.json() async def main(): async with aiohttp.ClientSession() as session: builder_response = await execute_request(session, { "model": "bodybuilder", "messages": [ { "role": "user", "content": "Объясни гравитацию с помощью Gemini и Claude" } ] }) generated = json.loads(builder_response["choices"][0]["message"]["content"]) tasks = [execute_request(session, request_body) for request_body in generated["requests"]] results = await asyncio.gather(*tasks) for request_body, result in zip(generated["requests"], results): print(request_body["model"]) print(result["choices"][0]["message"]["content"]) print() asyncio.run(main()) ``` ## Когда это полезно ### Сравнение моделей Например: ```text Напиши хайку про программирование с помощью Claude Sonnet, GPT-5 и Gemini ``` ### Проверка надёжности Можно запустить один и тот же вопрос на нескольких моделях и сравнить ответы: ```text Ответь на вопрос "Сколько будет 2+2?" с помощью трёх разных моделей ``` ### A/B-тестирование промптов Можно быстро посмотреть, какая модель лучше справляется с вашей задачей: ```text Сделай краткое резюме этой статьи с помощью пяти сильных текстовых моделей ``` ### Исследование моделей Если вы ещё не знаете, какая модель лучше для творчества, кода, анализа или резюме, `bodybuilder` помогает быстро собрать серию параллельных запусков. ## Как он выбирает модели `bodybuilder` ориентируется на вашу текстовую инструкцию и старается: - понять, какие модели вы имели в виду - подобрать актуальные идентификаторы моделей - собрать минимально достаточные тела запросов Если вы называете семейство моделей неформально, `bodybuilder` обычно пытается подобрать подходящие конкретные ID автоматически. **Warning.** Идентификаторы моделей со временем меняются. Если вам нужна строгая воспроизводимость, после эксперимента зафиксируйте конкретные модели вручную. ## Стоимость - генерация тел запросов через `bodybuilder` не является основным платным прогоном модели под вашу задачу - выполнение самих сгенерированных запросов тарифицируется по обычным правилам выбранных моделей ## Ограничения - входной запрос должен использовать формат `messages` - ответы `bodybuilder` нужно парсить как JSON перед выполнением - сгенерированные тела запросов могут потребовать вашей валидации перед массовым запуском - если вам нужна строгая структура, полезно дополнительно проверять `requests` перед отправкой ## Когда лучше не использовать `bodybuilder` Лучше обойтись без него, если: - вы уже точно знаете, какие модели хотите вызвать - вам не нужен параллельный запуск - вы хотите полностью вручную контролировать каждое тело запроса ## Частые вопросы #### Чем bodybuilder отличается от alltokens/auto? `alltokens/auto` выбирает одну подходящую модель и сразу выполняет запрос. `bodybuilder` не выполняет задачу напрямую, а сначала генерирует несколько готовых тел запросов под разные модели. #### Можно ли сразу выполнить все сгенерированные запросы? Да. Обычно их выполняют параллельно через `Promise.all`, `asyncio.gather` или аналогичный механизм. #### Можно ли доверять сгенерированным телам запросов без проверки? Для быстрых экспериментов — обычно да. Для продакшен-сценариев лучше валидировать JSON и проверять выбранные модели перед массовым запуском. #### Это заменяет route preview? Нет. `route preview` показывает кандидатов для маршрутизации, а `bodybuilder` собирает несколько отдельных тел запросов для параллельного запуска. # Провайдеры > Чем в AllTokens отличается модель от провайдера и как устроена доступность. В AllTokens модель и провайдер — это не одно и то же. ## Коротко - Модель: Это то, что вы выбираете в поле `model`: например, `openai/gpt-4.1-mini` или `anthropic/claude-sonnet-4`. - Провайдер: Это инфраструктурный слой, через который модель фактически выполняется. Одно и то же семейство моделей может быть доступно у разных провайдеров. ## Зачем это понимать - чтобы настроить поведение при недоступности одного из провайдеров - чтобы ограничить маршрут по конкретным провайдерам - чтобы разбирать задержку и стабильность - чтобы понимать, почему routing-модель сделала именно такой выбор ## Выбор провайдера на практике Если вы передаёте `provider_policy`, AllTokens использует её как ограничение маршрута: ```json request.json { "model": "alltokens/auto", "messages": [{"role": "user", "content": "Ответь кратко"}], "metadata": { "provider_policy": { "only": ["Anthropic", "OpenAI"], "allow_fallbacks": true } } } ``` ## Что это даёт продуктово #### Надёжность Если один провайдер недоступен, `alltokens/auto` может уйти на резервный маршрут, если это разрешено политикой. #### Предсказуемость Если вам нужны строгие ограничения или фиксированная инфраструктура, можно оставить только разрешённый список провайдеров. #### Доступ без VPN Для российских команд это важно: AllTokens скрывает сложность прямых интеграций с внешними AI-провайдерами за единым методом доступа. ## Где посмотреть список провайдеров Откройте [`GET /api/providers`](https://docs.alltokens.ru/api/providers.md). Эти же имена используются в `provider_policy.only` и `provider_policy.ignore`. # Параметры > Самые важные параметры запросов к AllTokens без лишнего перегруза. AllTokens старается оставаться максимально совместимым с OpenAI API, поэтому большинство параметров знакомы вам ещё до первого запроса. ## Базовый набор | Параметр | Где нужен | Что делает | | --- | --- | --- | | `model` | chat/completions, completions, embeddings, images | Выбирает конкретную модель или routing-модель вроде `alltokens/auto` | | `messages` | chat/completions | Передаёт историю диалога | | `prompt` | completions, images | Передаёт одиночный текстовый prompt | | `stream` | chat/completions, completions | Включает потоковый ответ | | `temperature` | текстовые методы | Управляет вариативностью ответа | | `max_tokens` | текстовые методы | Ограничивает длину ответа | | `top_p` | текстовые методы | Альтернатива `temperature` | ## Параметры AllTokens поверх совместимого API | Параметр | Где передавать | Для чего нужен | | --- | --- | --- | | `metadata.objective` | `metadata` или `extra_body` | Приоритет cheapest / fastest / reliable / balanced | | `metadata.allowed_models` | `metadata` или `extra_body` | Белый список моделей | | `metadata.blocked_models` | `metadata` или `extra_body` | Чёрный список моделей | | `metadata.provider_policy` | `metadata` или `extra_body` | Контроль провайдеров и переключения между ними | ## Полезное правило **Tip.** Начните с минимального тела запроса: `model` + `messages`. Добавляйте параметры маршрутизации и управления генерацией только тогда, когда понимаете, какую задачу они решают. ## Сначала совместимость, потом тонкая настройка #### Запустите обычный совместимый запрос Убедитесь, что интеграция проходит без параметров маршрутизации. #### Добавьте stream или temperature Если вам нужна UX-скорость или другой стиль ответа. #### Добавьте metadata Только после этого подключайте `objective`, `allowed_models` и другие параметры маршрутизации. ## Дальше по теме - [Маршрутизация](https://docs.alltokens.ru/concepts/routing.md): Когда и как использовать `metadata`. - [Чатовый метод API](https://docs.alltokens.ru/api/chat-completions.md): Полный запрос и ответ главного метода. # Вызов инструментов > Как использовать tools и function calling в AllTokens через совместимый chat/completions API. Вызов инструментов позволяет модели не просто отвечать текстом, а предлагать вызвать внешнюю функцию. Сама модель не вызывает инструмент напрямую: она только возвращает `tool_calls`, а уже ваш код выполняет нужную функцию, получает результат и отправляет его обратно модели. Это удобно для: - поиска данных во внешнем API - работы с базой данных - вызова внутренних сервисов - построения простых агентных сценариев ## Что поддерживается В совместимом `POST /api/v1/chat/completions` можно использовать: - `tools` - `tool_choice` - сообщения с `role: "tool"` - возврат результата инструмента через `tool_call_id` Если хотите подобрать модель с поддержкой инструментов, смотрите `supported_parameters=tools` в [каталоге моделей](https://docs.alltokens.ru/api/models.md) или на [alltokens.ru/models](https://alltokens.ru/models). ## Как это работает Обычно цикл состоит из трёх шагов: 1. Вы отправляете запрос с `tools` 2. Модель возвращает `tool_calls` 3. Вы выполняете инструмент локально и отправляете результат вторым запросом ## Шаг 1. Первый запрос с tools Пример тела запроса: ```json { "model": "google/gemini-3-flash-preview", "messages": [ { "role": "user", "content": "Какие книги написал Джеймс Джойс?" } ], "tools": [ { "type": "function", "function": { "name": "search_gutenberg_books", "description": "Ищет книги в библиотеке Project Gutenberg", "parameters": { "type": "object", "properties": { "search_terms": { "type": "array", "items": { "type": "string" }, "description": "Список поисковых фраз" } }, "required": ["search_terms"] } } } ] } ``` ## Шаг 2. Выполнение инструмента в вашем коде После ответа модели вы читаете `tool_calls`, вызываете нужную функцию у себя и готовите результат: ```javascript const toolResult = await searchGutenbergBooks(["James", "Joyce"]); ``` ## Шаг 3. Второй запрос с результатом инструмента Во втором запросе важно передать: - исходное пользовательское сообщение - ответ модели с `tool_calls` - сообщение `role: "tool"` с результатом вызова - тот же массив `tools` ```json { "model": "google/gemini-3-flash-preview", "messages": [ { "role": "user", "content": "Какие книги написал Джеймс Джойс?" }, { "role": "assistant", "content": null, "tool_calls": [ { "id": "call_abc123", "type": "function", "function": { "name": "search_gutenberg_books", "arguments": "{\"search_terms\": [\"James\", \"Joyce\"]}" } } ] }, { "role": "tool", "tool_call_id": "call_abc123", "content": "[{\"id\": 4300, \"title\": \"Ulysses\"}]" } ], "tools": [ { "type": "function", "function": { "name": "search_gutenberg_books", "description": "Ищет книги в библиотеке Project Gutenberg", "parameters": { "type": "object", "properties": { "search_terms": { "type": "array", "items": { "type": "string" } } }, "required": ["search_terms"] } } } ] } ``` **Note.** `tools` лучше передавать в обоих запросах: и в первом, и во втором. Так схема инструмента остаётся в контексте и повторно валидируется одинаково. ## Полный пример Ниже пример с Project Gutenberg: модель просит инструмент, ваш код выполняет поиск книг, а затем возвращает результат модели. ### Подготовка ```typescript TypeScript const messages = [ { role: 'system', content: 'Ты полезный помощник.', }, { role: 'user', content: 'Какие книги написал Джеймс Джойс?', }, ]; const tools = [ { type: 'function', function: { name: 'search_gutenberg_books', description: 'Ищет книги в библиотеке Project Gutenberg', parameters: { type: 'object', properties: { search_terms: { type: 'array', items: { type: 'string' }, description: 'Список поисковых фраз', }, }, required: ['search_terms'], }, }, }, ]; async function searchGutenbergBooks(searchTerms: string[]) { const query = searchTerms.join(' '); const response = await fetch(`https://gutendex.com/books?search=${query}`); const data = await response.json(); return data.results.map((book: any) => ({ id: book.id, title: book.title, authors: book.authors, })); } ``` ```python Python import json import requests messages = [ {"role": "system", "content": "Ты полезный помощник."}, {"role": "user", "content": "Какие книги написал Джеймс Джойс?"} ] tools = [ { "type": "function", "function": { "name": "search_gutenberg_books", "description": "Ищет книги в библиотеке Project Gutenberg", "parameters": { "type": "object", "properties": { "search_terms": { "type": "array", "items": {"type": "string"}, "description": "Список поисковых фраз" } }, "required": ["search_terms"] } } } ] def search_gutenberg_books(search_terms): query = " ".join(search_terms) response = requests.get("https://gutendex.com/books", params={"search": query}) simplified = [] for book in response.json().get("results", []): simplified.append({ "id": book.get("id"), "title": book.get("title"), "authors": book.get("authors") }) return simplified ``` ### Первый вызов модели ```typescript TypeScript (fetch) const firstResponse = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'google/gemini-3-flash-preview', messages, tools, }), }); const firstData = await firstResponse.json(); const assistantMessage = firstData.choices[0].message; messages.push(assistantMessage); ``` ```python Python first_response = requests.post( "https://api.alltokens.ru/api/v1/chat/completions", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, json={ "model": "google/gemini-3-flash-preview", "messages": messages, "tools": tools, }, ) first_data = first_response.json() assistant_message = first_data["choices"][0]["message"] messages.append(assistant_message) ``` ### Обработка `tool_calls` ```typescript TypeScript for (const toolCall of assistantMessage.tool_calls ?? []) { const toolName = toolCall.function.name; const toolArgs = JSON.parse(toolCall.function.arguments); if (toolName === 'search_gutenberg_books') { const toolResult = await searchGutenbergBooks(toolArgs.search_terms); messages.push({ role: 'tool', tool_call_id: toolCall.id, content: JSON.stringify(toolResult), }); } } ``` ```python Python for tool_call in assistant_message.get("tool_calls", []): tool_name = tool_call["function"]["name"] tool_args = json.loads(tool_call["function"]["arguments"]) if tool_name == "search_gutenberg_books": tool_result = search_gutenberg_books(tool_args["search_terms"]) messages.append({ "role": "tool", "tool_call_id": tool_call["id"], "content": json.dumps(tool_result) }) ``` ### Второй вызов модели ```typescript TypeScript (fetch) const secondResponse = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'google/gemini-3-flash-preview', messages, tools, }), }); const secondData = await secondResponse.json(); console.log(secondData.choices[0].message.content); ``` ```python Python second_response = requests.post( "https://api.alltokens.ru/api/v1/chat/completions", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, json={ "model": "google/gemini-3-flash-preview", "messages": messages, "tools": tools, }, ) second_data = second_response.json() print(second_data["choices"][0]["message"]["content"]) ``` ## `tool_choice` Параметр `tool_choice` позволяет контролировать использование инструментов. Примеры: ```json { "tool_choice": "auto" } ``` ```json { "tool_choice": "none" } ``` ```json { "tool_choice": { "type": "function", "function": { "name": "search_gutenberg_books" } } } ``` ## Практические рекомендации - давайте инструментам понятные и точные имена - подробно описывайте `description`, чтобы модели было проще выбрать правильный инструмент - делайте схему параметров максимально конкретной - валидируйте аргументы перед реальным вызовом функции - не забывайте добавлять в `messages` и ответ модели, и результат инструмента ## Что важно учитывать - не каждая модель поддерживает `tools` - лучше заранее проверять `supported_parameters` - сам инструмент вызывается вашим кодом, а не моделью - для надёжных продакшен-сценариев стоит обрабатывать ошибки инструмента отдельно ## Частые вопросы #### Модель сама вызывает инструмент? Нет. Модель только возвращает `tool_calls`. Сам вызов делает ваш код, а результат вы затем отправляете обратно модели. #### Нужно ли передавать tools во втором запросе? Да, это хороший и безопасный вариант. Так схема инструмента остаётся доступной и во втором шаге. #### Как понять, поддерживает ли модель tool calling? Смотрите `supported_parameters` в [каталоге моделей](https://docs.alltokens.ru/api/models.md). Если там есть `tools`, модель подходит для такого сценария. #### Где лучше выполнять сам инструмент? В вашем серверном коде или в контролируемом backend-слое. Не стоит доверять модели прямой доступ к внешним системам без вашей валидации. # Структурированный вывод > Как получать строго структурированный JSON-ответ от моделей через response_format и JSON Schema. Структурированный вывод позволяет попросить модель вернуть ответ в заранее заданной JSON-схеме. Это полезно, когда вам нужен не свободный текст, а стабильный JSON, который можно безопасно разобрать в коде. ## Когда это нужно Структурированный вывод особенно полезен, если вы хотите: - получать предсказуемый JSON-ответ - уменьшить число ошибок при парсинге - исключить лишние поля - строить типобезопасную обработку результата в приложении ## Как это работает Для этого в запрос передаётся `response_format` с типом `json_schema`. Внутри вы описываете схему объекта, который модель должна вернуть. Пример: ```json { "model": "openai/gpt-4o", "messages": [ { "role": "user", "content": "Какая сейчас погода в Лондоне?" } ], "response_format": { "type": "json_schema", "json_schema": { "name": "weather", "strict": true, "schema": { "type": "object", "properties": { "location": { "type": "string", "description": "Город или локация" }, "temperature": { "type": "number", "description": "Температура в градусах Цельсия" }, "conditions": { "type": "string", "description": "Краткое описание погоды" } }, "required": ["location", "temperature", "conditions"], "additionalProperties": false } } } } ``` Ожидаемый ответ: ```json { "location": "London", "temperature": 18, "conditions": "Partly cloudy with light drizzle" } ``` ## Поддержка моделей Структурированный вывод поддерживают не все модели. Перед использованием проверьте: - `supported_parameters` - наличие `structured_outputs` - наличие `response_format` Для этого используйте [каталог моделей](https://docs.alltokens.ru/api/models.md) или [alltokens.ru/models](https://alltokens.ru/models). **Note.** Если модель не поддерживает `structured_outputs` или `response_format`, запрос может завершиться ошибкой или модель проигнорирует ограничение схемы. ## Полный пример Ниже пример через обычный совместимый `chat/completions` API. ```typescript TypeScript (fetch) const response = await fetch('https://api.alltokens.ru/api/v1/chat/completions', { method: 'POST', headers: { Authorization: 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json', }, body: JSON.stringify({ model: 'openai/gpt-4o', messages: [ { role: 'user', content: 'Какая сейчас погода в Лондоне?', }, ], response_format: { type: 'json_schema', json_schema: { name: 'weather', strict: true, schema: { type: 'object', properties: { location: { type: 'string', description: 'Город или локация', }, temperature: { type: 'number', description: 'Температура в градусах Цельсия', }, conditions: { type: 'string', description: 'Краткое описание погоды', }, }, required: ['location', 'temperature', 'conditions'], additionalProperties: false, }, }, }, }), }); const data = await response.json(); const weatherInfo = data.choices[0].message.content; console.log(weatherInfo); ``` ```python Python import requests response = requests.post( "https://api.alltokens.ru/api/v1/chat/completions", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json", }, json={ "model": "openai/gpt-4o", "messages": [ { "role": "user", "content": "Какая сейчас погода в Лондоне?" } ], "response_format": { "type": "json_schema", "json_schema": { "name": "weather", "strict": True, "schema": { "type": "object", "properties": { "location": { "type": "string", "description": "Город или локация" }, "temperature": { "type": "number", "description": "Температура в градусах Цельсия" }, "conditions": { "type": "string", "description": "Краткое описание погоды" } }, "required": ["location", "temperature", "conditions"], "additionalProperties": False } } } }, ) data = response.json() weather_info = data["choices"][0]["message"]["content"] print(weather_info) ``` ## Практические рекомендации ### Делайте схему максимально конкретной Чем точнее `properties`, `required` и `additionalProperties`, тем стабильнее результат. ### Используйте `strict: true` Так модель сильнее привязывается к схеме и реже отдаёт лишние поля. ### Добавляйте `description` Пояснения внутри JSON Schema помогают модели лучше понять смысл поля. ## Потоковая выдача Если модель поддерживает и `stream`, и структурированный вывод, можно использовать оба режима вместе: ```json { "stream": true, "response_format": { "type": "json_schema" } } ``` Но для прикладного кода обычно проще сначала отладить сценарий без `stream`, а потом добавлять потоковую выдачу. ## Что может пойти не так ### Модель не поддерживает structured outputs В этом случае вы можете получить ошибку или обычный текстовый ответ вместо строгого соответствия схеме. ### Схема слишком сложная Чем сложнее и глубже JSON Schema, тем выше риск, что модель будет справляться хуже, особенно на менее сильных моделях. ### Ответ всё ещё приходит как строка В OpenAI-совместимом `chat/completions` поле `message.content` по-прежнему может приходить как строка, даже если внутри неё JSON. Значит, дальше этот JSON нужно отдельно разбирать в приложении. ## Когда это особенно полезно - извлечение структурированных данных из текста - генерация объектов для интерфейса - нормализация пользовательского ввода - формирование ответов для автоматической обработки без ручного парсинга текста ## Частые вопросы #### Это гарантирует идеальный JSON в каждом ответе? Это сильно повышает шанс получить корректный JSON, но надёжность всё равно зависит от конкретной модели. Для критичных сценариев всегда полезно дополнительно валидировать ответ на своей стороне. #### Как понять, поддерживает ли модель structured outputs? Смотрите `supported_parameters` в [каталоге моделей](https://docs.alltokens.ru/api/models.md). Ищите `structured_outputs` и `response_format`. #### Можно ли использовать это вместе с stream? Во многих случаях да, если выбранная модель это поддерживает. Но начинать интеграцию обычно проще без потока. #### Нужно ли потом всё равно парсить JSON в коде? Да. Даже если модель следует схеме, ваш код всё равно должен разобрать `message.content` и при необходимости провалидировать результат. # Потоковый ответ > Как включить потоковый ответ в AllTokens и получить сведения о запросе после стрима. Потоковый ответ в AllTokens нужен, когда вы хотите показывать ответ пользователю по мере генерации, а не ждать готовый текст целиком. ## Как включить Добавьте `"stream": true` в `POST /api/v1/chat/completions` или `POST /api/v1/completions`. ```json request.json { "model": "alltokens/auto", "stream": true, "messages": [ {"role": "user", "content": "Объясни потоковую выдачу в трёх коротких пунктах"} ] } ``` ## Что приходит в ответ AllTokens возвращает `text/event-stream` в OpenAI-совместимом формате. Вы читаете чанки по мере поступления и обновляете интерфейс постепенно. ```text sse.txt data: {"id":"gen-...","choices":[{"delta":{"content":"Потоковая"}}]} data: {"id":"gen-...","choices":[{"delta":{"content":" — это"}}]} data: [DONE] ``` ## Что важно после стрима **Info.** После потокового запроса итоговые сведения о маршруте удобнее получать отдельно по `id`, а не ждать, что весь контекст маршрутизации будет встроен прямо в поток. ## Рекомендуемый порядок #### Начните читать поток Показывайте `delta.content` сразу в UI или логах. #### Сохраните generation id Обычно он приходит в чанках и нужен для последующей отладки. #### После завершения вызовите generation или route explain Так вы узнаете фактическую модель, провайдера, задержку и стоимость. ## Частые вопросы #### Когда stream реально нужен, а когда нет? `stream` нужен там, где пользователь должен видеть ответ по мере генерации: в чатах, ассистентах и интерактивных UI. Для серверных задач, фоновых процессов и простых интеграций можно спокойно начинать без него. #### Почему после стрима нужен generation id? По `id` проще отдельно получить итоговые сведения о запросе, фактическую модель, провайдера и дополнительные данные, которые неудобно собирать из кусков потока. #### Как получить итоговый полный ответ после потока? Обычно клиент сам собирает текст из `delta.content` по чанкам. Если вам также нужны сведения о выполнении запроса, после завершения потока используйте [`/api/generation`](https://docs.alltokens.ru/api/generation.md) или [`/api/route/explain`](https://docs.alltokens.ru/api/route-explain.md). #### Что делать, если клиент плохо работает с SSE? Начните без `stream` и убедитесь, что обычный запрос работает стабильно. Если поток всё же нужен, проверьте, умеет ли ваш HTTP-клиент читать `text/event-stream` без буферизации всего ответа. ## Куда идти дальше - [Сведения о запросе](https://docs.alltokens.ru/concepts/generation-metadata.md): Что можно вытащить по `id` после запроса. - [Объяснение маршрута](https://docs.alltokens.ru/api/route-explain.md): Как получить текстовое объяснение выбора маршрута. # Сведения о запросе > Как использовать `id` запроса в AllTokens. Каждый успешный запрос в AllTokens получает `id` генерации. Это связующее звено между ответом модели, стоимостью запроса и маршрутизацией. ## Зачем нужен generation id - чтобы понять, какая модель сработала фактически - чтобы узнать провайдера и задержку - чтобы разбирать маршрут после потокового ответа ## Два главных метода - [GET /api/generation](https://docs.alltokens.ru/api/generation.md): Возвращает подробные сведения по `id`. - [GET/POST /api/route/explain](https://docs.alltokens.ru/api/route-explain.md): Возвращает текстовое объяснение, почему был выбран именно такой маршрут. ## Рекомендуемый сценарий #### Сохраните id из ответа В обычном ответе он приходит сразу в корневом объекте. В потоковом режиме его тоже нужно сохранять из частей потока. #### Если нужны полные сведения, вызовите generation Вы получите стоимость, токены, задержку и другие поля учёта. #### Если нужно понять решение routing-модели, вызовите route explain Этот метод удобнее для человека: он отдаёт текстовую причину выбора модели и провайдера. ## Когда использовать что #### generation Лучше для подробного разбора конкретного запроса. #### route explain Лучше для проверки того, почему был выбран именно этот маршрут. # Авторизация > Справка по авторизации в AllTokens API. Все запросы к AllTokens API используют API-ключ. ## Адрес API `https://api.alltokens.ru/api/v1` ## Заголовки | Заголовок | Обязателен | Когда использовать | | --- | --- | --- | | `Authorization: Bearer ` | Да | Основной и рекомендуемый способ | ## Быстрый пример ```bash curl -X GET "https://api.alltokens.ru/api/v1/models" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## Что нужно знать **Info.** Передавайте ключ только с серверной стороны и не встраивайте его в публичные клиентские приложения. ## Типовые ошибки | Код | Что означает | | --- | --- | | `401` | Ключ отсутствует, неверный или отозван | | `429` | Сработали лимиты запросов | ## Смежные страницы - [Авторизация для старта](https://docs.alltokens.ru/authentication.md): Упрощённая версия для первого запуска. - [Быстрый старт](https://docs.alltokens.ru/quickstart.md): Минимальный сценарий подключения без лишней теории. # Чатовые ответы > Главный метод AllTokens: POST /api/v1/chat/completions. `POST /api/v1/chat/completions` — главный метод AllTokens для работы с LLM в совместимом с OpenAI формате. ## Когда использовать - чат-интерфейсы - сценарии помощника в коде и чате - вызов инструментов - потоковые ответы - маршрутизация через `alltokens/auto` и `alltokens/free` ## Request ```bash curl -X POST "https://api.alltokens.ru/api/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "alltokens/auto", "messages": [ {"role": "system", "content": "Отвечай кратко."}, {"role": "user", "content": "Объясни, что такое векторная база данных"} ], "temperature": 0.2, "stream": false, "metadata": { "objective": "balanced" } }' ``` ## Главные поля запроса | Поле | Тип | Что делает | | --- | --- | --- | | `model` | string | Конкретная модель или routing-модель `alltokens/auto` / `alltokens/free` | | `messages` | array | История диалога | | `stream` | boolean | Включает потоковый ответ через серверные события | | `temperature` | number | Управляет вариативностью ответа | | `max_tokens` | integer | Ограничивает размер ответа | | `metadata` | object | Цели маршрутизации и ограничения | | `extra_body` | object | Альтернативное место для параметров маршрутизации | ## Поддерживаемые параметры маршрутизации | Поле | Тип | | --- | --- | | `objective` | `cheapest` \| `fastest` \| `reliable` \| `balanced` | | `allowed_models` | string[] | | `blocked_models` | string[] | | `provider_policy` | object | ## Response ```json { "id": "gen-...", "object": "chat.completion", "model": "openai/gpt-4.1-mini", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Vector database хранит embeddings и умеет искать похожие записи." }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 24, "completion_tokens": 13, "total_tokens": 37, "cost": 0.72 } } ``` ## Что важно в ответе | Поле | Зачем нужно | | --- | --- | | `id` | Используйте для `generation` и `route/explain` | | `choices[0].message.content` | Основной текст ответа | | `usage.cost` | Сведения о стоимости запроса | | `model` | Фактическая модель, если ответ был не потоковым | ## Потоковый ответ Передайте `"stream": true`, если хотите получать поток через серверные события. **Tip.** После потокового ответа удобнее разбирать фактический маршрут через [`/api/route/explain`](https://docs.alltokens.ru/api/route-explain.md), а не пытаться собирать всю отладочную информацию из частей потока. ## Коды ответов | Код | Причина | | --- | --- | | `400` | Невалидный JSON или отсутствуют обязательные поля | | `401` | Проблема с ключом | | `402` | Недостаточно баланса | | `404` | Не найдена модель или не осталось подходящих кандидатов под ограничения | | `429` | Превышена допустимая частота запросов | ## Частые вопросы #### Какой минимальный body нужен для рабочего запроса? В большинстве случаев достаточно `model` и `messages`. Всё остальное, включая `stream`, `temperature` и `metadata`, лучше добавлять уже после того, как базовый запрос стабильно заработал. #### Куда класть metadata: в metadata или extra_body? Если ваш клиент позволяет, используйте обычное поле `metadata` как основной и более понятный вариант. `extra_body` полезен как обходной путь для SDK или обвязок, которые не дают пробросить произвольные поля напрямую. #### Чем этот метод отличается от completions? `chat/completions` работает с массивом `messages` и лучше подходит для современных чатовых и агентных сценариев. `completions` уместнее там, где у вас уже есть старый формат с одиночным `prompt`. #### Когда включать stream в этом методе? Включайте `stream`, если ответ нужно показывать пользователю частями сразу по мере генерации. Если важнее простота интеграции и обработки ответа, начните с обычного нестримингового вызова. ## Связанные страницы - [Маршрутизация](https://docs.alltokens.ru/concepts/routing.md): Как управлять `objective`, `allowed_models` и другими параметрами маршрутизации. - [Объяснение маршрута](https://docs.alltokens.ru/api/route-explain.md): Как понять, почему маршрутизатор принял конкретное решение. # Методы модели > Справка по GET /api/v1/models/{author}/{slug}/endpoints. `GET /api/v1/models/{author}/{slug}/endpoints` показывает, через какие методы доступна конкретная модель и сколько они стоят. ## Когда это полезно - нужно понять, доступна ли модель для чата, эмбеддингов или генерации изображений - нужно посмотреть цены и ограничения у конкретной модели - нужно сравнить, что меняется для одной модели на разных методах ## Пример запроса ```bash curl -X GET "https://api.alltokens.ru/api/v1/models/openai/gpt-4.1-mini/endpoints" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Tip.** Если вам достаточно просто выбрать модель для `chat/completions`, чаще всего хватит `GET /api/models`. Этот метод полезен уже на этапе более точной настройки. # Провайдеры > Справка по GET /api/v1/providers. `GET /api/v1/providers` возвращает список провайдеров, через которых доступны модели в AllTokens. ## Пример запроса ```bash curl -X GET "https://api.alltokens.ru/api/v1/providers" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## Когда этот метод нужен - чтобы собрать whitelist или blacklist провайдеров - чтобы использовать `provider_policy.only` и `provider_policy.ignore` - чтобы разбираться с маршрутизацией ## Практическое правило Имена провайдеров из этого ответа используются в routing-политике как есть. ```json { "metadata": { "provider_policy": { "only": ["Anthropic", "OpenAI"] } } } ``` ## Смежная тема - [Провайдеры](https://docs.alltokens.ru/concepts/providers.md): Объяснение разницы между моделью и провайдером. # Ошибки > Типовые ошибки AllTokens API и как их интерпретировать. AllTokens возвращает ошибки в формате JSON с полем `error`. ```json { "error": { "code": 400, "message": "Detailed error description" } } ``` ## Основные коды | Код | Что означает | | --- | --- | | `400` | Невалидный JSON, отсутствуют обязательные поля, неверные параметры | | `401` | Ключ не передан, передан неверно или отозван | | `402` | Недостаточно средств на балансе для выполнения запроса | | `404` | Не найдена модель, генерация или подходящий маршрут под ограничения | | `429` | Сработало ограничение по частоте запросов | | `500` | Внутренняя ошибка сервера | ## Типовые ситуации - `400` — проверьте тело запроса и имена полей - `401` — перепроверьте `Authorization: Bearer ...` - `402` — пополните баланс и повторите запрос - `404` — проверьте `model`, `generation_id` и ограничения маршрутизации - `429` — повторите запрос позже с увеличивающейся задержкой ## Практический совет **Tip.** При работе с маршрутизацией сначала ослабьте ограничения. Если убрать слишком жёсткие `allowed_models` или `blocked_models`, ошибка `404` часто исчезает. # Предпросмотр маршрута > Справка по POST /api/v1/route/preview. `POST /api/v1/route/preview` строит превью маршрута без реального вызова модели. ## Пример запроса ```bash curl -X POST "https://api.alltokens.ru/api/v1/route/preview" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "metadata": { "objective": "cheapest", "allowed_models": ["openai/*", "anthropic/*"], "top_n": 5 } }' ``` ## Что приходит в ответ | Поле | Что означает | | --- | --- | | `candidates` | Список кандидатов маршрута | | `winnerReason` | Короткая причина, почему победил верхний кандидат | ## Как читать candidates В каждом кандидате обычно интересны: - `modelId` - `name` **Check.** Это удобный способ заранее проверить правила маршрутизации до реального запроса. # Объяснение маршрута > Справка по GET/POST /api/v1/route/explain. `GET /api/v1/route/explain` и `POST /api/v1/route/explain` объясняют, как именно был выбран фактический маршрут по `generation_id`. ## Два варианта вызова ```bash GET curl -X GET "https://api.alltokens.ru/api/v1/route/explain?generation_id=gen-..." \ -H "Authorization: Bearer YOUR_API_KEY" ``` ```bash POST curl -X POST "https://api.alltokens.ru/api/v1/route/explain" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"generation_id":"gen-..."}' ``` ## Что приходит в ответ | Поле | Что означает | | --- | --- | | `generation_id` | Идентификатор генерации | | `model` | Фактическая модель | | `provider_name` | Фактический провайдер | | `latency_ms` | Задержка | | `generation_time_ms` | Время генерации | | `router` | Какая routing-модель использовалась | | `total_cost` | Сведения о стоимости | | `decision_reason` | Текстовое объяснение выбора | **Tip.** Если нужны полные сведения о запросе, переходите к [`GET /api/generation`](https://docs.alltokens.ru/api/generation.md). # Текстовые дополнения > Справка по POST /api/v1/completions. `POST /api/v1/completions` — метод для дополнения текста без массива `messages`. ## Когда использовать - если у вас уже есть старый клиент с одним полем `prompt` - если вам не нужен chat format - если удобнее работать с полем `prompt` ## Пример запроса ```bash curl -X POST "https://api.alltokens.ru/api/v1/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "alltokens/auto", "prompt": "Столица Франции —", "max_tokens": 10 }' ``` ## Что важно - поддерживает `stream` - принимает параметры маршрутизации через `metadata` и `extra_body` - возвращает `id`, который можно использовать в `generation` и `route/explain` **Note.** Для новых интеграций чаще удобнее сразу использовать `chat/completions`. # Эмбеддинги > Справка по POST /api/v1/embeddings. `POST /api/v1/embeddings` возвращает embeddings для текста или массива текстов. ## Пример запроса ```bash curl -X POST "https://api.alltokens.ru/api/v1/embeddings" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "text-embedding-3-small", "input": "Быстрая коричневая лиса перепрыгнула через ленивую собаку." }' ``` ## Основные поля запроса | Поле | Что делает | | --- | --- | | `model` | Выбирает embedding-модель | | `input` | Текст или массив текстов | | `encoding_format` | Формат выхода, например `float` или `base64` | | `dimensions` | Размерность, если модель это поддерживает | ## Когда использовать - семантический поиск - поиск по смыслу - deduplication - рекомендации и кластеризация # Модели эмбеддингов > Справка по GET /api/v1/embeddings/models. `GET /api/v1/embeddings/models` возвращает список embedding-моделей и их свойства. ## Пример запроса ```bash curl -X GET "https://api.alltokens.ru/api/v1/embeddings/models" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## Когда нужен этот метод - выбрать модель для поиска по смыслу - сравнить доступные embedding-модели - проверить pricing и поддерживаемые свойства до боевого вызова **Tip.** Для большинства команд порядок простой: сначала открыть этот список, затем выбрать одну модель и уже после этого подключать `POST /api/v1/embeddings`. # Генерация изображений > Справка по POST /api/v1/images/generations. `POST /api/v1/images/generations` — совместимый с OpenAI метод для генерации изображений. ## Пример запроса ```bash curl -X POST "https://api.alltokens.ru/api/v1/images/generations" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "google/gemini-3.1-flash-image-preview", "prompt": "Рыжий кот на подоконнике, мягкое утреннее освещение", "size": "1024x1024" }' ``` Ответ: ```json { "created": 1773330518, "data": [{"b64_json": "iVBORw0KGgoAAAANSUhEUgAA..."}] } ``` ## Пример — URL ```bash curl -X POST "https://api.alltokens.ru/api/v1/images/generations" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "google/gemini-3.1-flash-image-preview", "prompt": "Акварельная открытка с видом Петербурга на рассвете", "size": "1024x1536", "response_format": "url" }' ``` ## Основные поля | Поле | Что делает | | --- | --- | | `model` | Выбирает модель, которая умеет создавать изображения | | `prompt` | Текстовое описание изображения | | `size` | Размер изображения | | `response_format` | `b64_json` или `url` | | `metadata` | Дополнительные параметры маршрутизации | ## Когда использовать - генерация креативов - макеты товаров - AI-иллюстрации - маркетинговые визуалы # Сведения о запросе > Справка по GET /api/v1/generation?id=.... `GET /api/v1/generation?id={generation_id}` возвращает подробные сведения по конкретному запросу. ## Пример запроса ```bash curl -X GET "https://api.alltokens.ru/api/v1/generation?id=gen-..." \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## Что можно получить | Поле | Что показывает | | --- | --- | | `model` | Фактическая модель | | `provider_name` | Провайдер | | `tokens_prompt` | Токены входа | | `tokens_completion` | Токены выхода | | `total_cost` | Сведения о стоимости | | `latency` | Полная задержка | | `generation_time` | Время генерации | | `router` | Какая routing-модель использовалась, например `alltokens/auto` или `alltokens/free` | ## Когда использовать - после потокового ответа - для просмотра стоимости и разбора запросов - для разборов инцидентов по конкретным запросам - когда нужно связать ответ модели со стоимостью # Библиотеки OpenAI > Как подключить AllTokens через официальные библиотеки OpenAI без переписывания приложения. Если ваше приложение уже использует библиотеки OpenAI, переход на AllTokens обычно сводится к двум изменениям: - заменить `base_url` - вставить API-ключ AllTokens ## Пример на Python ```python from openai import OpenAI client = OpenAI( base_url="https://api.alltokens.ru/api/v1", api_key="YOUR_API_KEY", ) response = client.chat.completions.create( model="alltokens/auto", messages=[{"role": "user", "content": "Привет"}], ) print(response.choices[0].message.content) ``` ## Пример на TypeScript ```typescript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.alltokens.ru/api/v1", apiKey: "YOUR_API_KEY", }); const response = await client.chat.completions.create({ model: "alltokens/auto", messages: [{ role: "user", content: "Привет" }], }); ``` **Check.** Для простого перехода этого обычно достаточно: модели и маршрутизация начинают работать сразу после замены адреса API. # Cursor > Как использовать AllTokens в Cursor через совместимый с OpenAI интерфейс. Cursor можно подключить к AllTokens как к совместимому с OpenAI провайдеру в тех местах, где ваша версия Cursor позволяет задать свой ключ и адрес API. ## Что подготовить - API-ключ AllTokens - адрес API `https://api.alltokens.ru/api/v1` - модель `alltokens/auto` для первого запуска или фиксированную рабочую модель ## Рекомендуемый порядок #### Откройте настройки провайдера в Cursor Найдите настройки провайдера или совместимого режима в вашей версии клиента. #### Укажите ключ и адрес API Вставьте API-ключ AllTokens и `https://api.alltokens.ru/api/v1`. #### Для первого теста выберите alltokens/auto Это поможет проверить соединение без ручного выбора модели. #### Если всё работает, зафиксируйте модель Для рабочей команды обычно лучше выбрать конкретную модель после теста. **Note.** Интерфейс Cursor может меняться между версиями. Если в вашей сборке нет явного поля для совместимого интерфейса, используйте вариант через библиотеки OpenAI на своей стороне. # Claude Code > Как использовать AllTokens как совместимый с OpenAI сервер в Claude Code. Claude Code и похожие консольные помощники обычно проще всего подключать к AllTokens через совместимый с OpenAI режим, если конкретный инструмент позволяет задать свой адрес API и ключ. ## Что передать в конфиг - `base_url`: `https://api.alltokens.ru/api/v1` - `api_key`: ваш ключ AllTokens - `model`: для старта `alltokens/auto`, затем фиксированная модель для разработки ## Практический порядок #### Начните с alltokens/auto Так вы быстро проверите, что консольный инструмент может достучаться до AllTokens. #### Прогоните короткую задачу Например, попросите модель объяснить файл или предложить исправление. #### Зафиксируйте подходящую модель После теста переходите на конкретную модель, если вам важны задержка, цена или поведение инструментов. **Tip.** Для таких сценариев полезно сохранять `generation_id` в журналах, чтобы потом разбирать спорные маршруты через `route/explain`. # n8n > Как подключить AllTokens в n8n через обычный запрос. Самый надёжный путь для n8n — использовать узел HTTP Request и вызывать AllTokens напрямую. ## Минимальная настройка #### Создайте узел HTTP Request Метод: `POST` #### Укажите URL `https://api.alltokens.ru/api/v1/chat/completions` #### Добавьте заголовки `Authorization: Bearer YOUR_API_KEY` и `Content-Type: application/json` #### Передайте тело запроса Используйте `model`, `messages` и при необходимости `metadata`. ## Пример тела запроса ```json { "model": "alltokens/auto", "messages": [ { "role": "user", "content": "Суммаризируй входной текст в 3 пунктах" } ] } ``` ## Почему этот путь удобен - не зависит от особенностей сторонних узлов - даёт полный контроль над параметрами маршрутизации - легко расширяется под потоковый режим, изображения и эмбеддинги # LangChain > Как подключить AllTokens к LangChain через совместимый с OpenAI клиент. В LangChain AllTokens проще всего использовать там, где библиотека принимает совместимый с OpenAI клиент или настраиваемый адрес API. ## Пример на Python ```python from langchain_openai import ChatOpenAI llm = ChatOpenAI( model="alltokens/auto", api_key="YOUR_API_KEY", base_url="https://api.alltokens.ru/api/v1", ) response = llm.invoke("Объясни RAG в двух предложениях") print(response.content) ``` ## Когда это удобно - поиск по смыслу и RAG - цепочки и составные сценарии - быстрый переход с OpenAI на платформу с несколькими моделями **Tip.** Начните с `alltokens/auto`, затем зафиксируйте рабочую модель, если важна стабильность качества или стоимости. # Частые вопросы > Короткие ответы на частые вопросы по AllTokens. #### Чем AllTokens отличается от прямого вызова OpenAI или Anthropic? AllTokens даёт единый метод доступа, доступ к 400+ моделям и работу без отдельной интеграции под каждого провайдера. #### Можно ли использовать библиотеки OpenAI? Да. В большинстве случаев достаточно заменить `base_url` на `https://api.alltokens.ru/api/v1` и вставить API-ключ AllTokens. #### Зачем нужен alltokens/auto? Чтобы быстро стартовать без выбора конкретной модели и затем при необходимости перейти к фиксированной модели. #### Почему я вижу 402? Потому что для выполнения платного запроса на балансе недостаточно средств. #### Где посмотреть, какая модель реально ответила? Используйте `id` из ответа и вызовите `GET /api/generation` или `GET /api/route/explain`. #### Есть ли потоковый ответ? Да, для чатовых и обычных текстовых запросов через потоковый режим. # Устранение неполадок > Типовые проблемы в AllTokens и быстрые способы их решить. ## 401 Unauthorized - проверьте, что передаёте `Authorization: Bearer YOUR_API_KEY` - убедитесь, что ключ не отозван ## 402 Недостаточно средств - пополните баланс в личном кабинете - повторите запрос после зачисления средств - если проблема повторяется, проверьте, что на балансе достаточно средств ## 404 Model not found - перепроверьте `model` - ослабьте `allowed_models` и `blocked_models` ## Потоковый ответ не работает - убедитесь, что передали `"stream": true` - проверьте, что ваш клиент умеет читать `text/event-stream` - сохраните `generation_id` и проверяйте результат через `generation` после завершения ## Не понимаю, почему routing-модель выбрала эту модель - сначала вызовите `POST /api/route/preview` - затем сохраните `id` реального запроса - после этого вызовите `GET /api/route/explain` ## Стоимость кажется неожиданной - проверьте `usage.cost` или `total_cost` - убедитесь, что вы смотрите на фактическую модель, а не только на исходную routing-модель