Meme 추천 시스템 개발기
🧑🏻🍳
최근 경쟁률이 매우 높은 (합격률 5% 내외) 교내 기술창업 동아리를 지원하는데 다음과 같은 질문이 있었습니다.
반드시 들어가고 싶었던 동아리였기에 많은 고민이 들었습니다. 사람마다 관심사와 웃음 코드가 다르며 특정 그룹에게는 웃긴 내용이 다른 그룹에게는 불쾌한 내용으로 다가갈 수 있기 때문입니다.
그러다 "차라리 선택에 기반해 meme을 추천해주는 서비스를 만들면 어떨까?"하는 생각이 들었습니다. 반응형 추천 시스템(새로 누적되는 데이터에 기반해 추천 내용이 동적으로 변하는 시스템)이 아니기 때문에 기술적인 복잡도도 그렇게 높지 않을 것 같았습니다. 마침 주말이 있었기 때문에 빠르게 만들어보기로 결정했습니다.
🎬 시스템 기획하기
우선 제가 재밌게 본 동영상들을 리스트업했습니다. (틱톡, 트위터, 인스타그램 대신 유튜브를 사용해도 상관 없을 것이라 판단했습니다.)
이후 Notion 페이지에서 카테고리별로 분류했습니다. 음악, 영화, 게임, 코딩, 일반적 Meme으로 나눌 수 있었습니다.
선택 기반 추천 테스트를 구상하다 보니 2가지 접근 방법이 있는 것 같았습니다. 하나는 질문의 답변마다 가중치를 주고, 최종 점수를 계산하여 결과를 추천해주는 시스템입니다. 나머지 하나는 전체적인 시나리오 트리를 설정해두고 선택지의 조합에 따라 결과를 추천해주는 것입니다. 요즘 유행하는 MBTI 결과물들을 분석해본 결과 대개 첫 번째 점수 기반 추천 시스템을 사용했습니다. 저는 두 번째 시나리오 트리 기반 추천 시스템을 사용했습니다. 이유는 다음과 같습니다.
- 점수 플래그 시스템을 구성하기 너무 복잡했습니다.
- MBTI는 점수 플래그가 단순합니다.
E/I
,N/S
,T/F
,J/P
이렇게 4개의 플래그만 존재하기 때문에 점수 상태관리를 하기 비교적 편리합니다. - 저는 당장 음악, 영화, 게임, 코딩, 일반 이렇게 5개의 카테고리가 존재했고 각 카테고리마다 다양한 하위 카테고리가 존재했기 때문에 플래그를 잡기가 애매했습니다.
- 예를 들어 단순히 게임 플래그 점수가 높다고 해서 무작정 롤 Meme 영상을 추천해줄 수는 없습니다. 롤의 규칙을 모르거나 그 웃음대에 공감하지 못할 수 있기 때문입니다. 즉 이 문제를 해결하려면 롤 점수 플래그를 추가하거나 "제일 좋아하는 게임" 플래그를 따로 지정해두어야 합니다.
- 이 경우 상태 관리가 무척 복잡해지며 그렇게까지 기술적 난이도를 높이고 싶지 않았습니다.
- 하지만 높아지는 기술적 난이도보다 더 올라가는 것은 기획적 난이도입니다. 무엇보다도 영상이 플래그마다 어느 점수 영역대에 추천되어야 하는지 정교하게 기획하기 매우 어렵다고 느꼈습니다. 즉, 점수 기반으로는 '취향저격'하기가 어렵습니다.
- MBTI는 점수 플래그가 단순합니다.
- 모든 엔딩 보기가 가능하게 만들고 싶었습니다.
- 선택 기반 게임에서는 마지막 결정 하나만 변경해서 다른 엔딩을 보고 싶을 수 있습니다 (특히 단순한 MBTI가 아닌 이런 Meme 추천은 더욱이 그럴 수 있습니다).
- 하지만 점수 기반 시스템은 대개 테스트를 처음부터 다시 시작해야하며 선택
undo
액션을 추가하려면 더 많은 엔지니어링이 투입되어야 합니다. - 시나리오 트리 기반을 활용한다면 이 부분이 더 편리해집니다. Parent Node로 이동하면 되기 때문입니다.
- 후술되겠지만, 저의 경우 Next Link를 활용했기 때문에 브라우저에서 뒤로 가는 것만으로 액션
undo
가 됩니다.
- 일반적인 선택지 어휘가 아닌 큐레이팅된 선택지 어휘를 넣고 싶었습니다.
- 점수 기반 시스템에서는 굉장히 일반적인 형태의 질문과 답변만 하게 됩니다. 즉 follow-up 질문을 하지 못합니다.
- 저는 시나리오 트리를 활용해 질문과 답변이 서로 정확하게 들어맞도록 만들어 저와 대화하는 듯한 경험을 주기 위해 노력했습니다.
- 또한 결과적으로 이 시스템은 "동아리 지원서에 첨부될" 목적입니다.
- 아무리 재미있는 영상을 추천해준다고 하더라도 제 이름을 기억하지 못하고 영상만 기억하게 된다면 본말이 전도된 것입니다.
🥞 기술 스택 결정하기
프론트엔드에 있어서는 별다른 고민을 하지 않았습니다. 최근 TypeScript Next와 사랑에 빠졌기 때문에 자연스럽게 선택하게 되었고 Vercel과 Next의 호환성을 알기에 Vercel에 호스팅하기로 결정했습니다. 스타일은 styled-component를 사용했습니다.
데이터를 어디에 저장할지에 대한 부분이 문제였습니다. Meme에 대한 데이터는 동적인 데이터가 아니고, 유저 정보는 저장할 일이 없다고 판단했기에 DB 또는 DBaaS를 따로 사용하는 대신 모든 데이터를 모듈화하여 하드코딩하기로 결정했습니다. 여기에서 하드코딩된 정보들을 보실 수 있습니다.
백엔드 또한 마찬가지로 구성할 필요가 없었습니다. 서버리스한 형태로 만들기로 했습니다.
💻 개발하기
다음과 같이 요약할 수 있습니다.
- 질문은 질문마다, 동영상은 동영상마다 고유 링크를 가지며, 선택지를 고르면 그 링크로 접속하는 것입니다.
- 각 선택지는 '다음 질문' 또는 '결과 동영상' 필드를 가진 Object 형태이며 이를 기반으로 인터페이스를 구성합니다.
getStaticProps
와getStaticPaths
를 사용해 반응 속도를 초고속으로 만듭니다.