← Docs hub

A2A Memory DB and Sync Contract

이 문서는 A2A 메모리 기능을 실제 구현으로 옮기기 위한 DB schema, sync cursor, privacy/delete 정책을 정의한다.

현재 구현 상태는 세션/voice_context 중심이다. 이 문서는 그 위에 장기 메모리를 얹기 위한 설계 기준이며, 아직 제품 DB 구현 완료를 의미하지 않는다.

A2A Memory DB and Sync Contract

1. 설계 목표와 제약

목표:

제약:

2. 아키텍처 개요

On-device local store
  conversation_pairs
  conversation_sessions
  active_workflow_cache
  sync_cursor

Cloud Memory DB
  short_term_summaries
  mid_term_summaries
  long_term_profile_candidates
  long_term_profile_items
  memory_audit_log

Planner Input
  recognized_text
  voice_context.recent_turns
  memory_snapshot.session_summary
  memory_snapshot.short_term
  memory_snapshot.mid_term
  memory_snapshot.profile_hints
  device_context

3. 컴포넌트 경계와 책임

컴포넌트 책임 하지 말아야 할 것
On-device 최근 pair/session 보관, sync cursor 관리, Cloud 요청 시 compact snapshot 전달 장기 profile을 독단적으로 확정
Cloud Runtime memory snapshot을 Planner 입력으로 조립, memory update를 응답에 포함 현재 발화보다 memory를 우선 적용
Memory Summarizer session/day/week summary 생성 원문 전체를 무기한 보존
Profile Extractor 장기 후보 생성, confidence와 source 근거 보존 단발성 발화를 즉시 confirmed profile로 승격
Privacy/Retention Worker 삭제, 만료, 민감정보 마스킹 audit 없이 silent delete

3.1 현재 구현 상태

현재 repo에서 실제 구현되어 있는 부분은 DB가 아니라 runtime contract다.

구분 현재 구현 구현 근거
Memory context 수신 voice_context.memory_snapshot 또는 voice_context.memory_context 수용 gemini/a2a/runtime/memory_context.py
Memory context 정규화 a2a-memory-context-v1 형태로 short/mid/long/sync를 정규화 normalize_memory_context
Planner 전달 정규화된 memory를 voice_context.memory_context에 삽입 hydrate_memory_context, orchestrator.py
입력 크기 제한 recent_pairs=8, daily_summaries=7, profile_items=20 test/test_memory_context.py
Sync 보존 cursor/version 보존 normalize_memory_context, build_memory_update
Write candidate 생성 write_candidates.short_term_pair, device_cache_update 생성 build_memory_update
Unit test 정규화, limit, runtime 전달, memory_update 생성 검증 test/test_memory_context.py

현재 구현되지 않은 부분:

구분 미구현 내용
DB migration 실제 table 생성 migration 없음
Repository pair/session/summary/profile/cursor/audit repository 없음
Summarizer session/day/week 압축 worker 없음
Profile extractor long-term candidate 자동 추출 없음
Promotion gate candidate -> confirmed/rejected/expired 승격 없음
Privacy worker retention/delete/mask/audit 실행 없음
Sync worker on-device/cloud cursor conflict 처리 없음

따라서 현재 memory는 “Planner에 안전하게 전달되는 context layer + 응답에 포함되는 write 후보” 단계로 보는 것이 정확하다.

4. 데이터 모델/저장소 전략

4.0 저장소 구현 단위

v1 구현은 아래 repository/worker 단위로 나누는 것이 좋다.

구현 단위 책임 주요 table
PairRepository pair append, recent pair read, retention target 표시 conversation_pairs
SessionRepository session open/close, 최대 8 pair 관리, active workflow 연결 conversation_sessions
ShortTermSummaryRepository day summary read/write, open task 유지 short_term_summaries
MidTermSummaryRepository weekly digest, repeated pattern 관리 mid_term_summaries
ProfileCandidateRepository long-term 후보 생성/검토/거절/만료 long_term_profile_candidates
ProfileItemRepository confirmed profile read/write/delete long_term_profile_items
MemorySyncRepository device/cloud cursor, conflict 상태 관리 memory_sync_cursors
MemoryAuditRepository create/update/delete/mask/export audit memory_audit_log

Worker는 repository 위에서 동작한다.

