Backend Portfolio · 조창훈

문제를 나눠 보고, 선택의 이유를 설명하는 백엔드 개발자입니다.

Java/Spring 기반의 트랜잭션 기본기와 AI 서비스 백엔드 경험을 함께 쌓고 있습니다. 기능을 만드는 데서 끝내지 않고, 예상되는 실패 지점과 운영 비용, 데이터 정합성을 먼저 가정한 뒤 검증 가능한 해결책으로 좁히는 것을 중요하게 봅니다.

Representative Technical Brief

Malang: 전화형 AI 발화 연습 서비스에서 응답 지연을 줄인 경험

Malang은 한국어를 배우는 일본인 학습자가 전화 통화처럼 말하며 발화 연습을 하는 서비스입니다. 제가 맡은 핵심은 AI 모델 호출 자체가 아니라, 사용자의 한 문장이 들어온 뒤 서버가 어떤 상태를 읽고, 어떤 provider를 호출하며, 실패하거나 지연될 때 어떤 기준으로 복구할지를 백엔드 흐름으로 정리하는 일이었습니다.
프로젝트 개요

일본인 한국어 학습자가 전화 통화처럼 말하며 발화 연습을 하는 AI 기반 한국어 말하기 연습 서비스입니다.

담당 역할

메인 서버와 어드민 페이지 개발을 맡았습니다. 백엔드 API, 워크플로우 실행 흐름, 관리자용 데이터 관리 화면을 함께 구현했습니다.

구현 기능

영상 관리 어드민 페이지, AI 연습 대화용 워크플로우 작성, 커뮤니티 게시판, 유저 설정

기간

3개월

인원

2명

기술 스택

NestJS, Prisma, PostgreSQL, OpenAI, Vertex/Gemini, ElevenLabs, GCP, Firebase

커피 주문 연습 대화에서 어색한 흐름과 종료 조건을 제어해야 했습니다

AI 연습 대화의 대표 예시로 커피 주문 상황을 만들었습니다. 사용자가 메뉴, 온도, 사이즈 같은 필수 정보를 빠뜨리거나 중간에 다른 질문을 했을 때 대화가 어색하게 흐르거나 통화 종료 조건이 흔들릴 수 있었습니다. 이를 막기 위해 필수 slot 판정, JSON schema 출력, 최소 slot 판정 모델을 넣었고, 초기에는 이 판단들이 한 turn 안에 누적되며 응답까지 10-20초가 걸렸습니다.

처음에는 LLM 모델 자체가 느리다고 보기 쉬웠지만, 실제로는 한 turn 안에서 필수 slot 판정, JSON schema 강제, 최소 slot 판정 모델, 답변 생성, provider 호출, 네트워크 리전 이동이 누적될 가능성이 더 크다고 가정했습니다. 특히 JSON 출력 형식을 강제하면 서버 제어력은 높아지지만 프롬프트와 응답 토큰 길이가 늘어 응답 속도에 영향을 줄 수 있다고 봤습니다.

재현 조건커피 주문 연습에서 메뉴, 온도, 사이즈가 일부 누락된 발화를 반복 입력하고 다음 질문 생성까지의 응답 시간을 확인했습니다.
관찰 방식slot 추출, JSON 출력 강제, 응답 생성, provider 호출, 리전 왕복을 나눠 보고 어떤 단계가 대기 시간을 늘리는지 확인했습니다.
문제 확인LLM 호출 한 번만의 문제가 아니라, 대화 제어를 위해 추가한 구조화 프롬프트와 외부 provider 왕복이 함께 누적되는 문제라고 판단했습니다.
Slot필수 정보 수집대화 상태로 관리
JSON서버가 읽을 출력schema 강제
Token프롬프트/응답 길이속도 영향 확인
Model품질과 비용 차이provider 비교
Deploy리전과 실행 환경GCP Run 배포
판단 지점버린 선택지선택한 방식선택 이유
Branch 판단모든 분기를 LLM에 질문RULE로 확정되는 분기는 서버에서 처리지연과 비용을 줄이고 동일 입력의 재현성을 높이기 위해 선택
Slot 처리slot 추출 후 별도 응답 생성 호출slot 추출과 응답 생성을 single-call로 묶음한 turn 안의 provider 왕복 횟수를 줄이는 효과가 가장 직접적이어서 선택
응답 체감스트리밍으로 먼저 보여주기총 지연 원인인 호출 수와 리전을 먼저 줄임통화형 UX에서는 첫 토큰보다 다음 발화까지의 전체 대기 시간이 중요하다고 판단
문제 분석LLM Agent가 제안한 수정안을 바로 적용Codex/Claude로 후보를 만들고 CS 관점으로 병목 가설을 검증도구 제안보다 원인 분리를 우선해야 면접에서 설명 가능한 해결이 된다고 판단

1. 커피 주문 흐름을 slot 기반 워크플로우로 고정했습니다

메뉴, 온도, 사이즈처럼 반드시 필요한 정보를 slot으로 정의하고, 누락된 slot이 있으면 다음 질문을 이어가도록 했습니다. 모든 판단을 LLM에 맡기면 대화가 자연스러울 수는 있지만 통화 종료 조건과 필수 정보 수집이 흔들릴 수 있어 서버가 상태를 추적하는 구조를 선택했습니다.

2. JSON 형식 출력을 강제해 서버가 대화 상태를 해석하게 했습니다

모델 응답을 자유 문장만으로 받지 않고 intent, slots, missingSlots, shouldEnd, reply 같은 구조로 받도록 강제했습니다. 이 방식은 서버 제어력을 높였지만 토큰 길이가 늘어 응답 속도에 영향을 준다는 점도 함께 확인했습니다.

3. 모델 품질, Vertex, GCP Run 배포까지 비교하며 운영 관점을 얻었습니다

