# Chat Completions или Responses API: что меняется в интеграции

> Разбираем различия Chat Completions и Responses API в запросах, output Items, состоянии диалога, инструментах, JSON и streaming — без ложного дедлайна миграции.

- Source: https://www.aifreeapi.com/ru/posts/chat-completions-vs-responses-api
- Language: ru
- Published: 2026-08-25
- Updated: 2026-08-25
- Publisher: AI Free API (https://www.aifreeapi.com)

Если проект начинается сегодня, в большинстве случаев стоит брать Responses API. Если сервис на Chat Completions стабильно решает простую задачу генерации текста, срочной переписи нет. Текущее [руководство OpenAI по миграции](https://developers.openai.com/api/docs/guides/migrate-to-responses) одновременно говорит две важные вещи: Responses рекомендован для новых проектов, а Chat Completions продолжает поддерживаться.

Это не два имени одного JSON-протокола. Chat Completions строится вокруг массива сообщений и массива вариантов ответа. Responses использует типизированные **Items**: сообщение, reasoning, вызов функции и результат функции — разные элементы. Поэтому смена URL затрагивает парсер, состояние диалога, инструменты, streaming и наблюдаемость.

![Сравнение контрактов Chat Completions и Responses API для ввода, вывода, состояния, инструментов, structured output и streaming](https://www.aifreeapi.com/posts/ru/chat-completions-vs-responses-api/img/cover.webp)

## Сначала найдите контракт, от которого зависит код

Минимальные вызовы выглядят похоже:

```python
completion = client.chat.completions.create(
    model="gpt-5.6",
    messages=[{"role": "user", "content": "Классифицируй обращение"}],
)
text = completion.choices[0].message.content

response = client.responses.create(
    model="gpt-5.6",
    input="Классифицируй обращение",
)
text = response.output_text
```

Но `output_text` — удобный помощник SDK только для итогового текста. Если нужны вызовы инструментов, статусы или другие типы результата, приложение должно разбирать `response.output`.

| Контракт | Chat Completions | Responses API |
|---|---|---|
| Endpoint | `/v1/chat/completions` | `/v1/responses` |
| Вход | `messages` | `input` и при необходимости `instructions` |
| Выход | `choices[].message` | типизированные `output[]` Items |
| Несколько кандидатов | параметр `n` | одна генерация в response |
| Продолжение диалога | повторная отправка истории | `previous_response_id`, Conversations или ручной replay |
| Structured Outputs | `response_format` | `text.format` |
| Поток | chunks и `choices[].delta` | типизированные события |

Простой массив role/content можно передать в Responses как `input`. Это облегчает первый тест, но не делает протоколы взаимозаменяемыми.

## Состояние диалога не отменяет ответственность приложения

В Chat Completions приложение обычно хранит нужную историю и снова отправляет её в `messages`. Responses позволяет связать следующий ход через `previous_response_id`:

```python
first = client.responses.create(
    model="gpt-5.6",
    instructions="Отвечай как дежурный инженер.",
    input="Сгруппируй эти алерты по причине.",
)

next_turn = client.responses.create(
    model="gpt-5.6",
    previous_response_id=first.id,
    instructions="Отвечай как дежурный инженер.",
    input="Оставь только критическую группу.",
)
```

Повтор `instructions` здесь обязателен по смыслу. [API reference Responses](https://developers.openai.com/api/reference/resources/responses/methods/create) предупреждает: инструкции предыдущего response не переносятся автоматически только из-за `previous_response_id`.

Удобное продолжение и хранение данных — разные решения. В [документе OpenAI о данных](https://developers.openai.com/api/docs/guides/your-data) отдельно описаны `store`, Zero Data Retention, background mode, кэш, hosted tools и внешние сервисы. Сейчас для сохранённого Responses application state указан период не менее 30 дней, но организационные настройки и исключения меняют результат. Для требований к данным проверяйте реальную конфигурацию, а не один флаг.

## Function calling меняет весь цикл

![Цикл вызова инструмента в Chat Completions и Responses API с разными конвертами и конечными состояниями](https://www.aifreeapi.com/posts/ru/chat-completions-vs-responses-api/img/tool-call-cycle.webp)

В Chat Completions вызовы функций находятся внутри assistant message. Результат возвращается сообщением `role: "tool"`, связанным через `tool_call_id`. В Responses вызов — отдельный Item `function_call`, а результат — `function_call_output`, связанный через `call_id`.

```python
outputs = []
for item in response.output:
    if item.type == "function_call":
        outputs.append({
            "type": "function_call_output",
            "call_id": item.call_id,
            "output": run_tool(item.name, item.arguments),
        })
```

Нельзя обрабатывать только первый элемент: модель может вернуть параллельные вызовы. Приёмочные тесты должны покрывать ноль, один и несколько вызовов, неверные аргументы, timeout, ошибку инструмента и повторный вызов после результата. Актуальные конверты приведены в [официальном руководстве по function calling](https://developers.openai.com/api/docs/guides/function-calling).

Hosted tools — web search, file search, code interpreter и remote MCP — делают Responses особенно полезным для агентных сценариев. Но поддержка конкретного инструмента зависит от модели.

## Streaming требует диспетчера событий

Chat Completions отдаёт chunks, и интерфейс часто просто добавляет `choices[0].delta.content`. Responses отдаёт семантические события разных типов: текстовые delta, аргументы функции, завершение Item и финальный статус всего response. В [руководстве по streaming](https://developers.openai.com/api/docs/guides/streaming-responses) эти формы показаны отдельно.

Интерфейс должен различать `completed`, `failed`, `incomplete`, отмену пользователем и разрыв сети. HTTP 200 и первый текстовый fragment ещё не означают успешного завершения. Для диагностики полезно сохранять response ID, финальный статус, типы Items, usage и причину ошибки или незавершённости.

Structured Outputs тоже меняет форму запроса: `response_format` становится `text.format`. Проверяйте не только JSON Schema, но и поддержку модели, refusal и ветку ошибки. [Официальное руководство](https://developers.openai.com/api/docs/guides/structured-outputs) отдельно объясняет, когда нужна структурированная реплика пользователю, а когда function calling для действия в системе.

## Когда остаться, а когда перейти

![Матрица выбора API по типу нагрузки и проверки совместимости перед миграцией](https://www.aifreeapi.com/posts/ru/chat-completions-vs-responses-api/img/workload-choice-matrix.webp)

Responses лучше подходит новому проекту с инструментами, reasoning context, мультимодальным входом, длинной задачей или будущим агентным циклом. Chat Completions можно оставить для зрелого однопроходного текста, если миграция пока не даёт измеримой пользы.

Для сторонних сервисов важна переносимость. Надпись «OpenAI-compatible» часто означает совместимость именно с Chat Completions. Она не доказывает поддержку Responses. По документации провайдера отдельно проверяйте endpoint, Items, события потока, tool envelopes, продолжение состояния и ошибки.

Практичная миграция идёт за адаптером: сначала уберите из бизнес-кода прямой доступ к `choices[0]`, затем запустите shadow-трафик, выберите стратегию состояния, перенесите полный цикл инструментов, перепишите streaming и только после этого постепенно переключайте production. Готовность наступает не тогда, когда пример выдал текст, а когда диалог восстанавливается, все вызовы связаны, schema разбирается, поток корректно закрывается, а сбой можно объяснить.
