AIFreeAPI Logo

Chat Completions와 Responses API: 무엇이 실제로 달라지나

A
3 min readAI 개발

새 OpenAI 연동은 Responses API가 유리하지만, 안정적인 Chat Completions를 서둘러 폐기할 이유는 없습니다. 먼저 출력·상태·도구·스트리밍 계약을 확인하세요.

Chat Completions와 Responses API에서 달라지는 입력, 출력, 대화 상태, 도구, 구조화 출력, 스트리밍 계약

새 프로젝트라면 Responses API를 기본 후보로 삼는 것이 좋습니다. 이미 Chat Completions로 단순 텍스트 기능을 안정적으로 운영 중이라면 급하게 전면 재작성할 필요는 없습니다. OpenAI의 현재 마이그레이션 가이드는 Responses를 새 프로젝트에 권장하면서도 Chat Completions는 계속 지원된다고 명시합니다.

따라서 이 선택은 “곧 종료되는 API를 피하는 일”이 아닙니다. Chat Completions는 message 입력과 choice 출력을 중심으로 하고, Responses는 message, reasoning, function call, tool result를 서로 다른 타입의 Item으로 표현합니다. URL만 바꾸면 출력 파서, 대화 상태, 도구 왕복, 스트리밍 종료 조건이 깨질 수 있습니다.

요청과 출력의 기준점이 다르다

한 번의 텍스트 생성은 비슷해 보입니다.

js
const completion = await client.chat.completions.create({ model: "gpt-5.6", messages: [{ role: "user", content: "이 문의를 분류해 줘" }], }); const chatText = completion.choices[0].message.content; const response = await client.responses.create({ model: "gpt-5.6", input: "이 문의를 분류해 줘", }); const responseText = response.output_text;

output_text는 최종 텍스트를 꺼내는 SDK 편의 기능입니다. 도구 호출, reasoning summary, 출처, Item별 상태가 필요하면 response.output을 타입에 따라 순회해야 합니다.

애플리케이션 계약Chat CompletionsResponses API
endpoint/v1/chat/completions/v1/responses
입력messagesinput, 선택적 instructions
출력choices[].message타입이 지정된 output[] Items
여러 후보n으로 여러 choiceresponse당 한 generation
대화 연결메시지 이력 재전송previous_response_id, Conversations, 수동 replay
구조화 출력response_formattext.format
스트리밍chunk의 choices[].delta의미가 지정된 이벤트

단순한 role/content 배열을 Responses input에 재사용할 수는 있습니다. 이것은 최소 입력의 호환성일 뿐, 두 프로토콜의 응답 객체가 호환된다는 뜻은 아닙니다.

대화 상태와 데이터 보관을 분리한다

Chat Completions에서는 애플리케이션이 필요한 대화 이력을 저장하고 다음 messages에 다시 넣는 방식이 일반적입니다. Responses는 previous_response_id로 다음 턴을 연결할 수 있습니다.

js
const first = await client.responses.create({ model: "gpt-5.6", instructions: "간결한 장애 분석가로 답해라.", input: "알림을 원인별로 묶어 줘.", }); const next = await client.responses.create({ model: "gpt-5.6", previous_response_id: first.id, instructions: "간결한 장애 분석가로 답해라.", input: "즉시 대응할 그룹만 남겨 줘.", });

instructions를 반복한 데에는 이유가 있습니다. Responses API reference에 따르면 previous_response_id를 사용해도 이전 instructions는 자동으로 이어지지 않습니다. 지속되어야 할 정책은 애플리케이션이 다시 제공해야 합니다.

상태 연결과 데이터 보관도 같은 문제가 아닙니다. OpenAI의 데이터 제어 문서는 Responses, store, Zero Data Retention, background mode, cache, hosted tools를 별도로 설명합니다. 현재 저장된 Responses application state에는 최소 30일 보관이 명시되어 있지만 조직 설정과 예외가 적용됩니다. 개인정보 요구사항이 있다면 실제 사용 경로 전체를 확인해야 합니다.

