2P by GN⁺ 8시간전 | ★ favorite | 댓글 1개
  • 음성 기반 AI 시스템의 지연시간을 400ms 수준으로 줄인 자체 구축형 음성 에이전트 개발 사례를 다룸
  • STT, LLM, TTS를 실시간 파이프라인으로 연결해 기존 상용 플랫폼(Vapi 등)보다 2배 빠른 응답 속도 달성
  • Deepgram Flux로 발화 감지와 전환을 처리하고, Groq의 llama-3.3-70b 모델을 사용해 첫 토큰 생성 시간을 대폭 단축
  • 지리적 배치와 네트워크 최적화를 통해 EU 지역 배포 시 지연시간을 절반 이하로 감소
  • 음성 에이전트의 핵심은 실시간 오케스트레이션과 파이프라인 설계이며, 이를 직접 구현하면 성능 병목을 명확히 파악할 수 있음

음성 에이전트 구축 배경

  • 소비재 대기업을 위한 음성 에이전트 프로토타입 개발 경험을 바탕으로, 상용 플랫폼의 복잡성을 직접 다루기 위해 자체 구축 시도
  • ElevenLabs와 Vapi 같은 플랫폼은 편리하지만, 내부 동작을 이해하기 어렵고 세밀한 지연시간 제어가 불가능
  • 목표는 Vapi 수준의 성능을 직접 구현하는 것이었으며, 하루와 약 100달러의 API 크레딧으로 실현

음성 에이전트의 복잡성

  • 텍스트 기반 챗봇과 달리, 음성은 실시간 전환 관리(turn-taking) 가 필요
  • 사용자가 말하는 순간 시스템은 즉시 발화를 중단하고, 멈추면 빠르게 응답을 시작해야 함
  • 단순한 음성 감지(VAD)만으로는 발화 종료를 정확히 판단하기 어렵고, 지연·중첩 발화·불필요한 침묵이 발생

1차 구현: VAD 기반 테스트

  • FastAPI 서버와 Twilio WebSocket을 이용해 μ-law 오디오 스트림을 수신
  • Silero VAD로 음성 존재 여부를 판단하고, 발화 종료 시 미리 녹음된 WAV 파일을 재생
  • 단순하지만 즉각적인 반응성과 자연스러운 대화 흐름을 확인할 수 있었음
  • 이 단계에서 지연시간의 하한선을 측정하는 기준 확보

2차 구현: Deepgram Flux와 실시간 파이프라인

  • Deepgram Flux를 도입해 스트리밍 전사와 턴 감지를 통합
  • Flux가 발화 종료를 감지하면 다음 순서로 처리
    • 전사 결과와 대화 이력을 LLM에 전달
    • 첫 토큰이 생성되는 즉시 TTS(WebSocket) 로 스트리밍
    • 생성된 오디오를 Twilio로 실시간 전송
  • TTS 연결을 사전 유지(warm pool) 해 약 300ms의 지연을 절감
  • 사용자가 말을 시작하면 LLM·TTS·오디오 전송을 즉시 취소해 자연스러운 중단 처리 구현

지연시간 측정과 지역 배포

  • 터키 현지에서 로컬 실행 시 평균 1.6~1.7초 지연 발생
  • Railway EU 리전에 배포하고 Twilio·Deepgram·ElevenLabs를 EU 리전으로 맞추자
    • 평균 690ms(총 790ms) 로 단축, Vapi 대비 약 50ms 빠름
  • 지연 감소로 대화 반응성이 크게 향상, 발화 중단 처리도 매끄러워짐

모델 선택과 성능 향상

  • 초기에는 gpt-4o-mini 사용, 이후 Groq llama-3.3-70b로 교체
  • 테스트 결과 Groq 모델의 첫 토큰 생성 시간(TTFT) 이 OpenAI 대비 최대 3배 빠름
  • 평균 400ms 이하의 종단 간 지연 달성, 첫 오디오가 500ms 이내 도착
  • 이 수준에서는 사람보다 에이전트가 더 빨리 반응하는 체감

주요 기술적 교훈

  • 지연시간 최적화는 발화 종료부터 첫 음성 출력까지의 전체 경로 관리가 핵심
  • TTFT가 전체 지연의 절반 이상을 차지하므로, 저지연 모델 선택이 중요
  • STT→LLM→TTS를 순차 처리하지 않고 스트리밍 파이프라인화해야 함
  • 발화 중단 시 전 구성요소를 즉시 취소해야 자연스러운 대화 유지
  • 서비스 간 지리적 근접성이 지연에 결정적 영향을 미침

