추천을 넘어, 사용자 상태로 · 2부 / 전 3부
UMM 기반 추천 아키텍처의 기술 내부
기술 상태 기준 — UMM Recommendation Platform v0.1.0, 2026년 7월 24일. 공개 이벤트 카탈로그 v1(주요 이벤트 11개), 공통 상태 출력 계약 v2, Python·TypeScript UMM Platform ADK v0.4.0, API v1을 기준으로 설명합니다.
UMM의 입력은 거창한 심리 설문이 아닙니다. 상품 조회, 장바구니 추가, 콘텐츠 완주, 팔로우, 광고 숨김처럼 서비스가 이미 가지고 있는 행동 이벤트입니다. 개발자는 Python·TypeScript용 UMM Platform ADK를 사용해 이벤트를 구성·검증·전송하거나 API를 직접 호출합니다. 이 글에서 ADK는 이벤트 스키마와 검증, 서버 환경의 인증·전송·재시도 계약을 캡슐화한 클라이언트 도구를 뜻합니다. 브라우저용 ADK는 이벤트 구성과 검증만 담당하며, API 키를 노출하지 않도록 고객사 백엔드를 통해 전송합니다.
들어온 이벤트는 CanonicalDomainEvent라는 공통 형식으로 바뀝니다. 쉽게 말해 이벤트 ID, 발생 시각, 채널, 이벤트 종류, 고객사·앱·사용자 식별자, 세부 데이터를 같은 규격에 담는 과정입니다.
클라이언트가 구매 의도 점수 같은 최종값을 직접 넣을 수는 없습니다. 서버는 허용된 원시 행동만 읽고, 타입과 범위를 확인한 뒤 세션 상태 계산에 사용합니다. 공개 카탈로그는 커머스·콘텐츠·소셜·광고의 11개 주요 이벤트를 안정적으로 모델링하며, 모르는 이벤트는 수집 계약과 모델링 가능 여부를 분리해 처리합니다. 같은 이벤트 재전송은 고객사 ID와 이벤트 ID로 만든 멱등 키로 식별하며, 재시도된 이벤트가 사용자 상태에 중복 반영되지 않게 합니다.

