Notice
Recent Posts
Recent Comments
Link
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

Pause & Play

[MS AI School 최종 프로젝트] 하루 만에 DB 비용 10만 원이 청구됐다 — AI 회화 서비스 SimSpeak 개발기 (1/2) 본문

MS ai School

[MS AI School 최종 프로젝트] 하루 만에 DB 비용 10만 원이 청구됐다 — AI 회화 서비스 SimSpeak 개발기 (1/2)

eun_ll 2026. 7. 7. 02:30

React Native + Spring Boot + FastAPI 3-Tier로 설계한 AI 연애 시뮬레이션 영어 회화 서비스. 1편에서는 문제 정의와 전략적 팀 빌딩, 시스템 아키텍처, 그리고 관리형 MySQL에서 서버리스 PostgreSQL로 전환하게 된 비용 사고를 다룬다.

시리즈 1편 — 설계 편 (현재 글): 배경 · 팀 빌딩 · 아키텍처 · 인프라 비용 최적화
[2편 — 성능 편]: AI 응답 14초 → 1.5초, N+1 제거 p95 4.12초 → 1.99초, 신뢰성 설계


프로젝트 개요

서비스 SimSpeak — AI 연애 시뮬레이션 포맷의 영어 회화 학습 앱 (음성 대화 + 발음 진단 + 문법 교정 + 오답노트)
기간 2026.05.21 ~ 2026.06.25 (약 5주, 9개 마일스톤)
팀 구성 7명 (AI 3 / Backend 1 / Frontend·디자인 3) — 본인: Backend 리드 + 앱 디자인 + AI 보조
스택 React Native(Expo, Zustand) · Spring Boot(Security, WebClient) · FastAPI · Azure OpenAI(GPT-4o/4o-mini, Whisper) · Azure Speech · ElevenLabs · Neon PostgreSQL · Azure Blob Storage · Docker · Railway · k6 · App Insights

 

이 글(1편)의 핵심

  • 유지율 1.76% 시장에서 '채점' 대신 '호감도'를 선택한 문제 정의
  • FE 3 / AI 3 / BE 1 — 비대칭 팀 빌딩의 전략적 근거
  • 게이트웨이(Spring)와 오케스트레이터(FastAPI)를 분리한 4계층 아키텍처
  • DB 고정 비용 일 ~10만 원 → 사실상 0원 (서버리스 전환)

1. 프로젝트 배경: 교육 앱에서 7일 안에 98%가 떠나는 이유

외국어 학습 앱 시장은 공급 과잉이지만, 출시 후 7일 내 초기 유지율은 1.76% 수준에 불과하다(모바일 앱 리텐션 리서치 기준). 원인을 기존 서비스의 인터랙션 모델에서 찾았다.

기존 교육 앱의 이탈 루프
유저를 '학생' 취급 ──> 틀리면 빨간 줄·정색 ──> 대화 흐름 단절 ──> 앱 삭제

 

SimSpeak은 이 구조를 뒤집었다. 채점하는 선생님 대신 매력적인 AI 페르소나를 전면에 배치하고, 유저가 고급 표현을 쓸수록 캐릭터의 호감도가 오르고 더 달달한 답변·음성이 돌아오는 도파민 기반 보상 루프를 설계했다.

게이미피케이션의 효과는 데이터로도 뒷받침된다 — 게임화 결합 학습은 일반 학습 대비 코스 완료율 18% → 72%, 30일 지식 유지율 23% → 68%, 주 평균 체류 시간도 15.6시간 → 25.3시간으로 60% 이상 증가하는 것으로 조사됐다.

교정과 채점은 사라진 것이 아니라 백그라운드 파이프라인으로 숨겼다(2편에서 투트랙 아키텍처를 자세히 설명할 예정이다). 핵심 차별점은 LLM의 문맥 이해력을 교육 피드백에 직결시킨 것이다. 단순 키워드 매칭으로는 "notebook"이 '공책'인지 콩글리시 '노트북(laptop)'인지 판별할 수 없다. LLM이 문맥을 판별해 오용 시에만 유쾌하게 받아치며 호감도 페널티(-1)와 오답노트 적재를 수행한다.


2. 전략적 팀 빌딩:

7명을 통상적인 균등 배분 대신 FE·디자인 3 / AI 3 / BE 1로 배치했다. 근거는 서비스의 가치 사슬 분석이다.

Frontend + 캐릭터 디자인 3 React Native 하이브리드 앱은 인터랙션 퀄리티가 낮으면 '양산형 웹뷰 앱'으로 전락. 첫 화면부터 캐릭터 몰입을 만들어야 하는 서비스 특성상 비주얼·애니메이션 전담 인력 필수
AI 3 페르소나 일관성, 멀티턴 대화 기억, 흐름을 끊지 않는 정밀 피드백(문법·발음·콩글리시) — 세 가지 고난도 과제의 병렬 해결
Backend 1 인증·세션·영속화는 표준 패턴으로 압축 가능. 단, 초기에 데이터 계약(Contract)과 아키텍처를 완벽히 고정해야 한다는 전제가 붙음

