-
데분가
-
조회수 100
안녕하세요. 위어드섹터 래빗연구소입니다.
오늘은 서비스 운영에서 중요한 영역인 A/B 테스트 구조 개선에 대해 이야기해보려고 합니다.
A/B 테스트는 단순히 “버튼 색상, 문구등 클릭률을 비교하는 실험”이 아닙니다.
실제로는 페이지 레이아웃, 문구, 이미지, CTA 버튼, 특정 기능 노출 여부까지 기획자가 실시간으로 조정하여 운영해야 하는 경우가 존재합니다.
하지만 실무에서는 이런 요구가 항상 쉽지 않습니다.
- 개발자가 바쁘면 문구 하나 바꾸는 작업도 배포 일정 때문에 며칠씩 지연되고,
- 기획자·마케터와 개발자 간의 수정 요청/대응 커뮤니케이션 비용이 반복적으로 발생하며,
- 클라이언트가 갑자기 “A안 UI를 조금만 수정해달라”고 하면 또다시 코드 수정 → PR → 배포가 반복됩니다.
이런 구조에서는 빠르게 실험을 돌리기 어렵고, 데이터 기반 의사결정보다 배포 일정에 좌우되는 실험이 되어버리기 쉽습니다.
이번 글에서는 Amplitude Feature Expreiment를 활용해,
- 개발자는 A/B 테스트 페이지의 “분기 조건”만 구현하고
- 기획자·마케터는 Amplitude 콘솔에서 JSON Payload만 수정해서 텍스트/색상/UI를 실시간 변경하며
- 클라이언트 요청도 재배포 없이 즉시 반영할 수 있는 구조
즉 “개발 리소스가 부족해도 실험이 끊기지 않는 구조”를 만드는 방법을 소개드리려고 합니다.
Next.js 환경에서 Amplitude Feature Experiment 적용하기
위에서 이야기한 것처럼, 우리가 만들고 싶은 구조는 다음과 같습니다.
- 개발자는 분기 로직과 UI 컴포넌트만 만들어두고
- 기획자·마케터는 Amplitude 콘솔에서 JSON Payload를 바꾸는 것만으로
- 텍스트, 색상, 버튼 모양, 기능 토글 등을 실시간 변경하는 구조
이제 이를 Next.js + Amplitude Experiment SDK 기준으로 어떻게 구현하는지 살펴보겠습니다.
1. Amplitude Expreiment 설정
1-1. 기능 플래그 설정
Amplitude 콘솔 좌측 메뉴에서 기능 플래그로 이동한 뒤, 우측 상단의 기능 플래그 생성 버튼을 클릭합니다.

필수 입력 요소
- 이름 : A/B 테스트 (내부에서 정한 A/B 테스트 명칭)
- 프로젝트 : 배포 환경에 맞는 프로젝트 설정
- 키 : header-a-b (프론트 환경에서는 useFlag('header-a-b')로 접근)

1-2. 플래그 편집 화면 구성
플래그가 생성되면 편집 페이지가 나타납니다. 화면의 주요 영역은 다음과 같습니다.

- 기능 플래그 : 플래그 생성 단계에서 입력했던 키 (header-a-b)
- 배포 : 클라이언트 SDK에서 사용할 배포 키 선택
- 설명 : 생성한 A/B 테스트 목적과 설명
- 변형 : 실험에서 사용자에게 노출되는 특정 버전의 사용자 경험 기능 정의
- 타겟팅 및 롤아웃 비율 설정
1-3. 변형(Variant) 구성하기
기본적으로 A/B 테스트를 위해 두 가지 Variant를 생성합니다:
- A: old_header
- B: new_header
각 Variant에는 Payload(JSON) 을 추가해 UI를 제어합니다.