도식 · 이벤트 수집에서 외부 요약까지의 전체 파이프라인
설계 원칙 — 원시 행동은 채널 경계에 남고, UMM 상태값은 서버가 계산합니다. 외부에는 내부 세부 데이터가 아니라 사전에 승인된 요약만 제공합니다.
공개 기술과 비교하면 UMM의 위치가 선명해진다
UMM을 스트림 처리 엔진이나 피처 스토어, 추천 랭커와 같은 종류의 기술로 보면 역할이 겹쳐 보입니다. 실제로는 서로 다른 계층입니다. Apache Flink 같은 스트림 엔진은 이벤트의 시간과 순서를 다루고, Feast 같은 피처 스토어는 학습과 온라인 추론에 같은 피처를 제공하며, YouTube가 공개한 추천 구조는 후보 생성과 랭킹으로 아이템 목록을 만듭니다. UMM은 이 흐름 안에서 행동을 어떤 사용자 상태로 해석하고 어떤 근거와 함께 전달할지를 책임집니다.
Apache Flink — 이벤트를 상태 있게 처리한다
Flink는 끝없이 들어오는 이벤트를 사용자나 계정 같은 키로 나누고, 일정 시간의 윈도우와 상태를 유지하며 계산할 수 있는 스트림 처리 엔진입니다. 체크포인트와 저장된 상태를 이용해 장애가 발생해도 처리를 복구합니다. 7일 행동 수, 최근 10개 이벤트의 이동 평균, 세션별 완주율 같은 집계는 이런 계층에서 효율적으로 계산할 수 있습니다.
그러나 스트림 엔진은 content_complete가 왜 몰입의 근거가 되고 not_interested가 왜 회피의 근거가 되는지 자동으로 정하지 않습니다. 그 의미와 도메인 경계는 UMM의 번역 계약이 정의합니다. 즉 Flink가 “언제, 몇 번, 어떤 순서로 발생했는가”를 안정적으로 계산한다면, UMM은 “그 행동이 사용자 상태에서 무엇을 의미하는가”를 계산합니다.
Feast — 학습과 온라인 추론에 피처를 공급한다
Feast는 과거 시점의 피처를 학습 데이터에 맞게 조회하는 오프라인 저장소와, 최신 피처를 낮은 지연으로 제공하는 온라인 저장소를 연결합니다. UMM의 몰입 깊이, 탐색, 회피 같은 상태 묶음도 필요하다면 이런 피처 스토어에 저장해 여러 순위 모델이 읽게 할 수 있습니다.
하지만 피처 스토어가 상태의 의미를 대신 정하는 것은 아닙니다. 0.0과 관측 부재를 어떻게 구분할지, 근거 수와 신뢰도를 어떤 계약으로 제공할지, 고객사 간 데이터를 어디서 격리할지는 UMM이 책임집니다. Feast가 피처의 저장과 조회를 표준화한다면 UMM은 피처가 되기 전의 의미와 검증 규칙을 표준화합니다.
YouTube식 후보 생성·랭킹 — 최종 아이템 목록을 만든다
YouTube가 공개한 대표 구조는 먼저 방대한 영상 중 수백 개의 후보를 찾고, 별도의 랭킹 모델이 그 후보를 더 정밀하게 정렬하는 두 단계로 구성됩니다. UMM은 이 두 단계를 대체하지 않습니다. 후보 생성에는 반복적으로 관측된 장기 선호와 탐색·불확실성 수용 행동 신호를, 랭킹에는 실시간 몰입·피로·회피 상태를, 마지막 정책에는 노출 제한과 명시적 거절을 제공합니다.
| 기술 계층 | 중심 책임 | 시간 처리 | 직접 산출 | UMM과의 관계 |
|---|---|---|---|---|
| Apache Flink | 상태 기반 스트림 계산 | 이벤트 시간·윈도우·체크포인트 | 집계와 갱신된 스트림 상태 | UMM 상태 계산을 실행할 수 있지만 행동의 의미는 정하지 않는다. |
| Feast | 학습·추론 피처 관리 | 과거 시점 조회와 최신 온라인 값 | 모델이 읽는 피처 벡터 | UMM 상태를 저장·서빙할 수 있지만 상태 의미와 근거 계약은 UMM이 정의한다. |
| YouTube식 추천 | 후보 생성과 개인별 랭킹 | 최근 행동과 학습 이력을 모델 입력으로 사용 | 정렬된 아이템 목록 | UMM 상태를 입력으로 사용해 후보 폭과 최종 순서를 조정한다. |
| UMM | 도메인 행동을 공통 상태로 번역 | 세션·7일·30일을 서로 다른 속도로 갱신 | 상태값·신뢰도·근거·부재 | 스트림·피처·랭킹 계층 사이에서 사용자 문맥을 일관되게 연결한다. |

