
음성 AI의 300ms를 100ms로 느끼게 만드는 5가지 착각 해킹
요약
음성 AI의 물리적 레이턴시를 줄이는 대신, 사용자 경험(UX) 측면에서 체감 속도를 높이는 5가지 '착각 해킹' 기법을 소개합니다. Nielsen의 임계값 이론을 바탕으로, 물리적 한계를 극복하기 위한 효율적인 설계 전략을 다룹니다.
핵심 포인트
- 물리적 레이턴시 단축보다 지각(Perception) 설계가 ROI가 높음
- Nielsen의 삼중 임계값을 활용한 UX 설계의 중요성
- 필러(Filler) 음성 선행 재생을 통한 추론 시간 확보
- 단순 구현으로 체감 속도를 300ms에서 100ms로 개선
LLM을 빠르게 만드는 방향으로 3개월을 허비했습니다.
GPU 증강, 모델 경량화, STT의 병렬화. 그럼에도 실측치 300ms는 줄어들지 않았습니다.
어느 날 밤, 공동 개발자인 미사키가 커피를 놓으며 뒤돌아보며 말했습니다. "발상을 바꿔보자. 물리적으로 불가능하다면, 그렇게 느끼게 만들면 돼."
그 한마디에 방향을 틀었습니다.
그로부터 2주 만에, 물리적 레이턴시(Latency)는 바꾸지 않고 체감 속도를 100ms 근처까지 줄였습니다. 마술사가 물건을 없애는 것이 아니라, 없어진 것처럼 보이게 만드는 것과 같은 발상입니다.
이 기사에서는 지금까지 구현해 온 5가지 착각 해킹(Perception Hacks)을 정리합니다. 모두 구현 코드가 수십 줄 내외로 간단하면서도, 체감 단축 효과를 측정할 수 있는 것들만 골랐습니다. Nielsen의 삼중 임계값(Three Thresholds)과 현재의 Realtime API 사양을 언급하며, 왜 "실측보다 지각을 설계하는 것"이 비용 대비 효율이 높은지도 기술하겠습니다.
이 기사에서 다루는 5가지 해킹

