작성자: 조은비
블로그: https://wavicle.tistory.com/
깃허브: https://github.com/jio311
프로젝트 개요
github: https://github.com/GetOurRI
안녕하세요, 둥지동지의 개발자 조은비 입니다.
둥지동지 2.0.0 업데이트에서 Google Gemini API를 활용한 AI 자동 이미지 생성 기능이 새롭게 추가되었습니다. 이번 글에서는 2.0.0 버전을 중심으로 둥지동지의 시스템을 포함해 전반적인 개발 내용에 대해 다루었습니다.
업데이트 개요
AI를 활용한 자동 이미지 생성 기능
이번 2.0.0 업데이트에서는 서비스 유입층 확대와 콘텐츠 소비 구조 전환을 목표로 AI 편의 기능을 추가했습니다. 기존의 수동 방식의 설문지 작성 방식 외에도, 작성한 룸메이트 구인 글을 그대로 붙여넣으면 AI가 텍스트를 분석하여 설문 항목을 자동으로 완성하고 결과 이미지를 생성할 수 있도록 기능을 확장했습니다. 일종의 ‘짤방’ 생성 시스템을 만들어, 기존에 작성된 줄 글 형태의 구인글이나 정리되지 않은 글을 대상으로 새로운 유저를 확보할 계획입니다.

개발 기획 및 기술 스택
플로우 차트

아키텍처 설계

Frontend
- Vue: SPA 아키텍처, 상태 관리 및 라우팅 구성을 통해 사용자 인터랙션을 효율적으로 처리함.
- Vuetify: Vue 기반 머티리얼 UI 컴포넌트로 사용함.
Backend
- Python: 서버 로직 및 AI 연동 구현 언어로 사용함.
- FastAPI: RESTful API 서버 프레임워크로, 비동기 처리(AIOHTTP 기반), 의존성 주입 기능을 통해 안정적이고 확장성 있는 서버 구조를 제공함.
AI
- Google Gemini: 백엔드 내 LLMManager를 통해 Google Gemini 모델을 비동기적으로 호출함. prompt, placeholders, GenerationConfig 등을 활용하여 AI 기능을 수행함.
DB
- Firebase: Firestore 를 활용해 룸메이트 구인글 데이터 관리에 사용함.
CI/CD
- Render: FastAPI 백엔드의 컨테이너 기반 자동 빌드·배포 파이프라인을 운영 목적으로 활용함.
- GitHub Pages: 기반 프런트엔드 빌드 산출물을 정적 사이트 형태로 자동 배포에 사용함. GitHub Actions와 연계하여 커밋 시 CI/CD 자동화 파이프라인 구성함.
협업 도구
- Figma: UX/UI 와이어프레임, 프로토타이핑, 디자인 시스템 관리
- GitHub: 이슈/PR 코드 리뷰, 브랜치 전략 및 릴리즈 관리
- Google 스프레드시트: 규격서, PN/CR, TODO 리스트 등 개발 관련 업무 현황 관리 및 공유용 실시간 협업 문서로 활용.
- Notion: 서비스 기획서, 기능 정의서, 회의록 관리
주요 기능
1. text to IMG 기능
기능개요
Google Gemini API를 기반으로 룸메이트 구인 게시글을 자동 분석하고, 비정형 텍스트를 구조화된 설문 데이터(JSON) 형태로 변환하는 LLM 파이프라인을 구현했다.

