·5 мин. чтения

Responses API и Chat Completions: в чём разница

Чем Responses API отличается от Chat Completions, какой формат выбрать и как вызвать оба через PlusVibe: curl и Python, история, инструменты.

Responses API и Chat Completions: в чём разница

У OpenAI-совместимых API сейчас два основных формата запросов: давний /v1/chat/completions и более новый /v1/responses. PlusVibe принимает оба с одним ключом и одним базовым адресом https://plusvibeapi.ru/v1. Ниже — чем они отличаются на практике, какой выбрать и где подвох, если вы переходите с одного на другой.

Коротко: чем отличаются форматы

Chat Completions Responses Адрес POST /v1/chat/completions POST /v1/responses Вход массив messages input — строка или массив элементов Системная инструкция сообщение с ролью system поле instructions Ответ choices[0].message массив output: рассуждение, сообщение, вызовы функций Лимит ответа max_tokens max_output_tokens Кто использует большинство SDK, фреймворков и чат-интерфейсов Codex CLI, новые агентные SDK

Модель, цена и токены от выбора формата не зависят: один и тот же запрос к gpt-5.6-luna через оба адреса тарифицируется одинаково — по входным и выходным токенам модели.

Один и тот же запрос в двух форматах

Нужен ключ PlusVibe вида sk-pv-… — его можно создать после регистрации. Chat Completions:

curl https://plusvibeapi.ru/v1/chat/completions \
  -H "Authorization: Bearer $PLUSVIBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-luna",
    "messages": [
      {"role": "system", "content": "Отвечай одним предложением."},
      {"role": "user", "content": "Чем полезен кэш промптов?"}
    ],
    "max_tokens": 300
  }'

Responses:

curl https://plusvibeapi.ru/v1/responses \
  -H "Authorization: Bearer $PLUSVIBE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-luna",
    "instructions": "Отвечай одним предложением.",
    "input": "Чем полезен кэш промптов?",
    "max_output_tokens": 300
  }'

В ответе Chat Completions текст лежит в choices[0].message.content. В ответе Responses — внутри output: у рассуждающих моделей первым элементом идёт reasoning, текст ответа — в элементе с типом message. Разбирать массив руками не обязательно: в Python SDK есть готовое свойство output_text.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://plusvibeapi.ru/v1",
    api_key=os.environ["PLUSVIBE_API_KEY"],
)

# Chat Completions
chat = client.chat.completions.create(
    model="gpt-5.6-luna",
    messages=[
        {"role": "system", "content": "Отвечай одним предложением."},
        {"role": "user", "content": "Что такое HTTP 429?"},
    ],
)
print(chat.choices[0].message.content)

# Responses
resp = client.responses.create(
    model="gpt-5.6-luna",
    instructions="Отвечай одним предложением.",
    input="Что такое HTTP 429?",
)
print(resp.output_text)

Перед публикацией мы запустили оба варианта. Кроме gpt-5.6-luna, через /v1/responses ответили claude-sonnet-5 и deepseek-v4.1-flash: Responses работает не только с моделями OpenAI.

История диалога: передавайте её сами

Это главное, что нужно знать при переходе. У OpenAI Responses умеет хранить диалог на стороне сервера: следующий запрос ссылается на предыдущий через previous_response_id. PlusVibe переписку не хранит, поэтому previous_response_id не продолжает прошлый запрос, а поле store игнорируется (это описано в документации). Ошибки при этом не будет: модель просто не увидит прошлых реплик. Мы проверили: на вопрос «Как меня зовут?» с одним только previous_response_id модель ответила «Неизвестно».

Рабочий вариант — передавать всю историю в input, как в Chat Completions передают messages:

history = [{"role": "user", "content": "Меня зовут Аня. Запомни."}]
first = client.responses.create(model="gpt-5.6-luna", input=history)
history.append({"role": "assistant", "content": first.output_text})

history.append({"role": "user", "content": "Как меня зовут? Ответь одним словом."})
second = client.responses.create(model="gpt-5.6-luna", input=history)
print(second.output_text)  # Аня

