본문 바로가기
Review

[리뷰] SPARCS Service Hackathon 2024 참가 후기 - 최우수상 수상!

by r4bb1t 2024. 2. 18.
반응형

우리의 생각이 한계까지 함께하는 곳, SPARCS Service Hackathon 2024

이번 2월 14일부터 16일까지, 대전광역시 및 KAIST에서 주관하고 KAIST 산하 개발자치단체이자 KAIST 학부 총학생회 산하 특별기구인 SPARCS에서 주관한 SPARCS Service Hackathon 2024에 참가했습니다!

참가 신청은 구글 폼으로.

이번 스팍스 해커톤은 개인 혹은 2인 지원이 가능해서, 동아리 친구인 KUCC 공식 카피바라 민됴리님과 함께 신청서를 제출했습니다. 팀은 총 4명으로 구성되는데, 저희 팀은 저와 백엔드 개발자 쿼카, 그리고 서울대학교 과 동기 사이인 프론트엔드 개발자 하나와 기획자 동경이로 구성되었어요.

머쓱한 뉴트리아(96년생). 그래도 다 말을 놓았습니다.

행사 전 공지를 통해 공개된 해커톤의 테마는 지역 사회 문제 해결하기였습니다. 공식적으로 대회 1일차에는 데이터 분석 및 시각화 미션이 진행되는데, 이 미션에서는 대전광역시의 특징이나 문제점 발굴하기가 주제였습니다. 저희는 행사 전에 미리 개발을 하기에는 시간이 부족해서, 사전에는 구글 밋을 이용해 비대면으로 회의를 두 차례 가져 개발할 서비스의 주제만 정하고, 데이터 시각화나 서비스 개발 모두 대회장에서 진행하기로 했습니다.

저희 팀이 사전 회의에서 발견한 대전시의 문제점은 크게 두 가지. 높은 노인 자살율과 지역 내 교육 격차였습니다. 많은 사례들을 조사해본 결과 대전이 6개 광역시 중 노인 자살률 1위라는 점, 서울과의 교육격차는 크지 않은 반면 지역 동부, 서부 내 교육 격차가 심하다는 점이 저희가 가장 집중할 수 있는 문제점이라고 생각했습니다. 저는 개인적으로 지역 내 교육 격차 쪽을 조사하고 있었는데, 이런저런 아이디어를 내봐도 이미 다 EBS에서 하고 있더라고요. (진짜 최고) 그래서 결론적으로 저희 팀은 치료적 관점에서의 자서전 쓰기에 주목하여, 자서전을 작성하는 과정에서의 자기 성찰과 회고를 제공하기로 하였습니다. 그렇게 저희의 주제는 노인을 위한 AI 자서전 제작 서비스로 결정되었습니다. 사실 저는 처음 다른 팀원들이 자서전 서비스를 이야기했을 때, 자서전을 쓰는 주체는 명확한데 읽는 주체가 명확하지 않아서 의미가 있을까? 라는 생각이 들어 걱정을 제기했었는데, 자서전을 쓰는 과정 자체에서 얻는 효용을 이해하고 난 후에는 적극적으로 동의했습니다😅

 

고령화 사회 속 ‘노인 자살’ 비상… 대전 노인복지 인프라 전국 최하위 - 충남일보

[충남일보 김기랑 기자] 전국적으로 고령화 현상이 심화되고 있는 가운데 노인의 자살 문제가 주요 사회 현안으로 떠올랐다. 특히 대전 지역은 6개 광역시 중 노인 자살률 1위에 위치하나 노인복

www.chungnamilbo.co.kr

자기소개부터 레포지토리 바로가기, 회의록 등은 노션으로 관리하였습니다.

그러던 와중, 해커톤 전날 저희 팀의 기획자 동경이가 코로나에 걸리는 슬픈 일이 일어났어요.

그래서 아쉽지만 동경이는 비대면으로 참여하기로 하고... KAIST 본원 N1 김병호 김삼열 IT 융합빌딩에서 행사가 시작되었습니다 👀 저만 동아리 바람막이 입고온 줄 알았는데 쿼카는 거기다 한 술 더 떠서 동아리 후드티까지 챙겨왔더라고요...

A3팀. 단체사진을 자세히 보면 휴대폰 속에 사람이...!

