신뢰할 수 있는 메트릭과 실험 플랫폼
Config Metric 프로젝트 - XPC Metric System 재설계하기
2026년 2월 6일QQ, Hayden, Minsoo

온라인 실험은 제품 개발 과정에서 기능 변경의 효과를 통계적 방법으로 수치화해 증명하고, 롤아웃 여부와 같은 핵심 의사결정을 데이터로 뒷받침하기 위한 수단으로 중요한 역할을 합니다. 이러한 실험은 PO, SWE, DA의 일상 업무와 긴밀하게 연결되어 있습니다. PO는 실험의 목적과 성공 기준을 정의하고, SWE는 실험이 가능한 제품 동작과 계측을 구현하며, DA는 메트릭 정의와 검증을 통해 결과가 해석 가능한 상태로 만들어야 합니다. 세 역할이 맞물려 돌아가는 만큼, 정의·계측·해석 중 어느 하나만 어긋나도 실험의 결론과 의사결정은 쉽게 흔들릴 수 있습니다.


▲ XPC가 업무에 사용되는 일련의 과정들
▲ XPC가 업무에 사용되는 일련의 과정들


XPC는 이러한 업무 흐름을 지원하며 실험의 라이프사이클을 트래픽 할당과 데이터 수집, 표준 분석, 결과 공유까지 하나의 흐름으로 묶고, 그 과정에서 메트릭 정의·분석 절차·의사결정 규칙을 시스템에 내재화한 실험 플랫폼입니다. 빠르게 반복되는 실험 사이클에서 해석의 일관성, 통계적 엄밀성, 재현성이 유지되는 의사결정 프로세스로 운영됩니다.

지난 포스팅 오늘의집 A/B 실험 플랫폼 구축기에서는 실험 플랫폼 (XPC)의 초기 버전을 구축하며 겪었던 고민들을 공유해 드렸습니다. 오늘의집은 그 이후 수많은 A/B 테스트를 수행하며 데이터 기반 의사결정에 XPC를 지속적으로 활용해 왔습니다. 그 과정에서 실험 결과를 의사결정의 핵심 기준으로 사용할수록, ‘실험 결과의 일관성’과 ‘메트릭 관리의 어려움’이 점차 구조적인 문제로 드러나기 시작했습니다.


✔️ 왜 같은 실험 데이터를 두고 팀마다 해석이 다를까.

✔️ 실험 메트릭을 등록하고 검증하는 과정이 왜 이렇게 어려울까.


데이터 플랫폼 팀은 이러한 문제를 해결하기 위해 메트릭의 정의부터 분석 파이프라인, 통계 검증까지 전 과정을 재설계하는 Config Metric 프로젝트를 시작했습니다. 이번 글에서는 신뢰할 수 있는 실험 분석을 가능하게 한 XPC Metric System의 기술적 구조를 소개합니다.


초기 XPC 를 운영하며 어려웠던 것들

초기 시스템은 빠르게 구축하여 활용할 수 있었지만, 실험 규모가 커짐에 따라 다음과 같은 구조적 한계에 부딪혔습니다.

시트(Sheet) 기반의 관리와 휴먼 에러 : 저희는 메트릭 쿼리와 속성을 스프레드시트에서 관리했습니다. 접근성은 좋았지만, 스키마 관리나 변경 이력 추적이 불가능했고 입력 실수로 인한 장애가 빈번했습니다.

▲ 초창기 XPC Metric 이 관리되고 있던 시트
▲ 초창기 XPC Metric 이 관리되고 있던 시트


복잡하고 취약한 쿼리 : 메트릭마다 긴 SQL 쿼리를 직접 작성해야 했습니다. 특정 Spark Job 규칙에 맞춰야 했기에 작성이 까다로웠고, 쿼리 내에 중복된 계산 로직(Sub-query)이 많아 비효율적이었습니다.


통계 검정의 불일치 : 팀마다 T-Test, U-Test, Chi-Squared Test 등 서로 다른 검정 방식을 사용하고 있었고, 검정 방식이 다르면 같은 데이터에서도 유의성 판단이 달라질 수 있습니다. 이에 의사결정 과정에 혼선을 줄 수 있고, 논의가 결과가 아니라 방법론 자체로 흐르기 쉬운 상황이 반복되었습니다.


