케듀올
경력근거: 사용자 피드백, 행동 데이터 등을 바탕으로 제품의 사용성을 개선합니다
※ 실제 산출물이 아닌 AI 예측 시안입니다.
케듀올 PE 자리는 프론트엔드를 중심으로 사용자에게 직접 보이는 인터페이스와 흐름을 구현하고, 사용자 피드백·행동 데이터로 제품의 사용성을 개선하는 일입니다. 이 콘솔이 짚는 '어느 화면 단계에서 왜 빠져나가는가'는 케듀올이 운영하는 실제 웹/앱 서비스의 화면 흐름과 행동 로그가 있어야 의미가 있습니다. 다른 회사의 화면 구조로는 이 진단→개선→검증 사슬을 그대로 만들 수 없습니다. 다만 이 포트폴리오가 보여주는 것은 React·Next.js·Vue·TypeScript 프론트 구현과 행동 데이터 기반 개선 설계라는 기술 역량이며, 케듀올 도메인 자체의 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
주요업무가 프론트엔드를 중심으로 사용자에게 직접 보이는 인터페이스와 흐름을 구현하고, 작은 디테일(로딩·에러·반응성)로 제품 완성도를 높이는 일입니다. 그래서 산출물은 추상 점검이 아니라 실제로 고친 화면이어야 합니다.
우대사항이 사용자 행동 데이터·로그·피드백을 바탕으로 제품을 발전시켜본 경험입니다. 어느 화면에서 왜 빠져나가는지를 로그로 짚어 개선안까지 잇는 루프가 이 자리의 핵심입니다.
다양한 AI 도구를 적극 활용해 개발·실험·반복 작업의 효율을 높이고, AI 기반 워크플로우(하네스)를 설계해 본 경험을 우대합니다. 진단·제안 생성에 LLM 을 붙이되 정답은 규칙으로 채점하는 하네스로 만듭니다.
웹/앱 서비스의 사용자 행동 이벤트 로그(화면 이동·클릭·입력·오류·이탈)를 넣으면, 한 화면 흐름에서 사람들이 어느 단계에 가장 많이 빠져나가는지 퍼널로 결정론적으로 계산해 짚습니다. 그 단계의 UI/인터랙션 개선안 3건을 근거 수치(이탈률·rage-click·로딩시간)를 붙여 카드로 만들고, 고친 화면을 React 프로토타입으로 실제 렌더합니다. 1주차만으로 진단부터 고친 화면까지 도는 완성품이고, 프레임워크 중립 이식(Vue)·UX 검토(2주차), 성능·접근성 축 결합(3주차)으로 키웁니다. 근거는 채용공고 정렬이고, 데이터는 작성자가 만든 더미입니다.
케듀올 PE. 기획자·디자이너와 함께 '이 화면에서 왜 사람들이 빠져나가지'를 매번 감으로 추측하던 상황을 끝내고, 이탈이 큰 단계와 개선안, 고친 화면을 한 콘솔에서 근거와 나란히 확인하고 싶은 사람입니다.
행동 이벤트를 한 스키마로 모으고 화면 표기를 정규화하면, 퍼널 엔진이 (a) 이탈이 가장 큰 단계를 규칙으로 결정하고, (b) LLM 이 그 단계의 UI/인터랙션 근거 수치를 붙인 개선안 3건을 몇 초 안에 만들며, (c) 다음 기간 실제 이탈률로 그 제안이 맞았는지 확인합니다.
행동 로그를 넣으면 이탈이 가장 큰 화면 단계를 퍼널로 짚고, 그 단계의 UI/인터랙션 개선안 3건을 근거 수치를 붙인 카드로 만들며, 고친 화면을 React 프로토타입으로 렌더하는 동작하는 콘솔입니다. 실서비스 계측 SDK 연동 대신 합성 행동 이벤트 로그를 입력으로 가정하고 시작해, 1주에 혼자 완결합니다.
같은 개선 컴포넌트를 Vue 로도 이식해 프레임워크 중립 구현을 보이고, UX 디자이너 페르소나 2명이 제안 타당성을 라벨링하며, 지난 기간 예상 이탈 감소폭을 다음 기간 실제값과 맞춰보는 검증 대시보드입니다.
LCP·키보드 접근성·반응형 계측을 퍼널에 결합해 '느린 단계·접근성 막힌 단계'를 진단하고, 보정된 기준으로 다시 제안→확인 주기를 돌려 신뢰도를 누적하는 단계입니다.
이탈 급증 플로우 8개를 넣으면 가장 이탈이 큰 단계와 개선안 3건, 고친 화면 프로토타입이 몇 초 안에 나오는 걸 시연합니다
진단 카드가 인용하는 단계·수치가 퍼널 엔진이 계산한 실제 값과 100% 일치하는지 자동 검사합니다. '가장 이탈 큰 단계'는 LLM 이 아니라 규칙으로 결정되므로 이 일치 검사는 객관적입니다. 단, 데이터 자체를 작성자가 만들었으므로 '성능 검증'이 아니라 '데모 조건 동작'입니다
일부러 만든 결측·경계·미매핑 입력 30종을 넣어도 출력 형식(스키마)이 한 번도 안 깨지고, 화면 표준에 없는 단계는 추측 대신 '미매핑'으로 표시합니다
위 수치는 전부 작성자가 만든 합성 행동 로그 자가채점이며, 실제 이탈 감소·개선 효과는 케듀올 실서비스 계측 데이터와 실 UX 검수가 있어야 측정 가능합니다. 이 콘솔은 그 검증을 바로 돌릴 수 있는 상태로 만듭니다
이건 고객·실데이터 없이 혼자 만든 포트폴리오입니다. 모든 수치는 합성 행동 로그 자가채점이라 '성능 증명'이 아닙니다. 면접에서 '데모 조건 동작 + 실검증 준비 상태'로 솔직히 설명합니다
정답을 작성자가 만들었으니 잘 맞는 것이 당연합니다. 결측(계측 누락)·경계값(로딩 0ms·8초)·미매핑(화면 표준에 없는 신규 단계)·표기흔들림(같은 화면의 다른 이름)을 더미에 일부러 섞어, 쉬운 문제만 푸는 게 아님을 보입니다
'이 UI 때문에 이탈했다'는 상관일 뿐 인과가 아닐 수 있습니다. A/B 없이 단정하지 않도록 단정 표현을 누그러뜨리고 별도 LLM 검사로 우회 표현을 거릅니다
화면 이름 표기가 제각각입니다('인증번호 입력'·'이메일 인증'이 같은 단계). 이름 유사도 + 플로우·단계번호로 같은 화면으로 묶고, 못 묶은 건 추측하지 말고 '미매핑'으로 알립니다
실제 도입 시 달라지는 것을 분리 명시합니다. 실 행동 로그 분포와 이탈 기준은 더미와 다르므로 임계값·보정값을 다시 맞춰야 하고, UX 페르소나 검수도 실 디자이너 검수로, 합성 로그도 실 계측 SDK 로 교체해야 합니다(도입 단계 과제)
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
세션별 화면 이동·클릭·입력·오류·이탈 행동 이벤트 로그입니다. 퍼널 엔진이 가장 먼저 소비하는 테이블입니다. 운영 현실대로 계측 누락(로딩시간 null·요소 null)·미등록 신규 화면(step_id null orphan)·별칭 표기(step_raw)·경계값(로딩 0ms·8초, rage-click 폭증)을 일부러 섞어, 쉬운 데이터만 푸는 게 아님을 보입니다.
| session_id | ts | flow_id | step_raw | step_id | step_no | event | element_id | load_ms | device |
|---|---|---|---|---|---|---|---|---|---|
| s_1042 | 2026-03-16T10:02:11Z | f_signup | 시작 화면 | s_landing | 1 | view | — | 620 | mobile |
| s_1042 | 2026-03-16T10:02:29Z | f_signup | 이메일 입력 | s_email | 2 | submit | btn_next | 480 | mobile |
| s_1042 | 2026-03-16T10:02:58Z | f_signup | 인증번호 입력 | s_verify | 3 | rage_click | btn_resend | 3,820 | mobile |
| s_1042 | 2026-03-16T10:03:20Z | f_signup | 인증번호 입력 | s_verify | 3 | exit | — | — | mobile |
| s_1043 | 2026-03-16T11:14:03Z | f_signup | 이메일 인증 | s_verify | 3 | view | — | 4,110 | desktop |
아래 JSON Schema 에 맞는 웹/앱 사용자 행동 이벤트 로그 2개 플로우(f_signup 6단계, f_checkout 4단계) × 세션 40개 분량 JSON 배열로 생성. 세션마다 view→submit→(다음 단계) 순서로 이어지되 일부는 중간 단계에서 exit/back 으로 이탈.
{"type":"object","properties":{"session_id":{"type":"string"},"ts":{"type":"string"},"flow_id":{"type":"string"},"step_raw":{"type":"string"},"step_id":{"type":["string","null"]},"step_no":{"type":"integer"},"event":{"enum":["view","click","focus","submit","validation_error","rage_click","back","exit"]},"element_id":{"type":["string","null"]},"load_ms":{"type":["number","null"]},"device":{"enum":["mobile","desktop","tablet"]}},"required":["session_id","ts","flow_id","step_raw","step_no","event","device"]}
쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라(쉬운 문제만 푸는 함정 회피): (1) 같은 단계의 별칭 표기 혼입(step_raw '인증번호 입력'·'이메일 인증'이 모두 step_id s_verify 로, '결제하기'·'결제 확인'이 s_pay 로 정규화돼야 함), (2) 미등록 신규 화면 step_id=null 2~3건(화면 표준에 없는 orphan), (3) 결측. load_ms 또는 element_id 가 null 인 행 각 2~3건(계측 누락·이탈 이벤트), (4) 경계값 load_ms 0(캐시 즉시)·8000 이상(심한 지연) 각 1건, (5) rage_click·validation_error·exit·back 이벤트를 특정 단계(s_verify, s_pay)에 몰아 이탈이 큰 단계가 분명히 드러나게. JSON 배열만.{"type":"object","properties":{"session_id":{"type":"string"},"ts":{"type":"string"},"flow_id":{"type":"string"},"step_raw":{"type":"string"},"step_id":{"type":["string","null"]},"step_no":{"type":"integer"},"event":{"enum":["view","click","focus","submit","validation_error","rage_click","back","exit"]},"element_id":{"type":["string","null"]},"load_ms":{"type":["number","null"]},"device":{"enum":["mobile","desktop","tablet"]}},"required":["session_id","ts","flow_id","step_raw","step_no","event","device"]}화면 단계의 표준 ID + 별칭 + 메타입니다. 같은 화면이 '인증번호 입력/이메일 인증'처럼 다른 이름으로 들어와도 한 단계로 묶어, 퍼널이 표기 차이로 분산되는 문제를 없앱니다.
| step_id | flow_id | canonical_name | aliases | step_no | component_type | is_critical |
|---|---|---|---|---|---|---|
| s_landing | f_signup | 시작 화면 | ["랜딩","가입 시작"] | 1 | cta | false |
| s_email | f_signup | 이메일 입력 | ["이메일 등록","계정 입력"] | 2 | form | true |
| s_verify | f_signup | 인증번호 입력 | ["이메일 인증","OTP 입력","인증 확인"] | 3 | modal | true |
| s_profile | f_signup | 프로필 입력 | ["정보 입력","추가 정보"] | 4 | form | true |
| s_done | f_signup | 완료 | ["가입 완료","환영"] | 6 | detail | false |
아래 JSON Schema 에 맞는 화면 표준 screen_master 24행 JSON 배열로 생성. 플로우 3~4개(가입·결제·검색·설정)의 단계를 담고, 같은 단계가 별칭 2~3개를 갖도록.
{"type":"object","properties":{"step_id":{"type":"string"},"flow_id":{"type":"string"},"canonical_name":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"step_no":{"type":"integer"},"component_type":{"enum":["form","list","detail","modal","nav","cta"]},"is_critical":{"type":"boolean"}},"required":["step_id","flow_id","canonical_name","aliases","step_no","component_type","is_critical"]}
조건: component_type 분포 자연스럽게, is_critical 은 입력·결제·인증 단계에 true. flow_events 의 step_id 와 매칭되도록(단, flow_events 에 일부러 넣은 orphan step_id=null 은 screen_master 에 일부러 없음). JSON 배열만.{"type":"object","properties":{"step_id":{"type":"string"},"flow_id":{"type":"string"},"canonical_name":{"type":"string"},"aliases":{"type":"array","items":{"type":"string"}},"step_no":{"type":"integer"},"component_type":{"enum":["form","list","detail","modal","nav","cta"]},"is_critical":{"type":"boolean"}},"required":["step_id","flow_id","canonical_name","aliases","step_no","component_type","is_critical"]}UX 디자이너 페르소나(LLM 시뮬 외부 검토자) 2명이 콘솔이 만든 개선 제안에 부여한 라벨입니다. 제안이 UI 상식에 맞는지(ui_valid)·상관을 인과로 비약했는지(causal_overclaim)를 담아, 두 사람 답이 얼마나 일치하는지(κ)의 입력이 됩니다.
| proposal_id | reviewer | agree | ui_valid | causal_overclaim | note |
|---|---|---|---|---|---|
| pp_verify_01 | ux_designer_p1 | true | true | false | SMS 자동입력·재발송 타이머는 표준 패턴 |
| pp_verify_01 | ux_designer_p2 | true | true | false | — |
| pp_verify_01 | self | true | true | false | — |
| pp_profile_02 | ux_designer_p1 | true | true | false | 인라인 검증 타당 |
| pp_profile_02 | ux_designer_p2 | false | true | false | 검증오류 표본 부족. 일반화 어려움 |
아래 JSON Schema 에 맞는 ux_review_labels 를 40 제안 × 검토자 3(p1/p2/self) = 120 행 JSON 배열로 생성.
{"type":"object","properties":{"proposal_id":{"type":"string"},"reviewer":{"enum":["ux_designer_p1","ux_designer_p2","self"]},"agree":{"type":"boolean"},"ui_valid":{"type":"boolean"},"causal_overclaim":{"type":"boolean"},"note":{"type":["string","null"]}},"required":["proposal_id","reviewer","agree","ui_valid","causal_overclaim"]}
조건: 검토자 간 agree 70% 내외, 불일치 시 note 에 UX 사유(표본 부족·디바이스 미고려 등), causal_overclaim=true 인 케이스 10% 내외(그때 note 에 인과 비약 사유), agree=true 면 note 는 null 또는 근거 한 줄. JSON 배열만.{"type":"object","properties":{"proposal_id":{"type":"string"},"reviewer":{"enum":["ux_designer_p1","ux_designer_p2","self"]},"agree":{"type":"boolean"},"ui_valid":{"type":"boolean"},"causal_overclaim":{"type":"boolean"},"note":{"type":["string","null"]}},"required":["proposal_id","reviewer","agree","ui_valid","causal_overclaim"]}| TypeScript | 이벤트 스키마·퍼널 계산·output_schema 런타임 검증까지 전 계층 타입 정의(primary language) |
| React | 진단 카드·개선 제안 카드·퍼널 시각화 컴포넌트 + before/after 개선 프로토타입 렌더 |
| Next.js | 콘솔 앱(App Router). 로그 업로드 → 퍼널 API 라우트 → 대시보드 스트리밍 렌더 |
| Vue | 개선 프로토타입을 Vue 로 재구현해 프레임워크 중립 컴포넌트 이식을 보여줌(JD 가 React·Vue 둘 다 요구) |
| REST API | 이벤트 적재·퍼널 조회·진단 생성 엔드포인트를 프론트에서 연동(로딩·에러·재시도 처리 포함) |
| 상태관리(Zustand/Pinia) | 기간·디바이스·플로우 필터와 진단 선택 상태를 프론트에서 관리 |
| Node.js/NestJS | 이벤트 ingest·퍼널 집계·진단 생성을 담는 경량 백엔드 API |
| 성능·접근성 계측 | LCP·rage-click·키보드 트랩·반응형 지표를 퍼널 단계에 결합(우대사항 구현 수단) |
| Git | 기획자·디자이너와 협업하는 코드 리뷰·문서화 이력 관리 |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우고 싶으면 2주차(Vue 이식·UX 검토·제안 검증)로 진행합니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우면 3주차(성능·접근성 축 결합, 두 번째 주기 보정)로 진행합니다.
한 플로우에 대해 1) 이탈이 큰 단계 진단 카드(해석·근거 지표·완곡 표현), 2) 그 단계의 UI/인터랙션 개선 제안 3건 + 예상 이탈 감소폭 + 확신도, 3) 지난 주기 제안이 다음 기간 실제 이탈률과 맞았는지 검증. 진단→제안→확인 한 주기를 한 스키마에 담습니다. 근거 지표(evidence_metrics)의 이름·값은 퍼널 엔진 계산값만 인용해야 하므로 자동 대조로 채점됩니다.
{"type":"object","properties":{"flow_id":{"type":"string"},"period":{"type":"string"},"diagnosis":{"type":"array","minItems":1,"maxItems":5,"items":{"type":"object","properties":{"finding_id":{"type":"string"},"step_id":{"type":"string"},"headline":{"type":"string","minLength":10},"interpretation":{"type":"string","minLength":20},"evidence_metrics":{"type":"array","minItems":1,"items":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":["number","string"]}},"required":["name","value"]}},"hedge":{"type":["string","null"]}},"required":["finding_id","step_id","headline","interpretation","evidence_metrics"]}},"proposals":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"object","properties":{"proposal_id":{"type":"string"},"target_step_id":{"type":"string"},"ui_change":{"type":"string","minLength":10},"rationale":{"type":"string","minLength":20},"predicted_drop_reduction_pp":{"type":"number"},"confidence":{"enum":["low","mid","high"]},"confidence_prob":{"type":"number"}},"required":["proposal_id","target_step_id","ui_change","rationale","predicted_drop_reduction_pp","confidence","confidence_prob"]}},"verification":{"type":["object","null"],"properties":{"prior_period":{"type":"string"},"hit_rate_within_tolerance":{"type":"number"},"brier_score":{"type":"number"},"hits":{"type":"array","items":{"type":"object","properties":{"target_step_id":{"type":"string"},"predicted_pp":{"type":"number"},"actual_pp":{"type":"number"},"within_tolerance":{"type":"boolean"},"confidence_prob":{"type":"number"},"actual_hit_binary":{"type":"number"}},"required":["target_step_id","predicted_pp","actual_pp","within_tolerance","confidence_prob","actual_hit_binary"]}}},"required":["prior_period","hit_rate_within_tolerance","brier_score","hits"]}},"required":["flow_id","period","diagnosis","proposals"]}[
{
"input_ref": "f_signup / 2026-03-16 ~ 2026-03-20 (1주차 첫 주기. verification 은 다음 주기부터)",
"output": {
"flow_id": "f_signup",
"period": "2026-03-16 ~ 2026-03-20",
"diagnosis": [
{
"finding_id": "fd_signup_01",
"step_id": "s_verify",
"headline": "가입 이탈 최대 지점: 인증번호 입력 모달",
"interpretation": "이 단계 진입 대비 이탈이 41%로 전체 단계 중 가장 큽니다. 100세션당 rage-click 12회, 중앙 로딩 3.8초가 함께 관찰됩니다.",
"evidence_metrics": [
{
"name": "drop_rate_pct",
"value": 41
},
{
"name": "rage_click_per_100",
"value": 12
},
{
"name": "median_load_ms",
"value": 3800
}
],
"hedge": "표본 5일. 인증 재발송 지연이 원인일 수 있어 A/B 교차 검증을 권합니다."
},
{
"finding_id": "fd_signup_02",
"step_id": "s_profile",
"headline": "프로필 폼에서 검증 오류가 반복됨",
"interpretation": "제출 대비 검증오류율이 27%이고, 휴대폰 형식 오류가 다수입니다. 오류 직후 이탈이 동행합니다.",
"evidence_metrics": [
{
"name": "validation_error_rate_pct",
"value": 27
},
{
"name": "step_drop_rate_pct",
"value": 19
}
],
"hedge": "필드별 오류 분해는 후속 작업입니다."
}
],
"proposals": [
{
"proposal_id": "pp_verify_01",
"target_step_id": "s_verify",
"ui_change": "인증번호 SMS 자동입력 + 재발송 타이머 노출 + 오류를 인라인 메시지로 표시",
"rationale": "rage-click 과 3.8초 로딩 대기가 이탈과 동행합니다. 대기 상태를 눈에 보이게 하면 이탈이 완화될 것으로 봅니다.",
"predicted_drop_reduction_pp": 12,
"confidence": "mid",
"confidence_prob": 0.6
},
{
"proposal_id": "pp_profile_02",
"target_step_id": "s_profile",
"ui_change": "휴대폰 번호 실시간 마스킹 + 제출 전 인라인 검증",
"rationale": "검증오류 27%가 재이탈을 유발합니다. 오류를 제출 전에 잡으면 이탈이 줄 것으로 봅니다.",
"predicted_drop_reduction_pp": 8,
"confidence": "mid",
"confidence_prob": 0.6
},
{
"proposal_id": "pp_email_03",
"target_step_id": "s_email",
"ui_change": "소셜 로그인 버튼을 이메일 입력 위로 우선 배치",
"rationale": "이메일 수기 입력 부담을 줄이는 대안 경로입니다. 다만 이 단계 이탈 신호는 약해 확신은 낮습니다.",
"predicted_drop_reduction_pp": 5,
"confidence": "low",
"confidence_prob": 0.4
}
],
"verification": null
}
},
{
"input_ref": "f_signup / 2026-03-23 ~ 2026-03-27 (두 번째 주기. verification 은 첫 주기 제안 결과)",
"output": {
"flow_id": "f_signup",
"period": "2026-03-23 ~ 2026-03-27",
"diagnosis": [
{
"finding_id": "fd_signup_03",
"step_id": "s_verify",
"headline": "인증 단계 이탈은 줄었으나 여전히 최대 지점",
"interpretation": "이 단계 이탈이 41%에서 31.5%로 내렸지만 아직 전체 중 가장 큽니다. rage-click 은 100세션당 12회에서 7회로 감소했습니다.",
"evidence_metrics": [
{
"name": "drop_rate_pct",
"value": 31.5
},
{
"name": "rage_click_per_100",
"value": 7
}
],
"hedge": "합성 기준 추정입니다. 실 계측에서는 감소폭이 달라질 수 있습니다."
}
],
"proposals": [
{
"proposal_id": "pp_verify_04",
"target_step_id": "s_verify",
"ui_change": "인증 실패 시 이메일 재입력 경로를 모달 안에서 바로 제공",
"rationale": "재발송 후에도 남는 이탈은 오입력 정정 경로 부재와 동행합니다. 정정 경로를 열면 추가 완화가 기대됩니다.",
"predicted_drop_reduction_pp": 6,
"confidence": "mid",
"confidence_prob": 0.6
},
{
"proposal_id": "pp_profile_05",
"target_step_id": "s_profile",
"ui_change": "선택 입력 필드를 접어서 필수 필드만 먼저 노출",
"rationale": "폼 길이가 이탈과 동행합니다. 필수만 먼저 보이면 완료율이 오를 것으로 봅니다.",
"predicted_drop_reduction_pp": 5,
"confidence": "mid",
"confidence_prob": 0.6
},
{
"proposal_id": "pp_landing_06",
"target_step_id": "s_landing",
"ui_change": "가입 소요 시간 안내 배지 추가(약 1분)",
"rationale": "시작 단계 기대 설정이 이후 이탈에 영향할 수 있습니다. 다만 근거 표본이 얕아 확신은 낮습니다.",
"predicted_drop_reduction_pp": 3,
"confidence": "low",
"confidence_prob": 0.4
}
],
"verification": {
"prior_period": "2026-03-16 ~ 2026-03-20 (첫 주기 제안)",
"hit_rate_within_tolerance": 0.67,
"brier_score": 0.19,
"hits": [
{
"target_step_id": "s_verify",
"predicted_pp": 12,
"actual_pp": 9.5,
"within_tolerance": true,
"confidence_prob": 0.6,
"actual_hit_binary": 1
},
{
"target_step_id": "s_profile",
"predicted_pp": 8,
"actual_pp": 3,
"within_tolerance": false,
"confidence_prob": 0.6,
"actual_hit_binary": 0
},
{
"target_step_id": "s_email",
"predicted_pp": 5,
"actual_pp": 4.2,
"within_tolerance": true,
"confidence_prob": 0.4,
"actual_hit_binary": 1
}
]
}
}
},
{
"input_ref": "f_checkout / 2026-03-16 ~ 2026-03-20 (결제 플로우 첫 주기)",
"output": {
"flow_id": "f_checkout",
"period": "2026-03-16 ~ 2026-03-20",
"diagnosis": [
{
"finding_id": "fd_checkout_01",
"step_id": "s_pay",
"headline": "결제 이탈 최대 지점: 결제 버튼 응답 지연",
"interpretation": "결제 단계 이탈이 48%로 가장 큽니다. 결제 버튼 클릭 후 중앙 로딩 5.3초, 100세션당 rage-click 15회가 함께 관찰됩니다.",
"evidence_metrics": [
{
"name": "drop_rate_pct",
"value": 48
},
{
"name": "median_load_ms",
"value": 5300
},
{
"name": "rage_click_per_100",
"value": 15
}
],
"hedge": "표본 5일. 결제사 응답 지연이 원인일 수 있어 구간 분해가 필요합니다."
}
],
"proposals": [
{
"proposal_id": "pp_pay_01",
"target_step_id": "s_pay",
"ui_change": "결제 버튼을 눌렀을 때 즉시 로딩 상태로 전환 + 중복 클릭 잠금 + 진행 표시",
"rationale": "5.3초 대기와 rage-click 이 이탈과 동행합니다. 진행 상태를 보여주면 재클릭·이탈이 줄 것으로 봅니다.",
"predicted_drop_reduction_pp": 14,
"confidence": "high",
"confidence_prob": 0.8
},
{
"proposal_id": "pp_pay_02",
"target_step_id": "s_pay",
"ui_change": "간편결제(토스·카카오페이) 버튼을 카드 입력 위로 우선 배치",
"rationale": "카드 수기 입력 부담이 이탈과 동행합니다. 간편결제 우선 노출로 완화가 기대됩니다.",
"predicted_drop_reduction_pp": 9,
"confidence": "mid",
"confidence_prob": 0.6
},
{
"proposal_id": "pp_address_03",
"target_step_id": "s_address",
"ui_change": "배송지 주소 자동완성 도입",
"rationale": "주소 입력 시간이 다음 단계 이탈로 이어질 수 있습니다. 다만 이 단계 자체 이탈은 낮아 확신은 낮습니다.",
"predicted_drop_reduction_pp": 4,
"confidence": "low",
"confidence_prob": 0.4
}
],
"verification": null
}
}
][자동 검증] 1. output_schema(JSON Schema) 형식 통과: 필수 필드·타입·개수(diagnosis 1~5, proposals 정확히 3)가 맞는지 파싱으로 거릅니다. 2. 근거 일치: diagnosis 의 step_id 가 퍼널 엔진이 규칙으로 정한 '가장 이탈 큰 단계'와 같은지, evidence_metrics 의 name·value 가 엔진 계산값과 일치하는지 대조합니다(값을 지어내면 실패). 3. 인과 단정 차단: '때문에·탓에·기인' 등 단정 토큰 매칭 + LLM-as-judge 로 우회 표현까지 검출합니다. 4. 검증 루프: verification 은 다음 기간 실제 이탈률로 자동 조인해 적중률·Brier score(확신도가 실제와 얼마나 맞았는지 0~1, 낮을수록 정확)를 계산합니다(첫 주기는 null). [수동 검증] 1. UX 디자이너 페르소나 2명이 제안 타당성(ui_valid)을 비동기 라벨링하고, 두 사람 답의 일치도(Cohen's κ: 우연 이상으로 얼마나 일치하는지 0~1)를 봅니다. 2. judge 결과의 5%를 사람이 표본 점검합니다.
근거: 사용자 피드백, 행동 데이터 등을 바탕으로 제품의 사용성을 개선합니다