Yejun Cheon
log
study
read
coffee
로그인
Log

AppBuildChat 인턴에서 내가 배운 것

예
예준천
2025년 9월 5일9달 전
카테고리
비어 있음

회고

내 첫 인턴 생활이 6개월이 지난 현재 시점에서 내가 배운 것, 내가 기여한 것, 느낀 것들을 정리해보고자 한다.

왜 하게 되었나

군대 생활관에 누워있던 병장은 당시 스타트업과 급변하는 AI 기술에 관심이 많았다. K-Startup 왕중왕전까지 진출하여 PM 겸 엔지니어로 세상에 나만의 가치를 만들어 나간다는 것의 가치와 즐거움을 느끼고 있었다.
발표를 준비하면서는 EO채널, Bizcafe 같은 채널들을 즐겨보며 구루들의 생각과 사고 방식, 설득력있는 대화를 배웠다.
고등학교 단톡방에 재우가 채용공고를 올렸다. 사실 플러터는 다뤄본 적도 없었다.
군대에 있다보니 돈을 받고, 가치를 창출하는 일을 하고 싶어졌다. (군대는 가만히만 있어도 돈을 주는 대표적인 조직이다.) 그리고 사실 검증의 목적도 있었다. '아니 몇개월동안 걸리는 앱개발을 어떻게 3일만에 만들어주겠다는거지? 사기아니야?' 라는 생각과, '되니까 하는거겠지? 설마 재우가 사기꾼이겠어' 라는 생각이 공존하며 내가 들어가서 일해보며 그들이 일하는 방식과 어떻게 할 수 있었는지를 파헤쳐보고 싶었다.
첫날 커피챗을 하면서 나는 회사의 히스토리와, 현재의 시스템이 어떻게 돌아가고 있는지 들었다. 연이은 질문은 회사의 보안 정책에 아슬아슬하게 걸쳐있었다. 그날 이야기 해보며 나는 아래와 같은 이유로 일해보고 싶었다.
1 AI 로 고객에게 (꽤나 큰) 가치를 창출해주는 스타트업에서 일해보고 싶다.
2 개선할 여지가 보이는 포인트들이 많았고, 내가 기여할 수 있는 부분이 보인다.
3 사실 플러터를 배워서 만들어 보고 싶은 개인적인 프로젝트도 있다.
4 스타트업이 일하는걸 내부에서 보고 싶다.

당시 상황

회사는 대표님, AI팀 2명, 제품팀 3명, 미국팀 2명, 군인(재우) 1명으로 이루어져 있었다. 주에 1개 정도의 신규 고객 앱 제작 요청이 들어오고 있었고, 내부 생산성 향상을 위한 인터널 툴 개발도 이루어지고 있었다.
처음에는 신기했다. 월 40만원 가까운 돈을 지불하며 사람들은 자신의 앱을 만들고자 하는구나.
특히 인스타그램 인플루언서 마케팅이 알고리즘에 오른 날은 앱이 5개씩 쏟아져 오고 하루에 수백명씩 가입하기도 했다.
그때의 프로세스는 다음과 같았다.
1 고객이 채팅으로 만들고 싶은 앱을 작성한다
2 기획 담당 AI가 대화를 통해 기획을 구체화하고, PRD를 작성한다.
3 (AI 팀 직원이) 구글드라이브에 쌓인 기획서를 플러터 전문 모델에 input으로 넣고 3시간동안 기다린다.
4 각 페이지별로 통합된 플러터 코드가 작성된다.
5 (AI 팀 직원이) 파이어베이스 연결, SSO 로그인, 애플/안드로이드 메타 정보 등록, 특수 기능에 대한 API 및 Key 연결을 한다.
6 (AI 팀 직원이) 고객이 요구한 기능들이 동작하는지 확인한다. 구현되지 않았거나 오류가 발생하는 경우 수정한다.
7 (제품팀 직원이) 앱의 컬러시스템과 컴포넌트 작업을 아주 일부 진행한다. UI를 매끄럽게 바꾸기 위해 cursor와 함께 무한 바이브 코딩을 진행한다.
8 고객에게 앱을 전달한다. 피드백을 받고 수정한다.

갈등