정규 분석과 후속 분석의 괴리 : 정규 분석은 계산 파이프라인이 수행하고, 후속 분석은 별도 쿼리나 개인 환경에서 다시 계산하면 수치가 서로 다를 수 있습니다. 이 차이를 설명하기 위해 계산쿼리와 데이터를 추적하는 시간이 늘어나고, 실험 해석의 리드타임이 길어졌습니다.


이런 문제점들이 누적되면서 분석 결과의 일관성이 떨어지고, 실험 플랫폼 자체의 신뢰도에도 영향을 미치기 시작했습니다. 그래서 저희는 새로운 메트릭 시스템을 정의하고, 이를 기반으로 파이프라인과 UI, 후속 분석까지 전반적인 구조를 다시 구축하기로 결정했습니다.


메트릭은 무엇을 측정하는가

A/B 테스트는 기본적으로 그룹(A/B)으로 나뉜 피험자 집합을 비교하는 실험이며, 비교의 대상은 피험자(Subject)별로 측정된 값(value) 입니다. 각 그룹에서 subject별 값을 모아 평균 같은 요약값을 만들 수 있지만, 평균만으로는 통계적 유의성을 판단할 수 없고 검정 계산을 통해 p-value를 얻어 결론을 내려야 합니다. 즉, 메트릭 계산은 피험자마다 측정된 값을 수집하고 이를 그룹 간 차이를 검정할 수 있는 형태로 변환하는 작업입니다.

온라인 서비스에서 이 측정의 출발점은 대부분 유저의 행위(Event) 입니다. 예를 들어 CTR 같은 지표의 경우, 관측해야 하는 사실은 “노출이 있었는가”와 “클릭이 있었는가”라는 이벤트이며, 이를 어떤 기준으로 묶고 집계해 ‘전환’으로 해석할지는 메트릭 정의의 영역입니다. 그래서 저희는 피험자마다 측정하고 그룹별로 취합하는 계산을 관측된 사실(Event) 과 이를 해석하는 방법(Metric)으로 분리하여 설계했습니다. 이 분리가 가능해지면 동일한 이벤트 정의를 재사용하면서도 서로 다른 해석(집계/필터/슬라이스)을 안전하게 확장할 수 있고, 동시에 시스템 차원에서 무엇이 표준인지를 명확하게 고정할 수 있습니다.


Event란?

Event는 상품 조회나 구매 완료처럼 관찰 가능한 사용자 행동을 표현하며, 데이터 소스는 로그뿐 아니라 DB 테이블 등 다양한 형태를 지원합니다.

▲ 유저들이 발생시키는 다양한 이벤트들
▲ 유저들이 발생시키는 다양한 이벤트들


다만 어떤 소스를 사용하더라도, Event 정의 쿼리는 사전에 약속된 스키마를 반드시 준수해야 합니다. 이 스키마는 device_id, session_id, user_id, platform 같은 유저 관련 필드와 event_id, event_time 같은 이벤트 공통 속성, 그리고 정수/실수/문자열 형태의 측정값(Event Params)을 포함합니다.

이 스키마를 실무에서 일관되게 지키기 위해, 저희는 Event를 YAML 기반의 Event Config로 정의합니다. Event Config에는 이벤트 식별자(id), 메타정보(owner, team, description), 그리고 표준 스키마를 반환하는 SQL이 포함됩니다. 또한 어떤 원천 테이블을 읽는지 추적할 수 있도록 dependencies를 명시해 이벤트 계산의 선행 조건을 관리합니다.


▲ Event Yaml의 기본적인 형태
▲ Event Yaml의 기본적인 형태


Metric은 Event를 활용하자

