к тексту
api

документация api

родной формат модели

когда запрос уходит без перевода и что теряется, если формат и вендор не совпадают.

последняя редакция: 18 сентября 2026

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

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

как проходит перевод формата

разберём на запросе к 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/completionsopenai/gpt-5-miniбез перевода
anthropic, /v1/messagesanthropic/claude-sonnet-4.5без перевода
gemini, /v1beta/…:generateContentgoogle/gemini-3.5-flashбез перевода
openai, /v1/chat/completionsanthropic/claude-sonnet-4.5перевод в формат anthropic messages
anthropic, /v1/messagesgoogle/gemini-3.5-flashперевод в формат gemini

правило простое: формат openai родной для моделей openai, формат anthropic messages — для моделей anthropic, формат gemini — для моделей google. формат responses на /v1/responses — тоже формат openai.

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

что даёт родной формат

  • официальная библиотека вендора. клиент anthropic на /v1/messages, клиент google на /v1beta — со своими типами и своими методами.
  • документация вендора применима буквально. передать можно любое поле из его описания, даже если в формате openai аналога нет.
  • заголовки вендора работают. на /v1/messages передаётся anthropic-beta, которым включаются бета-возможности anthropic.
  • новые возможности доступны сразу. поле, которое вендор добавил только что, работает, не дожидаясь поддержки в переводе формата.

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

curl "https://api.airakurs.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.

поддержка airakurs.official@gmail.com
© airakurs

20 статей. поддержка airakurs.official@gmail.com