← Docs hub

Speaker Identity Service Planning

이 문서는 Voice ID를 제품 서비스 identity 체계 안에서 어떻게 정의할지 정리한다.

현재 제품에는 최소 세 종류의 사용자 식별 단서가 존재한다.

핵심 결론은 Voice ID를 계정 또는 얼굴 ID와 무조건 1:1 대응시키면 안 된다는 것이다. 제품 구조상 계정, 얼굴, 목소리는 각각 다른 인증 강도와 생성 시점, 실패 모드, 개인정보 리스크를 가진다. 따라서 중간에 Person Profile 또는 Identity Link 계층을 두고 느슨하게 연결해야 한다.

Identity Service Model

1. 왜 1:1 대응이 위험한가

항목 계정 바이탈 사인 얼굴 ID Voice ID
생성 주체 앱/계정 시스템 얼굴 인식/바이탈 사인 기능 화자 등록/음성 임베딩
입력 데이터 로그인/프로필 이름 얼굴 영상/얼굴 특징 음성/WAV/임베딩
인증 강도 계정 소유 기반 얼굴 매칭 기반 음성 매칭 기반
공유 가능성 가족 공용 계정 가능 얼굴은 개인 단위 목소리는 유사/변화 가능
실패 모드 로그인/권한 문제 조명/각도/마스크/카메라 소음/거리/감기/다화자
개인정보 민감도 계정 정보 생체/건강 정보 생체/음성 정보
적합한 역할 권한/소유/동의 건강 이력 기준 현재 발화 주체/context

따라서 아래처럼 강제하면 위험하다.

voice_id == face_id == account_user_name

권장 구조는 다음이다.

Control App Account
  -> Person Profile
      -> linked_voice_ids[]
      -> linked_vital_face_ids[]
      -> display_name
      -> consent_state
      -> authority_level
      -> personalization_profile

즉 Voice ID는 “계정”도 아니고 “얼굴 ID”도 아니다. Voice ID는 현재 발화의 주체를 추정하는 context key이고, 서비스가 개인화/건강 이력/권한을 쓰려면 Person Profile에 연결되어야 한다.

2. 권장 Identity 모델

2.1 계층 구조

Identity Linking Flow

계층 역할 예시
account_id 앱/클라우드 계정 식별 가족 대표 계정, 관리자 계정
account_display_name 계정에 붙은 사용자 이름 “최용재”
person_id 실제 서비스 사용자 프로필 person_001
voice_id 음성 임베딩 등록 단위 voice_001, voice_002
vital_face_id 얼굴/바이탈사인 사용자 단위 face_001
external_identity Google/Apple 등 외부 계정 연동 google_sub, apple_sub

권장 관계:

account_id 1 --- N person_id
person_id 1 --- N voice_id
person_id 1 --- N vital_face_id
person_id 1 --- N external_identity

이 구조를 쓰는 이유:

2.2 연결 상태

상태 의미 서비스 정책
unlinked voice_id는 있으나 person_id와 연결되지 않음 개인 건강/민감 정보 접근 금지
suggested 얼굴/계정/이름 유사성으로 연결 후보 앱에서 확인 필요
linked 사용자가 앱에서 연결 승인 개인화/이력 조회 가능
verified 강한 인증 또는 반복 검증 완료 민감 서비스 허용 범위 확대
revoked 연결 해제/삭제 이력 접근 중단, 캐시 삭제

3. 바이탈 사인 연동 서비스 확장

화자 인식이 Person Profile에 연결되면 다음 서비스가 가능해진다.

예시 발화:

내 최근 바이탈 상태 어때?
지난주보다 스트레스가 높아졌어?
요즘 심박 상태를 설명해줘.
내 건강 체크 이력 요약해줘.

서비스 흐름:

Vital Sign Voice Extension

1. 사용자가 발화한다.
2. 온디바이스가 voice_id를 추정한다.
3. voice_id가 person_id에 linked/verified 상태인지 확인한다.
4. person_id와 연결된 vital_face_id를 조회한다.
5. vital sign history를 가져온다.
6. Cloud LLM 또는 온디바이스 응답 계층이 안전한 요약을 생성한다.
7. 민감 정보이므로 신뢰도/권한/주변 사용자 상태에 따라 응답 범위를 제한한다.

정책:

조건 응답 가능 범위
voice_id linked + 단일 화자 + confidence high 개인 바이탈 이력 요약 가능
voice_id linked but confidence medium 확인 질문 후 제한 요약
unknown speaker 개인 이력 접근 금지
multi-speaker/overlap 개인 이력 접근 금지
주변 사용자 존재 가능 상세 수치 대신 앱 확인 유도 또는 확인 질문
미성년/게스트 권한 보호자/관리자 정책 필요

주의:

4. 컨트롤 앱 계정과의 관계

현재 조건:

이 상태에서 Voice ID를 앱 계정에 바로 붙이면 아래 문제가 생긴다.