기억이 안 나지만 참가 신청할 때 역할을 작성했던 게 이름표에 들어간 모양이더라고요😄 다들 간결한데 저는 디자인, 서버, 웹이라고 적혀있어서 민됴리가 왜 너는 세 개냐고 그랬습니다.

1-2일차: 데이터 시각화 및 개발

우선 1일차에 후원사인 엘리스에서 제공되는 “Streamlit으로 나만의 웹 애플리케이션 만들기” 강의를 수강한 후 Streamlit으로 시각화한 결과를 제출하는 미션을 진행해, 다음 날 오전까지 제출해야 했는데요. 문제점을 찾고, 그 과정에서 아이디에이션을 할 수 있도록 유도한 것 같아요. 해커톤을 통해 만든 서비스의 설득력을 스스로 생각해볼 수 있는 기회가 되는 좋은 미션이었다고 생각합니다.

첫 날 동경이와 하나는 미션을 위해 Streamlit으로 자살 통계 대시보드를 제작하고 저와 쿼카는 각자 프론트, 백엔드 개발 환경을 구성하였습니다.

저는 평소에 (특히 혼자 개발할 때에는) Next.js로 개발을 하는데, 하나는 Next.js를 사용해본 적이 없었고 해커톤이라는 짧은 기간동안 Next.js 기능들을 활용하여 개발하기에는 들이는 노력 대비 효용이 크지 않을 것 같다고 생각해 React + Vite로 진행하기로 했습니다. 다행히 프론트엔드 개발자 둘 다 Typescript와 Tailwind를 사용해서 기술 스택 맞추는 건 어렵지 않았어요.

라우팅을 설정하다가, Next.js에서 기본 제공하는 것처럼 폴더 구조대로 라우팅을 할 수 있게 설정한 글을 발견했습니다. 해당 글을 참고하여 다음과 같이 route.ts를 작성했습니다.

더보기
import { ComponentType, Fragment } from "react";
import { Routes, Route } from "react-router-dom";

const BASIC: Record<
  string,
  { [key: string]: ComponentType<unknown> | undefined }
> = import.meta.glob("/src/pages/404.tsx", { eager: true });

const COMPONENTS: Record<
  string,
  { [key: string]: ComponentType<unknown> | undefined }
> = import.meta.glob("/src/pages/**/[a-zA-Z]*.tsx", { eager: true });

const basics: { [key: string]: ComponentType<unknown> | undefined } =
  Object.keys(BASIC).reduce((basic, file) => {
    const key = file.replace(/\/src\/pages\/|\.tsx$/g, "");
    return { ...basic, [key]: BASIC[file].default };
  }, {});

const components = Object.keys(COMPONENTS).map((component) => {
  const path = component
    .replace(/\/src\/pages|index|\.tsx$/g, "")
    .replace(/\[\.{3}.+\]/, "*")
    .replace(/\[(.+)\]/, ":$1");

  return { path, component: COMPONENTS[component].default };
});