Payload란?
- Payload는 기획자가 원하는 UI 요소를 JSON 형태로 정의해서 코드를 수정하지 않고도 실험 중 즉시 UI를 변경할 수 있도록 해주는 핵심 기능입니다.
중요한 점 – Payload는 “고정된 구조”가 아닙니다.
아래 JSON 예시는 단순한 샘플이며, 이 키들만 사용할 수 있다는 의미가 절대 아닙니다.
Payload 스키마는 개발자가 사전에 일부 기준을 만들어 두되, 기획–개발 간 협의를 통해 필요할 때마다 새로운 키를 자유롭게 추가하고 UI에서도 확장해 반영할 수 있는 구조로 설계하는 것이 가장 효율적입니다.
- Payload = 실험을 위해 확장 가능한 설정값 집합
- 개발자가 특정 키를 강제하는 것이 아니라
- 기획에서 원하는 실험 요소에 맞춰 유연하게 키를 늘려갈 수 있습니다.
예를 들어 아래처럼 title, items, cta 관련 설정을 넣었다면 기획 요청에 따라 bannerImage, badgeText, layoutType 같은 필드를 추가할 수 있습니다.
샘플 Payload 예시

아래는 사전에 협의된 예시일 뿐, 회사의 서비스 구조·실험 의도에 따라 필드를 자유롭게 확장할 수 있습니다.
- title : 헤더 제목 텍스트
- color : 제목 글자 색상
- fontSize : 제목 폰트 크기
- ctaText : CTA 버튼 텍스트
- ctaColor : CTA 배경색
- ctaShape : 버튼 모양 (pill / rounded / square)
- ctaAlign : 버튼 위치 (left / center / right)
- showLogo : 로고 노출 여부 (true/false)
- featureEnabled : 하단 리스트(새 플로우) 보이기 ON/OFF
- items : 리스트에 들어갈 문구 배열
Amplitude에서 제공하는 Experiment 가장 큰 가치는
기획자
- 실험 중 문구/색상/배너/레이아웃 등 원하는 설정값을 Payload로 실시간 변경 가능
- 배포 없이 즉시 실험 조정 가능
개발자
- UI 컴포넌트에서 Payload를 어떻게 사용할지만 정의해두면
- 이후 기획이 Payload에 새로운 키를 추가하더라도 컴포넌트에 해당 로직만 간단히 연결해 확장 가능
- 실험이 바뀔 때마다 PR/배포를 반복할 필요 없음
Payload는 단순히 텍스트 한 줄을 바꾸는 도구가 아니라 기능·레이아웃·정책까지 포함한 UI/UX 실험을 무한하게 확장할 수 있는 실험 엔진 역할을 하게 됩니다.
1-4. 롤아웃 비율 설정 Variant(변형) 설정을 완료하면, 타겟팅 섹션에서 실험을 어떤 사용자에게, 어떤 비율로 적용할지 설정할 수 있습니다.

- 롤아웃 비율
- 실험을 전체 사용자에게 적용할지, 또는 특정 일부 사용자에게만 적용할지를 결정하는 설정입니다.
- 일반적인 A/B 테스트 상황에서는 100% 롤아웃으로 설정하여
- “전체 사용자를 A/B 그룹에 고르게 분배” 하는 방식으로 운영합니다.
- 예:
- 100% 롤아웃 → 전체 사용자에게 실험 적용
- 50% 롤아웃 → 최근 7일 사용자 중 절반에게만 실험 적용
- A/B 그룹(Variant) 비율 설정
- 롤아웃이 100%일 때, 그 안에서 A/B를 어떤 비율로 나눌지 지정합니다.
- old_header : 50%
- new_header : 50%
이렇게 설정하면, 전체 사용자 중 절반은 기존 헤더(old_header), 절반은 새로운 헤더(new_header)를 보게 됩니다.
1-5. 세그먼트 기반 타겟팅
아래와 같이 Amplitude 사용자 속성을 활용해 특정 조건의 사용자에게만 실험을 적용할 수도 있습니다.

가능한 세그먼트 예시:
- 특정 국가 사용자만 (Country = KR)
- iPhone 사용자만 (Device family = iPhone)
- 특정 버전의 앱 사용자만
- 신규 가입자만 (최근 3일 이내 가입자)
즉, A/B 실험을 전 사용자에게 적용할 수도 있고, 특정 그룹만 골라서 진행할 수도 있습니다.
콘솔에서 실험 설정을 마쳤다면, 이제 이 플래그를 실제 코드에서 활용할 차례입니다.
2. 패키지 설치
먼저 Experiment SDK를 설치합니다.