문제 설명
가족 공용 계정 한 계정으로 여러 사람이 제품을 쓰면 voice_id와 account_name이 불일치한다.
이름 중복/변경 계정 표시 이름은 identity key로 안정적이지 않다.
권한 모호성 계정 소유자와 실제 발화자가 다를 수 있다.
삭제 범위 계정 삭제, voice 삭제, face 삭제가 서로 다른 범위일 수 있다.

권장:

5. Google 계정 연동 확장성

Google 계정 연동은 Voice ID 자체를 대체하지 않는다. Google 계정은 외부 인증/캘린더/개인 서비스 연결을 위한 identity provider다.

확장 예시:

서비스 필요한 연결
개인 일정 읽기 person_id -> google_sub -> calendar permission
개인 루틴 추천 person_id -> preference profile -> schedule/vital/device history
개인 알림 person_id -> external identity or app push token
음성 기반 권한 확인 voice_id -> person_id -> account role
건강/바이탈 요약 voice_id -> person_id -> vital_face_id

권장 모델:

{
  "person_id": "person_001",
  "display_name": "용재",
  "linked_identities": {
    "voice_ids": ["voice_001"],
    "vital_face_ids": ["face_001"],
    "external_accounts": [
      {
        "provider": "google",
        "subject": "google_sub_hash",
        "scopes": ["calendar.readonly"],
        "linked_at": "2026-07-07T00:00:00Z"
      }
    ]
  },
  "consent_state": {
    "voice_personalization": true,
    "vital_history_summary": true,
    "external_calendar": false
  }
}

6. 개인화 서비스 기획 방향

6.1 Must

기능 이유
Voice ID를 Person Profile에 연결/해제 개인화의 기본 단위
voice_id confidence 기반 응답 범위 제한 오인식 리스크 방지
unknown/multi-speaker에서 민감 정보 차단 개인정보/건강 정보 보호
앱에서 연결 상태 확인/수정 사용자 통제권
voice_id 삭제와 history 삭제 개인정보 관리

6.2 Should

기능 이유
Voice ID와 Vital Face ID 연결 바이탈 이력 설명 서비스 확장
사용자별 선호 공간/모드/스케줄 기억 로봇 개인화 가치
권한 등급 가족/게스트/아이 상황 대응
Google 계정 연동 일정/루틴/외부 서비스 확장

6.3 Could

기능 이유
감정/긴급도 추정 사용자 상태 context 확장
다중 화자 회의식 요약 가정 내 여러 사용자 context
프로필 자동 merge suggestion voice/face/account 연결 편의성

7. 성능/UX 리스크: 화자인식 지연

화자인식은 STT 이후 추가 처리로 들어가기 때문에 응답 지연이 생긴다.

현재 예상:

STT 완료 후 speaker identification 추가 지연: 약 0.5초 이내

리스크:

리스크 설명
체감 응답 지연 사용자는 STT가 끝난 뒤 바로 응답을 기대한다.
Cloud fallback 지연 누적 STT -> speaker ID -> Cloud LLM -> TTS 순서면 전체 턴 시간이 늘어난다.
다화자/겹침 분석 비용 diarization까지 매번 수행하면 짧은 명령에서도 비용이 생긴다.
저사양/부하 상황 로봇 이동/청정/센서 처리와 동시에 실행 시 latency 변동 가능

대응:

대응 설명
단계적 적용 민감/개인화 기능에만 speaker ID를 blocking 처리한다.
fast path 일반 기능은 speaker context 없이 먼저 처리하고, speaker 결과는 memory/profile에 후처리 반영한다.
cache/recent speaker 직전 화자 boost와 최근 화자 cache로 반복 발화 비용을 줄인다.
timeout policy 0.5초 내 결과가 없으면 speaker_state=unknown_timeout으로 내려가 기존 기능을 유지한다.
async enrichment Cloud 요청에는 unknown으로 보내고, speaker 결과가 늦게 나오면 다음 turn context에 반영한다.
UX copy 민감 정보 접근 시에만 “사용자 확인 중입니다” 같은 짧은 안내를 사용한다.

권장:

8. 의사결정이 필요한 질문

질문 권장 방향
Voice ID를 계정과 1:1로 묶을 것인가? 아니오. Person Profile을 중간 계층으로 둔다.
Voice ID를 Vital Face ID와 1:1로 묶을 것인가? 아니오. 사용자 승인 기반 link 관계로 둔다.
계정 표시 이름을 사용자 identity로 쓸 것인가? 아니오. display name 후보로만 사용한다.
건강 이력 조회를 voice만으로 허용할 것인가? linked/verified + confidence high + 단일 화자 조건에서만 제한 허용한다.
Google 계정은 무엇을 의미하는가? 외부 서비스 권한 provider이며 voice/face를 대체하지 않는다.
0.5초 지연을 모든 기능에 감수할 것인가? 아니오. 민감/개인화 기능에만 blocking 적용한다.

9. 다음 문서/구현 반영점

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