도구 호출은 연결 ID와 결과 봉투가 바뀐다

Chat Completions의 tool call은 assistant message 안에 있으며, 실행 결과는 원래 호출의 tool_call_id를 가진 role: "tool" message로 돌려줍니다. Responses는 독립적인 function_call Item을 반환하고, 애플리케이션은 같은 call_id를 가진 function_call_output Item을 보냅니다.

js
const outputs = response.output .filter((item) => item.type === "function_call") .map((call) => ({ type: "function_call_output", call_id: call.call_id, output: JSON.stringify(runTool(call.name, call.arguments)), }));

첫 번째 call만 처리하면 안 됩니다. 병렬 호출, 잘못된 인자, timeout, 도구 실패, 결과 이후의 추가 호출을 모두 테스트해야 합니다. 현재 양쪽 형식은 OpenAI function calling 가이드에서 확인할 수 있습니다.

Responses가 제공하는 web search, file search, code interpreter, remote MCP 같은 hosted tools는 agentic workflow에서 큰 장점입니다. 단, 실제 지원 여부는 모델별 기능입니다.

스트리밍은 텍스트 연결보다 넓은 상태 머신이다

Chat Completions UI는 보통 choices[0].delta.content를 이어 붙입니다. Responses는 텍스트 delta, 함수 인자, Item 완료, 전체 response 완료를 서로 다른 이벤트로 보냅니다. 공식 스트리밍 가이드에 맞춰 이벤트 타입별 handler를 두는 편이 안전합니다.

HTTP 200이나 첫 텍스트 도착만으로 성공을 판단하지 마세요. completed, failed, incomplete, 사용자 취소, 네트워크 단절을 구분하고 response ID, 최종 status, Item type, usage, 오류 또는 incomplete reason을 기록해야 합니다.

Structured Outputs도 response_format에서 text.format으로 위치가 바뀝니다. Structured Outputs 가이드를 기준으로 schema뿐 아니라 모델 지원, refusal, parse failure를 검증해야 합니다.

워크로드별 API 선택과 제3자 Responses 호환성 확인 체크리스트
워크로드별 API 선택과 제3자 Responses 호환성 확인 체크리스트

새 구현과 기존 구현의 답은 다를 수 있다

reasoning context, hosted tools, 여러 단계의 함수 호출, 멀티모달 입력, 긴 작업이 필요하면 Responses가 더 나은 기반입니다. 성숙한 단발 텍스트 서비스이고 실질적 이득이 작다면 Chat Completions를 유지할 수 있습니다. Assistants API의 종료 일정을 Chat Completions에 적용해서는 안 됩니다.

Chat Completions에서 Responses로 단계적으로 이전하는 순서와 Go 또는 No-Go 승인 경계
Chat Completions에서 Responses로 단계적으로 이전하는 순서와 Go 또는 No-Go 승인 경계

안전한 이전은 adapter 뒤에서 진행합니다. 비즈니스 코드의 choices[0] 직접 의존을 제거하고, 대표 요청을 두 경로로 shadow 실행합니다. 문장 일치가 아니라 구조화 결과, refusal, 잘림, tool intent, usage를 비교한 뒤 상태, 전체 도구 왕복, 스트리밍, 데이터 제어를 순서대로 바꿉니다.

또한 “OpenAI-compatible”이라는 제3자 설명은 대개 Chat Completions 호환을 뜻하며 Responses 호환을 보장하지 않습니다. endpoint, Item, 이벤트, tool envelope, 상태, 오류 객체를 공급자 문서에서 따로 확인하세요. 샘플이 한 번 답한 것이 아니라 대화가 복구되고, 모든 call이 연결되고, schema가 파싱되고, stream이 닫히며, 실패 원인을 추적할 수 있을 때 마이그레이션이 끝납니다.