본문으로 건너뛰기
마크다운으로 보기

스트리밍

chat/completions 요청에서 stream을 true로 설정하면 생성되는 토큰을 server-sent events(SSE)로 실시간 수신합니다. 게이트웨이는 모델 서버의 이벤트를 도착하는 대로 전달합니다. 여기에 keepalive 주석을 더하고, usage를 요청하면 마지막 usage 청크에 비용을 추가하며, 요청하지 않으면 그 청크를 제거합니다.

요청

stream은 JSON 불리언 true로 보내세요. 게이트웨이는 문자열 "true"와 숫자 1도 스트리밍으로 읽지만, SDK와 다른 OpenAI 형식 서버는 불리언을 기대합니다. 공식 OpenAI SDK는 이 값을 대신 설정하고 스트림도 파싱합니다.

bash
curl https://api.bricksum.com/v1/chat/completions \
  -H "Authorization: Bearer sk-bk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-32b",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": true
  }'

이벤트 형식

응답의 Content-Type은 text/event-stream입니다. 각 이벤트는 chat.completion.chunk를 담은 data: 줄 하나이며, choices[0].delta에 새 텍스트가 들어 있습니다. 마지막 delta에 finish_reason이 실리고, 스트림은 data: [DONE]으로 끝납니다.

text/event-stream
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1710000000,"model":"qwen3-32b","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1710000000,"model":"qwen3-32b","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]
참고
대부분의 OpenAI SDK는 stream=true를 넘기면 SSE를 대신 파싱해 delta 객체를 돌려줍니다. 빈 줄로 나누고 주석 줄을 건너뛰는 처리는 원시 HTTP 클라이언트에서만 필요합니다.

keepalive 주석

모델이 아직 토큰을 내지 않은 동안에는 게이트웨이가 15초마다 SSE 주석 줄을 보내 프록시와 클라이언트의 타임아웃을 막습니다. 부하가 높아 요청이 모델 서버의 대기열에서 기다리는 동안도 여기에 포함됩니다. 콜론으로 시작하는 줄은 주석이며 데이터가 없으므로 무시하세요. 부하가 높을 때 첫 토큰까지 오래 걸리는 것은 정상이며 에러가 아닙니다.

comment line
: keepalive

토큰 사용량과 비용

기본적으로 스트림에는 usage가 실리지 않습니다. 요청에서 stream_options.include_usage 값을 true로 설정하면 스트림 끝에 청크가 하나 더 옵니다. 이 청크는 choices가 비어 있고 usage 객체에 토큰 수가 담겨 있습니다.

request
{
  "model": "qwen3-32b",
  "messages": [{"role": "user", "content": "Hello!"}],
  "stream": true,
  "stream_options": { "include_usage": true }
}
final chunk
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1710000000,"model":"qwen3-32b","choices":[],"usage":{"prompt_tokens":9,"completion_tokens":12,"total_tokens":21,"cost":0.000001155}}

data: [DONE]

게이트웨이는 그 청크에 usage.cost를 추가합니다. 이 값은 이 요청으로 크레딧에서 차감된 USD 금액이며, usage의 토큰 수와 모델의 토큰 단가로 계산합니다. 비스트리밍 응답에도 같은 usage.cost 필드가 실립니다. usage를 요청하지 않으면 이 청크는 클라이언트에 도달하기 전에 제거됩니다. 이 예시의 토큰 수와 cost는 gpt-oss-120b에서 측정한 예시 값이며, qwen3-32b의 값이 아닙니다.

계측된 모든 응답에는 X-Neocloud-Generation-Id 헤더가 실립니다. 값은 이 요청의 사용량 이벤트 ID입니다. 로그와 함께 저장해 두면 차감 내역이나 에러를 해당 요청까지 추적할 수 있습니다.

연결 끊김과 에러

  • 클라이언트가 스트림 도중 연결을 끊어도 생성이 즉시 취소되지는 않습니다. 게이트웨이는 사용량을 기록하기 위해 스트림을 끝까지 읽으며, 생성된 토큰은 과금됩니다.
  • 모델 서버가 스트림 도중 실패하면 에러가 그대로 전달되고 그 요청은 과금되지 않습니다.
  • 스트림이 finish_reason: "length"로 끝나면 max_tokens를 늘리세요. reasoning 토큰도 max_tokens에 포함됩니다. 알려진 제한은 API 레퍼런스를 참고하세요.