입사 첫 주에는 사내 백오피스 툴로 디자이너를 위한 컬러팔레트를 만드는 프로젝트를 진행했다.
목표는 '한 theme의 color 간의 관계성을 수식화하여 일관된 톤을 가지게 만들고, 컬러 세트의 생성을 편리하게 하자' 였다.
하지만 모호하고 정립되지 않은 기획에 대해 구체화하는 협업과정에서 어려움을 겪었다. 처음에는 기획 구체화 요청을 업무시간이 아닌 사석에서 구두로 전달 했었다. 이 과정에서 상호 소통간의 정보의 유실이 생기고, 이 유실은 책임 소재가 불분명하게 되었고 갈등으로 이어졌다.
이 날 배운 건 협업과정에서 소프트한 쿠션 언어를 사용하고, 업무요청은 분명하게 요청사항과 기한을 명시하여 문서로 남겼고, 필요한 데이터들을 정확하게 요구하는 방향을 협업을 진행하게 되었다. 물론 터놓고 편안한 분위기도 중요하지만, 특히 서로의 언어가 다를 때는 원하는 방향이 뭔지 정확하게 명시하는게 중요하다는 것을 배웠다.

반복되는 앱 작업

입사 전부터 플러터 공부를 해서, 2~3개의 고객 앱을 처리하다보니 워크플로우와 개발에 익숙해졌다. 대체로 고객의 요청 앱들은 유사한 카테고리 안에 있었고 예측 가능했다.
나는 제품 팀에서 cursor 와 함께 어플리케이션의 UX 개선, 일관성 있는 UI 만들기, 깔끔한 디자인으로 수정을 메인 업무로 했었는데, 이 과정이 거의 모든 페이지에 유사한 워크플로우로 구성되었다.
1 일단 오류가 안날때까지 수정한다
2 애뮬레이터를 열어 유저플로우를 따라가며 테스트한다.
3 디자인이 마음에 들지 않으면 레퍼런스와 디자인 용어로 바이브코딩한다.
4 페이지간 디자인 일관성을 맞춘다.
이 과정이 페이지별로 진행되고, 반복되기에 이걸 페이지마다 AI에게 요청하는 디자인 봇을 만들어 시도했다.
프롬프트 엔지니어링과 dart language 자체의 오류 디버깅 기능, claude API를 사용하여 4일동안 최대한 완성도를 높여봤다. 결과물은 생각보다는 아쉬웠다. 먼저 AI는 실시간으로 개발되는 화면을 볼 수 없었고(당시 MCP는 공개되지 않았었고 애뮬레이터나 실행중인 앱의 UI를 LLM이 조회하기는 어려웠다.), 코드로만 디자인을 판단했다. 두번째로는 동일한 레퍼런스와 프롬프트를 넣어도 페이지간 일관성을 유지하기는 어려웠기 때문이다.

이대로는 안된다.

하나의 앱을 처리하는데 너무 많은 시간이 소요되었고, 아무리 봐도 고객이 증가하면 지속가능하지 않을 것 같았다. 인턴 기간동안의 앱 처리 작업 7시간으로 단축을 내 인턴 생활의 KPI로 설정하고 실행했다.
나는 크게 3가지를 개선해야한다고 생각했다. 한 주간 휴가를 다녀오며 아래와 같은 내용들을 정리하여 팀과 공유했다.

코드 생성 방식의 개선

