보이스 프로필 제품 구조와 구현 현황
구현 요청 문서 분리 (2026-09-21): 직접 연동은 DeviceAgent ↔ AI-Agent, DeviceAgent ↔ 등록 App을 기준으로 검토한다. 담당별 구현 범위에서 전달 대상을 확인한다. 이 페이지의 APP·Backend·IoTAgent 연결은 E2E Sample 참고이며, 해당 구간의 제품 통신 설계는 SoC와 APP·Backend 담당이 협의한다.
설계·인터페이스 바로가기
제품 연동 보강: 완료 조건 · 실패·복구 · 삭제·동의 철회 · 계정 권한 · 변경 반영 · 관심사 활용 · 연동 시험 16건. 현행 코드와 제품 제안 규칙을 구분한다.
관심사는 샘플 서버 저장, 화자 프로필과 기준 임베딩은 현재 기기 파일 관리다. 제품에서는 서버에도 voiceId·계정 연결과 임베딩을 저장해야 하지만, 임베딩 업로드는 아직 연결되지 않았다. 실제 저장 위치와 남은 작업을 먼저 확인한다.
모바일 등록은 설정 → 관심사 선택(생략 가능) → 등록요청·진행 확인 순서다. 선택한 관심사는 기기 등록 성공 후 실제 voiceId에 저장한다. 이후에도 화자 탭에서 화자를 선택해 관심사를 수정할 수 있다. 화면 순서·저장·취소 명세.
| 구분 | 문서 | 확인할 내용 |
|---|---|---|
| 관심사 관리 | 서버 중심 관심사 관리·구조도 | 최초 등록·상시 수정, 서버 저장, AI-Agent 조회와 구현 범위 |
| 전체 연동 | 전체 프로토콜 명세 | 등록·조회·삭제 흐름과 상세 명세 진입점 |
| 기기 공통 | DeviceAgent Binder 인터페이스 | 연결, 공통 Bundle, 라우팅과 결과 반환 |
| 등록 화면 | 등록 App ↔ DeviceAgent | 버튼별 요청, 화면 제어와 상태 콜백 |
| AI-Agent 연동 | AI-Agent ↔ DeviceAgent | 등록·임베딩 전달, 서버 관심사 조회 요청과 응답 |
| 서버 통신 | IoTAgent ↔ 서버 MQTT 토픽 | 발행·구독 주체, 메시지 필드와 예시 |
| 모바일 | 모바일 App 인터페이스 | HTTPS 요청·결과와 관심사 저장 |
| 내부 설계 | AI-Agent 화자인식 구조 | 등록·인식 모듈과 데이터 흐름 |
| 데이터 관리 | 등록 상태·관심사 관리 | 기기 프로필 파일과 서버 관심사의 역할 구분 |
개발은 내부(등록 App·AI-Agent), SoC(DeviceAgent·IotAgent), 모바일·관제(App·AWS Backend) 세 그룹으로 나눈다. 아래 실행 주체별 역할과 구분하며, 담당별 구현 범위와 연결 작업은 3개 개발 그룹과 연동 인터페이스에서 확인한다.
이 문서는 보이스 프로필의 제품 흐름, 역할, 데이터 보관 위치와 현재 구현 범위를 설명한다. 토픽, 필드, Binder 메서드와 상태값은 보이스 프로필 연동 규격에서 확인한다.
한눈에 보기
- 등록 화면: A1의 화자인식 등록 App이 표시한다.
- 녹음·음질 검사: OnDevice Agent Service가
AudioRecord를 단독 소유하고 처리한다. - Voice ID: OnDevice Agent Service가 UUID로 생성하며 실제 화자 식별 키로 사용한다.
- 닉네임: 화면·TTS용 이름이며 화자 식별 키가 아니다.
- 원본 음성: 클라우드로 보내지 않고 등록 처리 후 폐기한다.
- 등록 임베딩: 제품 구조에서는 암호화 전송 대상이다. 현재 PoC는 DeviceAgent 대기 저장까지만 구현했다.
- AWS 연동: 제품 publish/ACK와 재전송 경로는 아직 구현되지 않았다.
현재 구현과 제품 목표
| 구분 | 현재 동작 | 제품 적용 시 필요한 동작 |
|---|---|---|
| 모바일 연결 | 모바일 Sample App이 PC Gateway의 HTTPS API 호출 | 서비스 모바일 App이 AWS Backend API 호출 |
| 기기 명령 | PC Gateway → 로컬 MQTT → IotAgent | AWS Backend → AWS IoT Core → IotAgent |
| 등록 화면 | DeviceAgent가 화자인식 등록 App 실행 | 동일 |
| 등록 처리 | OnDevice Agent Service가 녹음·검증·임베딩·Voice ID 생성 | 동일 |
| 등록 결과 전달 | DeviceAgent가 암호화 대기 저장 후 LOCAL_TEST_ACK 또는 WAITING_CLOUD_SYNC 반환 |
IotAgent가 AWS로 업로드하고 Cloud ACK를 DeviceAgent에 전달 |
| 재부팅 후 재전송 | 미구현 | 대기 항목 조회·재전송·ACK 후 삭제 구현 |
| 상태 실시간 전달 | 로컬 MQTT 시험 Bridge에서 동작 | AWS IoT Core의 response/event publish 연결 |
중요:
persist.sys.vp.local_ack=true는 로컬 PoC를 끝까지 시험하기 위한 설정이다. 클라우드 저장 완료를 증명하지 않는다.
역할과 책임
| 구성 요소 | 책임 | 하지 않는 일 |
|---|---|---|
| 모바일 App | 닉네임·관심사 입력, 등록/취소/조회 요청, 상태 표시 | MQTT 직접 접속, 음성 녹음, 임베딩 생성·발음 설정 |
| AWS Backend | 계정과 voiceId 연결, 권한 확인, 명령 발행, 등록 임베딩 저장 |
A1 마이크 제어, 기기 내 화자 매칭 |
| AWS IoT Core | 명령·응답·이벤트 전달 | 제품 정책 판단, 프로필 생성 |
| IotAgent | A1의 MQTT 단일 접점, MQTT와 Binder 변환 | 등록 화면, 녹음, Voice ID 생성 |
| DeviceAgent | 요청 검증, 등록 App 실행, Binder 중계, 전달 대기 데이터 보호 | 음성 분석, 사용자 계정 관리 |
| 화자인식 등록 App | 등록 안내, 진행률, 재녹음, 취소·완료 화면 | 직접 녹음, 임베딩 계산 |
| OnDevice Agent Service | 녹음, 음질 검사, 임베딩 생성, 동일 화자 검사, Voice ID 생성, 로컬 식별 | 모바일 계정 관리, MQTT 연결 |
등록 흐름
아래는 제품 연결 목표를 포함한 흐름이다. 현재 PoC는 AWS Backend/IoT Core 대신 PC Gateway와 로컬 MQTT를 사용한다. Cloud 업로드·ACK는 아직 연결되지 않았다.
- 모바일 App이 AWS Backend에 등록을 요청한다.
- AWS Backend가 기기 권한을 확인하고 AWS IoT Core에 명령을 발행한다.
- IotAgent가 명령을 받아 DeviceAgent에 Binder
Bundle로 전달한다. - DeviceAgent가 계약 버전,
requestId, 유효 시간과 호출자를 검사하고 등록 App을 연다. - 사용자가 등록 App에서 시작을 누르면 OnDevice Agent Service가 등록 세션을 시작한다.
- Service는 일반 Wake Word/STT 흐름을 멈추고 5개 음성 세트를 차례로 녹음한다.
- 각 세트의 음질을 검사한다. 실패하면 해당 세트만 다시 녹음한다.
- 5개 임베딩이 같은 화자인지 검사한 뒤 대표 임베딩과
voiceId를 만든다. - Service가 DeviceAgent에 프로필을 전달하고 DeviceAgent가 암호화 대기 저장소에 보관한다.
- 제품 환경에서는 IotAgent가 AWS에 업로드하고 Cloud ACK가 돌아오면 완료 처리한다.
- Service의 종료 경로에서 녹음을 정리하고 일반 음성 기능을 복구한다. 다만 생성 중 취소와 늦은 완료의 경합 방어는 아직 보완이 필요하다.
등록 화면과 상태
상태 이벤트는 stateSequence가 증가하는 순서로 표시한다. 이미 표시한 번호보다 작거나 같은 이벤트는 무시한다.
이는 UI의 수신 규칙이다. 현재 Service의 생성 완료·품질 실패 경로에서는 순번이 되돌아갈 수 있어 정상 이벤트도 누락될 수 있다. UI 규칙을 해제하는 대신 송신측 순번 관리를 보완해야 한다.
| 상태 | 화면 의미 | 기본 동작 |
|---|---|---|
WAITING_START |
등록 안내 | 시작, 나가기 |
RECORDING_SET |
음성 녹음 중 | 진행률, 뒤로가기, 나가기 |
SET_ACCEPTED |
현재 세트 통과 | 다음 세트로 자동 이동 |
SET_REJECTED |
음질 또는 발화 실패 | 실패 이유, 다시 녹음, 나가기 |
PERSONALIZATION_SETTINGS |
개인화 사용 여부 선택 | 설정 저장 또는 뒤로가기. 발음 수정 화면은 아님 |
CREATING_LOCAL_PROFILE |
임베딩과 Voice ID 생성 | 중복 실행 방지 |
PENDING_DEVICE_DELIVERY |
DeviceAgent 전달 중 | 중복 실행 방지 |
COMPLETED |
등록 완료 | 완료 후 닫기 |
PROFILE_FAILED |
프로필 생성 실패 | 재시도 또는 나가기 |
DELIVERY_FAILED |
DeviceAgent/Cloud 전달 미완료 | 전달 재시도 또는 나가기 |
CANCELLED |
등록 취소 | 임시 데이터 정리 후 닫기 |
등록 시작 대기 화면은 5분, 완료 화면은 60초 후 자동으로 닫힌다.
녹음과 품질 검사
녹음 기준
| 항목 | 현재 값 |
|---|---|
| 샘플레이트 | 16 kHz |
| 등록 세트 수 | 5개 |
| 세트당 목표 음성 | 5초 |
| 캡처 종료 타이머 | 5.2초 |
| 진행률 갱신 | 0.5초 |
| 통과 화면 유지 | 0.7초 |
각 세트의 음질 기준
| 검사 | 현재 기준 | 실패 코드 |
|---|---|---|
| 음성 없음 | 샘플 없음 | NO_SPEECH |
| 길이 | 3초 미만 | TOO_SHORT |
| 숫자 유효성 | NaN/Infinity 포함 | INVALID_AUDIO |
| 전체 음량 | RMS 0.005 미만 | TOO_QUIET |
| 클리핑 | 비율 3% 초과 | TOO_LOUD |
| DC 편향 | 0.05 초과 | AUDIO_BIAS |
| 실제 발화량 | 합계 1.5초 또는 연속 0.3초 미만 | INSUFFICIENT_SPEECH |
| 신호 대 잡음비 | 측정 가능할 때 5 dB 미만 | TOO_NOISY |
5개 세트의 임베딩은 차원이 같고 값이 유효해야 한다. 모든 쌍의 코사인 유사도 최솟값이 0.45 미만이면
INCONSISTENT_SPEAKER로 거절한다.
데이터 모델과 보관 위치
표의 Cloud 저장은 제품 목표다. 현재 확인된 저장은 기기 로컬과 DeviceAgent 전달 대기 저장이며, Cloud 저장 완료를 뜻하지 않는다. 원본 음성의 메모리 보관·비전송 설명은 새 voice-profile-v2 등록 경로에 한정한다. 기존 수동 등록 경로의 WAV 저장과 구분한다.
| 데이터 | 생성·입력 주체 | 보관 위치 | 기기 밖 전송 |
|---|---|---|---|
voiceId |
OnDevice Agent Service | 기기 프로필 저장소 + 제품 Cloud Registry | 허용 |
nickname |
모바일 사용자 | 기기 메타데이터 + Cloud | 허용 |
| Reference Embedding | OnDevice Agent Service | 기기 프로필 + DeviceAgent 전달 대기 저장소 + 제품 Cloud | 암호화·권한 통제 조건으로 허용 |
| 원본 PCM/WAV | OnDevice Agent Service | 등록 세션 임시 메모리 | 금지 |
| 대화 중 Query Embedding | OnDevice Agent Service | 일시 사용 | 금지 |
| 관심사 | 모바일 사용자 | 서버 원본, 기기는 조회 결과만 임시 보관 | 허용 |
nickname은 변경 가능한 표시 이름이고 voiceId는 식별 키다. Cloud는 voiceId를 실제 사용자 계정과 연결한다.
기기는 사용자 계정 ID를 화자 매칭 키로 사용하지 않는다.
모바일 Sample App은 닉네임만 전달한다. 발음 처리는 AI-Agent 내부에서 선택적으로 수행하며 기본값은 비활성이다.
취소와 실패 처리
- 등록 중 나가기 또는 원격 취소가 오면 같은
requestId세션만 취소한다. - 세트 녹음 실패는 현재 세트를 다시 받는다. 생성 단계의 동일 화자 품질 실패는
SET_REJECTED로 돌아가며 5개 세트를 모두 다시 받아야 한다. - 프로필 생성 실패와 전달 실패를 구분한다.
DELIVERY_FAILED + WAITING_CLOUD_SYNC는 음성 등록 실패가 아니라 Cloud 동기화 미완료다.- 완료·취소는
terminal=true다. 실패는 경로별로 다르며, 생성/전달 실패는 재시도 가능한false도 있다. - 생성 재시도·취소 경합·중복 start의 현재 한계는 전체 Binder 명세에서 확인한다.
- 취소 처리 경로는 녹음 정리와 Wake Word/STT 복구를 수행한다. 생성 coroutine과 700ms 후속 작업의 늦은 실행까지 차단하는 보장은 아직 없다. 이미 저장된 프로필의 삭제도 취소와 별도다.
등록 후 식별
- Wake Word 이후 들어온 음성에서 Query Embedding을 만든다.
- 기기 안의 Reference Embedding과 비교한다.
- 임계값을 넘으면
voiceId를 확정하고nickname을 화면·TTS에 사용한다. - 첫 턴이 화자 A이고 후속 턴이
unknown이면 A를 유지한다. - 후속 턴에서 등록 화자 B가 확인되면 B로 바꾼다.
- 새 대화의 첫 턴이
unknown이면 특정 화자에게 귀속하지 않는다.
대화내역은 이번 차수에서 제외한다. 관심사는 서버에서 voiceId를 기준으로 관리한다. 관심사는 최초 보이스 등록 후와 상시 App 설정에서 모두 수정한다. 서버 조회 규격을 우선 적용한다. 등록 상태와 관심사 흐름은
화자별 관심사 관리를 참고한다.
구현 완료와 남은 작업
현재 코드에서 확인된 범위
- 등록 App 화면과 상태 reducer
- DeviceAgent의 호출자·payload 검증과 App 실행
- OnDevice Agent Service의 5세트 녹음, 품질 검사, 임베딩 검사, Voice ID 생성
- 등록 중 일반 Wake Word/STT 정지와 종료 후 복구
- DeviceAgent의 암호화 전달 대기 저장
- 로컬 MQTT Bridge와 PC Gateway를 이용한 등록·조회·삭제 PoC
- 기기 내 화자 식별·프로필 파일 관리, 서버 관심사 API (작업본·샘플 Backend 기준)
제품 적용 전에 필요한 범위
- AI-Agent: 중복 start, 생성 중 취소, 지연 작업, 상태 순번, 생성 재시도 보완
- 등록 App·SoC: 다른 등록 요청과 충돌하거나 화면 실행이 실패할 때 원격 호출자에게 실패 전달
-
SoC: 공유 system UID의 호출자 검사 한계와 삭제 대기 사본 정리 실패 처리 보완
-
AWS Backend API와 계정-
voiceIdRegistry - IotAgent의 제품 AWS response/event publish
- Reference Embedding 암호화 업로드와 Cloud ACK
- DeviceAgent 대기 저장소의 조회·재전송·ACK 후 삭제
- 네트워크 중단, 재부팅, 중복 명령에 대한 제품 환경 통합 시험
담당별 완료 조건은 프로토콜의 보완 작업표를 기준으로 확인한다. 이번 검토는 소스 대조이며 새 APK 설치나 실기기 회귀 시험 완료를 뜻하지 않는다.
구현 근거
| 영역 | 기준 소스 |
|---|---|
| OnDevice Agent Service | skmagic_ondeviceai_agent_speaker_recognition, feature/cpu-speaker-recognition |
| 상태·오디오 품질 | VoiceProfileIpcContract.kt, VoiceProfileAudioQualityGate.kt, VoiceProfileEmbeddingQualityGate.kt |
| DeviceAgent·IotAgent | a1-packages-mr6, speaker_identification |
| DeviceAgent 계약·대기 저장 | VoiceProfileContract.java, VoiceProfilePendingStore.java, DeviceAgent.java |
| 로컬 Gateway | tools/voice_profile_sample_gateway |
| 모바일 Sample | apps/VoiceProfileMobileSample |
| 등록 App | apps/VoiceProfileRegistrationApp |