Speaker Context Contract
이 문서는 온디바이스 화자 인식 결과를 Cloud A2A가 안정적으로 소비하기 위한 speaker_context 계약을 정의한다. 계약은 additive field로 설계해 기존 voice_context와 호환되도록 한다.
1. 계약 원칙
원칙:
- Cloud는 화자를 직접 추론하지 않는다.
- Cloud는 온디바이스가 만든
speaker_context를 evidence로만 사용한다. - 현재 발화(
recognized_text)가 항상 최우선이다. - speaker confidence가 낮으면 개인화/권한/side-effect 실행을 보수적으로 처리한다.
- raw embedding과 음성 파일은 Cloud로 보내지 않는다.
2. 요청 Payload
권장 payload:
{
"voice_context": {
"recognized_text": "거실 청정하고 10분 뒤에 침실로 와",
"session_id": "sess_001",
"asr_confidence": 0.94,
"audio_locale": "ko-KR",
"speaker_context": {
"contract_version": "speaker-context-v1",
"speaker_id": "user_001",
"display_name": "아빠",
"speaker_confidence": 0.72,
"person_id": "person_001",
"identity_link_state": "linked",
"speaker_state": "identified",
"speaker_count": 1,
"overlap_ratio": 0.0,
"unknown_ratio": 0.0,
"max_score": 0.72,
"safety_gate": "pass",
"personalization_allowed": true,
"authority_level": "normal",
"consent_scope": {
"voice_personalization": true,
"vital_history_summary": false,
"external_calendar": false
},
"linked_vital_face_ids": [],
"external_identity_scope": [],
"latency_budget_ms": 500,
"source": "ondevice_sherpa_poc"
}
}
}
2-1. 제품 Identity 확장 필드
speaker_id는 “현재 발화가 어떤 목소리와 매칭되었는가”를 나타내는 evidence다. 반면 person_id는 개인화, 바이탈 이력, 외부 계정, 권한 정책의 기준이 되는 서비스 사용자 단위다.
따라서 제품 계약은 아래처럼 두 계층을 분리한다.
| 필드 | 의미 | 사용처 |
|---|---|---|
speaker_id |
음성 임베딩/화자 등록 단위 | 현재 발화 주체 추정, confidence 판단 |
person_id |
Voice ID, Face ID, Account, Google 계정을 연결하는 사용자 프로필 | 개인화, 메모리, 바이탈 이력, 권한 |
identity_link_state |
unlinked, suggested, linked, verified, revoked |
민감 정보 접근 가능 여부 |
consent_scope |
기능별 동의 범위 | 바이탈/외부계정/개인화 응답 허용 |
linked_vital_face_ids |
person에 연결된 바이탈 사인 얼굴 ID 목록 | 건강 이력 조회 scope |
external_identity_scope |
Google/Apple 등 외부 계정 scope 요약 | 일정/외부 개인 서비스 접근 |
latency_budget_ms |
화자인식에 허용한 지연 budget | timeout/fallback 판단 |
권장 원칙:
speaker_id == person_id == vital_face_id == account_name으로 강제하지 않는다.speaker_id만으로 건강 이력, 일정, 개인정보를 조회하지 않는다.person_id가 없거나identity_link_state가linked/verified가 아니면 민감 정보 접근은 차단한다.latency_budget_ms내 결과가 없으면 기존 기능 회귀를 막기 위해speaker_state=unknown_timeout또는unknown으로 낮춘다.
3. 상태값
speaker_state |
의미 | 권장 Cloud 처리 |
|---|---|---|
identified |
등록 화자와 충분한 confidence로 매칭 | 개인화/메모리/일반 실행 가능 |
unknown |
등록 화자 없음 또는 threshold 미달 | 개인화 금지, 일반 응답 또는 확인 질문 |
ambiguous |
최고점은 있으나 margin/confidence 부족 | side-effect 실행 전 확인 |
multi_speaker |
2명 이상 화자 존재 | 명령 주체 확인 또는 재시도 |
overlap |
동시에 말한 구간 비율 높음 | 재시도 안내 |
far_speech |
거리/에너지 조건 불량 | 가까이 말하도록 안내 |
unknown_timeout |
화자인식이 latency budget 안에 끝나지 않음 | 개인화 금지, 기존 기능 fallback |
4. safety_gate
safety_gate |
의미 | 처리 |
|---|---|---|
pass |
실행 가능 | Cloud A2A 정상 처리 |
reprompt |
다시 말해야 함 | Cloud 호출 전 온디바이스 차단 권장 |
block |
실행하면 안 됨 | side-effect 기능 금지 |
온디바이스에서 이미 reprompt 또는 block으로 판단했다면 Cloud를 호출하지 않는 편이 낫다. 다만 분석/로깅 목적의 shadow mode에서는 Cloud에 전달할 수 있다.
5. Cloud Runtime 반영 위치
| 위치 | 반영 방식 |
|---|---|
normalize_voice_context() |
speaker_context 기본 구조 추가 |
route_turn() |
speaker 상태를 prompt support context로 전달 |
build_session_state() |
workflow_owner_speaker_id, last_speaker_id 후보 |
build_memory_update() |
speaker별 short-term pair/profile candidate |
build_device_task_requests() |
side-effect task gate/confirmation |
6. 응답 Payload 확장 후보
Cloud가 온디바이스에 돌려줄 수 있는 speaker-aware 결과:
{
"orchestration": {
"session_state": {
"last_speaker_id": "user_001",
"workflow_owner_speaker_id": "user_001",
"speaker_policy": {
"personalization_applied": true,
"authority_gate": "pass",
"confirmation_required": false
}
},
"memory_update": {
"write_candidates": {
"short_term_pair": {
"speaker_id": "user_001",
"user_text": "거실 청정하고 10분 뒤에 침실로 와"
}
}
}
}
}
이 응답은 온디바이스가 다음 턴에서 active workflow와 speaker owner를 이어가는 데 사용할 수 있다.