아내를 위해 만든 앱 성장기

앱 성장기 시리즈 — 아내를 위해 만든 단식 앱 케톤의 격주 회고.

앱 성장기 시리즈 이전 글

에피 0에서 "다음 3개월 뒤에 다시 오겠다"고 써놓고 2주 만에 돌아왔습니다. 3개월은 너무 길더라고요. 그 사이에 까먹은 얘기가 쌓이고, 숫자 안 좋을 땐 조용히 넘어가고 싶은 마음도 생기고요. 그래서 시리즈 포맷을 격주로 바꿨습니다. 2주마다 숫자를 꺼내놓고 이야기하는 쪽이 저한테도 더 솔직해지는 것 같아서요.

오늘 꺼내는 숫자는 좀 섞여 있어요. 좋은 숫자, 나쁜 숫자, 그리고 재밌는 숫자가 한 장에 같이 있습니다. WAU가 2배가 됐고, 유입 국가가 9개국으로 넓어졌고, 러시아 유저에게 처음으로 별 다섯 개짜리 리뷰를 받았어요. 동시에 D7 잔존은 계단처럼 뚝 떨어졌고, 앱을 떠받치는 유저 수는 여전히 한 손으로 셀 수 있는 수준입니다. 오늘 글은 그 섞여 있는 상태에 대한 얘기입니다.

이번 2주의 숫자

먼저 3주치 추이부터 공개합니다. 에피 0을 쓰던 주(W14)가 왼쪽 끝이에요.

지표 W14 (에피 0) W15 W16
WAU 22 35 (+59%) 47 (+34%)
신규 설치 13 20 21
단식 완료자 (유니크) 3 8 9
단식 완료 (이벤트) 8 13 17
주간 리텐션 59% 74%

01-wau-3week-trend

WAU가 22에서 47로 두 배 조금 넘게 올랐습니다. 주간 리텐션도 59%에서 74%로 올랐고요. 여기까지만 보면 기분이 꽤 좋은 2주였어요. 밤에 대시보드를 켜고 이 표만 보면 “잘 돼가고 있네” 싶었습니다.

근데 숫자가 재밌는 건 여기부터예요. 같은 2주 동안 유저 구성 자체가 뒤집혔거든요.

지표 W14 W15 W16
해외 유저 비율 31% 55% 71%
유입 국가 수 3개 6개 9개

3주 전에는 열에 일곱이 한국 유저였어요. 지금은 반대로 뒤집혔습니다. 열에 일곱이 한국 바깥에서 들어온 분들이에요. 그것도 마케팅비 0원으로요. 국가 리스트를 훑어보다가 저도 좀 놀랐는데, 이번 주에 유입이 잡힌 나라가 한국, 러시아, 조지아, 독일, 헝가리, 일본, 벨라루스, 미국, 루마니아 이렇게 아홉 곳이더라고요. 3주 전에 한국 중심으로 돌아가던 작은 앱이 지금은 유럽 중동부 어딘가에서도 켜지고 있는 거예요.

체중 기록 쪽도 조용히 움직이고 있었어요. 체중을 기록한 유니크 유저가 9명에서 15명으로 67% 늘었고, 단식 시작할 때 체중을 같이 입력하는 fasting_start_weight 이벤트 채택이 2건에서 9건으로 네 배 반 정도 뛰었습니다. 모수가 작으니까 퍼센트가 과장되긴 하는데, 그래도 "타이머만 켜는 앱"에서 "몸 상태까지 남기는 앱"으로 조금씩 이동하고 있다는 신호로 읽혔어요.

배운 것 — 3주 동안 해외 유저가 한국 유저를 따라잡았고, D7이 그 대가로 내려앉았습니다

좋은 숫자가 붙어 있는 동안 제일 오래 들여다본 건 나쁜 숫자였습니다. 세 가지 신호가 있었어요.

신호 1 — D7 잔존이 계단처럼 내려앉았고, 범인이 누군지 감이 잡혔습니다

새로 들어온 분들이 일주일 뒤에도 남아있냐를 보는 D7 잔존이 3주 연속 빠지고 있었습니다. 그것도 부드럽게가 아니라 계단처럼요.

  • W14 cohort (13명): D7 잔존 38.5%
  • W15 cohort (20명): D7 잔존 30.0%
  • W16 cohort (21명): D7 잔존 4.8%