Metric은 Event들로부터 Subject(피험자) 당 값을 어떻게 모을지를 정의하는 규칙입니다. 여기서 Subject는 보통 user_id 같은 실험 단위이며, Metric은 이 Subject별 값이 통계 검정(Statistical test)에 바로 들어갈 수 있는 형태가 되도록 만듭니다. 또한 Metric을 표준 스키마로 고정함으로써, 같은 이름의 지표가 팀마다 다른 의미로 계산되는 문제를 줄일 수 있습니다.

Metric을 표준화하기 위해, 저희는 Metric을 Event 1개 또는 2개 조합으로 정의하도록 설계했습니다. 먼저 Event 1개 메트릭은 하나의 이벤트에서 값을 뽑아 Subject별로 집계하는 형태입니다. 예를 들어 ARPU(Average Revenue Per User)는 구매 이벤트에서 결제 금액을 추출하고, 이를 Subject별로 SUM으로 모아 값 표본을 만듭니다.

# Metric Config 예시: Event 1개 (ARPU) metric: metric_id: ARPU type: CONTINUOUS subject: xpc_key denominator: event: TRIGGERED agg: COUNT value: xpc_key numerator: event: PURCHASE agg: SUM value: revenue

다음으로 Event 2개 메트릭은 전형적인 비율 지표를 표현합니다. CTR(Click-Through Rate)은 노출(분모)과 클릭(분자)처럼 두 이벤트를 조합해 정의합니다. 이때 2개 이벤트 메트릭은 단순한 나눗셈이 아니라, 전환이라는 의미를 내포하므로 이벤트 간 선후 관계가 해석에 영향을 미칩니다.

# Metric Config 예시: Event 2개 (CTR) metric: metric_id: CTR type: BINOMIAL subject: xpc_key denominator: event: IMPRESSION agg: COUNT value: xpc_key numerator: event: CLICK agg: COUNT value: xpc_key

Metric 언어는 Event를 조합하고 집계해 Subject별 value를 만든다는 의미를 담고 있습니다. Metric은 1개 또는 2개 Event만 참조하며, 집계 방식(agg)과 값(value), 그리고 subject/slices 같은 구조만 선언합니다. 반대로 어떤 데이터를 어떻게 뽑아 Event로 만들 것인가는 Event Config가 책임집니다. 이 관심사의 분리 덕분에 Event 쪽에 필요한 자유도를 두면서도, Metric은 표준화된 형태로 재사용과 검증이 가능한 상태를 유지할 수 있습니다.


Metric Pipeline

앞에서 정의한 Event yaml과 Metric yaml는 정의에 해당하고, Metric Pipeline은 그 정의를 받아 실제 계산을 수행하는 실행 계층입니다. 파이프라인의 목표는 Subject별 샘플과 Slice 집계 결과를 표준 형태로 생산하는 것입니다. 구조는 크게 두 단계로 나뉘며, 먼저 Subject Level Aggregation에서 Subject별 value를 계산한 뒤, Slice Level Aggregation에서 Data Cube 방식으로 breakdown과 rollup을 함께 생성합니다. 이 단계의 결과물은 UI에서 요구하는 여러 슬라이스 조합을 일관된 규칙으로 제공하기 위한 결과 조합입니다. 이 과정에서 통계 검정에 필요한 요약 통계치도 함께 계산되도록 설계합니다.

▲ High Level Pipeline Overview
▲ High Level Pipeline Overview


Subject Level Aggregation : 실험의 표본을 만드는 과정

Subject Level Aggregation의 역할은 실험의 샘플을 만드는 단계입니다. 각 실험 대상(Subject)마다 해당 메트릭의 분모/분자값을 계산해 하나의 샘플로 정리합니다. 이 단계의 결과물은 이후 Slice Level Aggregation에서 집계되는 재료가 됩니다. 특히 2-event 메트릭(CTR/CVR 등)에서는 전환의 의미가 포함되기 때문에, 분모 이벤트와 분자 이벤트의 관계(예: 특정 기준 시점 이후만 인정)를 일관된 규칙으로 적용해 Subject별 값을 구성합니다.

Slice Level Aggregation