가장 크게 문제를 느낀 부분이었다. 그동안 가장 초보적이고 안티패턴으로 여겨졌던 '책임 분리 없이 한 페이지에 필요한 모든 코드를 한 파일에 담기'가 고객 앱에 쌓이고 있다. 여기서 '한 페이지에 필요한 모든 코드'는 UI 위젯 코드부터, 프론트엔드 상태관리, 로직, 파이어베이스 DB구조까지를 모두 포함한다. 그래서 두 페이지에서 같은 테이블을 봐야하는데 서로 속성명이 다른 상황도 심심치 않게 일어났다.
무엇보다 우리는 만들어진 앱들을 유지보수 하고 변화하는 요구사항들을 반영해야 할 책임을 가지고 있었다. 단일 서비스를 가지고 있는 스타트업이 기술 부채를 가지고 가는건 괜찮다. 하지만 고객 수의 증가가 서비스 개수의 증가와 정비례하는 이 구조에서 유지보수하기 매우 어려운(그리고 AI에 의해 확률적으로 가능한) 구조를 유지하다가는 엄청난 눈덩이로 다가올 것이라고 확신했다.
물론 어느 정도의 이유는 있다. 파일을 나눌 수록 정보는 분산되고, 분산된 정보는 AI에게 맥락으로 제공되기 어렵다. 그래서 싱글 파일에 모두 몰아 넣는 편이 더 AI가 이해하기 쉽다. 또한 우리가 아키텍쳐고 불리우는 것은 인간 개발자가 개발할 때 필요했던 것들이다. AI도 과연 이런 아키텍처가 필요할 것인지는 고민해봐야 했다.
'클린아키텍쳐' 책을 읽으며 영감을 많이 얻었고, 90%의 앱들을 커버할 수 있는 가장 적절한 아키텍쳐가 무엇일지 고민했다. 결합되면 AI는 맥락이 읽기 쉬워지고 단계가 줄어들지만, 코드의 중복이 발생하고 책임이 통합된다. 코드의 중복은 동일해야하는 로직이 다르게 구현시키고, 책임의 통합은 원하지 않는 수정을 만든다.
많은 리서치 끝에 mvvm 아키텍처를 사용했다. riverpod으로 view의 상태관리를 책임졌고, 로직은 viewmodel로 분리시켰다. 파이어베이스를 사용하기에 백엔드가 없다. 저장 될 데이터의 원형을 정의하기 위한 model 객체와, 외부와의 통신을 위한 repo는 분리시켰다. 각 계층의 단계적 구현을 하기 위해서는 다른 파일에 대한 정보를 컨텍스트로 넣어야하는데, 이때 인터페이스 방식을 사용했다. 세부적인 구현은 감추되, 상호작용하는 영역만 노출시켰다.
[[코드구조 재수립 TF의 향후 목표]]
Flutter 공통(Core) 모듈: 예외 처리, 인증, 라우팅 설계 문서

디자인 기반의 설계

보통의 소프트웨어 개발은 디자인 시안을 기반으로 프론트엔드 코드를 만들어낸다. 코드가 디자인보다 선행된다면 다음과 같은 문제가 발생한다고 생각한다. 1. 디자인에 비해 비교적 비싼 코드가 너무 많이 생성된다. 2. 코드가 만들어낼 시각적 효과를 예측할 수 없다.
그래서 다음과 같은 기능들을 기획하고, 제안하고, 일부는 실행해보았다. 가장 먼저 생각한건 figma import 기능이었다.
바이브코딩 플랫폼 lovable의 figma import 기능. 잘 만들어준다. .fig 파일을 분석해서 코드로 만드는 방법이나 연동하기가 어려워서 일단 미뤄뒀다.
두번째로는 SVG를 이용해서 기획단계에서 앱의 뼈대를 고객에게 미리 보여줘 수정을 하고, 이를 기반으로 코드를 생성하는 방법론들을 실험해봤다.
또 한편으로는 일관성을 유지해야한다. 그래서 생각한게 기획과정에서 미리 정의된 디자인 컴포넌트 셋을 선택할 수 있게 하거나, 기획에 맞춰 컴포넌트들을 미리 생성해두는 Pre Generated Component Set 방식도 시도해보았다. 기업마다 필요한 디자인의 톤앤 매너가 있고, 자주 사용되는 설계요소들을 디자인 시스템으로 만든다. 이 방법론을 차용해 기획서 단계 이후에 디자인 시스템을 만들자는 것이다.
결론적으로 여기서 하고자 했던건 사용자가 머릿속에 상상으로 가지고 있던 만들고 싶은 앱의 이미지를 텍스트보다 직접적으로 전달하게 하고, 더 완성도 높은 디자인의 결과물을 만드는 것이었다.

일하는 방식의 변화