LLM classification 활용
프론트엔드에서 전달받은 사용자 입력 원문을 기반으로 백엔드에서 AI 분석을 수행, 구조화된 설문 데이터(JSON) 형태로 반환한다. 이때 AI 모델은 단순 요약문을 생성하는 방식이 아닌, 입력된 텍스트를 사전에 정의된 설문 항목 기준으로 분류하여 값을 매핑하는 방식으로 동작한다.
예를 들어, “비흡연자에 청소 자주 하는 룸메 구해요” 라는 텍스트는 아래와 같은 수행 단계를 거쳐 설문 값으로 매핑된다.
- 의미 분류
- “비흡연자”: smoke = 0
- “청소 자주 함”: clean = 1
- 스키마 맵핑
TEXT_TO_JSON_PROMPT에 정의된 survey 스키마 기준으로 해당하는 값을 부여한다."smoke": null, // int - 흡연 여부 // 0: 비흡연자 // 1: 흡연자(연초) // 2: 흡연자(전자담배) "clean": 0, // int - 청소 성향 // 0: 더러워지면 치움 // 1: 매일 // 2: 주 1~2회 // 3: 몰아서 정리 - 결과 보정
원문 텍스트로부터 알 수 없는 정보는 null 혹은 기본값으로 처리한다. 이때, 명시된 정보는 반드시 추출하고, 유추 가능한 내용은 최대한 반영하도록 프롬프팅하였다.
I/O 예시
request
{
"tid": "1705298638704",
"orig_text": "명3 룸메 구합니다.\\n
- 나이 비슷했으면 좋겠습니다.\\n
- 디자인학부, 타과 선호합니다.\\n
- 보통 7- 8시쯤 일어나요. 1교시가 많아요.\\n
- 과제로 늦게 잘 때가 있어 서로 양해 가능했으면 좋겠습니다.\\n
- 드라이기는 샤워실에서 하는 것 선호합니다.\\n
- 헤어 트리트먼트나 고정 스프레이 써서 냄새 너무 예민하지 않으셨으면 해요. 룸메 분도 뿌리셔도 됩니다.\\n
- 피곤할 때 이갈이 조금 있어요. 이전 룸메는 못 들었다고 했지만, 예민하지 않으신 분이면 좋겠습니다.\\n
- 피곤하지 않으면 알람 듣고 바로 깨는 편입니다.\\n
- | 빼고는 반반이에요.\\n
- 비흡연자이고, 술 잘 안 마십니다.\\n
- 벌레 잘 잡는 분이었으면 좋겠어요.\\n
- 시험기간에는 도서관에 있다가 늦게 들어올 수 있어요.\\n
- 스탠드 마음대로 하시고, 아침에 저보다 일찍 깨시면 불 켜도 상관 없습니다. 서로 양해 가능했으면 좋겠어요.\\n
- 상대방이 과제나 시험공부할 땐 이어폰 필수\\n
- 바닥 더러우면 같이 실내 슬리퍼 신어요. *^^*\\n
- 공강 없습니다.."
}
response
{
"tid": "1705298638704",
"status": {
"code": "S0000",
"msg": "성공"
},
"data": {
"dorm": 3,
"birth": null,
"studentId": null,
"college": 1,
"mbti": "",
"smoke": 0,
"drink": "0-0-00",
"sdEtc": "술 거의 안 마심",
"wakeUp": "07-30",
"lightOff": null,
"bedTime": null,
"sleepHabit": 3,
"clean": 0,
"bug": 2,
"eatIn": 1,
"noise": 0,
"share": 1,
"home": 0,
"selectTag": [
"디자인학부",
"이른 기상",
"과제",
"비흡연"
],
"notes": "이갈이, 냄새, 소등 양해 필요"
}
}
다중단계 프롬프트 설계
LLM 모델의 출력 일관성과 데이터의 품질을 보장하기 위해 다중 단계 프롬프트 체계를 사용했다.
| 프롬프트 | 목적 | 내용요약 |
| INITIAL_PROMPT | 역할 정의 | 모델이 ‘중앙대 기숙사 룸메이트 구인 게시글 분석기’로 동작하도록 설정 |
| TEXT_TO_JSON_PROMPT | 구조 변환 | 사용자의 자연어 입력을 설문 스키마(survey)에 맞게 JSON 구조로 변환 |
| JSON_OUTPUT_PROMPT | 형식 보장 | 출력 결과를 항상 JSON 형식으로 한정하여 반환 |
2. 사용자 유형 분류 및 타이틀 생성 기능
기능개요
입력된 설문 데이터를 분석하여 사용자의 생활 패턴, 청결도, 수면 습관 등의 항목을 주요 지표로 삼아 ‘조용한 아침새’, ‘흥많은 올빼미’ 등 개성있는 타이틀을 자동으로 생성한다.