Slice Level Aggregation은 Subject Level에서 만든 샘플을 모아, 사용자가 해석하기 쉬운 breakdown 결과와 rollup 결과를 만드는 단계입니다. Slice는 platform, country 같은 차원을 의미하고, 동일한 샘플을 여러 관점으로 분리된 결과를 제공합니다. 이 단계에서는 대푯값으로 표시하는 평균값뿐만 아니라, 통계 검정에 필요한 분자분모 곱의 합, 분모 제곱합, 분자 제곱합 등 요약 통계치도 함께 산출합니다.

# Metric 내에서 Slice 를 명시하는 방식 metric: subject: - xpc_key slices: - platform - ad_platform - inventory - candidate_producer

Data Cube 형태가 필요한 이유는, 사용자가 요구하는 결과가 단일 breakdown에 그치지 않기 때문입니다. 실무에서는 (platform=all, country=all) 같은 전체 결과뿐 아니라, (platform=iOS, country=all)처럼 한 차원만 고정한 rollup, (platform=iOS, country=KR)처럼 여러 차원을 동시에 고정한 drilldown이 반복적으로 필요합니다.

이 조합을 매번 개별 쿼리로 생성하면 조합 수가 급격히 늘고 운영 비용이 커집니다. 그래서 Slice Level Aggregation 단계에서 rollup/drilldown 조합을 포함하는 Data Cube를 한 번에 구성해 UI와 후속 분석이 일관된 규칙으로 필요한 조합을 즉시 조회할 수 있게 합니다.

// Spark snippet: Slice Level Aggregation (Data Cube) # 구현 예시: 슬라이스별 집계 수행 slice_cube_df = ( subject_value_df.cube(*metric.slices) # 모든 슬라이스 조합 생성 .agg( F.sum("denominator_value").alias("denominator_sum"), F.sum("numerator_value").alias("numerator_sum"), F.count("subject").alias("subject_count"), # 각종 slice level 통계치들을 계산 ) )

예를 들어 플랫폼과 실험 그룹 두 가지 슬라이스로 메트릭을 정의했다면, 시스템은 위의 cube 연산을 통해 다음과 같은 모든 조합을 자동으로 계산합니다. 최종적으로 만들어지는 Cube형태는 아래와 같습니다. 이는 rollup까지 포함된 결과이며, 필요한 일부 통계치들이 생략되어 있습니다.

+----------+--------+---------------+-------------+ | platform | country| denominator | numerator | +----------+--------+---------------+-------------+ | ALL | ALL | 1000 | 150 | # 전체 합계 | iOS | ALL | 600 | 95 | # iOS 전체 | Android | ALL | 400 | 55 | # Android 전체 | ALL | KR | 500 | 80 | # 한국 전체 | ALL | JP | 500 | 70 | # 일본 전체 | iOS | ID | 300 | 50 | # iOS / ID 국가 | iOS | UD | 300 | 45 | # iOS / UD 국가 ..... | Android | A | 200 | 30 | # Android / A 국가 | Android | B | 200 | 25 | # Android / B 국가 +----------+--------+---------------+-------------+


Incremental Processing

기존 방식의 가장 큰 비효율은 실험 분석을 실행할 때마다 실험 전체 기간을 처음부터 재계산해야 했다는 점이었습니다. 이 방식은 실험이 길어질수록 처리 시간이 메트릭 x 실험 기간에 비례해 증가했고, 결국 실험이 길어지면 분석이 지연된다는 운영 문제로 이어졌습니다. 배치 작업이 누적되면서 처리 시간이 수 시간 단위로 늘어나면, 실험 결과가 필요한 시점에 제공되지 못해 의사결정의 리드타임 자체가 길어졌습니다. Config Metric 시스템은 이 문제를 구조적으로 해결하기 위해 증분 처리(Incremental Aggregation)와 동적 분석 범위(Dynamic Range Analysis)를 함께 도입했습니다. 핵심은 이전 계산 결과를 재사용하여, 마지막 계산 이후에 추가된 이벤트만 읽고 계산한 뒤 기존 결과와 병합하는 것이었습니다.