3. ExperimentProvider로 “실험 전역 상태” 관리하기
ExperimentProvider는 앱 전체에서 실험 정보를 공유하는 전역 레이어입니다.
- Amplitude Experiment 클라이언트 초기화
- device_id 동기화 (Analytics SDK ↔ Experiment SDK 동일하게)
- fetch() 호출로 현재 유저가 어떤 variant인지 받아오기
- Context로 ready, variant()를 제공 → 하위 컴포넌트 어디서든 useFlag()로 접근
1. device_id 고정 (Sticky Assignment)

- 로그인 전/후 상관없이 동일 사용자는 항상 같은 variant를 받도록 하는 장치입니다.
- Analytics SDK와 Experiment SDK가 서로 다른 device_id를 쓰지 않도록 맞춰 줍니다.
- Amplitude Analytics를 사용하면서 Experiment를 동시에 사용할 경우 device_id를 맞춰주셔야 사용자 매칭이 가능합니다.
2. Experiment SDK 초기화 + 도메인 프록시 연계

- NEXT_PUBLIC_EXPERIMENT_DEPLOYMENT_KEY는 반드시 client-로 시작하는 키를 사용해야 합니다.
- serverUrl을 /amp/exp로 지정해서, 앞에서 구성한 Nginx 도메인 프록시를 그대로 이용합니다.
- 도메인 프록시를 사용안할경우 serverUrl를 제거하시고 사용하시면 됩니다.
- fetch()로 variant 불러오기 + ready 플래그

- 최초 1회만 fetch()를 수행해서 이 유저의 실험 배정 결과(variant + payload) 를 가져옵니다.
- 완료되면 ready=true가 되어 하위 컴포넌트가 실험값을 사용해 렌더링할 수 있게 됩니다.
4. Context로 variant() 제공

- variant(flagKey)를 호출하면 해당 플래그의 변형 값과 payload를 가져옵니다.
- 최초 접근 시 $exposure 자동 기록
- 같은 키는 캐시에 저장해서 불필요한 SDK 호출을 줄입니다.
5. layout.tsx에서 전역으로 감싸기

- 이렇게 감싸두면, 앱 전체에서 useFlag()로 실험 상태를 쉽게 쓸 수 있습니다.
4. A/B 테스트 진행 할 헤더 컴포넌트에 variant + payload 활용하기
이제 실제 페이지에서 사용하는 헤더 컴포넌트가
어떻게 Experiment의 variant + JSON payload를 활용하는지 구조를 살펴보겠습니다.
1. 현재 변형(variant) + JSON payload 읽기

- useFlag('header-a-b') → Amplitude Experiment에서 플래그 키가 ‘header-a-b’인 실험의 현재 변형을 가져옵니다.
- variant.value 예시
- old_header
- new_header
- variant.payload 안에는 Amplitude 콘솔에서 설정한 JSON이 통째로 들어옵니다.
- asHeaderPayload()는 이 JSON을 타입 안전하게 가공해서
- title, color, ctaText, items, ctaAlign 같은 필드를 꺼내 쓰기 좋게 만들어주는 유틸입니다.
2. JSON payload로 문구 / 색상 / 버튼 위치 / 리스트까지 제어

- p.title, p.color, p.ctaText, p.ctaColor, p.ctaShape, p.ctaAlign 등은 모두 콘솔에서 JSON으로 제어합니다.
- 예: 버튼을 오른쪽 정렬하고 싶으면 payload에 "ctaAlign": "right"
- 버튼 모양을 Pill로 바꾸고 싶으면 "ctaShape": "pill"
- 버튼 문구만 바꾸고 싶으면 "ctaText": "무료로 시작하기" 식으로 변경
- items는 목록형 문구들을 담는 배열입니다.
- 예: B 그룹에서만 아래 문구를 보여주고 싶다면 payload에 이렇게 설정해두고:

- 코드에서는 그대로 items.map(...)으로 렌더링하면서, 기획자가 콘솔에서 내용만 바꾸면 바로 UI에 반영됩니다.
3. CTA 클릭 이벤트 트래킹

