Запрос к модели идёт одним из двух путей. Если формат запроса совпадает с форматом, на котором говорит конечный сервис, тело запроса передаётся ему без изменений. Если не совпадает, включается перевод формата: по пути к сервису запрос приводится к нужному виду, а ответ переводится обратно.

Рабочие оба. ProxyAPI следит за актуальностью перевода формата и старается сохранить в нём все возможности модели. Но перевод — всё же промежуточный слой, и там, где важна каждая деталь запроса, надёжнее обойтись без него.

Разберём на запросе к anthropic/claude-sonnet-4-5 из библиотеки OpenAI.

Шаг 1. Пришло на /v1/chat/completions в формате OpenAI

{
    "model": "anthropic/claude-sonnet-4-5",
    "messages": [
        {"role": "system", "content": "Отвечай коротко."},
        {"role": "user", "content": "Назови столицу Австралии."}
    ],
    "max_tokens": 100,
    "temperature": 0.2
}

Шаг 2. Переведено в формат Anthropic Messages и отправлено в Anthropic

{
    "model": "claude-sonnet-4-5",
    "system": [
        {"type": "text", "text": "Отвечай коротко."}
    ],
    "messages": [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Назови столицу Австралии."}
            ]
        }
    ],
    "max_tokens": 100,
    "temperature": 0.2
}

Изменились не только имена полей. Инструкция, которая была сообщением с ролью system, стала отдельным полем system. Строка в content стала списком блоков. Идентификатор модели потерял приставку вендора: конечный сервис знает эту модель под именем claude-sonnet-4-5. А temperature и max_tokens совпали в обоих форматах и поехали как есть.

Шаг 3. Anthropic ответил в своём формате

{
    "id": "msg_01abc",
    "type": "message",
    "role": "assistant",
    "model": "claude-sonnet-4-5",
    "content": [
        {"type": "text", "text": "Канберра."}
    ],
    "stop_reason": "end_turn",
    "usage": {"input_tokens": 18, "output_tokens": 4}
}

Шаг 4. Переведено обратно и отдано клиенту в формате OpenAI

{
    "id": "chatcmpl-6b9cf7a4-427d-404a-9c90-031b2ff36bc3",
    "object": "chat.completion",
    "model": "claude-sonnet-4-5",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "Канберра."
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 18,
        "completion_tokens": 4,
        "total_tokens": 22
    }
}

Текст оказался там, где его ждёт библиотека OpenAI — в choices[0].message.content. stop_reason: "end_turn" стал finish_reason: "stop", а input_tokens и output_tokensprompt_tokens и completion_tokens.

Код при этом отправил и получил формат OpenAI — о двух переводах по пути он не знает.

Если же формат для модели родной, шагов 2 и 4 нет: тело уходит сервису таким, каким пришло, и возвращается таким, каким сервис его сформировал. Это самое прямое обращение к конечному сервису, которое возможно через шлюз.

Формат запросаМодельЧто происходит
OpenAI, /v1/chat/completionsopenai/gpt-5-miniбез перевода
Anthropic, /v1/messagesanthropic/claude-sonnet-4-5без перевода
Gemini, /v1beta/…:generateContentgoogle/gemini-2.5-flashбез перевода
OpenAI, /v1/chat/completionsanthropic/claude-sonnet-4-5перевод в формат Anthropic Messages
Anthropic, /v1/messagesgoogle/gemini-2.5-flashперевод в формат Gemini

Правило простое: формат OpenAI родной для моделей OpenAI, формат Anthropic Messages — для моделей Anthropic, формат Gemini — для моделей Google. Формат Responses на /v1/responses — тоже формат OpenAI, для его моделей он родной.

Модели остальных вендоров каталога — DeepSeek, Qwen, Llama и другие — обслуживает сервис, говорящий на формате OpenAI, поэтому для них родные /v1/chat/completions и /v1/responses.

  • Официальная библиотека вендора. Клиент Anthropic на /v1/messages, клиент Google на /v1beta — со своими типами и своими методами.
  • Документация вендора применима буквально. Передать можно любое поле из его описания, даже если в формате OpenAI аналога нет.
  • Заголовки вендора работают. На /v1/messages передаётся anthropic-beta, которым включаются бета-возможности Anthropic.
  • Новые возможности доступны сразу. Поле, которое вендор добавил только что, работает, не дожидаясь поддержки в переводе формата.

Например, у Anthropic бюджет на размышления задаётся точным числом токенов. В формате OpenAI такого поля нет — там задаётся только уровень. На /v1/messages число передаётся как есть:

curl "https://api.proxyapi.ru/v1/messages" \
    -H "Content-Type: application/json" \
    -H "X-API-Key: <КЛЮЧ>" \
    -d '{
        "model": "anthropic/claude-sonnet-4-5",
        "max_tokens": 8192,
        "thinking": {"type": "enabled", "budget_tokens": 4096},
        "messages": [
            {"role": "user", "content": "Сколько нулей в конце числа 100!?"}
        ]
    }'

Перевод покрывает основное: сообщения и роли, параметры генерации, вызов функций, структурированный вывод, разметку кэша. Теряется то, чему в целевом формате нет соответствия. Несколько примеров:

  • Точность параметра. Бюджет на размышления у Anthropic задаётся числом токенов, а в формате OpenAI — уровнем: low, medium или high. При переводе одно заменяется другим, поэтому точное число задать не получится.
  • Поля ответа без аналога. Подпись блоков размышлений у Anthropic, структурированные цитаты, метаданные поиска у Google — в схеме OpenAI для них не предусмотрено места. Они возвращаются дополнительными полями рядом со стандартными, и официальная библиотека OpenAI о них не знает.

Формат OpenAI — когда важно, чтобы один и тот же код обращался к любой модели: прототип, сравнение моделей, замена одной на другую без правок.

Родной формат модели — когда задача требует возможностей конкретного сервиса: длинные диалоги с рассуждениями, точная разметка кэша, работа с документами и цитатами, бета-возможности.

Частые вопросы

Как понять, переводился ли запрос?

По таблице выше: всё определяют формат запроса и вендор модели. Отдельного признака в ответе нет.

Формат OpenAI работает хуже родного?

Для обычной генерации текста, вызова функций и структурированного вывода разницы нет. Она появляется там, где нужны поля, которых в схеме OpenAI не существует.

Можно ли передать поле, которого нет в формате OpenAI?

В родном формате — да, любое поле из документации вендора. При переводе формата рассчитывать на это не стоит: конечный сервис ответит ошибкой 400 на неизвестное ему поле.

Стоит ли переписывать работающий код под родной формат?

Нет, если задача решается. Смысл в переходе появляется тогда, когда нужна конкретная возможность, недоступная через формат OpenAI.

Последняя редакция: 3 сентября 2026 г.