고객의 앱 흐름을 관리하는 사내 툴이 필수적으로 필요하다고 느꼈다. 작업 파일이 AI와 여러 사람의 손을 거치고, 앱스토어에 배포되는 과정이 Slack과 Notion에 너무 강하게 결합되어 있고, 명문화되어 있지 않았다. 그래서 웹사이트를 리뉴얼하는 김에 이 파이프라인도 구축하기 위해 기획했다.
또한 AI팀에서는 모델 발전에 집중해야 한다고 생각했기에, 고객 어플리케이션의 feature 수정의 책임을 제품팀으로 이관했다. 새롭게 만든 flutter 아키텍쳐의 기술적 복잡도가 올라가고, 기능 수정의 책임까지 가중되어 제품팀의 업무 부담이 높아졌었지만, 커뮤니케이션 코스트는 줄었고, AI팀은 더 적은 오류를 내뱉는 어플리케이션을 초안으로 전달 할 수 있었다.
사실 이거 말고도 해보다가 끝나고만 아쉬운 것들이 많았다. UI 테스트 자동화, 앱스토어 스크린샷 자동화, AI 코드 초안 작성후 자체 테스트 사이클 반복으로 무한 수정, 디자인 AB 테스트를 통한 DPO 개선 ... 등등

배우고 느낀 점

실행력

사실 인턴을 처음 시작하면서는 이렇게까지 많은 영역을 터치해보고 변화를 일으킬 수 있을지 몰랐다. 특히 나는 어떤 가설이 있을 때 실행력이 부족했다. 대표님과 팀원들에게 가장 감사한건, 어떤 아이디어가 괜찮다면 바로 실행할 수 있는 리소스를 지원해주며 이끌어주셨다. 머뭇대고 생각만으로 점점 잊혀져가기보다 빠르게 실행해서 실패 or 성공의 확인을 하는편이 낫다. 아직도 파트타임 플러터 전문가 채용과 외주 시도를 통한 데이터셋 구축은 머뭇대다가 못 해본게 아쉬움이 남는다.

소프트웨어의 설계 철학

역설적이지만, 소프트웨어 자동화를 위해서 최신의 바이브코딩 방법론보다 고전적인 개발 방법론들을 찾아보게 되었다. 객체지향과 clean code, clean architecture와 같은 범용적인 방법론들과, 프론트엔드에서 상태와 컴포넌트를 어떻게 관리하는지와 같은 부분들을 리서치했다. 어쩔때 보면 하루종일 책만 읽고 있어서 회사에 일하러 가는게 아니라 개발 공부하러 가는 것 같았다.
cognitive load 와 관련한 부분은 인간 개발자와 AI 모두 같은 문제를 겪는다. 코드를 작성할 때 기억하고 염두해야할 정보가 많아질 수록 오류가 발생하기 쉽다. 이걸 해결하기 위해 발전해온 방법론들은 AI에게도 적용해 볼 법 했고, 직관적으로 좋은 성능을 냈다. 예를 들자면, 여러 계층으로 나뉘어 코드가 분리되었을 때, 모든 코드를 컨텍스트에 넣기 어려우니, 각 코드의 핵심적인 상호작용 요소(메서드/프로퍼티)들을 인터페이스 형식으로 정리해서 그걸 외우도록 했다. 인간 개발자도 방금 본 파일의 메서드의 구현방식까지 모든걸 외우고 있지는 않는다. 그걸 모방해봤다.

AI 엔지니어링

