Запрос к модели идёт одним из двух путей. Если формат запроса совпадает с форматом, на котором говорит конечный сервис, тело запроса передаётся ему без изменений. Если не совпадает, включается перевод формата: по пути к сервису запрос приводится к нужному виду, а ответ переводится обратно.
Рабочие оба. 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_tokens — prompt_tokens и completion_tokens.
Код при этом отправил и получил формат OpenAI — о двух переводах по пути он не знает.
Если же формат для модели родной, шагов 2 и 4 нет: тело уходит сервису таким, каким пришло, и возвращается таким, каким сервис его сформировал. Это самое прямое обращение к конечному сервису, которое возможно через шлюз.
| Формат запроса | Модель | Что происходит |
|---|---|---|
OpenAI, /v1/chat/completions | openai/gpt-5-mini | без перевода |
Anthropic, /v1/messages | anthropic/claude-sonnet-4-5 | без перевода |
Gemini, /v1beta/…:generateContent | google/gemini-2.5-flash | без перевода |
OpenAI, /v1/chat/completions | anthropic/claude-sonnet-4-5 | перевод в формат Anthropic Messages |
Anthropic, /v1/messages | google/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 — когда важно, чтобы один и тот же код обращался к любой модели: прототип, сравнение моделей, замена одной на другую без правок.
Родной формат модели — когда задача требует возможностей конкретного сервиса: длинные диалоги с рассуждениями, точная разметка кэша, работа с документами и цитатами, бета-возможности.
- Формат Anthropic Messages — запрос и ответ на
/v1/messages. - Формат OpenAI Responses — запрос и ответ на
/v1/responses. - Формат Google Gemini — запрос и ответ на
/v1beta.
Частые вопросы
Как понять, переводился ли запрос?
По таблице выше: всё определяют формат запроса и вендор модели. Отдельного признака в ответе нет.
Формат OpenAI работает хуже родного?
Для обычной генерации текста, вызова функций и структурированного вывода разницы нет. Она появляется там, где нужны поля, которых в схеме OpenAI не существует.
Можно ли передать поле, которого нет в формате OpenAI?
В родном формате — да, любое поле из документации вендора. При переводе формата рассчитывать на это не стоит: конечный сервис ответит ошибкой 400 на неизвестное ему поле.
Стоит ли переписывать работающий код под родной формат?
Нет, если задача решается. Смысл в переходе появляется тогда, когда нужна конкретная возможность, недоступная через формат OpenAI.
Последняя редакция: 3 сентября 2026 г.