export const Router = () => {
  const NotFound = basics?.["404"] || Fragment;

  return (
    <Routes>
      {components.map(({ path, component: Component = Fragment }) => (
        <Route key={path} path={path} element={<Component />} />
      ))}
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
};

tmi: 숙소는 롯데시티호텔 대전이었는데요, 너무 좋았습니다. 호텔방에서도 계속 개발했어요.

저희 서비스의 메인 기능은 STT(speech-to-text)와 TTS(text-to-speech), 그리고 LLM을 활용해 직접 대화하는 것 같은 경험을 제공하는 것이었습니다. 하나가 Web Speech API를 이용해 STT를 개발하였고, 저는 openai의 API를 이용해 TTS를 설정하였습니다.

이런 과정에서, 저희 팀 개발자들은 기술 스택에 구애받지 않고 프론트와 서버를 넘나들며(ㅋㅋ) 개발을 했는데요.

개발자 세명이 모두 달라붙은 백엔드 레포지토리

카피바라가 CI/CD 구축을 하며 고생하는 동안 저는 소셜 로그인 및 질문 답변 API를 개발하고, 하나는 openai 세팅과 프롬프트를 작성해서 계속 테스트를 진행했어요.

저희는 비대면으로 참여하는 팀원도 있었기 때문에 진행 사항 공유가 중요했어요. 그래서 노션에 칸반 보드를 만들어 각자 하고 있는 일들을 정리하면서 개발했습니다.

저희는 2박3일동안 원하던 서비스 구현을 거의 완벽하게 해냈습니다. (자랑입니다.)

자서전 작성 과정

공통 질문은 에릭슨(Erikson E. H.)의 이론을 참고하여 인생의 시기를 단계별로 나눈 후, 여러 자서전 작성 관련 논문을 참고하여 작성했습니다. 이 과정에서 LLM은 답변을 받아 유저의 답변에 공감하고 답변을 더 구체화할 수 있는 질문을 생성합니다. 예를 들어, 학창 시절에 관한 질문에 "제가 나온 고등학교는 서울에 있었어요. 시설이 좋았어요."라고 답변한다면 "그렇군요. 시설이 좋았다니 참 좋았을 것 같아요. 고등학교에서 있었던 가장 기억에 남는 일이 있나요?"라고 다시 질문하는 식입니다.

이 과정에서 실제로 대화하는 느낌을 받을 수 있도록 여러 TTS 모델을 붙여보았는데 openai TTS의 'nova' 목소리가 가장 자연스럽고, 공감을 잘 하면서도 진중한 AI 자서전 코디네이터 '보미'의 이미지와 가장 어울려 이를 채택하였습니다.

기본 / 작성 중 / 말하는 중

'보미'가 생생하게 느껴지도록 Gif-PT을 이용하여 '안경을 쓴, 깃털이 달린 펜으로 책에 글을 쓰는 사람의 이미지'를 생성한 후 포토샵으로 어색한 부분을 수정하고, 눈을 깜빡인다든지 입을 움직이는 등의 애니메이션까지 한땀한땀 작업하였습니다. 저도 '보미'랑 정든 것 같아요...

하나가 작업한 자서전 미리보기 부분. LLM이 요약한 각 질문에 대한 대답을 보여주는 부분입니다. 다양한 배경 이미지를 변경할 수 있는 부분까지 구현하였는데 너무 좋은 아이디어고 완성도를 한층 높여주는 부분인 것 같아요. 하나 짱.

3일차: 발표 및 시상

3일차 행사는 대전 드림아레나에서 진행되었습니다. e스포츠 경기장인데 되게 신기하더라고요. 주최측에서 성심당 튀김소보로도 주셨어요.

동경이의 미친 발표자료

저희 팀 개발자들이 2박3일동안 개발에 매달려있을 수 있었던 이유는 엄청난 기획자가 비대면으로 함께하고 있었기 때문입니다. 코로나로 아픈데도 불구하고 계속해서 함께 데이터 정리와 발표자료 제작을 해준 동경이... (정말 동경할 수밖에 없네요)

저희 팀은 20팀 중 12번째로 발표를 하게 되었는데요. 글쎄 바보 뉴트리아가 발표가 시작하자마자 저희 서비스 이름인 인생 기록을 인생네컷이라고 말해버리는 게 아니겠어요!!!!!! 저랑 하나는 웃겨서 그때부터 거의 흐느끼면서 발표를 들었고... 정작 쿼카 본인은 본인이 그렇게 말한 걸 모르고 있었던 게 다행이라면 다행입니다. 비록 인생 기록을 인생네컷이라고 말했지만 그래도 발표 너무 잘해준 웜뱃에게 감사!🤭 하루종일 인생네컷 생각나서 웃음 참느라 힘들었어요... 다른 팀들의 발표도 정말 흥미롭게 들었습니다. 다들 다양한 문제의식을 가지고 서비스를 개발한 것 같아요.

그리고 저희는 최우수상인 KAIST 총장상을 수상하게 되었습니다!

대전을 한껏 즐긴 해커톤이었습니다. KAIST 학교 구경은 물론 숙소 근처에는 성심당 DCC점도 있었고, 저희는 아쉽게 시간이 나지 않았지만 신세계백화점이나 38층에 있는 리버뷰 스타벅스도 가까웠어요. 서울 올라오는 길에는 성심당 본점에 들러 빵도 왕창 샀습니다. 정말 너무 즐거운 2박 3일이었어요.

저희 팀 네컷 사진으로 글을 마무리하겠습니다! 서비스는 여기에 배포가 되어있긴 한데 서버가 언제 내려갈지 몰라요🥹

반응형

댓글