원래 나는 제품팀이었지만 후반에는 AI팀과 더 많이 일하게 되었다. 기존에 작성된 워크플로우부터 RAG와 RLHF의 방법론까지 배웠고, 새롭게 생각한 워크플로우를 제안했다. 하나의 아이디어에 대해서 수십번의 프롬프트를 바꿔보고, 어떤 컨텍스트를 넣을지 지속적으로 수정했다.
어떤 AI 모델을 만들 때 deterministic problem으로 만드는게 중요하다고 생각한다. 초반에는 모델이 만든 산출물에 대해 내가 주관적으로 평가했지만, 정량화된 평가 기준이 필요하다고 생각했다.
그래서 이후에는 새로 들어오는 고객 요청에 대해서 변경한 모델을 시도했고, 후처리 작업자가 얼마나 오랜 시간을 사용했는가 + 디자인 및 고객 만족도를 지표로 사용하여 조금씩 개선해보았다.
너무 단순하지만 그래도 깨달은 건,
1.
프롬프트에 예시는 조심해서 넣자.
mvvm 아키텍쳐의 각 파일의 특정 구조를 일관성 있게 만들게 하기 위해 프롬프트에 예시 코드를 작성했었다. AI는 어디까지가 따라야 할 구조인지, 바꿔도 되는 부분인지를 모른다. 선택지를 열어주고, 오히려 예시를 추상화해야 더 좋은 결과가 나왔다.
2.
개발환경에서 알고 있어야 할 전역 정보는 항상 컨텍스트로 넣어주자.
현재의 개발환경과, 사용하는 라이브러리, 사용할 아키텍쳐 및 방법론은 프롬프트에 넣어줘야한다. 일관성을 잊고, 도메인별로 다른 개발환경을 사용할 수 있다. (특히 우리가 사용하기로 한 라이브러리보다 더 대중적인 표준이 있을 때 그러했다.) 그런데 사실 관심사의 분리와는 조금 모순되긴 한다. UI를 생성하는 코드에서 파이어베이스를 사용한다는 사실을 알려주면, 가끔은 UI에서 쿼리를 작성하기도 해버리는 오류를 저지르기에 적절한 sweet spot을 찾아야한다.
3.
추상화하자
코드베이스의 모든 코드를 고려한채로, 최적의 판단을 내리는 모델은 없다고 가정했다. 당시 gemini를 필두로
magic.dev 와 같은 초 대용량 컨텍스트 모델들이 등장하고 있었다. 아무리 대용량 모델이더라도, 그렇게 모든 코드를 한줄 한줄 고려하고 있는 방법보다, 필요한 영역만 기억하는 것이 더 좋은 성능을 낼 것이다.
그래서 시도했던 건 어떤 영역이 필요한 영역일 것인가를 찾아내는 것이었다. 객체지향에서 외부에 노출되는 인터페이스의 param, return, method 명이면 충분한가? javadoc 방식처럼 주석으로 이 함수의 역할과 부수효과까지 적는 것이 맞는가? 그러다보면 설명이 원래 코드보다 길어지는 웃픈 상황도 나왔다.
4.
에이전틱 워크플로우의 중간 단계는 저장하자.
꼭 코딩이 아니더라도 어떤 큰 작은 task로 나뉘어서 문제를 처리하는 에이전틱 워크플로우에서는 중간 단계를 기록하고 확인 할 수 있어야하는 것 같다. 특히 가끔은 중간 산출물이 그 자체로 가치있는 결과물일 수도 있다.
5.
AI 비용은 생각보다 비싸다
나의 클릭 한번으로 (한번의 워크플로우 실행이) 몇만원의 비용이 청구된다. AI 프로덕트를 만들 때는 이 일련의 작업(AI에게 요구하는)이 정말로 고객이 필요로 하는 것인가, 그 생성물의 가치가 비용을 넘는가를 항상 고민해야할 것 같다. Scale law라고 해서 모델의 성능은 좋아질 것이고, 비용은 저렴해질 것이라는 믿음이 사회 전반에 있다. 하지만 그럼에도 아래 두가지는 고려해볼법 하다. 현재 LLM 회사들은 손해를 감수하며 할인하고 있는 것이고, 지금의 가치로도 수익성을 증명할 수 있다면 저렴해졌을 때도 경쟁력이 있을 것이다.

플러터로 앱 정도는 만들지

사실 인턴을 처음 시작하면서 플러터를 배워 앱을 만들고 싶은 기초적인 욕구도 있었다. 고객 어플리케이션을 처리하면서 빠르게 기능을 구현하고, 여러 외부 기능들(구글 맵, SSO, 결제, push 알림)을 앱에 붙이는 방법들에 익숙해졌다. 고객들의 피드백을 받으며 해외 제작자들은 어떤 UI와 기능들을 선호하는지도 조금은 공감하게 된 것 같다. 덕분에 내가 만들어보고 싶던 앱을 만들 역량도 생겼고, 그걸 빠르게 실행할 수 있는 방법론도 배우게 되었다.
AppBuildChat - Chat. Build. Launch.
Build mobile applications through conversational AI. AppBuildChat handles everything - you just need to chat.
appbuildchat.com
Clrprp - Fly with Confidence
Essential aviation safety app that helps pilots ensure they're fit to fly with the IMSAFE checklist, risk assessments, real-time weather data, and personal proficiency tracking. Stay safe and prepared for every flight.
clrprp.com
내가 수정하던 서비스들.
'Yejun Cheon' 구독하기
사이트를 구독하면 새 포스트 등 최신 업데이트를 알림과 메일로 가장 먼저 받아보실 수 있습니다.
Slashpage에 가입하고 'Yejun Cheon'을 구독하세요!
구독
👍