Worker Trigger 역할
SessionSummarizer session close, 8 pair 도달, timeout pair를 session summary로 압축
DailyMemorySummarizer day close, 일정 pair 수 초과 session summary를 short-term day summary로 압축
WeeklyPatternSummarizer week close, daily summary 누적 반복 topic/device pattern을 mid-term으로 압축
ProfileCandidateExtractor weekly pattern, proactive feedback, explicit preference long-term candidate 생성
MemoryPromotionGate candidate confidence 상승, 명시 확인, 반복 증거 pending candidate를 confirmed/rejected/expired로 변경
PrivacyRetentionWorker retention 만료, user delete request mask/delete/audit 처리

4.1 conversation_pairs

최소 대화 원자다.

필드 타입 설명
pair_id string pk user/assistant pair id
user_id string 사용자 또는 household scope
device_id string 기기 id
session_id string session id
turn_index integer session 내 순서
user_text text STT normalized user utterance
assistant_text text assistant response summary 또는 full text
route_family string DEF/ODL/FRG/SCH 등
planner_summary json selected route, steps, confidence
created_at timestamp 생성 시각
retention_until timestamp 원문 보존 만료 시각
sensitive_flags json 민감정보 분류 결과

4.2 conversation_sessions

최대 8 pair를 묶는 단기 흐름 단위다.

필드 타입 설명
session_id string pk session id
user_id string 사용자 scope
device_id string 기기 scope
started_at timestamp 시작 시각
ended_at timestamp nullable 종료 시각
pair_count integer 포함 pair 수
active_workflow_id string nullable 진행 중 workflow
session_summary text compact summary
last_route string 마지막 route family
status string active/completed/expired

4.3 short_term_summaries

하루 단위 최근 맥락이다.

필드 타입 설명
summary_id string pk summary id
user_id string 사용자 scope
device_id string 기기 scope
date_key string YYYY-MM-DD
summary_text text 하루 단기 summary
open_tasks json unresolved tasks
recent_preferences json 당일 선호/반복 표현
source_session_ids json 근거 session id 목록
created_at timestamp 생성 시각
expires_at timestamp 만료 시각

4.4 mid_term_summaries

일주일 단위 반복 주제와 최근 패턴이다.

필드 타입 설명
summary_id string pk summary id
user_id string 사용자 scope
week_key string ISO week
summary_text text 주간 summary
repeated_topics json 반복 주제
device_usage_patterns json 기기 사용 패턴
unresolved_items json 미해결 항목
source_summary_ids json short-term 근거
expires_at timestamp 만료 시각

4.5 long_term_profile_candidates

장기 profile 후보이며, 바로 확정하지 않는다.

필드 타입 설명
candidate_id string pk 후보 id
user_id string 사용자 scope
category string preference/constraint/habit/device_pattern
claim text 후보 내용
confidence float 신뢰도
source_refs json pair/session/summary 근거
status string pending/confirmed/rejected/expired
created_at timestamp 생성 시각
reviewed_at timestamp nullable 검토 시각

4.6 long_term_profile_items

확정된 장기 memory다.

필드 타입 설명
profile_item_id string pk profile item id
user_id string 사용자 scope
category string preference/constraint/habit/device_pattern
value json 확정 memory 값
confidence float 확정 confidence
source_candidate_ids json 후보 근거
last_confirmed_at timestamp 마지막 확인 시각
expires_at timestamp nullable 만료 시각
delete_policy string user_delete/retention_expire/manual_review

4.7 memory_sync_cursors

온디바이스와 Cloud 동기화 위치다.

필드 타입 설명
cursor_id string pk cursor id
user_id string 사용자 scope
device_id string 기기 id
last_pair_seq integer 마지막 업로드 pair sequence
last_cloud_update_seq integer 마지막 다운로드 memory update sequence
last_sync_at timestamp 마지막 sync 시각
sync_status string ok/pending/conflict/error
conflict_state json nullable 충돌 상세

4.8 memory_audit_log

memory 변경 이력이다.

필드 타입 설명
audit_id string pk audit id
user_id string 사용자 scope
event_type string create/update/delete/export/mask
target_table string 대상 table
target_id string 대상 row id
actor string device/cloud/user/admin
reason string 변경 사유
created_at timestamp 발생 시각

5. API 계약 및 시퀀스

5.1 Runtime read path

