
프로젝트 개요
제목: 방토리 - AI 기반의 스마트 룸 컨디션 매니저
기간: 25년 6월 6일 ~ 25년 9월 26일 (112일)
팀원: 정상민(팀장), 박민용, 이민규, 이효근, 조은비
수상: 다학제 캡스톤 공모전 아이디어 우수상 수상
방학부터 학기 초까지 기계공학과, 소프트웨어학부 학우분들과 진행했던 프로젝트 입니다.
공학대학에서 주도로 진행한 다학제 캡스톤인데, 본선 기준으로는 유일한 다빈치 캠퍼스 학생이자 예술공학대학 학생으로 참가했습니다. 전시 당일에 오고가며 부스를 발견하신 분들도 있던 것 같더라구요. (특히 피지컬 컴퓨팅 수강하시는 분들께 제보를 많이 받았습니다 ㅋㅋㅋ…) 매년 열리는 대회인 듯 하니 참고하셔서 공모전 참가하시면 좋을 것 같습니다.
저는 AI M/W 서버 개발, LLM 프롬프팅, PPT 제작 및 UX/UI 등 디자인 부분을 전담해 개발했습니다. 참고로 현재 블챌에 함께 해주시고 있는 이효근님이 프론트 개발을 담당했습니다.


1. 기획
기획은 본선 발표에 사용하였던 PPT로 간단히 줄이겠다. 청결관리가 꾸준히 필요한 공간에 ‘스마트 룸 컨디셔너 어플리케이션’을 솔루션으로 제안했다.



2. 설계 및 기술
설계는 하드웨어와 소프트웨어로 나누어 진행했다. 하드웨어 설계 및 프로그래밍은 기계공학과인 정상민 팀장님이 담당하였고, 소프트웨어 부분은 저를 포함하여 4명의 팀원이 프론트엔드와 백엔드로 나누어 설계 및 개발했다. 설계 및 기술 세부 항목 또한 PPT로 짧게 줄인다.
2-1. 하드웨어


2-2. 소프트웨어