상용 플랫폼과의 비교

  • Vapi·ElevenLabs는 API, 안정성, 관찰성 등 부가 기능을 제공하므로 대부분의 팀에는 여전히 유용
  • 그러나 직접 구축을 통해 실제 병목과 파라미터 의미를 이해할 수 있으며,
    특정 요구에 맞춘 맞춤형 오케스트레이션이 가능
  • 음성 시스템은 결국 오케스트레이션 문제이며, 구조를 명확히 보면 해결 가능한 엔지니어링 과제임

소스 코드

  • 전체 구현은 GitHub에서 공개됨: github.com/NickTikhonov/shuo
Hacker News 의견들
  • 이 글이 정말 흥미로움. 예전에 Amazon Alexa 팀에서 이 문제를 연구했고 관련 특허도 있음
    대화 중 사람 간 평균 지연은 0ms, 즉 상대가 말을 끝내기 전에 이미 다음 사람이 말을 시작함. 뇌가 상대의 말을 예측하며 동시에 답변을 준비하기 때문임
    반면 사람들은 음성 비서에게는 지연을 기대함. 이유는 두 가지 — 컴퓨터가 ‘생각’해야 한다는 인식, 그리고 휴대폰 통화의 지연 때문임
    Alexa의 응답 중 500ms 이하인 것은 거의 없음. 예전엔 단순히 300ms의 침묵을 ‘턴 종료’로 간주했지만, 진짜 핵심은 semantic end-of-turn
    지금은 계산 자원이 충분하니, 이 부분이 얼마나 발전했을지 궁금함. 지리적 근접 처리(엣지 컴퓨팅)가 큰 전환점이었음

    • 휴대폰 통화의 지연은 특히 연령대가 높은 사람들에게 스트레스를 줌. 유선전화 시절엔 거의 지연이 없었기 때문에, 왜 불편한지도 모른 채 답답함을 느낌
    • 2번 사실에는 동의하지 않음. 음성 비서의 지연 시간(latency) 은 여전히 너무 느림. “작동했나?” 하고 기다리게 됨. 휴대폰의 지연이 다른 기기에도 기대된다고 생각하지 않음
    • 300ms 침묵을 턴 종료로 보는 건 너무 불편했음. 그래서 일부러 “음…” 같은 채움말(filler) 을 넣어야 했고, 결국 음성 채팅을 포기하게 됨
    • 흥미로운 내용 공유에 감사함. 그런데 왜 Amazon/Google/Apple 은 최근 몇 년간 음성 비서 혁신을 멈췄는지 궁금함. 기존 사용자 기반만으로도 시장을 다시 정의할 수 있었을 텐데
    • LLM이 사용자의 발화를 예측적으로 이어받는 구조를 말하는 것 같음. 발화가 실제로 끝났을 때 예측과 일치하면 지연 없이 바로 응답 가능함. 여러 후보 스레드를 동시에 예측해가며 가지치기하는 방식도 가능해 보임
  • 음성은 결국 턴테이킹(turn-taking) 문제라고 생각함. 아무도 손대지 않은 쉬운 개선점이 있음 — 바로 채움말과 템포 조절
    LLM이 잠시 침묵을 감지하면, 실제 응답이 생성되는 동안 “음”, “그렇죠” 같은 맥락 있는 채움말을 넣는 식임. 이렇게 하면 대화가 훨씬 자연스러워짐

    • 완전 공감함. 작은 저지연 모델이 먼저 짧은 응답을 생성하고, TTS 결과를 캐시해두면 지연을 극단적으로 줄일 수 있음. “잠시만요, 생각 중이에요” 같은 문장은 밀리초 단위로 응답 가능함
    • 하지만 ‘쉬운 개선’은 아닐 수도 있음. 로봇 같은 시스템을 인간적으로 만드는 건 어렵고, 단순히 문장 구조를 바꾸면 오히려 더 기계적으로 들림. 직접 시도해봤지만 실패했음
    • 관련해서 LiveKit의 “Prompting Voice Agents to Sound More Realistic” 블로그가 흥미로움
    • 사용자가 말을 끝내기 전에 시스템이 응답을 예측할 수 있다면 훨씬 자연스러울 것임
    • 턴 종료를 잘못 감지했을 때, 음소 단위 filler 로 자연스럽게 이어붙이는 방법도 가능함. 반대로 너무 늦게 감지했다면, 첫 음절을 미리 정해두고 그걸로 답변을 시작하도록 프롬프트에 넣을 수도 있음
  • 훌륭한 글임. OpenAI Responses client가 최근 웹소켓을 도입해 지연이 줄었음.
    또 다른 방법은 초소형 LLM을 로컬에서 직접 실행하는 것임. 나는 ova 프로젝트를 통해 완전 로컬 파이프라인을 만들었고, 스트리밍 없이도 1초 미만의 왕복 시간을 얻었음

    • 멋진 프로젝트라서 즐겨찾기에 추가했음. 나중에 경험을 공유하며 이야기 나누고 싶음
  • 글의 스트리밍 파이프라인 구조와 단계별 지연 분석이 매우 유용했음. 직접 턴테이킹 루프를 구현한 점이 인상적임
    다만 “Vapi보다 2배 빠르다”는 비교는 약간 부정확함. Vapi는 툴 호출, 웹훅, 멀티테넌트 라우팅 등 훨씬 많은 작업을 수행함
    이 글의 진짜 가치는 ‘직접 만든 오케스트레이션 루프의 통찰’에 있음. 단순히 “직접 만들어보며 배운 점”으로 정리했다면 완벽했을 것임

  • 나도 Twilio + Deepgram + ElevenLabs + LLM API 조합으로 상용 음성 에이전트를 구축 중임
    핵심은 STT 정확도가 아니라 턴테이킹 UX였음. 고정된 침묵 임계값 대신 semantic end-of-turn 으로 바꾸자 체감이 완전히 달라졌음
    지역 간 지연도 중요함. 인도에서 미국 서버로 연결할 때 Twilio 엣지 홉만으로도 150~250ms 추가됨. 지역별 라우팅으로 개선했음
    Barge-in(중간 끼어들기) 처리도 복잡함. LLM과 TTS를 중단하는 것뿐 아니라, 이미 실행된 자동화 워크플로우를 되돌려야 함. 예전에 예약 확인 중 끼어들면 예약이 실제로 완료되는 버그도 있었음

  • Soniox Real-time(60개 언어 지원)은 endpoint detection을 모델 수준에서 처리함. VAD보다 훨씬 정확함
    기술 문서, Daily의 벤치마크, 데모 페이지 참고 가능함
    예전에 Soniox에서 근무했음. 실시간 endpoint detection을 최초로 구현한 서비스였음

    • 원문을 보면 Deepgram Flux를 사용했다고 나옴. 이것도 endpointing을 지원하며 VAD보다 상위 추상화 계층임
    • 현재 Soniox를 사용 중인데, 내부에서 일할 때 어땠는지 궁금함. 경쟁사 대비 저렴한 가격으로 SoTA 성능을 내는 비결이 무엇인지 알고 싶음
  • 개인적으로 STT → LLM → TTS 구조는 한계가 있다고 봄. 미래는 end-to-end 음성 모델
    2년 전 Chirpy 데모를 만들어봤지만, 실제로 쓸 만한 수준으로 가려면 전용 학습이 필요했음. 사이드 프로젝트로는 감당 불가였음

    • 그 관점이라면 NVIDIA의 PersonaPlex 연구가 흥미로울 것임: https://research.nvidia.com/labs/adlr/personaplex/
    • 나는 최근 몇 년간 음성 에이전트만 다뤘음. 계단식 모델(cascading model) 은 당분간 사라지지 않을 것임.
      기업 고객은 감사 가능성(auditability)신뢰성을 중시함. 의료·금융 같은 규제 산업에서는 STT와 LLM 출력을 각각 검증해야 함
      반면 end-to-end 음성 모델은 인터뷰나 설문처럼 서사적 용도에 더 적합함. 실제 고객들은 최신 모델보다 엔지니어링 완성도를 원함
    • 근본적으로는 “언제 내 차례인지 예측하는 능력”이 모델에 내장돼야 함. Moshi의 full-duplex 모드가 그 방향을 잘 보여줌: https://arxiv.org/abs/2410.00037
    • 계단식 구조의 장점은 각 단계별로 새 모델을 교체할 수 있다는 점임. STT, TTS, LLM의 발전 속도가 다르기 때문에 유연성이 큼
    • 최신 음성 토크나이저는 초당 약 12Hz 수준까지 도달했음. 일반 LLM보다 훨씬 많은 토큰을 사용함
  • 이번 접근은 게임 엔진 네트코드 초기 발전을 떠올리게 함. 지연은 모델 문제가 아니라 오케스트레이션 문제
    Carmack의 2013년 VR 논문에서도 같은 주장을 했음 — 파이프라인 전체를 추적해야 밀리초 단위 병목을 찾을 수 있음
    Latency Mitigation Strategies 참고할 만함. TTS 웹소켓 풀을 미리 열어 300ms를 절약한 사례가 완벽한 예시임

  • 오픈소스 음성 인식 앱 Handy를 소개하고 싶음. 완전히 오프라인으로 동작하며 확장 가능함
    나는 매일 Claude와 함께 사용 중인데, macOS 기본 받아쓰기보다 훨씬 잘 작동함

  • 좋은 글이지만, 턴테이킹만으로 대화를 설명하는 건 너무 단순함
    실제 대화에는 겹침 발화, 확인 신호, 청취 유지용 발화(phatic messages), 심지어 상대의 말을 완성해주는 협력적 행동도 있음
    이런 요소들은 단순한 턴테이킹 모델로는 잘 표현되지 않으며, 모델이 이를 생성하고 이해할 수 있어야 함