이를 위해 시스템은 메트릭 정의에 기반한 캐시 키(예: 메트릭 내용 해시 + 메트릭/실험 식별자)와 해당 결과가 반영하고 있는 이벤트의 마지막 시각(watermark)을 함께 관리했습니다. 정상 상황에서는 마지막 시각 이후의 구간만 읽어 증분 집계를 수행했고, 그 결과를 기존 집계 결과와 병합했습니다. 반대로 메트릭 정의가 변경될 경우(예: 집계 방식 변경, 참조 이벤트 변경, 값 필드 변경 등) 기존 결과를 그대로 재사용하면 정합성이 깨질 수 있었기 때문에, 정의 변경을 해시 값 변화로 감지해 캐시를 무효화하고 전체 기간 재분석으로 결과를 복구했습니다.


시스템은 각 집계 방식에 따라 서로 다른 병합 전략을 사용합니다.

  • Sum : Sum(Sum(Curr Data), Prev Merge Data)
  • Count : Sum(Count(Curr Data), Prev Merge Data)
  • Count Distinct : Cardinality(Prev Merge Data.merge(Curr Data))
  • Max : Max(Max(Curr Data), Prev Merge Data)
▲ 이전 시간의 요약 정보들은 현재 시점의 요약 정보들과 병합되어 새로운 값이 됩니다
▲ 이전 시간의 요약 정보들은 현재 시점의 요약 정보들과 병합되어 새로운 값이 됩니다


운영 관점에서 이 접근은 단순한 성능 개선을 넘어, 계산 비용과 지연을 예측 가능하게 만들고 장애 복구도 단순화했습니다. 전체 재계산을 상시 강제하는 구조에서는 실험이 길어질수록 처리 부담이 누적됐고, 작은 이슈가 전체 파이프라인 지연으로 확산될 수 있었습니다. 반대로 증분 처리와 동적 범위 전략을 결합한 이후에는, 대부분의 실행이 작은 변경분만 처리했고 예외 케이스(정의 변경 등)에서만 통제된 방식으로 전체 재계산을 수행했습니다.


Task Orchestration

실제 제출되는 Task 들은 Airflow가 제출하는 Spark 작업 형태입니다. Event, Metric Yaml들로 부터 Airflow 작업을 동적으로 구성하는 운영 구조입니다. 현재 활성화된 실험과 그 실험이 사용하는 메트릭 정의를 읽어 들여 해당 시점에 필요한 작업만 생성하는 방식이며, 작업 수와 실행 범위는 전체 메트릭 카탈로그 크기에 비례하지 않고, 활성화된 실험에서 실제로 사용되는 메트릭 개수 단위로 스케일됩니다.

▲ Metric Pipeline의 축소된 버전
▲ Metric Pipeline의 축소된 버전


또한 Metric 정의에 명시된 dependencies를 기반으로 선행 조건을 보장합니다. 메트릭이 참조하는 Event나 업스트림 데이터가 준비되지 않은 상태에서 계산이 시작되면 결과의 정합성이 깨질 수 있습니다. 때문에 시스템은 dependencies를 읽어 Sensor를 동적으로 생성하고 선행 데이터의 준비 상태를 확인한 뒤 다음 작업을 실행하도록 구성했습니다. 이 방식은 메트릭 추가가 곧바로 운영 복잡도 증가로 이어지지 않게 하면서도, 데이터 준비 상태를 DAG level에서 명확히 드러내어 장애 원인 추적과 복구를 단순화했습니다.


통계검정 일원화

실험 결과는 p-value, 신뢰구간, 유의성 판단 같은 통계검정을 통해서 의사결정에 연결됩니다. 팀마다 이 부분이 달라지면 동일한 실험이 서로 다른 결론으로 해석될 수 있습니다. 온라인 실험은 반복 주기가 빠르고 이해관계자가 많기 때문에, 검정 방식의 혼재는 곧 해석 비용과 커뮤니케이션 비용으로 이어졌습니다.


Z-test + Delta Method