Инструменты: другая форма описания

Function calling работает в обоих форматах, но описание функции выглядит по-разному. В Chat Completions поля функции вложены в объект function, в Responses — лежат прямо в элементе tools. Вызов функции приходит отдельным элементом function_call, а результат вы возвращаете элементом function_call_output с тем же call_id:

import json

tools = [{
    "type": "function",
    "name": "get_weather",
    "description": "Текущая погода в городе",
    "parameters": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
        "additionalProperties": False,
    },
}]

items = [{"role": "user", "content": "Какая погода в Казани?"}]
resp = client.responses.create(model="gpt-5.6-luna", input=items, tools=tools)

for item in resp.output:
    if item.type == "function_call":
        args = json.loads(item.arguments)
        result = {"city": args["city"], "temp_c": 12, "sky": "пасмурно"}  # ваша функция
        items.append({"type": "function_call", "call_id": item.call_id,
                      "name": item.name, "arguments": item.arguments})
        items.append({"type": "function_call_output", "call_id": item.call_id,
                      "output": json.dumps(result, ensure_ascii=False)})

final = client.responses.create(model="gpt-5.6-luna", input=items, tools=tools)
print(final.output_text)

В нашем прогоне модель вызвала get_weather с аргументом {"city": "Казань"}, а вторым запросом ответила, что в Казани 12 °C и пасмурно. Как то же самое выглядит в Chat Completions, мы разобрали в статье про function calling.

Потоковый режим

Оба формата поддерживают "stream": true, но события разные. Chat Completions присылает однотипные строки data:, где новый кусок текста лежит в choices[0].delta.content. Responses присылает именованные события: response.created, response.output_text.delta с кусками текста, response.completed в конце. Если вы разбираете поток сами, а не через SDK, парсер придётся писать под конкретный формат.

Какой формат выбрать

  • Chat Completions — если у вас уже есть код на нём или вы используете фреймворк, чат-интерфейс или no-code-платформу. Его понимает почти любой инструмент, и переписывать работающее ради смены формата незачем.
  • Responses — если его требует инструмент. Главный пример — Codex CLI: он ходит в /v1/responses, настройка описана в документации и в статье про Codex CLI в России. Ещё один повод — вы пишете новый агентный код на свежем SDK, где Responses используется по умолчанию.
  • Messages — третий формат, от Anthropic. Он нужен Claude Code и Anthropic SDK и живёт по адресу /v1/messages с заголовком x-api-key. Подробности — в разделе Messages и Responses.

Частые ошибки при переходе

Модель «забывает» диалог. Вы полагаетесь на previous_response_id. Передавайте историю в input целиком.

Пустой текст в ответе. Код читает output[0], а там элемент reasoning. Ищите элемент с типом message или берите output_text из SDK.

Ответ обрывается. Параметр называется max_output_tokens, а не max_tokens. У рассуждающих моделей в этот лимит входят и токены рассуждения, поэтому слишком маленькое значение может оставить ответ пустым.

Инструменты не вызываются. Описание функции скопировано из Chat Completions вместе с обёрткой function. В Responses поля name, description и parameters идут на верхнем уровне.

Итог

Chat Completions и Responses — два способа обратиться к одним и тем же моделям. В PlusVibe они работают с одним ключом, одинаковыми ценами и одинаковым каталогом. Если код уже написан, оставайтесь на Chat Completions. Responses нужен для Codex CLI и новых агентных SDK, только историю диалога передавайте в каждом запросе. Список моделей и цены — в каталоге, если нужен ответ строго по схеме, пригодится статья про Structured Outputs.

Chat Completions, Responses и Messages

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

Получить ключ →
OpenAI Responses APIChat Completionsresponses или chat completions/v1/responsesCodex CLI APIOpenAI API в Россииfunction calling responses

Попробуйте PlusVibe API

OpenAI-совместимый API: GPT, Claude, Gemini, видео и изображения — один рублёвый ключ. Работает из России без VPN, оплата рублями.

Читайте также

Responses API и Chat Completions: в чём разница