OpenAI API 응답 지연 모니터링 시스템 구축

문제 상황

사용자 대화 기능에서 GPT-4o API 호출이 간헐적으로 30초 이상 지연되는 현상이 발생했다. 특히 트래픽이 몰리는 시간대에 타임아웃이 빈번했고, 사용자 경험이 크게 저하되었다.

모니터링 구현

먼저 API 호출 시간과 실패율을 추적하는 래퍼 함수를 작성했다.

interface APIMetrics {
  startTime: number;
  endTime?: number;
  duration?: number;
  status: 'success' | 'timeout' | 'error';
  model: string;
}

const metrics: APIMetrics[] = [];

async function callOpenAIWithTimeout(
  messages: any[],
  timeout = 20000
) {
  const metric: APIMetrics = {
    startTime: Date.now(),
    status: 'success',
    model: 'gpt-4o'
  };

  try {
    const result = await Promise.race([
      openai.chat.completions.create({
        model: 'gpt-4o',
        messages
      }),
      new Promise((_, reject) => 
        setTimeout(() => reject(new Error('Timeout')), timeout)
      )
    ]);
    
    metric.endTime = Date.now();
    metric.duration = metric.endTime - metric.startTime;
    metrics.push(metric);
    
    return result;
  } catch (error) {
    metric.endTime = Date.now();
    metric.duration = metric.endTime - metric.startTime;
    metric.status = error.message === 'Timeout' ? 'timeout' : 'error';
    metrics.push(metric);
    throw error;
  }
}

재시도 로직 추가

타임아웃 발생 시 자동으로 재시도하는 로직을 구현했다.

async function callWithRetry(messages: any[], maxRetries = 2) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await callOpenAIWithTimeout(messages);
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}

메트릭 분석 엔드포인트

수집된 메트릭을 확인할 수 있는 API를 추가했다.

app.get('/api/metrics', (req, res) => {
  const last100 = metrics.slice(-100);
  const avgDuration = last100.reduce((sum, m) => sum + (m.duration || 0), 0) / last100.length;
  const timeoutRate = last100.filter(m => m.status === 'timeout').length / last100.length;
  
  res.json({
    avgDuration: Math.round(avgDuration),
    timeoutRate: (timeoutRate * 100).toFixed(2) + '%',
    total: last100.length
  });
});

결과

타임아웃을 20초로 설정하고 재시도 로직을 추가한 후 사용자 불만이 70% 감소했다. 메트릭을 통해 평균 응답 시간이 5~8초임을 확인했고, 타임아웃률은 3% 미만으로 유지되고 있다.

향후 모델별 응답 시간 차이를 분석하여 최적의 모델 선택 로직을 추가할 예정이다.