- 버튼이 클릭될 때마다 cta_click 이벤트를 Amplitude로 전송합니다.
- 함께 전송하는 속성:
- variant: 현재 사용자가 속한 실험군 (old_header, new_header 등)
- title_used: 그때 실제로 노출된 제목(콘솔에서 바꾼 문구 포함)
- feature_enabled: 리스트/새 플로우가 켜진 상태인지 여부
- 나중에 Amplitude에서:
- A 그룹 vs B 그룹의 CTA 클릭률
- featureEnabled on/off에 따른 행동 차이
- 특정 문구(title_used)에 따른 전환 차이등으로 쉽게 분석할 수 있습니다.
4. 리스트 렌더링 – featureEnabled + items 조합

- featureEnabled가 true이고, items 배열에 값이 있을 때만 리스트가 노출됩니다.
- 이 둘도 모두 콘솔에서 JSON으로 제어 가능:
- "featureEnabled": false → 리스트/새 플로우 숨김
- "featureEnabled": true + "items": [...] → 특정 그룹에만 메시지/혜택 설명 노출
4-3. 컴포넌트에서 Payload 사용하는 방법
앞에서 만든 플래그와 Payload는 컴포넌트에서 다음처럼 읽어옵니다.


마지막으로, 전체 실험 현황과 A/B 성과는 Experiment 대시보드에서 이렇게 확인할 수 있습니다.


여기서는 각 변형(old_header / new_header)에 대한 사용자 수, 전환 지표, 누적 성장 추이를 한눈에 확인할 수 있습니다. 이를 통해 어느 헤더가 실제 사용자 행동과 전환에 더 긍정적인 영향을 주는지, 실험이 진행되는 동안 성과가 어떻게 변화했는지를 명확히 파악할 수 있습니다.
즉, UI 변경이 “느낌상 좋아 보인다”가 아니라, 실제 데이터 기반으로 더 효과적인 버전을 선택할 수 있는 구조가 완성되는 것입니다. 이런 형태로 실험 구조를 구축해 두면, “개발자는 분기 로직만 관리하고”, “기획자는 콘솔에서 JSON만 수정하며 실험을 조정”하는 방식으로 A/B 테스트를 훨씬 더 가볍고 빠르게 운영할 수 있게 됩니다
마무리하며
이번 구조는 단순히 “A/B 테스트 기능을 붙였다”는 수준을 넘어, 개발–기획–클라이언트 모두가 빠르게 움직일 수 있는 실험 운영 체계를 구축했다는 데에 의미가 있습니다.
Amplitude Experiment를 활용하면 텍스트·색상·버튼 위치·리스트 노출 여부 같은 UI 요소는 물론, 더 나아가 레이아웃·정책·온보딩 흐름까지도 배포 없이 즉시 조정할 수 있습니다. 실험 중 필요해지는 새로운 설정값은 Payload에 자유롭게 추가해 확장할 수 있어, 실험의 범위가 자연스럽게 서비스 전체로 넓어집니다.
또한 Variant별 사용자 행동 데이터는 Experiment 대시보드에서 실시간으로 비교 분석할 수 있기 때문에, 어떤 UI/정책이 실제 전환에 더 효과적인지 명확한 근거를 가지고 판단할 수 있습니다.
결과적으로,
- 개발자는 분기 로직을 한 번만 구현하고
- 기획자는 콘솔에서 JSON만 수정해 즉시 실험을 운영하고
- 클라이언트 요청도 배포 없이 바로 반영되며
- 실험 성과는 데이터 기반으로 명확하게 검증됩니다.
A/B 테스트는 더 이상 버튼 색상 정도를 바꾸는 단순한 실험이 아니라, 제품 전략을 빠르게 검증하고 반복하는 핵심 운영 방식이 되고 있습니다. 앞으로도 실제 서비스 환경에 바로 적용할 수 있는 Payload 설계 패턴, 실험 구조 설계 방식, 운영 노하우 등을 더 깊이 있게 정리해 지속적으로 공유드리겠습니다.
재밌게 읽었어요
0