Twilio와 Gemini Live API 연동으로 전화하는 AI 에이전트 구축
Twilio를 사용하여 Gemini Live API에 전화 기능을 통합하여, 사용자가 전화로 AI 에이전트와 대화할 수 있도록 함
G.711 μ-law와 16-bit PCM 간의 오디오 형식 변환, 양방향 스트리밍, 인터럽트 처리를 통해 실시간 음성 통화(Real-time Voice Conversation)를 구현
FastAPI를 사용하여 HTTP 및 WebSocket 엔드포인트를 구축하고, Twilio Media Streams를 처리하여 오디오 스트리밍을 관리
오디오 샘플링 레이트 변환(Audio Sample Rate Conversion)을 위해 2단계 리샘플링(Resampling) 방식을 적용하여 음질 저하(Audio Quality Degradation)를 최소화함
Cloud Run 배포를 통해 프로덕션 환경 구축, API 키 관리(API Key Management) 및 보안 강화(Security Enhancement)를 위한 Secret Manager 활용
오디오 형식 변환(Audio Format Conversion) 심층 분석
본문에서는 Twilio의 G.711 μ-law 8kHz 오디오와 Gemini Live의 16-bit PCM 16kHz/24kHz 오디오 간의 변환 과정을 상세히 설명한다. audioop 모듈(audioop Module)을 사용하여 μ-law를 PCM으로 변환하고, 샘플링 레이트를 조정한다.
μ-law to PCM 변환: `audioop.ulaw2lin()` 함수를 사용하여 Twilio에서 수신된 μ-law 데이터를 PCM 데이터로 변환
샘플링 레이트 변환: Gemini Live의 요구사항에 맞춰 `audioop.ratecv()` 함수를 사용하여 8kHz에서 16kHz로 업샘플링(Upsampling) 수행
2단계 리샘플링(Two-step Resampling): Gemini Live의 출력(24kHz)을 Twilio에 맞게 8kHz로 다운샘플링(Downsampling)하기 위해 16kHz를 거치는 2단계 방식을 사용
이러한 변환 과정은 음성 통화 품질(Voice Call Quality)을 유지하면서 Gemini Live API와 Twilio 간의 호환성을 확보하는 데 필수적이다.
Twilio Media Streams를 활용한 양방향 오디오 스트리밍
Twilio Media Streams를 통해 Gemini Live API와 실시간 양방향 오디오 통신을 구현한다. WebSocket 연결(WebSocket Connection)을 통해 오디오 데이터를 송수신하며, FastAPI를 사용하여 WebSocket 엔드포인트를 구축한다.
Inbound Call Webhook: Twilio의 인바운드(Inbound) 콜을 처리하기 위해, TwiML(TwiML)을 반환하여 Twilio에 WebSocket 미디어 스트림을 시작하도록 지시
WebSocket 엔드포인트: Twilio Media Streams에서 수신된 오디오 데이터를 처리하고, Gemini Live API로부터 받은 오디오 데이터를 Twilio로 전송
오디오 버퍼링(Audio Buffering): Twilio가 일정한 프레임 크기(20ms)의 오디오 데이터를 요구하므로, `output_buffer`를 사용하여 오디오 데이터를 버퍼링하고, MULAW_FRAME_SIZE에 맞춰 전송
이러한 과정을 통해 실시간 통화(Real-time Conversation)를 가능하게 한다.
Gemini Live API 세션 관리 및 설계 결정
Gemini Live API 세션을 효율적으로 관리하기 위해, 재사용 가능한 `GeminiLive` 클래스를 설계한다. 이 클래스는 오디오 입력을 비동기 큐(Async Queue)를 통해 처리하고, 출력을 콜백(Callback) 함수를 통해 전달한다.
입력 샘플링 레이트(Input Sampling Rate): Twilio에서 수신되는 8kHz 오디오를 Gemini Live에 맞게 16kHz로 리샘플링(Resampling)하기 위해 `input_sample_rate`를 설정
비동기 콜백(Async Callback): `audio_output_callback` 함수는 동기 또는 비동기 함수를 모두 지원하며, `inspect.iscoroutinefunction()`을 사용하여 런타임에 감지
턴 커버리지(Turn Coverage): `turn_coverage="TURN_INCLUDES_ONLY_ACTIVITY"` 설정을 통해 Gemini가 실제 음성만 턴 입력으로 간주하도록 하여, 비용 절감(Cost Reduction) 효과를 얻음
이러한 설계 결정은 다양한 전송 방식(Transport)에 유연하게 대응하고, Gemini Live API를 효율적으로 활용하기 위한 것이다.
FastAPI를 이용한 웹 서비스 구축
FastAPI를 사용하여 Twilio와 Gemini Live API를 연결하는 웹 서비스를 구축한다. HTTP 엔드포인트(HTTP Endpoint)와 WebSocket 엔드포인트(WebSocket Endpoint)를 구현하여, 전화 통화 흐름을 제어한다.
/twilio/inbound 엔드포인트: Twilio의 인바운드 콜을 처리하고, TwiML을 반환하여 WebSocket 연결을 시작
/twilio/stream 엔드포인트: Twilio Media Streams에서 오디오 데이터를 수신하고, Gemini Live API와 통신하며, 오디오 데이터를 Twilio로 전송
/twilio/outbound 엔드포인트: Twilio REST API를 사용하여 아웃바운드(Outbound) 콜을 발신
이러한 엔드포인트들은 Twilio API(Twilio API)와 Gemini Live API 간의 통신을 중개하며, 전화 통화 기능을 구현하는 핵심 요소이다.
Cloud Run 배포 및 보안 고려 사항
프로덕션 환경을 위해 Google Cloud Run에 서비스를 배포하고, 보안을 강화하기 위한 몇 가지 고려 사항을 제시한다. Secret Manager를 사용하여 API 키를 안전하게 관리하고, 인증되지 않은 접근(Unauthenticated Access)을 방지한다.
Cloud Run 배포: `gcloud run deploy` 명령어를 사용하여 서비스를 배포하고, 환경 변수(Environment Variables)를 설정
Secret Manager 활용: API 키와 Twilio 계정 정보를 Secret Manager에 저장하여, 보안 취약점(Security Vulnerability)을 최소화
/twilio/outbound 엔드포인트 보안: API 키를 요구하거나, 내부 트래픽으로 제한하는 등, 무단 호출(Unauthorized Call)을 방지하기 위한 보안 조치 필요
이러한 조치들을 통해, 안정적이고 안전한 전화 기반 AI 에이전트 서비스를 운영할 수 있다.