OpenAI Realtime API 운영기: 세션 복구와 비동기 후처리를 먼저 설계한 이유
실시간 음성 기능은 데모와 운영 사이의 간극이 큰 영역이다. 말이 오가면 끝나는 문제가 아니라, 세션/상태/실패처리까지 살아 있어야 제품이 된다.
이 글은 OpenAI Realtime API 기반 음성 Agent를 실제 서비스로 운영하면서 무엇을 먼저 설계했는지 정리한 기록이다. 정리 기준 시점은 2024년 10월(OpenAI Realtime API 공개 이후)이다.
문제 정의
핵심 문제는 기능이 아니라 운영이었다.
- 음성 스트림이 끊겼을 때 세션은 어떻게 복구할 것인가
- 중간 실패가 났을 때 상태 정합성을 어떻게 보장할 것인가
- 후속 처리(로그/과금/이벤트)를 어디서 일관되게 실행할 것인가
설계 원칙
초기에 잡은 원칙은 세 가지였다.
- 실시간 대화와 비동기 후속 처리를 분리한다.
- 세션 상태를 명시적으로 관리해 암묵적 상태를 줄인다.
- 실패를 예외가 아니라 정상 흐름으로 취급한다.
구현 선택
실제 아키텍처는 다음 흐름으로 구성했다.
voice in/out -> realtime conversation -> agent -> state/session -> post-processing
핵심은 대화 품질보다 운영 경계를 먼저 그은 것이다.
이 경계를 분리해두면 기능 확장 시 장애 영향 범위를 제어하기 쉽다.
세션 상태 모델
운영 단계에서는 “연결됨/끊김"만으로는 부족했다. 세션을 아래 상태로 분해했다.
INIT->READY->STREAMING->DRAINING->CLOSED
복구 정책도 상태별로 달리 적용했다.
READY이전 실패: 빠른 재시작STREAMING중 실패: 짧은 타임아웃 후 재연결DRAINING실패: 후처리 큐 보존 후 세션 종료
비동기 후처리 분리
실시간 경로에 로그/정산/분석 작업을 같이 넣으면 지연이 급증한다. 그래서 대화 종료 이벤트를 발행하고 후처리는 별도 워커에서 처리했다.
- 실시간 경로 목표:
응답 가능성 - 비동기 경로 목표:
완결성
이 분리 덕분에 트래픽 급증 구간에서도 음성 응답 지연을 안정적으로 유지할 수 있었다.
운영에서 효과가 컸던 포인트
- 세션과 상태를 분리해 재접속 시 복원 전략이 명확해짐
- 실패 처리 경로를 표준화해 장애 대응 속도가 개선됨
- 이벤트 기반 후속 처리를 분리해 실시간 경로 부담을 줄임
체크리스트
- 세션별 idempotency 키 적용
- 종료되지 않은 세션의 정리 작업(cron) 운영
- 음성 품질 지표(RTT, packet loss, interruption count) 수집
- 사용자 체감 장애와 시스템 로그를 동일 세션 ID로 연결
참고 및 인용
참고: OpenAI Realtime 가이드는 실시간 세션, 이벤트, 오디오 스트리밍 통합 패턴을 제공한다. Realtime API guide
참고: WebRTC 통계 표준은 RTT, packet loss, jitter 등 음성 품질 지표의 공통 정의를 제공한다. Identifiers for WebRTC’s Statistics API
참고: OpenTelemetry는 실시간 경로와 비동기 후처리 경로를 같은 trace 문맥으로 연결할 때 유용하다. OpenTelemetry Docs