구현 알고리즘 요약
1. 성향 분류
분류 항목: 깔끔한 / 흥많은 / 조용한 / 세심한 / 무던한
생활 습관과 태그를 기반으로 성향을 분류하여 Prefix를 결정한다.
주요 지표: clean, eatIn, noise, share, home, selectTag
2. 생활 패턴 분류
분류 항목: 아침새 / 늦잠새 / 아기새 / 올빼미 / 보통새
기상·취침 시간을 기준으로 수면 리듬 분석 후 Suffix를 결정한다.
주요 지표: wakeUp, bedTime
3. 타이틀 합성
Prefix와 Suffix를 합쳐 최종 사용자 유형명을 생성한다. 생성된 유형은 이미지·아이콘 등과 매핑되어 반영된다.
주요 분류 기준 예시
| 항목 | 분류 기준 | 예시 |
| 청소 성향 (clean) | ≥3 → ‘깔끔한’ | “깔끔한 보통새” |
| 소음 민감도 (noise) | ≥3 → ‘흥많은’ / ≤1 → ‘조용한’ | “흥많은 올빼미” / “조용한 아침새” |
| 공유 성향 (share) | ≥3 → ‘무던한’ | “무던한 보통새” |
| 수면 패턴 (wakeUp / bedTime) | 0~6시 취침 → ‘올빼미’4~8시 기상 → ‘아침새’ | “세심한 올빼미”, “조용한 아침새” |
실제 데이터를 수집하기 전 서비스 준비 단계에서는 청소, 취식, 소음 등 주요 생활 성향 항목 간의 관계에 대한 가설을 설정하여 초기 유형 분류 알고리즘을 설계했다. 이후 실제 사용자 데이터를 수집, 분석함으로써 각 항목 간의 상관관계에 대한 가설을 검증하고, 이를 기반으로 분류 알고리즘의 타당성을 보완 및 개선하였다.
현재도 서비스 운영과정에서 축적되는 데이터를 반영하여 유형분류 알고리즘을 주기적으로 업데이트하고 있으며, 이를 통해 사용자 특성 분석의 정확도와 대표성을 지속적으로 향상시키고 있다. 데이터 분석에 대한 상세 내용은 카드뉴스로 별도 첨부한다.

3. 유지보수와 재사용성을 고려한 아키텍처 설계
UX/UI, 서비스 로직, AI 분석 모듈이 독립적으로 작동하면서도 유기적으로 연동될 수 있는 구조를 목표로 설계했다. 각 레이어를 명확히 분리함으로써 유지보수성과 재사용성을 높였으며, AI 모델 교체, 비즈니스 로직 교체, 기능 확장이 용이하도록 구성했다.

특히, 2.0.0 버전 업데이트에서 LLM 기능을 새롭게 추가하면서, 기존 서버 아키텍처의 구조적 원칙을 유지하며 AI 모듈을 통합할 필요가 있었다. 이에 따라 FastAPI 기반 서버에 AI 인터페이스 계층을 추가하고, LLM 기능을 독립된 모듈 형태로 설계하였다.
LLM 인터페이스 요구사항
1. 모든 LLM 매니저는 공통 인터페이스를 따르며, 전역 컨텍스트에 등록되어야 한다.
2. 각 모듈의 구조만 파악하면 전체 흐름 이해 및 유지보수가 가능해야 한다.
3. LLM 호출 기능은 목적별로 모듈 단위로 분리할 수 있어야 한다.
서버 설계 과정에서 데이터 분석 및 AI 개발자가 합류하였는데, 이때 AI 개발자가 전체 서버 구조를 처음부터 이해하지 않더라도 개발 및 유지보수 작업에 투입될 수 있도록 인터페이스를 명확히 정의할 필요가 있었다. 또한, DI와 IoC 원칙을 적용하여, 알고리즘이나 모델이 변경되더라도 서버 전체에 영향을 주지 않고 손쉽게 교체할 수 있는 구조를 구현하였다.
결과적으로 LLM 기능은 서버의 다른 구성요소들과 의존성을 최소화하면서도, 서비스 로직 및 UX/UI 계층과 유기적으로 연동될 수 있도록 설계되었다. 이를 통해 시스템은 AI 알고리즘 교체나 기능 확장 시에도 안정적으로 동작하며, 서비스의 확장성과 유연성을 크게 향상시켰다.
'DevLog' 카테고리의 다른 글
| DoQ 1차 시연 (0) | 2025.12.07 |
|---|---|
| [개발노트] 방토리 - AI 기반의 스마트 룸 컨디션 매니저 (1) | 2025.10.28 |
| 블챌 제출 시스템 개편 (4) | 2025.08.09 |
| LLM 스트리밍 UX를 위한 아키텍처 설계(1) (3) | 2025.08.01 |
| 프로젝트 관리 (2) | 2025.07.19 |