02-d7-3week-bars

21명 중에 D7까지 도달한 분이 딱 한 분이에요. -8.5%p, -25.2%p. 저도 이 숫자를 처음 봤을 때 눈을 한 번 비볐어요. 오타인가 싶어서 쿼리를 다시 돌렸거든요. 근데 맞았습니다.

WAU는 늘고 D7은 무너지는 게 한 장에 같이 있는 상태인데, 풀어서 말하면 이렇게 됩니다. WAU가 늘어난 건 새 유저가 계속 쌓여서가 아니라 기존에 쓰던 분들이 열심히 쓰고 있어서였어요. 새로 들어온 분들은 거의 다 일주일 안에 사라지는 중이었고요.

그럼 왜 빠지는가, 가설이 하나 떠올랐습니다. 위에서 말한 해외 유저 비율 뒤집힘이랑 이게 연결되거든요. 유입 국적이 넓어지는 속도랑 D7이 무너지는 속도가 거의 맞물려 있었어요. 특히 러시아어(ru-ru) 설정 유저들이 D1에서 나란히 이탈하는 패턴이 보였습니다. 같은 주간에 한국어, 일본어 설정 유저들은 그렇게까지 깔끔하게 빠지진 않았거든요. 유독 러시아어만 도장을 찍듯이요.

거기서 가설이 하나 더 나왔습니다. “번역 품질이 엉망인 거 아닐까?” 라는 쪽으로요. 케톤은 22개 언어를 지원하고 있는데, 솔직히 한국어 말고는 제가 한 글자도 못 읽거든요. 기계 번역에 많이 기대고 있었어요. 해외 유저가 적을 땐 이게 표면에 안 드러났는데, 3주 만에 해외 비중이 71%가 되니까 바로 올라온 거예요.

그래서 20개 언어를 전수로 다시 봤습니다. 러시아어에서 나온 게 꽤 재밌었는데, "단식"으로 번역한 단어가 정교회 사순절 쪽 종교 금식 어감이랑 섞여 있었어요. 건강 앱을 깔았더니 “사순절 시작” 같은 문구를 읽게 되는 상황이었던 거예요. 이 작업 과정은 따로 한 편으로 풀어놨습니다.

관련 글

4월 15일에 v1.1.1로 번역을 대폭 수정해서 배포했어요. 이 가설이 맞다면 W17 이후 D7 숫자가 다시 올라와야 합니다. 아직 모릅니다. 다음 에피에서 확인될 거예요. 틀렸으면 틀렸다고 그때 올리겠습니다.

신호 2 — 파워유저 세 분이 지표의 반 이상을 떠받치고 있어요

그래서 W16에 일어난 단식 완료 이벤트 17건을 누가 일으켰는지를 개별 ID로 뜯어봤습니다. 에피 0에서 7일 연속 OMAD 돌리던 파워유저 한 분 얘기를 했었죠. OMAD는 "One Meal A Day"의 줄임말인데요, 말 그대로 하루에 한 끼만 먹고 나머지 시간은 전부 단식으로 채우는 패턴입니다. 간헐적 단식 중에서도 꽤 빡빡한 축이에요. 지금은 그런 분이 세 명이에요. 각각 주 3회씩 단식을 완료하고 계십니다.

03-power-user-distortion

세 분이 W16 완료 이벤트의 절반 이상을 만들고 있어요. 단식 완료자가 3명에서 9명으로 늘었다고 위에서 썼는데, 이번 주에 "처음으로 단식을 완료한 신규 유저"는 한 명뿐입니다. 나머지 증가분은 전부 기존 파워유저들이 쌓아준 숫자였어요.

그런데 이 세 분을 하나씩 따로 놓고 보면 되게 재밌어요. 한 분은 단식도 하고 다이어리도 매일 쓰고 체중도 기록하는 올라운더 타입이시고, 또 한 분은 오직 단식 타이머만 씁니다. 다이어리는 한 번도 안 열어보셨어요. 마지막 한 분은 이번 주에 막 합류하신 분인데 첫 주부터 주 3회 페이스를 찍으셨어요. 같은 앱을 이렇게 다르게 쓰고 계신다는 건, 리텐션 경로가 꼭 하나가 아니어도 된다는 뜻이기도 합니다. 단식만 꽂혀도 남고, 전체 기록에 꽂혀도 남는다는 거예요.