모델에 따라 JSON 준수율, 대화 자연스러움, 응답 속도가 다르게 나타났고 이를 통해 모델 선택이 서비스 품질에 직접 영향을 준다는 것을 확인했습니다. Vertex를 사용한 내부 AI 서비스 구축 방식과 GCP Run 기반 배포 흐름도 함께 익혔습니다.

결과10-20초까지 늘어나던 주요 응답 경로를 0.2-1.3초 구간으로 줄였습니다.
품질커피 주문 예시에서 필수 slot 누락, 중간 질문, 종료 조건을 반복 확인하며 대화 흐름이 깨지지 않는지 검증했습니다.
학습토큰 길이, 모델별 응답 품질, Vertex 기반 내부 AI 구성, GCP Run 배포가 AI 서비스 백엔드에 미치는 영향을 확인했습니다.

Architecture

서비스 아키텍처와 원본 ERD

제가 맡은 메인 서버와 어드민 페이지가 어떤 데이터와 외부 provider를 다루는지 설명할 수 있도록, 서비스 흐름 요약과 원본 ERD를 함께 정리했습니다.
AI 연습대화 처리 구조
Mobile Appvoice inputNestJS APIauth · sessionWorkflow Enginerule · slot · turnProvider Adaptersingle-call · fallbackAI ProvidersOpenAI · GeminiElevenLabsState & OpsPostgreSQL · Firebase핵심 판단: 모델 성능보다 요청 왕복 횟수와 리전 거리를 먼저 줄였습니다.
핵심 테이블과 역할 요약
users서비스의 중심 사용자profile · provider · localeuser_settings학습 목적과 알림 설정level · voice · reminderAI 연습 대화daily_contentsdaily_content_dialoguesuser_daily_review_slots음성 세션speech_sessionsspeech_tokensvoip_message_hints단어 학습vocabulariesvocabulary_occurrencesuser_vocabulary_learning퀴즈quizzes · quiz_questionsquiz_choicesquiz_submissions커뮤니티community_postscomments · likespost_tags · translations결제 / 구독payment_attemptsuser_entitlementsstore_subscriptions운영 / 어드민asset_uploads · ai_usageslocales · notification_templates

원본 ERD는 전체 테이블 구조를 확인하는 자료로 두고, 이 요약도에서는 면접에서 설명할 핵심 도메인만 사용자 중심으로 다시 묶었습니다. 응답 지연 개선과 직접 맞닿는 부분은 AI 연습 대화, 음성 세션, 사용자 설정, 외부 provider 사용량입니다.

원본 ERD

실제 프로젝트에서는 사용자, AI 연습 대화, 음성 세션, 퀴즈, 커뮤니티, 결제/구독, 단어 학습 도메인을 포함한 PostgreSQL 스키마를 Prisma 기반으로 관리했습니다. 아래 이미지는 원본 ERD이며, 원본 보기에서 세부 테이블과 관계를 확인할 수 있습니다.

Malang 프로젝트에서 실제 사용한 Prisma ERD 전체 구조원본 ERD 크게 보기

Technical Skills

전체 기술 역량 요약

Malang 한 프로젝트의 하위 항목이 아니라, 지금 바로 어떤 범위까지 구현할 수 있고 어떤 프로젝트에서 증명했는지를 별도로 정리했습니다.
스택가능 수준가능한 작업근거
Java / Spring Boot구현 가능API, 인증/권한, 트랜잭션 경계, 멱등성, 비관적 락을 프로젝트에 적용GodLifeRouting에서 중복 요청과 동시성 충돌을 DB 제약과 트랜잭션으로 제어
NestJS / TypeScript주요 기능 구현 가능AI 응답 처리 API, provider adapter, workflow session, error/fallback 흐름 구현Malang에서 전화형 AI 응답 처리와 single-call 경로 개선
PostgreSQL / MySQL설계·검증 가능상태 모델링, migration, Unique 제약, 금액/필수값 검증 기준 설계Malang session/version 모델과 ERP 데이터 검증 흐름에서 활용
AI Provider Integration연동·성능 개선 가능OpenAI, Vertex/Gemini, ElevenLabs 호출 경로, 요청 묶기, fallback 기준 설계Malang 응답 지연을 10-20초에서 0.2-1.3초 구간으로 개선
LLM Agent Coding실무 루틴에 활용Codex/Claude로 코드 탐색, 변경 후보 작성, 테스트 보강, 문서화 루프 수행도구 제안을 그대로 적용하지 않고 CS 관점의 병목 가설로 검증
Workflow Automation업무 데이터 자동화 가능ERP Excel 원본 정제, 산출물 생성, 전표 입력 규칙화, 예외 목록 분리2-3일 걸리던 아파트 경리 반복 업무를 4시간 이내로 단축

Other Projects

나머지 프로젝트는 상세 페이지에서 확인

메인에서는 Malang을 대표 경험으로 집중하고, 다른 프로젝트는 문제 해결 포인트를 별도 상세 페이지로 분리했습니다.

Credentials & Awards

학습 성과와 백엔드 기본기

자격증과 수상은 나열보다 개발 역량과 연결되는 맥락을 함께 적었습니다.
정보처리기사 · SQLD

운영체제, 네트워크, 소프트웨어 공학, RDB/SQL 기본기를 백엔드 설계 판단에 연결하고 있습니다.

1학기 우수 교육생상

알고리즘, CS, Java/Spring 과제를 꾸준히 완수하며 단기간 학습 역량과 팀 과제 기여를 인정받았습니다.

SSAFY 11기 자율 프로젝트 우수상 · 깻냥

알림과 영상통화 기반 습관 인증 서비스에서 실시간 사용 흐름 안정화에 기여했습니다.