Z-test를 선택한 이유는 온라인 실험의 운영 제약과 잘 맞기 때문입니다. Z-test는 큰 표본에서의 정규 근사를 기반으로 하며, 표준화된 검정 통계량으로 p-value를 계산합니다. 구현 관점에서는 원본 데이터를 다시 읽지 않고도 요약 통계치만으로 분산과 표준오차를 계산할 수 있어 분산 파이프라인에 적합했습니다. 또한 Slice breakdown과 rollup처럼 결과가 여러 관점으로 확장되는 상황에서도 동일한 계산 프레임과 동일한 출력 형식을 유지할 수 있었습니다.

Delta Method를 함께 채택한 이유는 실험 메트릭에서 비율 형태가 매우 자주 등장하기 때문입니다. 메트릭이 늘면서 비율형과 수치형을 구분해 서로 다른 검정을 적용하는 방식은 운영에서 분기를 만들었고, 구현과 해석의 비용으로 이어졌습니다. 전문가 자문을 통해서 Delta method 를 활용하여 수치형 메트릭과 비율형 메트릭을 일반화 할 수 있는 방법론을 확인하고, 이를 시스템에 녹여내어 Scalable 한 지표 정의 체계를 만들고자 했습니다.

비율 메트릭은 분자와 분모가 동시에 변동하고, 두 값의 결합 구조를 반영하지 않으면 분산 추정이 쉽게 왜곡될 수 있습니다. Delta Method는 점근적으로 정규인 추정량의 함수에 대한 분산을 근사하는 방법으로, 비율 메트릭을 검정 가능한 형태로 번역하는 데 널리 사용됩니다. 이 선택을 통해 비율 메트릭과 수치형 메트릭을 일반화하여 동일한 검정(Z-test)으로 처리할 수 있게 되었고, 메트릭 유형에 따라 검정이 갈라지는 상황을 줄일 수 있었습니다. [1]

https://alexdeng.github.io/public/files/kdd2018-dm.pdf

▲ Delta method 를 적용한 variance of ratio
▲ Delta method 를 적용한 variance of ratio


Metric Pipeline 내에서의 통계검정

표준화된 통계검정을 시스템으로 운영하기 위해서는 메트릭 파이프라인 위에서 통계검정이 수행 가능해야 했습니다. 파이프라인에서 Group별 / Slice별로 집계할 때 평균만 계산한 것이 아니라, Z-test와 Delta Method에 필요한 요약 통계치를 함께 누적하도록 설계했습니다. 예를 들어 분자/분모의 합, 제곱합, 그리고 필요시 교차항 성격의 값들을 Slice 집계 결과와 함께 저장해 두면, 최종 단계에서는 이 값들을 공식에 대입해 표준오차와 검정 통계량을 계산할 수 있습니다. 결과적으로 집계 단계와 검정 단계의 경계가 명확해졌고, 실험 디테일 화면과 후속 분석 인터페이스가 동일한 검정 결과를 공유할 수 있게 되었습니다.


실험 인터페이스를 플랫폼으로

정의와 파이프라인, 통계 검정이 표준화되더라도 사용자가 결과를 읽고 해석하는 과정이 제각각이면 실험 결과는 다시 개인의 해석으로 돌아갈 수 있습니다. 그래서 UI는 단순한 결과 조회 화면이 아니라, 표준 계산 결과를 가장 덜 왜곡되는 형태로 전달하는 해석 계층입니다.


실험 디테일 페이지 개선

실험 디테일 페이지는 계산된 결과를 빠르게 확인하고 비교할 수 있게 제공하는 화면입니다. 다양한 외부 실험 플랫폼을 벤치마크하며, 의사결정에 필요한 정보와 그 정보의 배치 순서에 집중했습니다. Slice는 간편하게 펼쳐서 확인할 수 있도록 구성했고, 컬럼 배치와 정렬 방식은 비교 편의성을 최우선으로 설계했습니다. 숫자의 가독성을 위해 monospace font를 적용하고, 중요한 값은 시각적으로 구분되도록 강조했습니다. 또한 상세 트렌드 그래프는 기본 화면을 과밀하게 만들지 않도록 접어두고 필요할 때 펼쳐서 확인할 수 있게 했으며, 각 메트릭의 정의를 바로 확인할 수 있도록 정의 조회로 연결되는 링크를 제공했습니다.