Cloud Planner는 DB 전체를 직접 읽지 않고, runtime이 조립한 compact snapshot만 받는다.

request arrives
-> normalize_voice_context
-> hydrate_memory_context
-> memory_context injected into voice_context
-> planner prompt input

현재 구현 근거:

파일 역할
gemini/a2a/runtime/memory_context.py memory snapshot 정규화
gemini/a2a/runtime/orchestrator.py turn 시작 시 hydrate_memory_context 호출
gemini/a2a/planner/main_router_api.py planner input에 memory_context 포함
test/test_memory_context.py limits, contract version, runtime 전달 검증

5.2 Runtime write path

Turn 종료 후에는 실제 DB write가 아니라 write candidate를 먼저 만든다.

route result / session_state
-> build_memory_update
-> write_candidates.short_term_pair
-> repository write 또는 on-device cache update
-> summarizer/promotion worker

현재 build_memory_update가 만드는 최소 형태:

{
  "contract_version": "a2a-memory-context-v1",
  "source": "cloud_a2a_runtime",
  "sync": {
    "cursor": "cur-2",
    "version": "v2"
  },
  "write_candidates": {
    "short_term_pair": {
      "user_text": "나는 거실을 자주 청정해",
      "assistant_text": "",
      "route_family": "DEF",
      "workflow_id": ""
    },
    "profile_candidates": []
  },
  "device_cache_update": {
    "active_workflow_id": "",
    "last_route": "DEF",
    "session_summary": ""
  }
}

후속 구현에서는 assistant_text, planner_summary, device_task_result, task_event_summary, sensitive_flags를 채워야 한다.

현재 write candidate를 DB에 연결할 때의 최소 mapping:

write candidate field DB target 비고
short_term_pair.user_text conversation_pairs.user_text STT normalized text
short_term_pair.assistant_text conversation_pairs.assistant_text 현재는 빈 값, 후속에서 route result summary 필요
short_term_pair.route_family conversation_pairs.route_family 마지막 route 기준
short_term_pair.workflow_id conversation_pairs.planner_summary.workflow_id 또는 별도 field active workflow 추적
device_cache_update.active_workflow_id on-device active workflow cache interruption/cancel 처리
device_cache_update.last_route on-device session cache 다음 turn context
device_cache_update.session_summary conversation_sessions.session_summary 후보 현재는 session_state 값 의존
sync.cursor memory_sync_cursors.last_pair_seq 또는 opaque cursor cursor 해석 정책 필요
sync.version memory_sync_cursors.last_cloud_update_seq 또는 schema version 현재는 string 보존

5.3 On-device -> Cloud request

{
  "recognized_text": "안방으로 가서 청정해줘",
  "voice_context": {
    "session_id": "session-123",
    "recent_turns": [],
    "history_hint_strength": "weak",
    "active_workflow_id": ""
  },
  "memory_snapshot": {
    "session_summary": "오늘 사용자는 청정 관련 요청을 여러 번 했다.",
    "short_term": [],
    "mid_term": [],
    "profile_hints": []
  },
  "memory_sync": {
    "device_cursor": "pair_seq_42",
    "last_cloud_update_seq": 18
  }
}

5.4 Cloud -> On-device response

{
  "session_state": {
    "session_id": "session-123",
    "workflow_context": {}
  },
  "memory_update": {
    "cloud_update_seq": 19,
    "session_summary_delta": "안방 청정 요청이 진행 중이다.",
    "profile_candidates": [
      {
        "candidate_id": "cand-001",
        "category": "device_pattern",
        "claim": "사용자는 안방 청정을 자주 요청한다.",
        "confidence": 0.62,
        "status": "pending"
      }
    ]
  }
}

5.5 Sync API 방향

On-device와 Cloud는 항상 같은 시점에 완벽히 동기화된다고 가정하면 안 된다.

API 방향 목적 예시 payload
On-device -> Cloud local pair/session upload pairs[], device_cursor, session_id
Cloud -> On-device compact memory update download cloud_update_seq, session_summary_delta, profile_hints
On-device -> Cloud delete/mask request delete_scope=user|device|session|pair, target_id
Cloud -> On-device conflict response sync_status=conflict, expected_cursor, server_cursor

동기화 원칙:

6. Planner 사용 원칙

