← Docs hub

LLM Live 기기 Runtime

이 문서는 Live가 기기 안에서 실행되는 과정만 설명한다. Broker 설정은 현재 Broker, 조절값은 튜닝 파라미터, 사용자 정책은 음성 인터랙션 기획에서 관리한다.

동작 요약

  1. Wake-up 후 AudioRecord를 한 번 연다.
  2. 같은 16 kHz PCM을 로컬 판단과 Live Shadow에 전달한다.
  3. 제품 명령이면 기존 FunctionCallHandler를 실행하고 Shadow를 닫는다.
  4. SK_19면 Shadow를 Primary로 바꾸고 Gemini 응답 권한을 연다.
  5. Gemini의 24 kHz PCM을 재생하며 Barge-in을 감시한다.
  6. 답변 후 5초 동안 다음 말이 없으면 마이크와 WebSocket을 함께 닫는다.

주요 용어

용어 의미
PCM 압축하지 않은 음성 데이터. 입력은 16 kHz, Gemini 응답은 24 kHz다.
VAD 사람의 발화 시작과 끝을 찾는 기능이다.
Shadow 로컬 분류 전 Live 연결과 입력만 준비하는 상태다. 답변 권한은 없다.
Primary SK_19 판단 후 Gemini Live가 실제 답변을 담당하는 상태다.
WebSocket 연결을 유지하며 음성과 이벤트를 계속 주고받는 통신이다.
Barge-in 답변 중 사용자가 말하면 기존 답변을 멈추고 새 질문을 받는 기능이다.
Echo 스피커의 답변 음성이 다시 마이크에 들어오는 현상이다.

Runtime 흐름

Wake-up / F2
  -> AudioRecord 시작
  -> 동일 PCM: 로컬 STT/LLM + Live Shadow
  -> 로컬 분류
     -> 제품 명령: 기존 Device API, Shadow 종료
     -> SK_19: Live Primary 전환
  -> Gemini PCM 재생
  -> Barge-in 또는 답변 소진
  -> 다음 입력 대기
  -> 5초 무발화 또는 종료 신호
  -> AudioRecord + AudioTrack + WebSocket + UI 정리

상태와 종료

상태 PCM 처리 상태를 벗어나는 조건
STREAMING_INPUT 사용자 PCM을 Gemini에 전송 Gemini VAD가 약 800ms 무음을 확인. F3는 약 1.1초 뒤 보조
WAITING_RESPONSE 마이크는 유지하지만 PCM 전송은 중지 첫 응답, 20초 timeout 또는 오류
PLAYING_RESPONSE Gemini PCM 재생, 마이크로 Barge-in 감시 Interrupted, 재생 소진 또는 종료 신호
LISTENING_FOR_NEXT_INPUT 500ms 잔향 보호 후 입력 전송 재개 새 발화 또는 5초 무발화

F1은 발화 시작 힌트이고 F3는 현재 입력 턴 종료를 돕는다. 둘 다 Live 전체 세션을 직접 끝내는 신호로 사용하지 않는다. 700ms보다 짧은 F1-F3 구간은 발화 종료 근거에서 제외한다.

명시 종료, Gemini end_conversation, Device LLM_END, timeout과 오류는 LiveConversationTerminationGate로 모인다. 첫 종료 요청만 처리해 중복 AudioTrack 정지와 이전 턴의 지연 event가 새 상태를 덮는 것을 막는다.

maxSessionAgeMs는 14분으로 정의돼 있지만 RotateSession 후속 처리가 모든 경로에 연결되지 않았다. 14분 자동 교체는 아직 운영 보장 항목이 아니다.

Barge-in과 Echo

큰 소리만으로 답변을 끊으면 기기 자신의 음성을 사용자 발화로 오인한다. 현재는 로컬 Echo gate가 전송 후보를 거르고, Gemini VAD의 Interrupted 또는 의미 있는 입력 전사가 최종 중단을 확정한다.

  1. 20ms 마이크 chunk의 최근 60ms를 분석한다.
  2. 음량과 유효 sample 조건을 통과한 입력을 후보로 둔다.
  3. 24 kHz 재생 PCM과 16 kHz 마이크 PCM을 0~1초 범위에서 시간 정렬한다.
  4. 파형 상관도와 5ms 음량 윤곽 상관도 중 큰 값을 echoSimilarity로 사용한다.
  5. 0.74 이상이면 ECHO_REJECTED로 기록하고 Gemini 전송을 차단한다.
  6. 0.74보다 낮은 후보가 2 x 20ms 이어지면 후보 PCM까지 Gemini에 보낸다.
  7. 중단이 확정되면 AudioTrack을 멈추고 남은 PCM queue를 비운다.

이 방식은 Echo를 신호에서 제거하는 완전한 AEC가 아니다. 재생 음성과 비슷한 입력을 막는 gate이므로 거리, 기기 볼륨과 주변 소음별 실기기 검증이 필요하다.

로그 해석
ECHO_REJECTED, echoSimilarity=0.91 스피커 답변과 매우 비슷해 전송 차단
CANDIDATE, echoSimilarity=0.15 Echo가 아닌 사용자 발화 후보 확인 중
CONFIRMED 로컬 40ms 조건 통과
SERVER_VAD_FORWARDED Gemini VAD가 최종 발화 경계를 판단 중

기존 방식과 시간 비교

항목 기존 온디바이스 Gemini Live
답변 후 다음 입력 대기 필요한 멀티턴에서 최대 10초 모든 답변 뒤 5초
발화 종료 F3 후 약 1.65초 Gemini VAD 약 800ms, F3 보조
처음부터 무발화 약 3.5초 뒤 정리 다음 입력 대기 상태에서 5초 뒤 정리
녹음 한 입력 최대 10초 장치는 세션 동안 유지, VAD/F3는 현재 턴만 종료
Live 응답 대기 해당 없음 기본 20초, Barge-in 이후 10초

대화 기록

1턴은 사용자 질문과 어시스턴트 답변 한 쌍이다.

경로 보존 범위 세션 종료 시
Cloud REST 완료 16턴 + 처리 중 user 1개, 최대 33개 message 마지막 완료 1턴만 유지
Gemini Live 앱의 16턴 제한과 무관한 WebSocket 문맥 연결 종료와 함께 종료
Broker 별도 대화 기록 없음 1:1 중계 연결 해제

CloudConversationHistoryPolicy는 REST 요청 크기를 제한한다. 이 값을 바꿔도 Gemini Live의 문맥 길이는 바뀌지 않는다.

코드와 검증

역할 코드
전체 상태 연결 ForegroundService.kt, LiveConversationController.kt
마이크 fan-out AudioCaptureLine.kt, GeminiLiveStreamingConsumer.kt
Echo 판정과 재생 LivePlaybackEchoMatcher.kt, GeminiLiveAudioPlayer.kt
응답과 tool GeminiLiveResponseRouter.kt, GeminiLiveToolBridge.kt
종료 LiveStopCommandPolicy.kt, LiveConversationTerminationGate.kt

JVM 테스트 뒤에도 Release APK 실기기에서 첫 응답 시간, Barge-in 정지 시간, Echo 오중단, 첫 음절 보존, 재생 연속성, 5초 종료와 반복 세션 자원 회수를 확인해야 한다.

관련 문서

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date