▲ 메트릭을 잘 만들었으니, 사용자가 보기 편하게 제공하자
▲ 메트릭을 잘 만들었으니, 사용자가 보기 편하게 제공하자


후속 분석 Workspace

같은 Config와 파이프라인을 시스템과 사람이 공유하면, 정규 분석과 후속 분석 간 결과 불일치를 구조적으로 줄일 수 있습니다. 사내 JupyterHub를 통해 Metric을 자유롭게 생성, 변경, 실행해 볼 수 있는 Workspace를 제공했습니다. 이 Workspace는 신규 메트릭 개발 시 동작을 검증하거나 후속 분석에서 새로운 집계 기준을 시험하는 데 활용할 수 있습니다. 또한 Metric PR 리뷰 전에 실행 결과를 첨부하도록 지원하여, 정의 변경이 결과에 미치는 영향을 투명하게 공유할 수 있었습니다.

▲ 정규 분석 과정을 Workspace에서 그대로 따라가볼 수 있습니다
▲ 정규 분석 과정을 Workspace에서 그대로 따라가볼 수 있습니다


Metric 정의 카탈로그

Yaml로 Metric 정의가 존재하더라도 사용자가 쉽게 찾고 확인하지 못하면 표준은 운영 과정에서 효력을 갖기 어렵습니다. 사용자 관점에서는 메트릭이 어떤 이벤트를 사용하고 어떤 집계 규칙을 갖는지 빠르게 확인할 수 있어야 하고, 운영 관점에서는 책임(Owner)과 변경 이력, 적용 범위를 추적할 수 있어야 합니다. Metric 정의 카탈로그 화면을 통해 사용자는 특정 실험 결과를 보다가도 정의로 이동해 해석 근거를 확인할 수 있었고, 결과 공유 과정에서 불필요한 커뮤니케이션 비용을 줄이는 데 도움이 되었습니다.

▲ 메트릭 정의를 검색하고 확인할 수 있는 카탈로그
▲ 메트릭 정의를 검색하고 확인할 수 있는 카탈로그


AI Feature

Config Metric 전환 이후 메트릭 정의와 실험 결과 데이터가 표준 형태로 축적되었습니다. 정의와 결과가 플랫폼에 모이면서, AI 가 가장 잘 자동화 할 수 있는 형태로 재료들이 준비되었습니다. 빠르게 발전되고 있는 LLM 성능을 최대한으로 끌어내어 반복해서 투입되는 결과의 요약 작업을 AI 를 통해서 사람의 부하를 줄이고, 일관된 형태로 자동화할 수 있었습니다.

Metric/Event 생성 Agent

사용자의 의도를 입력으로 받아 기존 Metric / Event 카탈로그를 먼저 탐색하고, 이미 존재하면 재사용을 안내합니다. 존재하지 않으면 Config 형태의 초안을 생성해 PR 흐름으로 연결합니다.

▲ 메트릭 만들어주세요
▲ 메트릭 만들어주세요


실험 결과 분석 Agent

실험 디테일 페이지에서 결과를 AI가 요약하고, 규격화된 템플릿 형태로 실험 결과를 정리해 의사결정에 필요한 정보를 정리합니다.

▲ 실험 해석을 도와주세요
▲ 실험 해석을 도와주세요


실험 문화에도 개선이 필요합니다

Config Metric 시스템을 통해 신뢰성 있는 메트릭 계산과 표준 통계 검정을 제공할 수 있었지만, 이것만으로 실험을 잘하게 되지는 않았습니다. 실험 결과가 실제 의사결정으로 이어지려면, 실험을 설계하고 해석하는 규칙이 조직 내에서 반복 가능하게 지켜져야 합니다. 특히 동일한 수치를 두고도 결론이 갈리는 상황은 계산 오류보다 문화적 요인에서 더 자주 발생했습니다. 그래서 우리는 기술적 기반 위에 의사결정 규칙과 거버넌스를 정렬하고, 이를 문서와 프로세스에 고정하는 노력을 병행했습니다.