3. lesson learn
3-1. 아쉬운 점
아키텍처 설계에 있어 아쉬운 부분이 많았다. 이번 프로젝트에서는 기능 구현을 1순위로 두어, 모든 통신을 REST API로만 처리했다. 구현 난이도는 낮은 편으로 구조 또한 단순하지만 실제 운영에서는 IoT 모니터링 시스템의 필수 요구사항인 ‘실시간성’을 전혀 만족하지 못했다.
api 호출을 사용하기 때문에 센서 데이터나 가전 제어 상태를 api 호출로 확인하여야 변화 여부를 파악할 수 있다. 즉, 서버와 디바이스가 각자 n초 간격으로 데이터를 polling하여 센서 데이터나 가전 제어 상태를 반영한다. 따라서 서버와 디바이스 간의 호출 주기가 누적되며 시차가 발생, 이벤트가 즉각적으로 반응하지 않는 문제로 이어졌다.
회사에서는 MQTT 기반의 이벤트 기반 pub/sub 구조를 사용했기때문에 이런 지연 문제를 체감할 일이 거의 없었다. 그래서 너무 당연하게 MQTT, Redis, RabbitMQ를 사용하고 ‘왜 필요한가’에 대해 생각해볼 일이 없었는데 이번에 직접 경험해보면서 아… 이래서 쓰는구나… 싶었다. 앞으로는 굳이 똥찍먹을 안해도 똥인갑다. 구분이 가능하겠지...
3-2. 성과 - LLM 통합 I/F 개발
프로젝트를 진행하면서 Prompt + LangChain 기반 LLM 인터페이스를 완전히 분리했다.
자세한 I/F 설계 참고: https://wavicle.tistory.com/21
[캡스톤] LLM 인터페이스 설계
서버 아키텍처와 LLM 통합 구조현재 서버는 DB, Redis, MQ, WebSocket 등의 주요 기능을 AppContext 기반으로 통합 관리하고, 서비스 로직에서는 이를 유틸리티 레이어를 통해 일관되게 호출하는 구조를 채
wavicle.tistory.com
llm_manager
해당 매니저에 프롬프트 세트만 전달, 바로 LLM 모델을 호출하여 사용할 수 있다.
// 호출 예시
resp_text = await ctx.llm_manager.generate(
DAILY_REPORT_PROMPTS,
placeholders={"metrics": metrics},
temperature=0.7
)
- Provider 관리: 현재 프로젝트에서는 google gemini api를 사용하고 있다. 추후 chatGPT, ollama 등 다른 모델 api 로 변경가능 하도록 설계했다.
- 비동기 호출 구조
- 프롬프트 합성 시스템: {{ metrics }} 같은 플레이스홀더를 자동 치환하도록 파서 함수를 구현했다. 프롬프트는 문자열 또는 리스트 형태로 전달 가능.
- 결과 파싱
API는 단순 데이터 수집+LLM 호출+응답 파싱만 담당하도록 하여 LLM 관련 로직은 서비스 계층에서 분리될 수 있도록 했다.
Prompts 구조화
AI가 수행하는 각 분석 목적별로 프롬프트를 템플릿화했다.
방토리 서비스에서 사용하는 프롬프트 목록은 아래와 같다. 크게 역할/기준/출력형식으로 나누어 모듈화하였고, 필요에 따라 리스트로 조합하여 사용할 수 있도록 했다.
- INITIAL_PROMPT : AI의 역할 정의
- ANALYSIS_CRITERIA : 오염도 기준, 온습도 적정 범위 등 명시
- GENERATE_DAILY_REPORT : 하루 단위 평가
- GENERATE_MONTHLY_REPORT : 월간 요약 평가
- GENERATE_TIP_REPORT : 생활 카테고리 추천용
- JSON_OUTPUT_PROMPT : “모든 답변은 JSON으로 작성” 규칙 삽입
/dailyReport, /monthlyReport, /category 등의 API 엔드포인트에서 각각 다른 프롬프트 세트를 호출하여 사용한다. 이때 호출하는 프롬프트 세트의 예시는 아래와 같다.
// 프롬프트 세트 예시
SYSTEM_PROMPTS = [INITIAL_PROMPT, ANALYSIS_CRITERIA]
DAILY_REPORT_PROMPTS = [INITIAL_PROMPT, ANALYSIS_CRITERIA, GENERATE_DAILY_REPORT, JSON_OUTPUT_PROMPT]
MONTHLY_REPORT_PROMPTS = [GENERATE_MONTHLY_REPORT, JSON_OUTPUT_PROMPT]
TIP_REPORT_PROMPTS = [GENERATE_TIP_REPORT, JSON_OUTPUT_PROMPT]
전체 플로우 요약
FastAPI (llm_api)
↓
LLMManager (llm_manager)
↓
Prompts Registry (prompts_cfg)
↓
Prompt Templates (bantori_prompts)
↓
Gemini API (LLM)
- REST API → ctx.llm_manager.generate() 호출
- LLMManager → 프롬프트 합성 및 Gemini 호출
- Prompts 레이어 → 구조화된 템플릿 제공
- 결과는 parse_reports()를 통해 JSON 응답으로 변환하여 API에 전달
'DevLog' 카테고리의 다른 글
| LLM 정량평가하기(2) - 시나리오 기반의 AI 챗봇 테스트 자동화 (0) | 2026.01.08 |
|---|---|
| 아키텍처 재사용성 및 확장성 검증 (cloc 분석) (0) | 2025.12.07 |
| [개발노트] 둥동 제작기 - 둥지동지 2.0.0 개발노트 (0) | 2025.10.17 |
| 블챌 제출 시스템 개편 (4) | 2025.08.09 |
| LLM 스트리밍 UX를 위한 아키텍처 설계(1) (3) | 2025.08.01 |