그런데 좋은 쪽을 다 적고 나서도 남는 불안이 있어요. 세 분 중에 한 분이 다음 주에 바쁘시거나 마음이 식어서 일주일 쉬시면, 제 지표 전체가 -40% 찍힐 수 있다는 거예요. 에피 0에서 "유저 한 명 한 명의 행동을 볼 수 있다"고 썼는데, 그 말을 뒤집으면 "한 명이 빠져도 숫자가 흔들린다"는 뜻이 되거든요. 작은 앱의 장점과 단점이 여기서 맞붙어 있습니다.

신호 3 — 9개국에서 설치가 들어온 주였고, 러시아 유저에게 첫 5성 리뷰를 받았습니다

마케팅 비용 0원짜리 앱이 3주 사이에 한국 중심에서 9개국으로 넓어진 건, 앉아서 보면 꽤 신기한 일이에요. 조지아랑 벨라루스에서 설치가 들어왔다는 걸 처음 봤을 때 지도를 펴서 두 나라 위치를 찾아봤습니다. 이런 나라에서 어떻게 케톤을 발견하셨는지는 저도 모릅니다. 그냥 플레이스토어 검색 알고리즘이 어느 날 이 앱을 저 동네까지 밀어준 거겠죠.

06-nine-countries-map

위에서 말한 v1.1.1 번역 업데이트가 4월 15일 저녁에 나갔는데요. 이틀 뒤인 4월 17일에 스토어에 리뷰가 하나 달렸어요. 별 다섯 개에, 제가 한 글자도 못 읽는 러시아어로 긴 문장이 적혀 있었습니다. 번역기로 돌려보니까 “쾌적하고 사용자 친화적인 인터페이스에 멋지고 무료이며 미니멀한 기능을 갖춘 훌륭한 앱을 만들어주셔서 감사합니다” 라는 뜻이더라고요.

v1.1.1 덕분이라고 증명할 방법은 없습니다. 타이밍이 우연일 수도 있어요. 다만 2주 전만 해도 러시아 유저들이 깔끔하게 D1에 빠지고 있었는데, 번역 고쳐서 배포하고 이틀 뒤에 러시아 유저한테서 첫 5성 리뷰가 온다는 게 말이 안 되게 극적이긴 했어요. 인디 개발자한테 리뷰 하나가 주는 동력은 이게 꽤 큽니다. 그 날 밤에 그 리뷰를 한 번 더 번역기로 돌려서 읽었어요. 답글도 번역기로 한국어를 러시아어로 돌려서 적었습니다. 러시아 유저분과 저의 첫 대화가 이렇게 양쪽 다 기계 번역으로 일어났어요.

지난 2주 동안 한 것 — 혼자 하는 앱에 "함께"를 조금 섞는 중입니다

세 가지 신호를 다 종합해보면, 결국 밑바닥에 깔린 문제는 첫 주에 앱을 다시 열 이유가 약하다는 거였어요. 파워유저들은 이미 그 이유를 찾은 분들이고, 신규 유저 대부분은 못 찾고 나가는 상황입니다. 그래서 이번 2주 동안 가장 공 들여 만든 게 커뮤니티 탭이에요. 아직 릴리즈 전이고, 다음 2주 안에 공개를 목표로 마무리 중입니다.

왜 커뮤니티냐면, 간헐적 단식이 솔직히 외로운 일이거든요. 저녁 8시에 가족들은 밥 먹고 있는데 나 혼자 물 마시면서 타이머 보고 있는 상황, 이거 한 번만 해보시면 무슨 얘기인지 바로 오실 거예요. 앱으로 숫자는 다 기록되는데 버티는 그 몇 시간이 너무 조용합니다. 그 조용함을 아주 살짝만 깨주는 뭔가가 있으면 내일 다시 타이머를 켜는 이유가 하나 생기지 않을까 싶었어요.

