API 응답 스트리밍

API 응답 스트리밍

기본적으로 OpenAI API에 요청하면 모델의 출력 전체가 만들어질 때까지 기다렸다가, 그 완성본을 한 번에 하나의 HTTP 응답으로 돌려줘요. 긴 출력을 생성하는 경우에는 응답을 기다리는 시간이 꽤 걸리죠. 스트리밍을 켜면 모델이 아직 전체 응답을 만들고 있는 동안에도 맨 앞부분부터 출력하거나 처리하기 시작할 수 있어요. 이 가이드는 서버 전송 이벤트(SSE)를 쓰는 HTTP 스트리밍(stream=true)에 집중합니다. previous_response_id로 증분 입력을 받는 지속 WebSocket 전송이 필요하다면 Responses API WebSocket 모드 문서를 보세요.

출처: 공식문서

스트리밍 켜기

Responses 엔드포인트에 요청할 때 stream=True를 설정하면 스트리밍이 시작돼요:

from openai import OpenAI

client = OpenAI()

stream = client.responses.create(
    model="gpt-6-astra",
    input=[
        {
            "role": "user",
            "content": "Say 'double bubble bath' ten times fast.",
        },
    ],
    stream=True,
)

for event in stream:
    print(event)
import { OpenAI } from "openai";
const client = new OpenAI();

const stream = await client.responses.create({
  model: "gpt-6-astra",
  input: [
    {
      role: "user",
      content: "Say 'double bubble bath' ten times fast.",
    },
  ],
  stream: true,
});

for await (const event of stream) {
  console.log(event);
}

Responses API는 스트리밍에 **의미 있는 이벤트(semantic events)**를 사용해요. 각 이벤트에는 미리 정의된 스키마가 있어서, 애플리케이션이 자신이 필요한 이벤트만 골라 들을 수 있습니다.

이벤트 타입 전체 목록은 스트리밍 API 레퍼런스에서 확인할 수 있는데, 대표적인 몇 가지를 보여드릴게요:

StreamingEvent = (
    ResponseCreatedEvent
    | ResponseInProgressEvent
    | ResponseFailedEvent
    | ResponseCompletedEvent
    | ResponseOutputItemAdded
    | ResponseOutputItemDone
    | ResponseContentPartAdded
    | ResponseContentPartDone
    | ResponseOutputTextDelta
    | ResponseOutputTextAnnotationAdded
    | ResponseTextDone
    | ResponseRefusalDelta
    | ResponseRefusalDone
    | ResponseFunctionCallArgumentsDelta
    | ResponseFunctionCallArgumentsDone
    | ResponseFileSearchCallInProgress
    | ResponseFileSearchCallSearching
    | ResponseFileSearchCallCompleted
    | ResponseCodeInterpreterInProgress
    | ResponseCodeInterpreterCallCodeDelta
    | ResponseCodeInterpreterCallCodeDone
    | ResponseCodeInterpreterCallInterpreting
    | ResponseCodeInterpreterCallCompleted
    | Error
)
for await (const event of stream) {
  if (event.type === "response.output_text.delta") {
    process.stdout.write(event.delta);
  } else if (event.type === "response.completed") {
    console.log("\nResponse completed.");
  } else if (event.type === "error") {
    console.error(event.message);
  }
}

응답 읽기

SDK를 쓰고 있다면 모든 이벤트가 타입이 있는 인스턴스로 들어와요. 이벤트의 type 속성으로 개별 이벤트를 식별할 수도 있습니다.

일부 수명주기 이벤트는 한 번만 발생하고, 다른 이벤트는 응답이 생성되는 동안 여러 번 발생해요. 텍스트를 스트리밍할 때 자주 들을 만한 공통 이벤트는 다음과 같습니다.

- `response.created`
- `response.output_text.delta`
- `response.completed`
- `error`

들을 수 있는 이벤트의 전체 목록은 스트리밍 API 레퍼런스에서 확인하세요.

고급 사용 사례

도구 호출 스트리밍 같은 더 고급 사용 사례는 전용 가이드에서 다뤄요.

모더레이션 위험

운영 애플리케이션에서 모델 출력을 스트리밍하면 완성 생성물의 콘텐츠를 검열하기가 더 어려워질 수 있어요. 부분적인 완성 결과는 평가하기가 더 까다로울 수 있고, 이는 승인된 사용 범위에도 영향을 줄 수 있습니다. 생성 요청과 함께 모더레이션 점수를 요청하면 그 점수는 전체 생성 출력이 다 나온 뒤에 도착하고, 부분 출력 델타에는 포함되지 않아요.

더 알아보기 (Learn more)