- 🧠 프로젝트 소개
- 👀 서비스 소개
- 📅 프로젝트 기간
- 📎 GitHub 주소 (Frontend / Backend / AI)
- ⭐ 주요 기능
- 🔁 서비스 동작 구조
- ⚙ 시스템 아키텍처
- 📊 ERD 다이어그램
- 🖥 화면 구성 미리보기
- 🛠 기술 스택
- 🧼 데이터 전처리 과정
- 📂 FastAPI 서버 디렉토리 구조
- 🛠 설치 및 실행 (AI 서버 FastAPI)
- 📌 사용 예시
- 🤯 트러블슈팅 요약
- 👨👩👧👦 팀원 역할
- 📄 라이선스
(Agent Tool 기반 AI 정서 케어 챗봇 서비스)
- 서비스명: Milo
- 서비스 설명:
정서 표현이 어려운 사람들을 위한 AI 기반 정서지원 챗봇 플랫폼
사용자의 감정을 기억하고, 분석하고, 회복 문장과 위로 메시지를 제공합니다.
상담형/리허설형 챗봇, 감정 아카이브, 분석 리포트까지 포함된 개인 맞춤형 감정 도우미입니다.
2025.05.14 ~ 2025.07.10 (약 8주)
- Frontend : https://github.com/suhwan87/milo-fe
- Backend (Spring) : https://github.com/suhwan87/milo-be
- AI Server (FastAPI) : https://github.com/julle0123/milo-ai
| 구분 | 설명 |
|---|---|
| 상담 챗봇 | 감정을 분석하고 위로의 말을 건네는 GPT 기반 상담 챗봇 |
| 역할극 챗봇 | 이름/관계/말투/상황을 설정한 감정 리허설 챗봇 |
| 감정 리포트 | 일일/월간 감정 흐름 요약 리포트 생성 및 저장 |
| 회복 문장 | 유사 감정 기반 회복 문장 저장 보관함 구성 |
| 회복 컨텐츠 | 대화 중 사용자의 감정 변동에 따라 감정 회복 컨텐츠 추천 |
| 시각화 기능 | 감정 이모지 캘린더 / 월간 감정 레이더 차트 |
| 위험 감지 | 감정 분석 결과 위기 신호 시 안정 응답 + 기관 연결 |
- 프론트 → 백엔드(Spring)로 사용자 발화 전송
- Spring → FastAPI로 사용자 질문/기록 전달
- FastAPI(GPT Agent) → 감정 분석, 키워드 추출
- Qdrant로 유사 감정 사례 검색 → GPT가 회복 피드백 생성
- FastAPI → 감정 리포트 + 회복 문장 추천 응답
- Spring → DB 저장 후 프론트로 최종 응답 전달
- 리포트/감정 흐름/회복 문장 시각화에 반영됨
로그인 |
메인 화면 |
비밀번호 찾기 |
아이디 찾기 |
회원가입 |
상담 챗봇 |
하루 감정 리포트 |
하루 감정 리포트 달력 |
감정 아카이브 |
상담 스타일 변경 |
역할 정하기1 |
역할 정하기2 |
역할 정하기3 |
역할 정하기4 |
역할 정하기5 |
역할 챗봇 |
회복문장 |
설정 |
문의하기 |
회원탈퇴 |
| 구분 | 사용 기술 |
|---|---|
| Frontend | |
| Backend | |
| AI Server | |
| AI & LLM | |
| Database | |
| Infra / Deploy | |
| 개발 도구 | |
| 기획 / 디자인 도구 | |
| 협업 도구 |
- AI Hub 감성 대화 말뭉치
- CounselGPT 한국어 심리상담 데이터셋
- 하이닥 심리상담 Q&A 크롤링
- 감정 분류용 라벨 데이터 (기쁨, 슬픔, 분노, 불안, 상처, 당황 등)
| 단계 | 설명 |
|---|---|
| 1. 중복 제거 | 동일 문장 또는 유사도 0.95 이상 문장 필터링 |
| 2. 비어 있는 행 제거 | 질문 또는 응답이 누락된 row 제거 |
| 3. 감정 라벨 정제 | 대분류 감정만 추출 (예: "불안_긴장" → "불안") |
| 4. 텍스트 분리 | 멀티턴 데이터를 싱글턴 데이터로 분리 |
| 5. 특수문자 제거 | [^ㄱ-ㅎ가-힣a-zA-Z0-9\s] 패턴으로 클렌징 |
| 6. 분류용 데이터셋 생성 | 감정 분석 학습용 text, label 컬럼 구성 |
- KCELECTRA 활용
- 만들어진 모델로 데이터 전체 감정분류 적용
- https://huggingface.co/Seonghaa/emotion-koelectra --> 만든 감정분류 모델
text,label
"요즘은 너무 지치고 잠도 잘 못 자요.","불안"
"기분이 좋고 뿌듯해요. 다 잘 될 것 같아요.","기쁨"
"그 사람이 또 나를 무시했어. 너무 화가 나.","분노"- openai 3-small-textembedding 모델 활용하여 감정 + 사용자입력 데이터 30만 문장 임베딩
- metadata에 입력에 대한 응답 등을 포함하여 qdrant 벡터 DB에 저장하여 rag에 활용
--> 프론트와 백엔드는 다른곳에 기록됨.
milp-ai/
├──.github
│ └── workflows # git-action
├──app
│ ├── api/ # 라우터 정의
│ │ ├── chat.py # 상담 챗봇 API
│ │ ├── chat_end.py # 채팅 종료 API
│ │ ├── log.py # 로그 저장 API
│ │ ├── report.py # 리포트 기록 API
│ │ └── roleplay.py # 역할극 API
│ ├── core/ # 공통 설정 모듈
│ │ ├── client.py # openai 설정
│ │ ├── config.py # Settings(.env)
│ │ └── db.py # DB 연결 / 세션 관리
│ ├── models/ # SQLAlchemy 모델
│ │ ├── __init__.py # Python 패키지 인식용 파일 (import 가능하게 함)
│ │ ├── base.py # Base 선언
│ │ ├── chat_log.py # 상담 대화 기록DB
│ │ ├── daily_emotion_report.py # 하루 감정 리포트DB
│ │ ├── monthly_emotion_summary.py # 월간 감정 리포트DB
│ │ ├── rolecharacter.py # 역할DB
│ │ ├── role_play_log.py # 역할 챗봇 대화 기록 DB
│ │ ├── schema.py # 공통 Pydantic 스키마
│ │ └── user.py # 유저DB
│ ├── prompt/ # GPT 시스템 프롬프트 정의
│ │ ├── emotion_prompt_emotional.txt # 공감형(F) 프롬프트
│ │ ├── emotion_prompt_practical.txt # 조언형(T) 프롬프트
│ │ └── roleplay_prompt.txt # 역할 챗봇 프롬프트
│ ├── services/ # 비즈니스 로직 처리
│ │ ├── agent.py # AgentTool 기반 응답 생성
│ │ ├── agent_roleplay.py # 역할극 응답 처리
│ │ ├── emotion_service.py # 감정 분석/백터화
│ │ ├── memory.py # 기억 공간
│ │ ├── rag_service.py # rag 기능
│ │ └── report_service.py # 감정 리포트 저장 및 업데이트
│ ├── main.py # FastAPI 앱 진입점
├── .env # 환경 변수 설정 파일
├── .gitignore # git push 무시
├── Dockerfile # FastAPI Docker 배포 환경
├── README.md # 프로젝트 설명 파일
├── docker-compose.yml # 전체 서비스 연동 설정
└── requirements.txt # 의존성 목록
# 1. 가상환경 생성 및 활성화 (선택)
python -m venv venv
source venv/bin/activate
# 2. 라이브러리 설치
pip install -r requirements.txt
# 3. FastAPI 실행
uvicorn main:app --reload --port 8000"요즘 너무 불안하고 잠이 안 와요… 혼자 있는 게 무서워요."
- 주요 감정:
불안(0.91), 슬픔(0.68) - 대표 감정:
불안
여러 상담 데이터와 유사한 대화 3건 추출 후 GPT 프롬프트에 포함
"당신이 지금 느끼는 불안은 결코 가벼운 것이 아니에요.
누군가에게 기대고 싶다는 감정은 자연스러운 거예요.
너무 혼자 버티려고 하지 마세요. 함께 있어줄게요."
- 상담 내용 →
chat_log_TB - 감정 분석 결과 →
daily_emotion_report_TB - GPT 응답 → 회복 문장 추천 또는 저장 유도
- 3일 이상 하루 감정 분석 리포트가 작성 시 감정 아카이브 작성 ->
monthly_emotion_summary_TB
| 문제 | 원인 | 해결 |
|---|---|---|
| agent 구성시 create_react_agent()에서 agent_scratchpad 변수에 문제 발생 | 변수가 문자열로 전달되는데, 실제로는 메시지 리스트를 기대하기 때문에 발생, create_react_agent()는 특정한 프롬프트 구조를 요구, agent_scratchpad는 MessagesPlaceholder가 아닌 일반 문자열 플레이스홀더여야 함. |
create_react_agent에서 create_openai_functions_agent로 전환 |
| async def 기반으로 서비스 함수 수정 이후, 일부 DB 호출이나 OpenAI API 응답이 정상 동작하지 않음. | SQLAlchemy의 Session 객체는 기본적으로 동기이며, 이를 async 함수에서 그대로 사용할 경우 오류 발생. | 비동기 처리를 도입하되, DB 작업은 여전히 sync 방식으로 유지하거나 AsyncSession을 명확히 도입해야 함. 또는 asyncio.run() 사용을 피하고 명시적으로 await 처리해야 함. |
| TrainingArguments 클래스의 evaluation_strategy 인자에서 오류가 발생 | TrainingArguments 클래스의 evaluation_strategy 인자가 eval_strategy로 변경되어 기존 코드에서 evaluation_strategy를 사용하면 다음과 같은 오류가 발생 | 코드에서 TrainingArguments를 정의할 때 evaluation_strategy를 eval_strategy로 변경하면 문제가 해결! |
| EmotionSummary를 사용하여 GPT 응답을 구조화하고자 할 때, JsonOutputParser로 파싱한 후 .joy 같은 속성 접근 시 오류가 발생 | - LangChain의 JsonOutputParser는 pydantic_object=EmotionSummary 옵션을 사용하더라도 내부적으로 parsing이 실패하면 dict로 fallback 되는 경우가 있음. 이때 parsed.joy처럼 객체 속성으로 접근하면 오류 발생 마찬가지로 .dict() 메서드도 dict에는 존재하지 않기 때문에 에러가 발생 |
모든 필드 접근을 딕셔너리 키 방식으로 변경 summary, feedback, encouragement 등 모든 필드를 parsed_dict['필드명'] 형태로 접근하도록 수정 |
| 이름 | 역할 | GitHub |
|---|---|---|
| 김성하 | PM / 데이터 전처리 / DB 설계 / ERD 설계 / AI 모델링 / FastAPI 서버 | @julle0123 |
| 정수한 | 데이터 수집 / 데이터 전처리 / 프롬프트 설계 / AI 모델링 / FastAPI 서버 | @s2-honey |
| 김수환 | 프론트엔드 구현 / UI 구성 / 디자인 / Spring Boot API / DB 연동 | @suhwan87 |
| 김서연 | 프론트엔드 구현 / UI 구성 / 디자인 / Spring Boot API / DB 연동 | @kimseoyeon21 |
본 프로젝트는 오픈된 학습 자료로 누구나 자유롭게 사용할 수 있습니다.