그래서 지금 준비 중인 건 이런 구조예요.

  • 단식 중일 때만 익명 닉네임([형용사][동물][2자리] 형태, 예: 조용한판다42)이 커뮤니티 탭에 잠깐 뜹니다
  • 다른 분이 지금 단식 중인 목록이 거기 보이고, 프리셋 이모지 응원을 하루 1회씩 보낼 수 있어요 (박수, 근육, 불 같은 것들)
  • 단식을 끝까지 완료하거나 지방 연소 단계에 진입하면 뽑기권이 생기고, 카드 뒤집기 애니메이션으로 작은 보상이 열립니다
  • opt-out 가능하고, Remote Config로 언제든 끌 수 있게 설계했습니다
05-community-tab-teaser

아직 릴리즈 전이라 최종 모습은 조금 바뀔 수 있는데, 지금 개발 중인 화면은 대충 이런 느낌입니다.

프라이버시 걱정되실까봐 짧게 덧붙이면, 공개되는 정보는 무작위 생성된 익명 닉네임이랑 "지금 단식 중"이라는 상태뿐이에요. 프로필도 없고, 팔로우도 없고, 대화도 없습니다. 단식이 끝나면 닉네임도 목록에서 빠져요. 단식이라는 특정 순간에만 아주 얇게 연결되고, 끝나면 다시 조용해지는 구조입니다.

설계하면서 가장 오래 고민한 건 "얼마나 얇게 연결할 것인가"였어요. 응원을 자유 메시지로 받으면 금방 지저분해질 수 있고, 닉네임이 고정이면 익명성이 깨지고, 알림이 많으면 귀찮아지고요. 그래서 사전 정의된 이모지 3종, 하루 1회 제한, 단식 중에만 공개, 이 세 가지 제약을 기본값으로 뒀습니다. 아내가 시안을 먼저 보고 "이 정도면 안 거슬리겠다"고 하더라고요. 이 앱은 아내의 사용감이 기준이거든요.

이게 D7 잔존을 올려줄까요? 아직 모릅니다. 가설은 "첫 주에 한 번이라도 응원을 주고받은 분은 D7까지 살아남을 확률이 높을 것"이에요. 릴리즈 전이니까 당연히 숫자도 없고요. 다음 에피에서 실제 유저 반응으로 얘기할 수 있을지 봐야겠습니다.

커뮤니티 탭 옆으로 조용히 같이 들어간 것들도 몇 개 있어요. 하나씩 다 풀면 이 글이 너무 길어질 것 같아서 제목만 짧게 적어둘게요. 각각은 나중에 따로 글로 풀어볼 생각입니다.

  • "이야기 들려주세요" — 더보기 탭에 유저가 한 줄 피드백을 바로 보낼 수 있는 카드를 달았어요. 러시아어 사건에서 배운 게 "유저한테 직접 물어볼 줄 아는 앱을 만들어야 한다"였거든요. 그 창구를 드디어 열었습니다.
  • 단식 타이머 공유 넛지 — 타이머 화면을 이미지로 내보내는 기능은 원래 있었는데, 단식 중 적절한 시점에 “다른 분께도 보여드려 볼까요?” 하고 가볍게 유도하는 넛지를 얹었습니다. 바이럴 루프를 만들어보려는 작은 실험이에요.
  • 주간 인사이트 공유 힌트 — 기록 탭 주간 요약 쪽에도 비슷한 방향으로, 한 주치 단식 패턴을 공유할 수 있다는 걸 넌지시 알려주는 힌트를 넣었습니다.

다음 2주 목표

딱 두 개만 정했습니다.

첫째, 준비 중인 커뮤니티 탭을 실제로 릴리즈하고, 효과를 측정할 수 있는 상태로 내보내는 것. 지금은 "커뮤니티 탭을 본 유저"와 "안 본 유저"의 D7을 따로 뽑을 수 있는 이벤트가 아직 안 깔려 있어요. 이벤트 스키마를 같이 손봐서, 첫 주에 응원을 주고받은 유저의 D7 cohort를 따로 볼 수 있게 할 겁니다.

둘째, 단식 결과 화면에서 다음 날 다시 들어오고 싶어지는 작은 CTA 실험. 첫 단식을 끝낸 분한테 “내일 다시 오면 이게 보입니다” 같은 연결고리를 하나 만들어보려고 합니다.