Online Experiment Consulting

전문가의 기술 자문을 통해, 메트릭 파이프라인과 통계 검정 통합 과정에서 필요한 통계학적 전제와 운영 관점의 타협점을 정리했습니다. 그 결과 각 팀의 경험에 의존하던 판단 기준을 공통 언어로 정리해, 실험 결과를 읽는 방식과 의사결정 규칙을 정렬하는 데 도움이 되었습니다. (관련 아티클)

▲ Online Experiment Onsite Session
▲ Online Experiment Onsite Session


실험문화 TF

이미 각 팀에서 실험을 진행하던 practice들이 있었지만, 이를 명문화하여 일관된 프로세스로 정리할 필요가 있었습니다. 실험 문화 TF가 구성되어 실험 결과를 해석하고 의사결정을 내릴 때 필요한 규칙을 가이드라인으로 정리해 배포했고, 프로젝트가 시작되는 시점부터 실험을 준비할 수 있도록 PRD 템플릿에 A/B Test 관련 항목을 포함했습니다.

▲ 실험 문화를 명문화하자
▲ 실험 문화를 명문화하자


앞으로의 실험 플랫폼

Config Metric 전환 이후, 실험 결과의 신뢰성 문제는 일정 수준 개선되었습니다. Metric 정의와 계산, 통계 검정이 표준 프레임으로 묶이면서 결과 불일치와 해석 비용이 줄었고, 등록·배포·실행 흐름도 Config 기반으로 정착되었습니다. 초기에는 비개발자가 GitHub PR 기반으로 정의를 수정하고 리뷰 받는 방식에 어려움을 겪었지만, 현재는 조직 전반에서 이 흐름을 안정적으로 활용하고 있습니다.

▲ 수많은 논의와 고민들
▲ 수많은 논의와 고민들


다음 단계의 과제는 실험 메트릭 표준화를 넘어 조직 전반의 지표 표준화로 범위를 확장하는 것입니다. Config Metric 표준화는 소기의 목적을 달성했지만, 오늘의집에는 목적과 의미가 다른 메트릭이 여전히 산재해 있습니다. 이를 하나의 일원화된 소스와 단일 지표 레이어로 통합해, 메트릭을 한 번 정의하면 대시보드, 실험 리포팅, 이상 탐지, 정기 리포트 등 다양한 채널에서 동일한 정의로 재사용되도록 합니다. 이를 위해 물리 테이블 조인 방식에 대한 의존을 줄이고, 메트릭과 디멘션 중심으로 일관된 계산을 제공하며, 검증된 조합만 소비 계층에 노출하는 서빙 계층을 강화합니다. 결과적으로 지표 정의, 계산, 탐색, 공유, 실행이 동일한 규칙과 동일한 의미 체계로 연결할 수 있는 비전을 가지고 Metric Platform 을 발전시켜 나갈 예정입니다.

오늘의집에서 당신을 찾고 있습니다!
Senior Backend Engineer, Tech Lead & Manager, CommerceSenior Frontend Engineer, Tech Lead & Manager, CommerceSenior Backend Engineer, AdsSenior Backend Engineer, Core PlatformSenior Machine Learning Engineer, SearchSenior Machine Learning Engineer, Vision/GenAISenior Machine Learning Engineer, Ads & RecommendationSenior Android Engineer, Client FoundationBackend Engineer, Core PlatformBackend Engineer, Interior & LifeBackend Engineer, CommerceBackend Engineer, AdsFrontend Engineer, ContentFrontend Engineer, Interior & LifeFullstack Engineer, Life ServiceFullstack Product Engineer, AI AgentMachine Learning Engineer, ML PlatformMachine Learning Engineer, SearchMachine Learning Engineer, Ads & RecommendationMachine Learning Engineer, Ads & Recommendation (전문연구요원)iOS Engineer, ContentCloud EngineerSenior Data Analytics EngineerData Analytics EngineerAI Solutions EngineerQA EngineerQA Assistant (계약직)[오늘의집페이] Backend Engineer[오늘의집페이] Fullstack Engineer
목록으로 돌아가기