LLM Live 기존 사양 호환성
이 문서는 MR8의 기존 기능을 Live 적용 후에도 유지할 수 있는지 판단한다. 사용자 경험의 Before/After는 음성 인터랙션 기획, 서버 운영 목표는 향후 릴리즈 구조에서 관리한다.
결론
로컬 분류와 Device API 실행 원칙은 유지된다. 가장 큰 위험은 Live 음성을 일관되게 만들기 위해 로컬 TTS를 효과음으로 바꾼 범위가 오프라인 멀티턴과 제품의 추가 질문까지 없애는 것이다.
운영 적용 전에는 다음 네 가지가 필요하다.
- 제품 결과를 완료, 거부, 추가 질문, 정보 응답으로 구분한다.
- 오프라인 로컬 TTS와 기존 멀티턴을 보존한다.
- Live 첫 응답 전 장애의 fallback을 한 번만 수행한다.
- 음성 전송, 로그와 운영 Broker의 보안·개인정보 승인을 완료한다.
호환성 판정
| 영역 | 판정 | 현재 상태 | 필요한 조치 |
|---|---|---|---|
| 첫 질문 분류 | 호환 | 로컬 라우터가 제품 명령과 SK_19를 결정 |
유지 |
| 제품 실행 | 호환 | FunctionCallHandler -> Device API가 최종 실행 |
정확히 1회 실행 보장 |
| 마이크 | 호환 | AudioRecord 한 개를 로컬과 Live가 공유 | 중복 open 회귀 방지 |
| 일반 대화 | 의도된 변경 | 턴별 STT/LLM/TTS에서 Live WebSocket으로 변경 | 사용자 정책은 기획 문서에서 관리 |
| 발화 종료 | 의도된 변경 | F3 중심에서 Gemini VAD 중심으로 변경 | F1/F3는 보조로 제한 |
| TTS와 멀티턴 | 출시 차단 | 추가 질문이 효과음으로 바뀌고 세션이 닫힐 수 있음 | 결과 유형 계약 도입 |
| Live 장애 | 보완 필요 | setup 실패 뒤 Cloud REST 자동 복구 없음 | 첫 응답 전 fallback 1회 |
| 음성 인식 OFF | 보완 필요 | AudioRecord와 Live 논리 세션 종료가 분리될 수 있음 | 공통 종료 gate 연결 |
| 장시간 세션 | 보완 필요 | 14분 값은 있으나 RotateSession handler 미완성 |
watchdog/resumption 구현 |
가장 큰 충돌: TTS와 오프라인 멀티턴
문제
DeviceCommandCuePolicy는 단순 성공·실패 응답을 긍정·부정 효과음으로 바꾼다. Live의
rewrite_query 경로에서는 WAV가 아닌 결과를 의미 구분 없이 부정 효과음으로 바꾸고 세션까지
종료할 수 있다.
기존 볼륨 기능은 값이 없으면 다음 질문을 해야 한다.
사용자: 볼륨 조절해줘
기기: 현재 볼륨은 2단계입니다. 몇 단계로 조정할까요?
사용자: 3단계
기기: 볼륨을 3단계로 설정할게요.
추가 질문이 효과음으로 바뀌면 사용자는 무엇을 답해야 하는지 알 수 없고, -1 멀티턴 상태와
후속 “3단계”도 잃는다.
필요한 결과 계약
outcome |
음성 | 세션 |
|---|---|---|
COMPLETED |
짧은 완료 음성 또는 긍정 효과음 | 기본 종료 가능 |
REJECTED |
거부 이유 또는 부정 효과음 | 정책에 따라 종료 |
NEEDS_USER_INPUT |
Gemini의 같은 목소리로 추가 질문 | expectedSlot과 Live 유지 |
INFORMATION |
Gemini의 같은 목소리로 조회 결과 | 후속 질문 정책 적용 |
앱은 기존 로컬 로직을 먼저 실행하고 결과를 분류한 뒤 tool response를 반환해야 한다. Gemini는
Device API를 직접 호출하지 않고 speakText만 읽는다.
{
"outcome": "NEEDS_USER_INPUT",
"speakText": "현재 볼륨은 2단계입니다. 몇 단계로 조정할까요?",
"expectedSlot": "volume",
"allowedValues": [0, 1, 2, 3, 4, 5],
"keepSessionOpen": true
}
경로별 음성 정책
| 실행 경로 | 권장 처리 |
|---|---|
| 오프라인 로컬 | 기존 로컬 TTS와 multiTurnBusy 유지 |
| 온라인, Live 미진입 | MR8 로컬 TTS 유지 |
| Live 단순 완료·거부 | 짧은 효과음 또는 Live 결과 음성 |
| Live 추가 질문·조회 | Gemini Live의 같은 목소리, 세션 유지 |
단기 보완은 목소리가 잠시 달라져도 추가 질문과 조회 내용을 로컬 TTS로 보존하는 것이다. 기능과 정보가 사라지는 것보다 음색 차이가 작다.
그 밖의 출시 차단 항목
| 항목 | 확인된 gap | 출시 조건 |
|---|---|---|
| readiness | Wi-Fi 연결과 실제 Broker/Gemini setup 성공을 구분하지 못함 | /readyz와 setup 완료를 모두 확인 |
| 장애 fallback | 첫 응답 전 단절에도 기존 /llm/invoke 재전송 없음 |
보존 전사로 REST fallback 1회, 공통 turn ID 사용 |
| Cloud 정보 기능 | 웹 최신정보 search_rag는 연결됨. 기존 REST 전용 시간·날씨·dictionary와 내부 File Search는 별도 |
기능별 단일 소유권 결정, 내부 RAG 운영 권한 확인 |
| 응답 취소 | clientCancel은 Broker가 소비하고 upstream에 전달하지 않음 |
local queue, 새 음성, Interrupted를 같은 turn ID로 추적 |
WAITING_RESPONSE |
이 상태에서는 PCM을 Gemini에 보내지 않음 | thinking Barge-in 지원 여부를 제품 사양으로 결정 |
| 명령 범위 | rewrite_query 검증 어휘가 MR8 전체보다 좁음 |
Capability catalog에서 검증 규칙 생성 |
| 언어·목소리 | model과 Leda가 고정됨 |
기기 언어·음성 안내 설정 반영 |
| 음성 데이터 | 기존 S3 로그와 Gemini 전송이 동시에 발생 가능 | 목적, 보존, 삭제, 처리자와 마스킹 승인 |
| privacy/STOP | LLM_STOP 뒤 WebSocket이 남을 수 있음 |
AudioRecord, AudioTrack, WebSocket, UI 공통 종료 |
| 운영 Broker | 현재 ws://, 기기 인증과 rate limit 없음 |
운영 구조는 향후 릴리즈 gate 충족 |
현재 Broker에는 별도 세션 생성 API 또는 세션 DB 서버가 없다. 연결과 문맥 소유권은 현재 Broker에서 설명한다.
회귀 시험
| 영역 | 필수 확인 |
|---|---|
| 오프라인 멀티턴 | 네트워크 OFF에서 “볼륨 조절해줘 -> 3단계” 질문, 입력, 실행 |
| Live 멀티턴 명령 | 추가 질문이 들리고 후속 숫자를 같은 세션에서 처리 |
| 단순 명령 | 효과음 1회, Device API 1회 |
| 조회·오류 | 결과와 사용 불가 이유가 효과음으로 사라지지 않음 |
| 장애 | Broker 미기동, setup 실패, 응답 전/중 단절 후 UI와 입력 회수 |
| Barge-in | 거리·볼륨·소음별 Echo 오중단과 실제 사용자 미검출 |
| 종료 | 명시 종료, LLM_END, 5초 무발화, timeout 후 IDLE 복귀 |
| 자원 | 50세션 후 AudioRecord, AudioTrack, WebSocket과 thread 회수 |
| 개인정보 | 원본 PCM, 전사, S3 URL과 key가 일반 로그에 남지 않음 |
코드 근거
- TTS/효과음:
DeviceCommandCuePolicy,mappingTtsTextAndDeviceApi() - Live 명령 handoff:
beginLiveRewriteQueryHandoff(),finishLiveRewriteHandoffIfReady() - tool response:
GeminiLiveResponseRouter,GeminiLiveToolBridge - 볼륨 멀티턴:
SqliteHelper.initMultiTurnAnswer()의<sk_8> - 연결과 장애:
applyLiveRouteDecisionAfterLocalRoute(),handleLiveSessionFailure() - 입력 차단과 회전:
GeminiLiveStreamingConsumer,LiveConversationController