다음 에피는 2주 뒤 이맘때입니다. 숫자가 나빠져도 올립니다. 에피 0 끝에서 "다음에는 더 나은 숫자로 오겠다"고 썼는데, 생각해보니 그 약속이 좀 이상했어요. 더 나은 숫자가 안 나오면 침묵하겠다는 뜻이 되거든요. 그래서 오늘부터는 약속을 바꿉니다. 나쁜 숫자도 같이 올립니다. 그게 Build in Public 맞는 것 같아요.

오늘 글 끝까지 읽어주셔서 감사합니다. 간헐적 단식 기록을 조용히 남기고 싶으신 분이 있다면, 플레이스토어에서 “케톤” 검색해보세요. 조만간 단식 중에 박수 한 번 받을 수 있는 업데이트도 준비하고 있습니다.

👉 케톤 — Play Store에서 보기

러시아 유저에게 긍정 리뷰 하나를 받기까지

며칠 전에 스토어에서 리뷰 하나를 발견했습니다. 별 5개에, 제가 한 글자도 못 읽는 언어로 긴 칭찬이 달려 있었어요.

01-russian-review

언어 설정이 ru-ru인, 러시아 분으로 추정되는 유저였습니다. 해석기를 돌려봤더니 “쾌적하고 사용자 친화적인 인터페이스와 멋지고 무료이며 미니멀한 기능을 갖춘 훌륭한 앱을 만들어주셔서 정말 감사합니다” 라는 뜻이더라고요.

이 리뷰 하나를 받기까지 대략 한 달 정도가 걸렸습니다. 그리고 그 한 달 동안 저는 러시아어를 한 글자도 더 배우지 않았어요. 대신 좀 많이 오만했다는 걸 배웠고, 앞으로는 유저한테 직접 물어볼 줄 아는 앱을 만들어야겠다는 생각을 하게 됐습니다. 오늘 풀어놓을 이야기는 그 한 달입니다.

발단 — ru-ru 유저들이 연속으로 사라졌어요

W15, W16 주간 analytics 리포트를 보다가 눈에 걸리는 줄이 하나 있었어요. 러시아어 설정 유저들이 연달아 D1에서 이탈했다는 내용이었습니다. 설치 다음날 돌아오지 않은 거예요.

모수가 작은 편이라 통계적으로 유의하다고 말하긴 어려웠습니다. 처음엔 그냥 넘기려 했어요. “우연이겠지” 하고요. 근데 다음날 아침에 커피 마시면서 다시 보니까, 우연치고는 너무 깔끔하더라고요. 같은 주간에 영어나 한국어, 일본어 설정 유저들은 그렇게까지 나란히 빠지진 않았거든요. 유독 러시아어만 깔끔하게 이탈하고 있었습니다.

그래서 한 가지 가설이 머릿속에 떠올랐습니다.

설마, 번역 품질이 엉망인 거 아닐까?

오만한 믿음 — “스킬이 있으니까 괜찮겠지”

이 가설이 불편했던 이유는, 케톤에는 이미 /localize 라는 자체 스킬이 있었기 때문입니다. 새 문자열을 추가하면 22개 언어로 자동 번역해주고, 길이 초과 체크하고, format specifier 정합성까지 맞춰주는 도구였어요. 저는 이 스킬을 꽤 신뢰하고 있었습니다. 스킬 문서에도 "quality gates"라고 적어뒀거든요.

그래서 처음 든 생각은 이거였어요. “러시아어 번역이 이상하면 이미 스킬이 걸러냈을 텐데?”

근데 생각해보면 이게 얼마나 오만한 믿음이었는지 조금만 더 들여다보면 바로 보입니다. 제가 러시아어를 한 글자도 못 읽거든요. 폴란드어도, 힌디어도, 우르두어도요. 검증하는 주체인 저 자신이 결과를 읽을 수 없는데 “스킬이 검증해줄 거야” 라고 믿고 있었던 거예요. 이건 신뢰가 아니라 그냥 외면이었습니다.

한번 확인해보자, 싶어서 검수를 돌려보기로 했습니다.

조사 — 에이전트 23명으로 20개 언어 전수 검수

혼자서는 못 합니다. 저는 러시아어 Б도 못 읽으니까요.

