OpenAI API 스트리밍 응답 구현 시 주의사항
문제 상황
사내 챗봇 서비스에 GPT-4 API를 붙이면서 사용자 경험 개선을 위해 스트리밍 응답을 구현했다. 일반 요청 대비 체감 속도가 훨씬 좋았지만, 프로덕션 배포 후 간헐적으로 응답이 끊기는 현상이 발생했다.
원인 분석
첫 번째 문제는 Nginx의 proxy_read_timeout 설정이었다. 스트리밍 중 일정 시간 데이터가 오지 않으면 타임아웃이 발생했다. 두 번째는 OpenAI API의 에러가 스트림 중간에 발생할 경우 적절히 처리되지 않는 점이었다.
const stream = await openai.chat.completions.create({
model: 'gpt-4',
messages: messages,
stream: true,
});
for await (const chunk of stream) {
try {
const content = chunk.choices[0]?.delta?.content;
if (content) {
res.write(`data: ${JSON.stringify({ content })}\n\n`);
}
} catch (error) {
res.write(`data: ${JSON.stringify({ error: error.message })}\n\n`);
break;
}
}
res.write('data: [DONE]\n\n');
res.end();
해결 방법
Nginx 설정에 proxy_read_timeout 300s를 추가하고, 클라이언트에서도 heartbeat를 구현해 연결 유지를 확인하도록 했다. 또한 스트림 중 발생하는 에러를 별도 메시지로 전달해 프론트엔드에서 적절한 안내를 보여주도록 개선했다.
추가 개선
토큰 사용량을 실시간으로 추적하기 위해 tiktoken 라이브러리를 도입했다. 응답이 완료된 후가 아니라 스트리밍 중간중간 대략적인 토큰 수를 계산해 비용을 모니터링할 수 있게 되었다.
프로덕션 환경에서는 rate limit 대응도 중요했다. 429 에러 발생 시 exponential backoff를 적용하고, 사용자에게는 대기 메시지를 표시하도록 처리했다.