500ms 미만 latency의 voice agent를 밑바닥부터 만든 과정
Show HN: I built a sub-500ms latency voice agent from scratch
TL;DR Highlight
STT→LLM→TTS 파이프라인을 직접 조립해서 Vapi 같은 올인원 플랫폼보다 2배 빠른 ~400ms 응답 속도의 음성 에이전트를 하루 만에 만든 경험기. 음성 에이전트의 핵심이 모델이 아니라 오케스트레이션임을 보여준다.
Who Should Read
음성 AI 제품을 만들고 있거나, Vapi·ElevenLabs 같은 올인원 플랫폼을 쓰면서 latency 문제로 고민 중인 백엔드/풀스택 개발자
Core Mechanics
- 음성 에이전트의 핵심 난이도는 모델 성능이 아니라 turn-taking 오케스트레이션에 있다. 사용자가 말하는 중인지, 끝났는지를 정확히 판단하고 에이전트 오디오를 즉시 중단/시작하는 상태 머신을 잘 만들어야 한다.
- 전체 아키텍처를 두 가지 상태(사용자가 말하는 중 / 사용자가 듣는 중)와 두 가지 전환으로 단순화했다. 사용자가 말하기 시작하면 에이전트 생성·합성·버퍼를 전부 즉시 취소하고, 사용자가 멈추면 최소 지연으로 응답을 시작한다.
- VAD(Voice Activity Detection, 음성 구간 검출)만으로는 turn 종료를 판단할 수 없다. 사람은 말 중간에 멈추고, 더듬고, 필러를 넣기 때문에 semantic end-of-turn detection(의미 기반 발화 종료 판단)이 필요하다.
- STT, LLM, TTS를 스트리밍 파이프라인으로 연결해서 각 단계의 출력이 나오는 즉시 다음 단계로 넘기는 방식으로 latency를 줄였다. TTS WebSocket 커넥션을 미리 warm 상태로 유지하는 것만으로 ~300ms를 절약했다.
- 지리적 위치(서버-사용자 간 거리)와 모델 선택이 latency에 가장 큰 영향을 미쳤다. 처리 서버를 사용자 가까이 배치하는 것이 모델 최적화보다 효과적이었다.
- Vapi의 동일 구성 대비 2배 빠른 ~400ms end-to-end 응답 시간을 달성했다. 다만 이 비교는 tool call, webhook, 녹음 등 프로덕션 기능이 없는 순수 파이프라인 기준이라는 점에 유의해야 한다.
- 전체 구축에 약 하루, API 크레딧 약 $100이 소요되었고, 아키텍처 설계는 코드 작성 전에 ChatGPT와 반복적으로 멘탈 모델을 잡는 방식으로 진행했다.
Evidence
- 전 Amazon Alexa 엔지니어가 인간 대화에서 화자 전환 시 중간값 지연이 0ms라는 사실을 공유했다. 상대가 말을 끝내기 전에 이미 대답을 준비하기 때문이고, 예상과 다른 말이 나오면 'what?'이라고 한 뒤 0.5초 후 답하는 것도 이 메커니즘이라고 설명. Alexa도 'what time is it' 같은 로컬 응답도 거의 500ms 이하가 안 됐다고 밝혔다.
- STT→LLM→TTS 파이프라인 방식이 근본적으로 한계가 있고, end-to-end 모델(음성 입력→음성 출력을 단일 모델로 처리)이 미래라는 반론이 있었다. 직접 데모(chirpy)까지 만들어봤지만 실용 수준의 end-to-end 모델 학습에는 비용이 너무 크다는 경험도 공유됐다.
- Vapi 대비 2배 빠르다는 주장에 대해, Vapi는 tool call, webhook, 녹음, 멀티테넌트 라우팅 등 프로덕션 기능을 매 턴마다 처리하므로 공정한 비교가 아니라는 지적이 다수 있었다. 순수 파이프라인 vs 프로덕션 플랫폼이라는 차이를 각주로 명시해야 한다는 의견.
- 프로덕션 음성 에이전트를 운영 중인 개발자가 barge-in(사용자가 에이전트 말을 끊는 것) 처리의 어려움을 공유했다. LLM/TTS 취소뿐 아니라 이미 트리거된 하류 작업(예약 확정, DB 기록)과의 race condition 버그를 겪었다고 한다.
- LLM이 침묵을 감지하면 'mhmm', 'right, right' 같은 필러 단어를 먼저 내보내고 실제 응답을 생성하면 대화가 훨씬 자연스러울 것이라는 아이디어가 나왔다. 사용자 말이 안 끝났어도 필러이므로 끊김 문제가 없다는 점이 장점.
How to Apply
- Vapi나 ElevenLabs 같은 올인원 플랫폼의 latency가 병목이라면, Deepgram(STT) + GPT/Claude(LLM) + ElevenLabs(TTS)를 직접 스트리밍 파이프라인으로 연결해보라. TTS WebSocket을 미리 warm 상태로 유지하는 것만으로 ~300ms를 줄일 수 있다.
- 음성 에이전트에서 사용자 발화 종료 판단이 부정확하면, 단순 silence threshold(300ms 무음 등) 대신 Soniox 같은 semantic endpoint detection을 지원하는 STT를 검토하라. Daily의 독립 벤치마크(daily.co/blog/benchmarking-stt-for-voice-agents)에서 비교 결과를 확인할 수 있다.
- 음성 에이전트의 서버 위치를 사용자와 같은 리전에 배치하라. 특히 국제 통화의 경우 Twilio edge hop만으로 150-250ms가 추가되므로, caller 기반 라우팅으로 리전별 배포를 하면 체감 latency가 크게 줄어든다.
- barge-in 처리 시 LLM·TTS 취소뿐 아니라 하류 시스템(DB 쓰기, webhook, 예약 확정 등)의 race condition도 반드시 처리하라. 응답 경로에 이미 커밋된 사이드 이펙트를 롤백하는 로직을 넣어야 프로덕션에서 버그가 안 생긴다.
Terminology
VADVoice Activity Detection. 오디오에서 사람이 말하고 있는 구간과 침묵 구간을 구분하는 기술. 마이크에 대고 말할 때 녹음 버튼이 자동으로 켜지는 것과 비슷한 원리.
Turn-taking대화에서 '네 차례/내 차례'를 교대하는 것. 음성 에이전트에서는 사용자가 말 끝났는지를 정확히 감지해서 자연스럽게 교대하는 게 핵심 난제.
Barge-in사용자가 에이전트가 말하는 도중에 끼어드는 것. 이때 에이전트는 즉시 말을 멈추고 사용자 입력을 받아야 자연스러운 대화가 된다.
STTSpeech-to-Text. 음성을 텍스트로 변환하는 기술. Deepgram, Whisper 등이 대표적.
TTSText-to-Speech. 텍스트를 음성으로 변환하는 기술. ElevenLabs가 대표적이며, WebSocket으로 스트리밍하면 첫 음성 출력까지의 시간을 줄일 수 있다.
Semantic end-of-turn detection단순히 침묵 시간이 아니라 문맥과 의미를 분석해서 사용자가 진짜 말을 끝냈는지 판단하는 기술. '음...'이나 잠깐 멈춘 것과 실제 발화 종료를 구분할 수 있다.