그래서 AI 에이전트를 동원했습니다. 언어별로 네이티브 페르소나를 하나씩 세워서 총 19개 페르소나를 만들었어요. 예를 들면 “파리에 사는 30대 여성, Yuka와 Petit BamBou 같은 건강앱을 일상적으로 쓰는 사람” — 이 페르소나가 프랑스어 strings.xml을 한 줄씩 읽어내려가면서 “이건 어색해요”, “이 문장은 Sie와 Du가 섞여 있어요” 같은 리뷰를 남기는 식이었습니다. 거기에 Play Store 마케팅 카피까지 검수하는 에이전트 3명을 더 붙여서 총 23명.

검수 범위는 app/src/main/res/values-*/strings.xml 20개 + fastlane/metadata/android/*/ Play Store 카피 전수였습니다. 이게 몇 시간이 걸리더라고요. 에이전트들이 병렬로 돌아가는데도, 결과를 취합해서 HTML 리포트로 뽑고 다시 읽고 정리하는 시간까지 하면 하루를 통째로 썼습니다.

02-agent-library

그리고 결과가 나왔는데, 솔직히 좀 충격이었어요.

발견 — 한두 곳이 아니었습니다

결과를 요약하면 20개 언어 전부에서 크고 작은 이슈가 나왔습니다. 의학 효능 주장이 원문에 없는데 번역본에 추가돼 있다든지, 브랜드명 "Ketone"이 언어마다 Keton, Cetona, Chetone, ケトン 식으로 제각각 현지화돼 있다든지, 숫자 체계가 한 화면 안에서 데바나가리랑 라틴이 섞여 있다든지… 카탈로그로 정리해보니 언어를 넘나들며 반복되는 패턴이 10가지 정도였어요.

발단이 ru-ru 이탈이었으니 러시아어에서 특히 눈에 띈 것 몇 개만 짧게 짚어보겠습니다.

러시아어에는 "금식/단식"에 해당하는 단어가 크게 두 가지가 있다고 합니다. 하나는 정교회 사순절 같은 종교적 금식, 하나는 건강 목적의 세속 단식이요. 케톤은 세속 건강 앱인데 번역본에는 종교 단어가 여기저기 섞여 있었어요. 러시아 네이티브 페르소나의 리뷰를 읽다가 이런 말을 봤습니다. “건강앱을 켰는데 ‘사순절 시작’ 이라고 적혀 있으면 종교 앱인가 싶을 거예요.” 제가 만든 건 간헐적 단식 타이머인데 러시아 유저는 절반쯤 종교 앱 느낌으로 읽고 있었던 거예요.

그 외에도 러시아어는 굴절 언어라서 과거분사에 성별이 들어간다고 하더라고요. "나는 했다"가 남성형 기본값으로 쫙 깔려 있어서 여성 유저 입장에서는 자기 얘기처럼 안 읽히는 구조였고요. 반말과 존대가 한 앱 안에서 왔다갔다 하는 톤 혼용도 있었습니다. 정책 하나만 먼저 정해뒀어도 막을 수 있던 건데, 그 정책이 없었던 거예요.

실행 — 스킬을 다시 짰습니다

여기서 솔직히 고민이 들었어요. 러시아어만 고치고 끝낼 것인가, 아니면 이 10개 패턴이 앞으로 새 번역에 또 들어가지 않도록 구조적으로 막을 것인가.

후자를 택했습니다. 어차피 다음 번역에도 같은 함정이 반복될 거니까요.

세 가지를 손봤어요.

첫째, 용어집을 대폭 확장했습니다. 원래 .claude/glossary.md 에는 “케토시스는 ketosis로 번역” 같은 의학 용어 9개만 있었어요. 이걸 7개 정책으로 재구성해서, 브랜드명 보호·의학 주장 hedge·종교 단식 용어·톤 일관성·성별 중립·숫자 체계·중복 번역 금지까지 언어별 매트릭스로 담았습니다. 위에서 얘기한 러시아어 이슈들이 여기에 다 들어갔어요.

둘째, /localize 스킬에 Semantic QA 단계를 끼워넣었습니다. 기존 스킬은 "기계적 품질"만 체크했거든요. 길이 초과, format specifier, 중복 키 같은 거요. 여기에 “의미적 품질” 체크를 추가했습니다. 브랜드명이 현지화됐는지, 원문에 없는 의학 주장이 들어갔는지, 남성형 과거분사가 강제되는지 같은 걸 정규식과 에이전트 리뷰로 잡아내는 거예요.

/localize 파이프라인은 이런 흐름이 됐습니다.

04-localize-pipeline

주황색 부분이 이번에 새로 추가된 단계예요. 나머지는 원래 있던 것들인데 순서랑 범위를 다시 짰습니다.

셋째, /localize-audit 이라는 새 스킬을 하나 더 만들었습니다. 기존 /localize 는 “새 문자열을 번역할 때” 쓰는 증분 도구였어요. 근데 이번에 필요했던 건 “이미 있는 번역을 전수 검수” 하는 역방향 도구였거든요. 그래서 이번에 수동으로 한 작업을 그대로 스킬로 박제했습니다. 다음에 비슷한 의심이 들면 명령어 한 줄로 돌릴 수 있게요.

여기까지 쓰고 나서 v1.1.1 배포를 시도했습니다. 그리고 바로 Play Store API가 거부하더라고요. "폴란드어 제목이 30자 한도를 넘었다"고요. 검수 과정에서 폴란드어 Play Store 제목을 좀 더 자연스럽게 고치다가 속격 굴절 때문에 단어 길이가 늘어나버린 거예요. Semantic QA 끝나고 나서 길이 재검증을 안 한 탓입니다. 이 사고는 또 다른 교훈이었습니다 — “길이는 예전에 통과했으니까 안전” 이라는 가정이 얼마나 위험한지. 결국 “Ketone: Post Przerywany IF” (26자)로 줄여서 재배포했고, v1.1.1은 그렇게 세상에 나갔습니다.

보상 — 2일 뒤의 그 리뷰

v1.1.1 배포가 4월 15일 저녁이었어요. 그 리뷰가 도착한 게 4월 17일이었습니다. 딱 이틀 뒤요.

01-russian-review

솔직히 말씀드리면, 이 리뷰와 v1.1.1 업데이트의 인과관계를 증명할 방법은 없습니다. 우연의 일치일 수도 있어요. 이 유저분이 пост vs голодание 이슈를 눈치채고 달라진 걸 체감해서 리뷰를 남긴 건지, 아니면 그냥 어느 날 앱이 마음에 들어서 별점을 준 건지, 저는 모릅니다. 앞으로도 알 길이 없을 거예요.

다만 타이밍이 좀 극적이긴 했어요. 한 달 동안 ru-ru 이탈 6명 붙잡고 씨름하다가, 번역 고쳐서 배포하고, 이틀 뒤에 러시아 유저한테서 첫 5성 리뷰가 온다는 게 말이에요.

답장을 남겨야 하는데 저는 러시아어를 못하잖아요. 그래서 번역기를 띄우고 한국어로 “이 앱을 계속 써주셔서 정말 감사합니다. 앞으로도 잘 부탁드립니다” 같은 말을 적어서 러시아어로 돌렸어요. 돌린 문장을 다시 한국어로 역번역해서 이상하지 않은지 확인한 다음 답글을 달았습니다. 제가 러시아 유저와 나눈 첫 번째 대화입니다. 둘 다 기계 번역으로 대화한 거지만요.

근데 — 왜 러시아어를 지원하냐고요?

이 지점에서 한 번 솔직하게 말씀드리고 싶은 게 있습니다.

러시아어를 한 글자도 못 읽는 제가 왜 러시아어를 지원하고 있을까요? 아랍어도요. 힌디어, 우르두어, 벵골어, 태국어, 베트남어도 마찬가지예요. 1인 개발자가 22개 언어를 깔아두는 게 무리수라는 건 저도 압니다. 이번 같은 사건이 일어날 수밖에 없는 구조거든요.

근데 저는 인디 개발자니까요. 한국어랑 영어만 지원하면 타겟 시장이 좁아도 너무 좁아요. 반대로 22개 언어를 깔아두면 이론적으로는 세계 어디서든 접속해서 쓸 수 있는 앱이 됩니다. 마케팅 비용 0원짜리 앱한테는 이 "어디서든 쓸 수 있다"는 게 꽤 중요한 레버예요. 지난 주에 첫 유입이 생긴 국가가 몇 개 더 늘었거든요.

05-app-going-global

완벽하지 않은 걸 압니다. 아직 제가 못 읽는 언어의 번역본에 어떤 이슈가 남아있는지 다 모릅니다. 이번에 10개 패턴을 잡았지만 11번째 패턴이 또 있을 거예요. 그래도 AI 에이전트라는 도구가 손에 쥐어진 이상, 주어진 도구를 끝까지 써서 할 수 있는 데까지는 해보자는 쪽입니다. 23명 페르소나 세워서 검수 돌리고, 결과 보고 스킬 업그레이드하고, 다시 배포하고. 이번에 한 게 그 과정이었어요.

배운 것 — 데이터만 보면 추측밖에 못 합니다

이번 사건에서 진짜로 배운 건 따로 있습니다.

ru-ru D1 이탈 6명이라는 데이터는 "뭔가 문제가 있다"까지는 알려줬어요. 하지만 “왜” 는 끝내 알려주지 않았습니다. 제가 번역 품질을 의심한 건 데이터가 알려준 답이 아니라 저의 추측이었어요. 맞았을 수도 있고, 틀렸을 수도 있습니다. Бегун=Бегун 중복을 본 979fbfe8 유저가 진짜로 그 화면 때문에 나갔는지, 아니면 그냥 잊어버린 건지, 지금도 모르거든요.

데이터만 보고 “아마 이것 때문일 거야” 라고 추측해서 한 달 동안 에이전트 23명 동원하고 스킬 세 개 고치는 건 좀 가성비가 떨어집니다. 추측이 틀렸으면 이 한 달은 그냥 헛수고였을 거예요. 러시아 유저한테 “혹시 번역이 이상한가요?” 라고 한 번만 물어볼 수 있었다면, 하루 만에 답이 왔을 텐데 말이죠.

그래서 다음에 배포할 기능이 이거입니다.

다음 배포 — 유저한테 직접 물어볼 수 있는 채널

다음 버전에서 더보기 화면 상단에 “당신의 한마디가 필요해요” 라는 카드를 하나 추가하려고 합니다. 탭하면 모달이 올라오고, 자유 입력 텍스트 필드와 선택 이메일, 그리고 번역·버그·제안·칭찬 네 가지 카테고리 칩이 뜨는 간단한 폼이에요. 제출하면 Firestore의 feedback 컬렉션에 그대로 쌓입니다.

로그인 없어도 되고, 이메일도 선택 입력이에요. 그냥 유저가 "이 번역 이상해요"라고 한 문장 툭 던지고 앱으로 돌아갈 수 있으면 됩니다. 제가 Firebase 콘솔에서 읽고, 번역기로 번역해서, 필요하면 답을 남기는 식으로 운영할 생각이에요.

06-feedback-entry

07-feedback-modal

이게 있었으면 이번 한 달 중 적어도 절반은 아꼈을 거라고 생각합니다. 러시아 유저 중 한 명이라도 “이거 종교 앱 같은데요?” 라고 한 줄만 남겨줬으면 제가 거기서부터 팠을 거예요. 데이터만 보고 추측하는 대신요. 그리고 네이티브 스피커가 번역 오류를 지적해주기 시작하면, 기계 QA로는 절대 못 잡는 차원의 품질 개선이 열릴 거라고 봅니다. 어떤 문장이 "문법은 맞는데 어색하다"인지, 어떤 단어가 "직역은 맞는데 실제로 안 쓴다"인지는 결국 그 언어를 모국어로 쓰는 사람만 알거든요.

마치며

한 달 동안 있었던 일을 정리하고 나니 이런 느낌입니다. 한 명의 러시아 유저에게 긍정 리뷰 하나를 받기까지 에이전트 23명이 동원됐고, 스킬 세 개가 갈아엎어졌고, 배포가 한 번 거부당했고, 용어집이 아홉 배쯤 커졌습니다. 효율로 따지면 말이 안 되지만, 인디 개발자한테는 리뷰 하나가 꽤 큰 동력이 됩니다. 그래서 이만큼 한 걸 후회하진 않아요.

다음번에는 추측하지 않는 방법을 만들어둘게요. 유저가 직접 말해줄 수 있는 창을 하나 열어두는 것. 그게 이번 사건에서 제가 얻은 가장 실용적인 교훈이었습니다.

러시아 유저분, 다시 한 번 감사합니다. 답글 러시아어는 번역기가 도와줬지만 마음은 진짜였어요.

👉 케톤 — Play Store에서 보기