Planner는 memory를 아래 우선순위로 사용한다.

  1. 현재 recognized_text.
  2. active workflow / pending follow-up.
  3. recent_turns.
  4. session_summary.
  5. short-term / mid-term summary.
  6. confirmed long-term profile hints.

금지:

7. Memory 충돌/오염 방지 규칙

Memory는 도움이 되지만 잘못 쓰면 planner를 오염시킨다.

상황 잘못된 처리 올바른 처리
현재 발화가 명확한 ODL 과거에 사용자가 잡담을 많이 했다는 이유로 DEF 선택 현재 발화 우선, memory는 target/slot 보조만
long-term candidate만 있음 candidate를 confirmed 선호처럼 prompt에 주입 pending candidate는 planner에 숨기거나 낮은 신뢰 hint로 제공
삭제 요청된 profile local cache에 남아 계속 사용 delete audit 후 Cloud/on-device cache 모두 제거
noisy STT memory로 과하게 의미를 복원 current_turn_priority=required, 불확실하면 STT_NULL/clarify
반복 패턴 1회 profile 확정 short/mid-term candidate까지만

8. Retention / Privacy 기본값 후보

제품 정책 확정 전까지는 아래를 기본 후보로 둔다.

데이터 보존 후보 이유
raw pair text 7~30일 디버깅/요약 근거, 장기 보존은 부담
session summary 30~90일 단기/중기 압축 근거
short-term summary 7~14일 하루 맥락 유지
mid-term summary 4~8주 반복 패턴 판단
long-term candidate 30~90일 pending 후 expire 오염 방지
confirmed profile 사용자 삭제/만료 정책까지 개인화 핵심
audit log 제품/법무 정책 기준 삭제/수정 추적

민감정보 후보:

유형 처리
전화번호/주소/식별번호 기본 mask 또는 저장 제외
건강/민감 생활 패턴 candidate로 자동 승격 금지, explicit confirmation 필요
어린이/가족 구성원 정보 profile 저장 전 별도 정책 필요
위치/방 이름 household device 기능에 필요한 범위로 제한

9. 구현 단계

| 단계 | 작업 | 검증 | |---|---| | M0 | 현재 runtime contract 고정 | test/test_memory_context.py 유지, schema fixture 추가 | | M1 | pair/session repository | append/read/session-close unit test | | M2 | sync cursor repository | duplicate/conflict/retry test | | M3 | short-term/day summarizer | session -> day summary fixture | | M4 | mid-term/week summarizer | day summaries -> weekly digest fixture | | M5 | profile candidate extractor | repeated pattern -> pending candidate | | M6 | promotion gate | pending -> confirmed/rejected/expired | | M7 | privacy/delete worker | delete/mask/audit integration test | | M8 | planner integration | memory_context가 prompt에 들어가지만 current utterance를 덮지 않는 regression |

10. 비기능 요구 대응

요구 정책
개인정보 최소화 pair 원문은 짧은 retention, summary/profile은 목적 제한
삭제권 user/device 단위 delete request가 memory_audit_log에 남아야 함
네트워크 단절 on-device cursor 기준으로 pending upload 유지
충돌 처리 Cloud update seq와 device cursor가 불일치하면 sync_status=conflict
관측성 memory update, deletion, masking은 audit event로 기록

11. 리스크와 의사결정 로그

리스크 대응
memory가 router 판단을 오염 현재 발화 우선 원칙과 prompt guard 유지
장기 profile 오검출 candidate/confirmed 분리와 confidence threshold
민감 정보 저장 sensitive flag, masking, retention policy
온디바이스/Cloud 불일치 sync cursor, cloud update sequence, conflict state
과도한 DB 복잡도 v1은 pair/session/summary/profile/cursor/audit 최소 테이블로 시작

12. 구현 전 결정 필요

질문 제안
user scope는 개인인가 household인가 v1은 user_iddevice_id 둘 다 저장하고 권한 정책은 제품 정책에서 결정
long-term confirmation은 자동인가 수동인가 v1은 confidence 기반 pending 생성, confirmed는 명시 policy 후 승격
pair 원문 retention은 얼마인가 v1은 7~30일 후보, 제품 개인정보 정책에 맞춰 확정
LangGraph/LangMem을 쓸 경우 schema가 바뀌는가 내부 orchestration은 바뀔 수 있지만 제품 DB schema는 유지

관련 페이지

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