OpenAI Realtime API 비용 최적화 - 세션 타임아웃 전략

문제 상황

음성 기반 고객 상담 서비스에 OpenAI Realtime API를 적용했는데, 첫 달 청구 금액이 예상의 2배를 넘었다. 로그를 분석해보니 사용자가 대화를 끝낸 후에도 세션이 계속 유지되는 경우가 많았다.

원인 분석

기존 코드는 WebSocket 연결만 관리하고 있었다.

const session = await openai.realtime.sessions.create({
  model: 'gpt-4o-realtime-preview-2024-10-01',
  voice: 'alloy'
});

ws.on('close', () => {
  session.close();
});

문제는 사용자가 브라우저를 그냥 닫거나 네트워크가 끊겼을 때 close 이벤트가 즉시 발생하지 않는다는 점이었다. TCP keepalive 타임아웃까지 세션이 유지되면서 과금이 계속됐다.

해결 방법

  1. Heartbeat 구현: 클라이언트에서 30초마다 ping을 보내도록 하고, 60초간 응답이 없으면 서버에서 세션을 강제 종료했다.
const sessions = new Map();

function startSession(userId) {
  const sessionData = {
    session: await openai.realtime.sessions.create({...}),
    lastHeartbeat: Date.now()
  };
  
  sessions.set(userId, sessionData);
}

setInterval(() => {
  const now = Date.now();
  for (const [userId, data] of sessions.entries()) {
    if (now - data.lastHeartbeat > 60000) {
      data.session.close();
      sessions.delete(userId);
      logger.info(`Session timeout: ${userId}`);
    }
  }
}, 10000);
  1. 무음 감지: 사용자 발화가 3분간 없으면 세션을 자동 종료하는 로직을 추가했다.

  2. 비용 모니터링: CloudWatch에 활성 세션 수와 평균 세션 지속 시간 메트릭을 추가해 실시간으로 모니터링했다.

결과

  • 평균 세션 지속 시간: 12분 → 5분
  • 월 비용: $3,200 → $1,900 (40% 절감)
  • 좀비 세션 발생률: 23% → 2%

세션 관리는 Realtime API 비용 관리의 핵심이었다. 특히 모바일 환경에서 네트워크 불안정으로 인한 좀비 세션이 많았는데, 적극적인 타임아웃 정책이 효과적이었다.