백엔드를 1명으로 한 이유

백엔드 1인 체제의 리스크를 상쇄하기 위해 1주차에 ERD와 API 명세를 선행 확정하여, 이후 3개 파트가 계약 기반으로 독립 개발할 수 있는 구조를 만들었다. 데이터 계약의 구체적인 설계(ENUM 체계, turn_id 지연 결합, JSONB 캐시)는 2편에서 상세히 다룬다.

화면 플로우와 와이어프레임을 바탕으로 초기에 erd를 작성했다.

3. 시스템 아키텍처 개요

전체 시스템은 역할이 명확히 분리된 4계층으로 구성했다. Spring Boot는 인증·라우팅만 담당하는 얇은 게이트웨이로, FastAPI는 AI 호출·조립을 전담하는 오케스트레이터로 역할을 고정하여 장애 격리와 독립 배포를 확보했다.

주요 api만 정리하여 올린다.

 

 

백엔드가 노출하는 대화 관련 API 계약은 1주차에 다음과 같이 고정했다.

POST /api/chat/sessions 세션 생성 · 초기 대화 수신
POST /api/chat/message 유저 메시지 전송 및 즉시 응답
POST /api/chat/callback AI 비동기 평가 결과 콜백 수신
GET /api/chat/sessions/{session_id}/logs 메시지 히스토리 조회
GET /api/chat/sessions/active 이어하기 세션 조회

 

/message와 /callback이 분리된 이유 — 즉, 왜 하나의 요청을 두 개의 응답 경로로 쪼갰는지 — 가 이 프로젝트 성능 개선의 핵심인데, 이는 2편의 투트랙 아키텍처에서 다룬다.


4. [Trouble Shooting] 인프라 및 비용 최적화 — 관리형 MySQL에서 서버리스 PostgreSQL로

Problem

초기 백엔드 DB로 Azure Database for MySQL(Flexible Server)을 프로비저닝했다. 데이터 세팅 완료 후 24시간 만에 약 10만 원의 비용이 청구되었다.

원인 분석

  • Flexible Server 생성 시 컴퓨팅 계층(Compute Tier)을 기본값으로 두고 생성한 것이 직접 원인. 프로토타입 워크로드에 상시 가동형 고사양 인스턴스가 할당되어 있었다.
  • 근본 문제는 과금 모델과 트래픽 패턴의 불일치. 개발 단계 트래픽은 간헐적(bursty)인데, 상시 가동형 관리형 DB는 유휴 시간에도 고정 비용이 발생한다.

💡 교훈: 클라우드 관리형 DB 프로비저닝 시 기본값을 신뢰하지 말 것. 컴퓨팅 계층과 과금 모델을 워크로드 패턴에 맞춰 명시적으로 선택해야 한다.

Solution: 요구사항 기반 DB 재선정

비용 사고를 계기로 DB 요구사항을 처음부터 재정의했다.

대화 로그·AI 교정 데이터 등 스키마 가변성이 높은 데이터 적재 PostgreSQL JSONB — 인덱싱 가능한 반정형 저장
개발/데모 단계의 간헐적 트래픽 쿼리 발생 시에만 컴퓨팅을 사용하는 서버리스 과금 모델
1인 백엔드 체제에서 배포 오버헤드 최소화 GitHub 연동 즉시 빌드·배포되는 PaaS

 

최종 선택: Neon DB (Serverless PostgreSQL) + Docker + Railway

[Before]  Azure MySQL Flexible Server (상시 가동)
          └─> 유휴 시간에도 과금 ──> 일 ~10만 원

[After]   Neon Serverless PostgreSQL + GitHub ─> Docker ─> Railway 자동 배포
          └─> 쿼리 시에만 컴퓨팅 과금 ──> 고정 비용 사실상 0원
              + JSONB로 반정형 데이터 네이티브 지원

 

다만 이 선택에는 복선이 하나 깔려 있었다. 원격 서버리스 DB는 쿼리 1개당 네트워크 왕복(RTT) 비용이 로컬 DB보다 훨씬 크다. 이 특성이 이후 N+1 쿼리 문제와 만나 p95 응답시간을 4.12초까지 밀어올리게 되는 문제가 생겼다. — 이 해결방안은 2편에서 이어진다.


다음 편 예고

2편(성능 편)에서 다루는 내용:

  • AI 응답 14초 → 1.5초: 비동기 콜백 기반 투트랙 아키텍처와 io.BytesIO RAM-to-RAM 파이프라인
  • N+1 제거로 p95 4.12초 → 1.99초 (-52%): 그리고 "빨라진 게 진짜 내 덕분인지" 대조군으로 검증한 이야기
  • STT는 Whisper, 발음 채점은 Azure Speech: 음성 엔진 이원화 결정
  • 데이터 계약 설계: chat_log 허브 스키마, ENUM 체계, AI 호출 0회 리포트 서빙
  • 신뢰성 설계: 지수 백오프, 폴백, 403 삼원인 분해, isMounted 가드

[2편 — 성능 편 바로가기]