구현 개요와 체감 단축 밀리초(ms) 대응표. 단순 합산이 아니라 시너지 효과로 작용함
한 장에 압축했습니다.
모두 더하면 900ms 가까이 되지만, 실제로는 시너지 효과로 인해 100-200ms 정도의 체감 단축에 수렴합니다. 그럼에도 대화의 질은 충분히 달라집니다.
왜 "실측"보다 "체감"을 설계하는가
Jakob Nielsen이 1993년 『Usability Engineering』에서 정리한 삼중 임계값은 여전히 UX 설계의 토대입니다.
0.1초: 시스템이 즉각 반응한다고 느끼는 한계 -
1초: 사용자의 사고 흐름이 끊기지 않는 한계 -
10초: 사용자의 주의가 대화에 머무는 한계
음성 AI는 300ms의 영역입니다. 0.1초를 넘어 1초 미만의 존(Zone). 이곳은 "지연을 느끼고 있지만, 아직 대화는 성립하는" 중간 지대입니다. 이곳을 "지연을 느끼지 않는" 쪽으로 옮기는 것만으로도 경험이 바뀝니다.
OpenAI의 Realtime API(GPT-Realtime-2.1)조차, machine-side latency는 공칭 190ms이며, production 환경의 첫 번째 턴(First Turn)에서는 500-1200ms까지 늘어난다고 보고되고 있습니다.
물리적인 300ms는 현재의 음성 AI 엔지니어링에서 천장입니다.
천장을 뚫으려 하면 GPU를 늘리거나, 모델을 증류(Distillation)하거나, STT와 LLM을 병렬화하는 등의 대책을 세우게 됩니다. 모두 효과는 있습니다. 하지만 투입한 공수에 비해 체감 개선은 작습니다. 사용자는 20ms의 개선을 인식하지 못하기 때문입니다. Nielsen 자신도 1993년 당시에 "인간의 지각은 연속값이 아니라 단계적이다"라고 썼습니다.
그렇기에 발상을 바꿉니다.
실측치를 1ms라도 줄이기 위해 GPU를 쌓는 것보다, 체감을 150ms 줄이는 장치를 하나 넣는 것이 ROI(투자 대비 효율)가 압도적으로 높습니다.
해킹 1: 필러(Filler) 선행 음성으로 200ms 벌기
LLM의 추론을 기다리지 않고, 먼저 "음...", "그렇군요"를 재생합니다. 이는 Pipecat이 제창하는 Preemptive Speech Generation(선행 음성 생성)의 개념과 유사한 패턴입니다. VAD가 발화 종단을 예측한 순간, 확정을 기다리지 않고 TTS로 짧은 필러를 흘려보내기 시작합니다.
구현은 놀라울 정도로 단순합니다.
async def on_utterance_end_predicted():
# 추론을 요청함과 동시에, 필러를 선행 재생
await tts_stream("음...")
...
"이거, 반칙 아닌가?"라고 처음에는 생각했습니다. 하지만 인간도 생각하는 시간에 "음..."이라고 말합니다. 오히려 무음인 편이 더 부자연스러웠습니다.
ACM CUI 2025 연구에 따르면, 고지연 조건(4초 이상)에서 특히 필러의 효과가 현저하다고 보고되었습니다. 300ms 상황에서도 체감상 200ms 정도의 단축을 기대할 수 있습니다.
주의점: 필러가 매번 같으면 기계적인 느낌이 납니다. 5~8종류를 랜덤화하세요. "음...", "그렇군요", "음...", "글쎄요", "아하", "잠시만 기다려 주세요" 등 상황에 맞춰 사용하면 자연스러움이 더해집니다.
또 다른 함정은 필러 재생 중에 LLM이 에러로 응답하지 못할 경우의 설계입니다. 필러만 나오고 본론이 나오지 않는 사고가 발생할 수 있습니다. timeout을 설정하여 폴백(Fallback) 응답을 준비해 두어야 합니다.
해킹 2: 맞장구의 즉시 응답으로 150ms 벌기
필러가 "AI가 말을 시작하기 전의 윤활유"라면, 맞장구는 "사용자가 말하는 도중의 윤활유"입니다.
사용자가 "어제, 시부야에서"라고 말한 시점에, AI가 "응"이라고 대답합니다. 이 150ms의 맞장구가 들어가는 것만으로도 경험은 "내 말을 들어주고 있다"로 바뀝니다.
구현의 핵심은 VAD(Voice Activity Detection, 음성 구간 검출)의 임계값 조정입니다.
발화 중의 짧은 숨 고르기(200-400ms)에서 맞장구 삽입
if silence_duration > 200 and silence_duration < 400:
if not is_end_of_turn(context):
...
여기서 어려운 점은 턴 테이킹 (Turn-taking, 대화 순서 전환) 판정입니다. 맞장구를 치려는 의도로 대화에 끼어들면, 사용자는 "말을 끊겼다"고 느낍니다. 자세한 내용은 음성 AI의 턴 테이킹 (Turn-taking) 설계에 관한 글에서 다루었습니다.
"응"이라는 단 한 마디. 그것만으로도 150ms의 체감 단축이 가능합니다.
맞장구의 빈도 또한 설계 대상입니다. 인간 사이의 대화에서는 듣는 사람이 3~8초에 한 번꼴로 맞장구를 친다고 합니다. AI도 이와 비슷한 페이스를 기준으로 삼으면 자연스럽습니다. 5초에 한 번 정도, 화자가 숨을 고르는 타이밍에 가볍게 반응하는 식입니다. 너무 많으면 시끄럽고, 너무 적으면 "듣고 있지 않다"는 인상을 줍니다.
타입도 중요합니다. "응", "네", "그렇군요", "정말인가요" 등 내용에 따라 골라 사용하면 정밀도가 높아집니다. 감정 추정 (Emotion Estimation)과 결합하여, 사용자가 당황해 보인다면 "힘드시겠네요"라고 답하는 식의 설계도 있습니다. Hume AI의 Empathic Voice Interface가 채택하고 있는 방향성입니다.
해킹 3: 부분 결과 스트림으로 180ms 벌기
STT (음성 인식)도 LLM (대규모 언어 모델)도 내부적으로는 토큰 (Token)을 순차적으로 생성합니다. 이 중간 토큰을 확정될 때까지 기다리지 않고 계속 흘려보내는 것만으로도 체감은 완전히 달라집니다.
Google Speech-to-Text나 OpenAI Realtime API는 interim_results나 response.delta 이벤트를 통해 중간 결과를 스트리밍 (Streaming) 방식으로 전달합니다. TTS (음성 합성) 측도 청크 오디오 스트리밍 (Chunked audio streaming)을 지원하므로, LLM의 토큰이 하나 나올 때마다 TTS로 던지면 첫 오디오 (First audio)가 나오기까지의 시간이 크게 단축됩니다.
체감상으로는 "아직 생각 중이지만, 입은 움직이기 시작했다"는 상태가 됩니다. 인간의 대화와 매우 흡사합니다.
async for token in llm.stream(prompt):
await tts_stream_partial(token)
단 세 줄입니다.
그것만으로 180ms를 벌 수 있습니다.
다만 부작용도 있습니다. 중간 토큰은 수정될 가능성이 있기 때문에, TTS에 던진 후에 "사실은 틀렸습니다"라고 하게 되면 음성이 매끄럽지 못하고 끊기게 됩니다. 수정 빈도를 측정하여 임계값을 넘으면 중간 스트림을 일시 정지하는 설계가 필요합니다.
SuperWhisper와 같은 앱은 이 설계를 시각 UI 측면까지 확장하고 있습니다. ASR (자동 음성 인식)의 생결과를 회색 글자로 먼저 표시하고, 정제된 후에 교체하는 방식입니다. 사용자는 "입력이 반영되고 있다"는 것을 즉시 확인할 수 있습니다. 음성 UI에서도 동일한 원리를 사용할 수 있습니다. TTS는 수정이 어렵기 때문에, 대신 "말을 고치자면" 같은 문구를 삽입하는 방법도 있습니다. "아, 정확히는"이라는 한마디를 통해 수정이 자연스러운 대화의 일부가 되도록 만드는 것입니다.
해킹 4: 프로그레시브 응답으로 120ms 벌기
"세 가지 포인트가 있습니다. 첫 번째는..."
이것만으로도 사용자의 뇌 속 타이머는 멈춥니다. 전체적인 윤곽이 제시되는 순간, 남은 시간은 "답변을 기다리는 시간"에서 "정보를 받아들이는 시간"으로 전환되기 때문입니다.
심리학적으로는 이를 프레이밍 효과 (Framing Effect)라고 부릅니다. 똑같은 30초라도 "지금부터 3분 동안 이야기하겠습니다"라고 처음에 말하면 체감 시간은 짧아집니다. 바텐더가 "오늘은 조금 특별한 칵테일을 만들어 드릴게요"라고 한마디 덧붙이는 것과 비슷합니다.
프롬프트 설계를 통해 간단히 구현할 수 있습니다.
당신은 음성 AI입니다. 답변은 반드시 다음 형식으로 시작하세요:
"[요점 수]가지가 있습니다. 첫 번째는,"
체감 단축 효과는 120ms 정도로 완만하지만, 구현 비용이 거의 제로에 가깝기 때문에 도입하지 않을 이유가 없습니다.
부차적인 효과도 있습니다. 사용자가 "아, 세 가지가 있구나. 그럼 두 번째까지 듣고 판단해야지"라며 듣는 자세를 미리 갖출 수 있게 됩니다. 정보 수용 효율이 올라가는 것입니다. 긴 설명을 제공하는 프로덕트일수록 이 효과는 더욱 큽니다.
반면, 짧은 응답이 많은 프로덕트에서는 역효과를 낼 수 있습니다. "오늘 날씨는 어때?"라는 질문에 "한 가지가 있습니다. 그것은 맑음입니다"라고 답하는 것은 부자연스럽습니다. 프로덕트의 유스케이스를 살펴보고, 장문 답변이 중심이 되는 상황에만 한정하여 적용하십시오.
해킹 5: 우선순위 스트림 분할로 250ms 벌기
이 방법이 가장 효과적이었습니다.
답변을 "짧은 답변"과 "긴 설명"으로 나눕니다. 짧은 답변을 먼저 TTS로 보내고, 긴 설명은 뒤따라 흐르게 하는 설계입니다.
예를 들어 사용자가 "오늘 날씨는"이라고 물었을 경우.
- 선행 스트림 (先行ストリーム, Preemptive Stream) (즉시): 「도쿄는 맑습니다.」 -
후속 스트림 (後追いストリーム, Follow-up Stream) (1-2초 후): 「최고 기온은 32도이며, 습도가 높습니다. 오후부터...」
선행 스트림에서 250ms 이내에 음성이 응답되면, 사용자의 체감은 '즉답'입니다. 이후의 해설은 '보충'으로 받아들여집니다.
구현은 2-스트림 (2-stream) 설계입니다.
async def dual_stream_response(query):
# 먼저 short answer를 생성하여 즉시 재생
short = await llm.generate(query, max_tokens=20, priority="high")
...
짧은 답변용 LLM 호출은 max_tokens를 제한하면 수십 ms 내에 돌아옵니다. 이것이 250ms 단축의 정체입니다.
"같은 LLM을 두 번 호출하는 것은 비용이 2배 아닌가요?"라는 질문을 받았습니다. 절반은 정답입니다. 짧은 답변은 max_tokens가 작기 때문에, 실제 비용은 1.2~1.3배 정도입니다. 체감이 250ms 줄어든다면, 이 차액은 저렴합니다.
또 다른 변형은 짧은 답변을 LLM으로 보내지 않고, 미리 정의된 템플릿으로 반환하는 설계입니다. 날씨, 시간, 간단한 확인 응답 등 패턴화할 수 있는 질문은 LLM을 호출하지 않고 수 ms 내에 반환할 수 있습니다. GetStream이 제안하는 '투기적 도구 호출 (Speculative Tool Calling)' 개념과 유사한 패턴입니다.
5가지를 조합하면 어떻게 되는가
단순 합산으로는 900ms 단축이 되겠지만, 실제로는 그렇지 않습니다. 필러 (Filler)와 맞장구는 겹치면 과하게 느껴지고, 부분 결과 스트림과 우선순위 스트림 분할은 충돌합니다.
실제 운용에서는 다음과 같은 조합이 안정적입니다.
| 유스케이스 | 권장 해킹 (Hack) | 기대 단축 |
|---|---|---|
| 짧은 응답이 많은 대화형 AI | 1 + 5 | 200ms |
| ... |
300ms 실측 - 200ms 체감 단축 = 체감 100ms입니다. Nielsen의 0.1초 임계값, 즉 '즉각 응답하고 있다'고 느끼는 영역에 진입할 수 있습니다.
또 하나 중요한 것은 측정 설계입니다. '체감'은 주관적 지표이므로, A/B 테스트로 비교해야 합니다. 동일한 사용자에게 두 가지 설정을 짧은 시간 내에 체험하게 하고, 5단계 평가(1: 매우 느림 / 5: 매우 빠름)를 받습니다. 10~20명의 샘플에서 평균 점수가 0.5점 이상 올라가면 효과가 있다고 판단할 수 있습니다. 물리적 레이턴시 (Latency)는 변하지 않았는데 주관적 점수가 올라간 결과를 보면, 체감 설계의 위력을 실감하게 됩니다.
'빠르게 만들기'에서 '빠르게 느끼게 하기'로의 전환
3개월 동안 GPU와 격투한 끝에, 2주 만에 체감을 100ms에 가깝게 만들었습니다. 기술적 난이도는 후자가 더 낮습니다. 그럼에도 불구하고 많은 팀이 전자에 인건비를 쏟아붓고 있습니다.
물리적 레이턴시를 깎는 것은 돌에서 물을 짜내는 것과 같은 작업입니다. 300ms에서 200ms로의 개선은 GPU 예산을 10배로 늘려도 도달하지 못할 수도 있습니다.
반면 체감 설계는 코드 50줄을 추가하는 것만으로 150ms를 벌 수 있습니다.
물론 물리적 레이턴시 개선도 멈춰서는 안 됩니다. 다만 우선순위를 역전시킬 가치는 있습니다. 먼저 체감을 100ms에 가깝게 맞춘 다음, 그다음에 물리적 수치를 깎으러 가는 것입니다. 이 순서로 진행하면 사용자가 기다려 주는 시간이 길어지므로, 물리적 개선의 기한도 늘어납니다.
체감 설계는 '태만'이 아닙니다. '먼저 매출을 일으키는' 설계입니다.
음성 AI의 경험이 어디서 붕괴하는지는 '음성 AI 경험이 붕괴하는 3가지 절벽'에 정리해 두었습니다. 함께 읽어보시면 300ms/500ms/800ms의 각 절벽에 대해 어떤 해킹이 효과적인지 보일 것입니다.
요약
- 음성 AI의 300ms 실측치는 GPU 증설로는 줄어들지 않는 천장에 가깝다
- 체감 설계로 전환하면 코드 수십 줄로 150~200ms를 벌 수 있다
- 5가지 해킹(필러 선행/맞장구 즉시/부분 결과/프로그레시브/우선순위 분할)의 조합으로 체감 100ms에 다가갈 수 있다
- 구현 ROI(투자 대비 효율)는 체감 설계가 압도적으로 높다. 우선순위를 역전시킬 가치가 있다
- Nielsen의 3대 임계값(0.1s/1s/10s)은 지금도 음성 AI 설계의 나침반이다
"빠르게 만들기보다, 빠르게 느끼게 하라". 이 한 문장에 3개월 치의 수업료가 담겨 있습니다. 여러분은 같은 수업료를 내지 않도록 여기에 남겨둡니다.
참고 문헌
참고 문헌
- Nielsen, Jakob. "Response Times: The 3 Important Limits." Nielsen Norman Group, 1993.
- OpenAI. "How OpenAI delivers low-latency voice AI at scale." OpenAI Blog, 2026.
- ACM CUI 2025. "Mitigating Response Delays in Free-Form Conversations with LLM-powered IVAs." (LLM 기반 IVA를 사용한 자유 형식 대화의 응답 지연 완화)
- Pipecat (GitHub). "Preemptive speech generation option for seamless conversation." Issue #3321, 2025.
논의

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기