← Projects
진행 중개인 토이 프로젝트

햄이 (Hami)

자연어로 대화하며 일정 관리하는 데스크톱 펫 앱

일정 앱은 직접 열어야만 확인할 수 있어 자주 잊게 됩니다. 화면 위에 항상 머무는 햄스터가 말을 걸고, 자연어로 일정을 받아 정리해 주는 데스크톱 펫으로 일정 관리의 접근성을 높이고자 했습니다.

햄이 (Hami) 대표 화면
기간
2026.07 ~ (MS Store 배포 준비 중)
인원
개인
내 역할
기획부터 설계, 개발까지 전부

기술 스택

  • Electron
  • React
  • TypeScript
  • Gemini API
  • electron-store

아키텍처

Renderer(React)는 Preload(contextBridge)를 거쳐 IPC로만 Main Process에 요청할 수 있습니다. Gemini API 호출, 로컬 저장소, 트레이와 알림은 Main Process에서만 다룹니다.
Renderer(React)는 Preload(contextBridge)를 거쳐 IPC로만 Main Process에 요청할 수 있습니다. Gemini API 호출, 로컬 저장소, 트레이와 알림은 Main Process에서만 다룹니다.

내가 한 일

  • 투명하고 프레임 없는 펫 창을 만들었습니다. 드래그로 옮길 수 있고, 다시 켜도 마지막 위치가 복원되며, 투명 영역은 클릭이 뒤쪽 프로그램으로 통과합니다. 시스템 트레이도 구현했습니다.
  • 7가지 감정 상태 머신과 픽셀아트 애니메이션, 타자기 효과 말풍선을 구현했습니다.
  • Gemini API로 자연어 일정 등록, 수정, 삭제 대화를 구현했습니다. 정보 수집, 확인, 실행 단계를 거쳐 사용자가 승인한 뒤에만 등록하고, "다음 주 월요일" 같은 상대 날짜는 KST 기준으로 계산합니다.
  • 월간 달력 다이어리, 할 일, 뽀모도로 타이머, AI 감성 일기, 리마인더 알림, 공휴일 표시 기능을 만들었습니다.
  • contextBridge와 IPC 입력 검증으로 Renderer와 Main 사이의 보안 경계를 설계하고, 단일 인스턴스를 보장했습니다.
  • electron-builder로 Windows x64 portable 패키징을 했습니다.

트러블슈팅

01함수 반복 호출로 인한 API 오류와 응답 지연

증상
일정 등록 대화 중 AI가 필요한 정보를 확인하려고 함수를 반복 호출해서 Rate Limit에 걸리고 응답이 느려졌습니다.
원인
같은 요청이 중복 실행되고, 대화가 끝나기 전에 여러 함수 호출이 동시에 일어났습니다.
해결
한 번의 요청에서 실행할 수 있는 함수 호출 범위를 제한하고, 요청 큐로 Gemini 호출을 하나씩 직렬화했습니다. Rate Limit 응답에는 최대 3회 재시도하고, 타임아웃과 예외 처리를 추가했습니다.
요청 큐로 동시 호출을 제어한 과정
요청 큐로 동시 호출을 제어한 과정

02모호한 자연어 표현으로 인한 일정 정보 누락

증상
"금요일쯤 약속", "다음 주에 병원" 같은 표현에서 날짜나 시간이 빠지거나 파싱에 실패했습니다.
원인
AI 응답 형식이 일정하지 않아, 임의로 해석하면 잘못된 일정 데이터가 만들어졌습니다.
해결
필수 필드와 대화 단계를 담은 응답 스키마를 정의해 검증하고, 정보가 모호하면 추가 질문을 하게 했습니다. 저장 전에는 내용을 요약해 보여 주고, 사용자가 명확히 승인한 경우에만 등록합니다.
스키마 검증과 확인 단계로 잘못된 등록을 막은 과정
스키마 검증과 확인 단계로 잘못된 등록을 막은 과정

설계 결정

AI의 역할

선택지
자유 대화 챗봇 vs 자연어를 구조화된 일정 데이터로 바꾸는 도구
결정
구조화 변환과 감성 피드백(일기 코멘트)으로 역할을 좁혔습니다.
근거와 한계
일정 데이터는 틀리면 안 되기 때문에, LLM 출력은 스키마로 검증하고 사용자가 명시적으로 확인한 뒤에만 저장합니다.

데이터 저장

선택지
서버와 DB vs 로컬 저장소(electron-store)
결정
서버 없이 로컬 저장소에 저장했습니다.
근거와 한계
개인 일정이라 외부 서버 없이 빠르고 단순하게 동작하지만, 여러 기기 간 동기화는 지원하지 않습니다.

API 키 방식

선택지
앱에 키를 내장 vs 사용자가 자신의 Gemini 키를 입력(BYOK)
결정
BYOK 방식을 택했습니다.
근거와 한계
배포 앱에 비밀값이 들어가지 않습니다. 다만 입력받은 키를 아직 암호화하지 않고 저장하고 있어, 배포 전에 개선해야 합니다.

결과

배운 점

  • LLM 출력은 그대로 믿지 않고, 스키마 검증과 사용자 확인을 거쳐야 실제 데이터로 쓸 수 있다는 것을 배웠습니다.
  • 외부 API 호출은 Rate Limit을 전제로 요청 큐, 재시도, 타임아웃을 설계해야 안정적으로 동작한다는 것을 경험했습니다.

한계

  • 사용자가 입력한 Gemini API 키를 아직 암호화하지 않고 로컬에 저장합니다.
  • Windows 전용이며, 현재는 개발자 본인만 사용하고 있습니다.

진행 계획 (MS Store 배포)

  • API 키를 Electron safeStorage로 암호화해 저장
  • electron-builder에 MSIX 패키징 대상 추가
  • GitHub Actions로 typecheck, build, MSIX 생성까지 자동화
  • Partner Center 등록, 개인정보처리방침과 스토어 등록 정보 준비
  • Store 제출과 인증을 거쳐 출시하고, 이후 버전 관리와 업데이트 배포
햄이 (Hami) | Changmin.dev