도식 · Flink, Feast, YouTube식 추천과 UMM의 기술 역할 비교
콘텐츠 완주 이벤트 하나를 따라가 보자
사용자가 콘텐츠 하나를 끝까지 봤다고 가정해 보겠습니다. 클라이언트는 사용자 상태를 계산하지 않고 content_complete 이벤트와 콘텐츠 ID, 세션 ID, 실제 시청 시간을 보냅니다. 설명을 위해 길이 13분인 콘텐츠를 12분 13초 시청해 완주율이 0.94가 된 상황을 예로 들겠습니다.
content_complete는 인증된 UMM Platform ADK 또는 API 계약에서 허용된 행동 이벤트입니다. 서버는 고객사·앱·이벤트 ID와 필수 필드를 검증한 뒤 완주율과 사용자 상태를 계산합니다. 완주 이벤트는 계약에서 정한 완주 기준을 충족한 재생 SDK나 고객사 백엔드처럼 신뢰된 발행 주체만 전송할 수 있습니다.
- API는 고객사와 앱을 확인하고 이벤트를 공통 형식으로 바꿉니다.
- 중복 이벤트인지 확인해 같은 완주가 두 번 반영되지 않게 합니다.
- 서버는 완주율 0.94를 계산하고 최근 콘텐츠 목록과 몰입 상태를 갱신합니다.
- 7일 집계에는 주제와 크리에이터 선호가 쌓이고, 30일 집계에는 반복적으로 관측된 장기 선호와 느리게 변하는 신호가 반영됩니다.
- 콘텐츠 번역층은 이 결과를 몰입 깊이와 탐색 신호로 바꿉니다.
- 추천 서비스는 값·신뢰도·근거량을 읽어 다음 후보의 길이와 주제 폭을 조정합니다.
예시 숫자로 계산 결과를 읽어 보자
아래 값은 계산 계약을 쉽게 설명하기 위한 예시입니다. 완주 한 번만으로 강한 결론을 내리지 않고, 최근 세션과 누적 근거가 함께 반영된다는 점이 핵심입니다.
| 관측·상태 | 값 | 신뢰도 | 근거 수 | 추천 반영 |
|---|---|---|---|---|
| 이번 완주율 | 0.94 | 이벤트 검증 완료 | 1건 | 몰입과 주제 선호의 새 근거로 추가 |
| Session 몰입 깊이 | 0.76 | 0.84 | 최근 행동 12건 | 같은 주제의 중·장편 후보 비중을 10% 높임 |
| Session 탐색 | 0.42 | 0.63 | 최근 행동 5건 | 인접 주제 후보를 15% 범위에서 유지 |
| 현재 인지 부담 | 0.31 | 0.71 | 최근 행동 9건 | 자동 재생 강도를 유지하되 긴 연속 노출은 제한 |
| 크리에이터 반복 | 0.68 | 0.79 | 노출 8건 | 동일 크리에이터가 상위 후보의 20%를 넘지 않게 조정 |

도식 · 콘텐츠 완주 이벤트의 상태 계산과 추천 정책 반영 예시
클라이언트가 최종 점수를 보내지 않기 때문에 웹, 모바일, 서버 SDK가 달라도 같은 계산을 사용합니다. 계산법이 바뀌어도 클라이언트를 다시 배포할 필요가 없습니다.
하나의 사용자를 세 개의 시간 해상도로 본다
사용자는 고정된 벡터가 아닙니다. 방금 발생한 스킵과 지난 한 달 동안 반복적으로 관측된 장기 선호가 같은 속도로 움직이면 추천은 지나치게 흔들리거나 지나치게 둔해집니다. UMM은 이를 실시간 세션, 최근 7일, 최근 30일의 세 계층으로 나눕니다.
Session UMM은 최근 아이템·주제·creator_id와 최근 10개 행동의 이동 평균, 퍼널 단계, 광고 피로, 명시적 거절 등을 빠르게 반영합니다. Short-term UMM은 7일 창에서 상위 카테고리·주제·크리에이터, 위시리스트, 리뷰 참여, 환불률처럼 단일 이벤트로 확정할 수 없는 패턴을 집계합니다. Long-term UMM은 30일 창에서 반복적으로 관측된 장기 선호, 반복 구매, 가격대·브랜드 선호와 같은 상대적으로 느리게 변하는 신호를 다룹니다.

