← Docs hub

Speaker Memory Management

화자 인식의 가장 직접적인 서비스 확장 지점은 메모리 관리다. 같은 기기라도 사용자마다 선호 공간, 반복 명령, 응답 방식, 금지/허용 기능이 다를 수 있다. 따라서 대화 기록과 profile candidate는 speaker scope로 분리해야 한다.

다만 제품화 단계에서는 speaker_id만으로 장기 메모리를 관리하지 않는다. speaker_id는 음성 evidence이고, 장기 개인화의 기준은 person_id가 되어야 한다. 한 사람이 여러 voice_id를 가질 수 있고, 같은 person profile에 바이탈 얼굴 ID나 Google 계정도 연결될 수 있기 때문이다.

Speaker Memory Layers

1. 왜 화자별 메모리가 필요한가

Why Speaker Memory

예시:

2. 메모리 계층

Speaker Scoped Memory Model

계층 보관 내용 speaker scope 필요성
Working memory 현재 턴, active workflow, last speaker 후속 발화 owner 유지
Short-term memory 최근 대화 pair, 세션 요약 사용자별 대화 흐름 분리
Mid-term memory 일/주 단위 요약, 자주 쓰는 기능 사용자별 패턴 분석
Long-term profile 선호 공간, 선호 모드, 권한/보호자 설정 개인화와 권한 정책

2-1. speaker_id와 person_id의 역할 분리

기준 역할 memory 정책
speaker_id 현재 발화 주체 추정 evidence working/short-term attribution
person_id 서비스 사용자 프로필 mid/long-term memory, preference, authority
vital_face_id 바이탈 사인 이력 scope 건강 이력 요약 시 참조
external_identity Google/Apple 등 외부 서비스 scope 일정/루틴 연동 시 참조

권장:

3. 온디바이스 기록 구조와 확장

현재 UI 근거:

SpeakerListActivity.kt
SpeakerHistoryActivity.kt
filesDir/speaker_id/{speakerName}/history.txt

현재 history.txt는 session 배열과 turn 목록을 표시하는 구조로 사용된다.

확장 방향:

{
  "speaker_id": "user_001",
  "display_name": "아빠",
  "sessions": [
    {
      "session_id": "sess_001",
      "time": "2026-07-07T10:00:00+09:00",
      "turns": [
        {
          "user": "거실 청정해줘",
          "assistant": "거실 청정을 시작할게요.",
          "route_family": "ODL",
          "speaker_confidence": 0.76
        }
      ]
    }
  ]
}

4. Cloud memory_context 확장

현재 Cloud memory_context.pyshort_term, mid_term, long_term, sync를 정규화한다.

speaker-aware 확장 후보:

{
  "memory_context": {
    "contract_version": "a2a-memory-context-v1",
    "current_turn_priority": "required",
    "speaker_scope": {
      "speaker_id": "user_001",
      "person_id": "person_001",
      "identity_link_state": "linked",
      "speaker_confidence": 0.72,
      "personalization_allowed": true
    },
    "short_term": {
      "recent_pairs": []
    },
    "long_term": {
      "profile_items": [
        {
          "speaker_id": "user_001",
          "person_id": "person_001",
          "key": "preferred_cleaning_space",
          "value": "안방"
        }
      ]
    }
  }
}

5. memory_update 확장

Memory Update Flow

현재 build_memory_update()short_term_pairprofile_candidates를 만든다. 여기에 speaker_id를 붙이면 Cloud/Device 양쪽에서 사용자별 기록 분리가 가능하다.

권장 후보:

{
  "memory_update": {
    "write_candidates": {
      "short_term_pair": {
        "speaker_id": "user_001",
        "person_id": "person_001",
        "identity_link_state": "linked",
        "user_text": "내 방 청정해줘",
        "assistant_text": "안방 청정을 시작할게요.",
        "route_family": "ODL",
        "workflow_id": "wf_001"
      },
      "profile_candidates": [
        {
          "speaker_id": "user_001",
          "person_id": "person_001",
          "type": "preference",
          "key": "my_room_alias",
          "value": "안방",
          "confidence": "medium"
        }
      ]
    }
  }
}

6. 메모리 사용 정책

Memory Policy Gate

조건 메모리 읽기 메모리 쓰기 이유
identified, confidence high 허용 허용 사용자별 개인화 가능
identified, confidence medium 제한 허용 short-term만 오인식 리스크
ambiguous 금지 금지 또는 shadow 잘못된 사용자 기록 오염 방지
unknown 금지 공통 anonymous 세션만 개인정보 보호
multi_speaker/overlap 금지 금지 누가 말했는지 불명확

추가로, 개인 바이탈/외부 계정/장기 profile에 접근하려면 아래 조건이 필요하다.

speaker_state == identified
identity_link_state in linked, verified
person_id present
consent_scope for requested domain == true
multi_speaker/overlap == false

7. 서비스 예시

예시 A: 사용자별 공간 alias

아빠: "내 방 청정해줘" -> 안방
아이: "내 방 청정해줘" -> 아이방

예시 B: 사용자별 반복 패턴

엄마: "평소처럼 예약해줘" -> 평일 오전 8시 전체청정
아빠: "평소처럼 예약해줘" -> 밤 10시 나이트모드

예시 C: unknown speaker 보호

unknown: "내 기록 보여줘" -> 개인 기록은 확인할 수 없다는 안내

8. 구현 순서

  1. speaker_contextvoice_context에 추가한다.
  2. 온디바이스에서 speaker별 short-term history schema를 고정한다.
  3. Cloud memory_contextspeaker_scope를 추가한다.
  4. build_memory_update()speaker_id를 포함한다.
  5. confidence/safety gate에 따라 memory read/write를 제한한다.
  6. 삭제/동기화/retention 정책을 별도 문서로 분리한다.

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