도식 · 세 가지 시간축과 현재 반응 상태
별도의 현재 반응 상태도 관리합니다. 긍정·부정 정도, 활성도, 인지 부담을 최근 행동에 더 큰 비중을 주는 이동 평균으로 갱신합니다. 시간대와 광고 피로도 함께 반영합니다. 예를 들어 콘텐츠 완주는 긍정과 몰입을 높이고, 반복되는 광고와 명시적 거절은 피로와 회피 신호를 높입니다. 이것은 사람을 낙인찍는 성격 라벨이 아니라 “지금의 추천 강도와 탐색 폭을 조절하는 힌트”입니다.
세 계층이 모두 항상 존재하는 것도 아닙니다. 실시간 기록만 있는 신규 사용자, 7일 기록만 쌓인 사용자, 충분한 장기 이력이 있는 사용자를 각각 안전하게 처리합니다. 없는 값은 0으로 채우지 않고 관측 부재로 남깁니다. 외부 JSON 계약에서는 이를 null로 제공합니다.
세 시간축은 서로 경쟁하지 않는다
최근 세션의 피로 신호가 높고, 장기 상태에서는 해당 장르에 대한 반복 선호가 유지되는 것은 모순이 아닙니다. 추천 정책은 장르를 바꾸는 대신 같은 장르의 짧은 콘텐츠를 선택할 수 있습니다. 반대로 실시간 탐색 신호가 강하고 장기 선호의 신뢰도가 낮다면 새로운 주제를 더 넓게 보여줍니다.
이처럼 시간축을 나누면 최근 행동 하나가 장기 취향을 덮어쓰지 않습니다. 동시에 오래된 선호 때문에 현재의 거절 신호가 무시되는 일도 막습니다.
도메인 번역층과 공통 계산층을 나눈다
기술의 중심은 두 개의 층입니다. 도메인 번역층은 장바구니·결제 이탈·환불·위시리스트, 완주·스킵·주제 다양성, 소셜 반응, 광고 피로와 거절을 읽습니다. 그리고 이를 공통 신호로 바꿉니다. 신호에는 값뿐 아니라 근거가 된 행동 수와 데이터 범위, 계산 출처도 함께 담습니다.
공통 계산층은 원래 행동의 필드명을 모르며, 관측할 수 없는 고정 성격이나 민감 특성을 추론하지 않습니다. 대신 탐색·불확실성 수용 행동 신호는 새 카테고리 이동, 주제 다양성, 반복 피로처럼 관측 가능한 행동을 조합하고, 회피 반응 신호는 명시적 거절과 반복 스킵을 조합합니다. 가중치는 실제 추천 결과로 보정하며 결과는 0과 1 사이로 제한합니다. 근거가 하나도 없으면 값을 만들지 않습니다.

도식 · 산업별 행동 번역과 공통 상태 계산의 2단계 구조
이 분리 덕분에 두 종류의 변화가 독립적입니다. 새 산업이 들어오면 번역기만 추가합니다. 공통 사용자 상태의 계산법이 바뀌면 계산층만 교체합니다. 산업별 필드가 공통 코어로 새어 들어가지 않으므로 새 산업의 추가가 기존 산업의 모델을 흔들지 않습니다.
이 파이프라인은 몰입 깊이, 구매 의도, 사회적 반응, 탐색·불확실성 수용, 회피 반응의 다섯 공통 신호와 별도의 현재 반응 상태를 만듭니다. 추천 서비스 관점에서는 이를 여섯 개의 운영 입력으로 사용합니다. 이 값들은 고정 성격이나 심리검사 결과가 아니라, 지정된 시간창에서 관측된 행동을 추천 강도와 탐색 폭 조절 목적으로 요약한 상태값입니다. 각 값의 신뢰도와 근거량도 함께 추천 서비스에 전달하며, 모든 온라인 순위 모델은 이 공통 형식을 입력으로 사용합니다.
세션 상태는 이벤트 수신과 함께 갱신되고, 7일·30일 상태는 각 집계 주기에 따라 갱신됩니다. 추천 요청 시점에는 최신 유효 상태를 합성해 다섯 공통 신호와 현재 반응 상태를 실시간으로 산출합니다. 핵심은 기술 이름이 아니라 산업별 입력과 공통 계산을 독립적으로 교체할 수 있는 경계입니다.
모델보다 오래 살아남는 제품 계약
추천 알고리즘은 모델 코드만으로 제품이 되지 않습니다. 여러 고객사가 같은 플랫폼을 사용하면 고객사별 데이터 격리, API 권한, 중복 이벤트 방지, 장애 격리, 데이터베이스 변경, SDK 호환성이 모델 품질만큼 중요합니다. UMM은 고객사 ID와 앱 ID를 저장·조회·캐싱·동시성 제어의 모든 단계에서 유지합니다. API 키도 읽기 권한과 이벤트 수집 권한을 나눕니다.
외부 요약은 세션의 내부 데이터를 그대로 내보내지 않습니다. 외부에는 승인된 사용자 상태 요약과 원본 시스템의 직접 식별값을 노출하지 않는 변환 식별자만 제공합니다. 변환 식별자는 익명 데이터로 간주하지 않으며, 원본과의 재연결 권한은 별도로 통제합니다.

도식 · Clean Architecture와 제품화 가드레일
실행 호출은 API에서 사용 사례와 핵심 규칙으로 들어오지만, 코드 의존성은 API·실행 구성·저장소 어댑터 같은 외부 계층에서 사용 사례와 핵심 규칙이 있는 내부 계층을 향합니다. 따라서 핵심 규칙은 FastAPI나 특정 데이터베이스에 의존하지 않습니다. 엄격한 타입 검사, 의존성 규칙, 자동 테스트, 데이터베이스 변경 검사는 “좋은 알고리즘 아이디어”를 여러 팀이 안전하게 쓰는 제품으로 바꾸는 장치입니다.
정리하면 기술 흐름은 다음과 같습니다.
- 서로 다른 이벤트를 하나의 공통 형식으로 바꿉니다.
- 서버가 원시 행동을 검증하고 실시간 세션 상태를 계산합니다.
- 7일·30일 집계와 현재 반응 상태를 서로 다른 속도로 유지합니다.
- 산업별 행동을 도메인 중립적인 공통 신호로 번역합니다.
- 근거가 있는 사용자 상태만 값·신뢰도·근거량의 묶음으로 만듭니다.
- 고객사별로 격리된 API가 승인된 요약만 추천 서비스에 제공합니다.
장애가 나도 추천 전체가 멈추지 않게 한다
UMM은 추천 시스템의 중요한 입력이지만 단일 장애점이 되어서는 안 됩니다. 실시간 상태를 읽지 못하면 유효기간 내 마지막 안전 요약을 반환합니다. 사용할 수 있는 요약이 없으면 빈 요약을 반환하고, 추천 서비스는 이를 기본 추천으로 전환합니다. 복구 후에는 누락된 이벤트를 멱등하게 재처리해 사용자 상태를 회복합니다.
권장 폴백 순서는 최신 상태 → 유효한 마지막 안전 상태 → 빈 요약 → 기본 추천입니다. 이 원칙은 모델 성능과 운영 안정성을 분리합니다. 개인화 신호가 잠시 부족해도 서비스는 계속 동작하고, 복구된 뒤에는 누락된 이벤트가 상태에 중복 반영되지 않게 회복합니다.
3부에서는 이 구조가 커머스나 콘텐츠를 넘어 어떤 산업에 적용될 수 있는지, 그리고 어디까지 적용해서는 안 되는지를 산업별 시나리오로 살펴봅니다.
비교에 사용한 공개 자료
- Apache Flink의 “Stateful Stream Processing”
- Feast의 “Architecture Overview”
- Covington 외의 “Deep Neural Networks for YouTube Recommendations”(2016)
공개 자료는 각 기술의 공개 문서를 기준으로 합니다. 실제 구성은 조직의 환경에 따라 달라질 수 있습니다.
시리즈 · 추천을 넘어, 사용자 상태로
- 1부. 추천을 넘어 사용자 상태를 모델링하다
- 2부. 이벤트가 사용자 상태가 되기까지 — 지금 보는 글
- 3부. 추천 산업의 경계를 넓히는 방법


Leave a comment