
지난 이야기 이후, 이번 3편에서는 중간발표 후의 기능 고도화와 백엔드 개발에 대해 서술해보려 합니다. 1, 2편을 읽지 않으신 분들은 순서대로 봐주시면 감사하겠습니다 :D
Team Project: PetMind, 반려견 상담 AI 챗봇 개발기(1) 바로가기
Team Project: PetMind, 반려견 상담 AI 챗봇 개발기(2) 바로가기
기능 고도화는 여러가지 방면에서 이루어졌는데요.
우선 중간발표 시 지적 받았던 응답 시간을 개선하기 위해 노력하였으며, 초기 반려견 등록 시 반려견의 성향을 상담해 반영함과 동시에 재미요소를 더한 반려견 MBTI 검사 기능, 상담 내용을 기반으로 한 관련 콘텐츠 추천 기능, 반려견별 그동안의 상담 내용을 요약하여 분석하는 상담 요약 리포트 기능, 피드백 기능, 사진 인식이 가능한 멀티 모달 구조 등을 추가하였습니다.
개발 당시 평균 응답 속도는 18초 정도였는데, 프롬프트를 수정하고 로직을 변경하는 등 수정을 거친 뒤, 그라디오로 시간을 확인해보니 3~40초 정도로 크게 지연되었습니다. 해당 문제를 해결하기 위해 여러 시도를 해보았는데요:
시스템 프롬프트 길이 수정:
시스템 프롬프트의 문맥을 유지한 채 간결하게 수정하여 평균 2~3초 가량의 시간이 단축되었습니다.
GPU 사양 변경:
기존 사용하던 RunPod의 GPU 사양을 업그레이드 하여 속도가 크게 개선되었습니다.(약 10초 단축)
max_new_tokens 최적화:
응답 토큰 수를 2048 → 1024로 줄였고, 속도가 크게 개선되었습니다.(8~10초 단축)
Streaming 적용:
모델 응답 시 스트리밍을 적용하여 사용자의 체감 응답 속도를 개선하였습니다.
장기기억 구조 적용:
모델 응답 시 이전 상담 내역을 참고하여 새로운 대답을 생성하는데 기존 채팅 내역이 많을 경우 참조하는데 시간이 오래 걸리는 문제가 있어, 10턴마다 대화를 요약 → 저장하여 상담의 연속성과 맞춤형을 유지하면서도 저장 공간을 절약하고 응답 속도를 일부 향상 시켰습니다.
LangChain → LangGraph 구조 변경:
그 밖에 기존 LangChain 구조에서 LangGraph 구조로 변경하였는데, 오히려 응답 속도가 저하되어 기존 구조를 유지하였습니다.
반려견 MBTI:
단순 챗봇이 아닌 반려견의 특징을 반영한 맞춤형 챗봇 구현에 집중하기 위해 반려견 첫 등록 시, 성향 파악을 위한 요소로 견BTI(강아지 MBTI)를 추가하였습니다. 해당 기능은 GPT-4o 모델로 생성된 12문항을 통해 반려견의 성향을 파악하여 상담에 반영함과 동시에, 보호자는 자신의 반려견의 MBTI를 검사할 수 있는 재미 요소로, 사용자 유입을 유도하는 장치입니다.


추천 콘텐츠 시스템:
추천콘텐츠 시스템은 상담 내용 벡터화 + TF-IDF + 코사인 유사도 기반의 추천 방식으로 작동합니다. DB에 저장된 콘텐츠와 상담 내용을 유사도 순으로 정렬하여 상위 3개의 콘텐츠를 보여주는 알고리즘으로 관련성 높은 콘텐츠의 본문 요약과 원문 URL을 제공함으로써 클릭시 해당 페이지로 이동할 수 있도록 하였습니다.

상담 요약 리포트:
의료와 같이 민감한 정보를 직접 제공하기 어려운 상황을 고려하여, 사용자가 선택한 일자의 상담 내역을 요약해 리포트 형식의 PDF 파일 다운로드 → 전문가와의 상담을 연결할 수 있는 기능을 구현하였습니다. 상담리포트는 GPT-4o 모델에 시스템 프롬프트 설정 + 원샷 프롬프트를 통해 요약하여 생성합니다. 응답 모델인 Qwen3를 포함하여 타 오픈소스 모델과도 비교해 보았으나, 정성적(요약 내용) + 정량적(생성 시간)으로 고려하였을 때, GPT-4o가 압도적으로 우수하였습니다. 
system_prompt = (
"너는 반려견 상담 리포트를 요약해주는 요약 전문 모델이야. "
"보호자에게 전달하는 **친절하고 정리된 요약문** 형태로 작성해줘. "
"어렵고 전문적인 용어는 피하고 쉽게 설명해줘. "
"아래 형식을 그대로 따르고 예시는 절대 출력하지 마. "
"각 문단별 3~4줄 정도로 작성하고, 문단의 시작에 절대 띄어쓰기는 하지마."
)
# One-shot 예시
oneshot_example = """
**우리 마루는요**
마루, 5살, 푸들, 함께 산 지 3년 미만, 중성화 완료, 아파트에 살아요.
마루는 5살 푸들이며 함께한 지 3년이 채 되지 않았어요. 최근 들어 산책 중 소리에 민감한 반응을 일으키는데 특히 어린 아이들의 소리를 경계하는 것으로 보여요. 이런 변화는 휴식 부족, 스트레스의 문제일 수 있어요.
**보호자님에게 드리는 조언**
1. 고주파 소리에 대한 민감성 완화 훈련이 필요합니다.
2. 휴식 공간 마련을 권장합니다.
**다음 상담 시에는**
- 다음 상담일: 2025년 06월 06일
- 관찰 포인트: 자극 반응 및 훈련 성공 여부를 기록해주세요.
"""

백엔드는 Django 기반의 MVT(Model-View-Template) 아키텍처로 구성하였는데요,
데이터베이스 구조: MySQL DB 사용
- User 모델: 사용자 계정 관리 (UUID 기반, 이메일 인증)
- DogBreed & DogProfile 모델: 반려견 정보 및 견종 데이터
- Chat & Message 모델: 채팅방 및 메시지 저장
- Content & UserReview 모델: 추천 콘텐츠 및 사용자 피드백
앱 구조 및 라우팅: 3개의 독립적인 앱으로 기능 분리
- User 앱 (''): 홈페이지, 회원가입, 로그인, 사용자 관리
- Chat 앱 ('chat/'): 채팅 시스템, 리포트 생성, 추천 콘텐츠
- Dogs 앱 ('dogs/'): 반려견 프로필, 성격 검사
API 설계: DRF 혼합 API 구조를 사용
- REST API: 리포트 생성/다운로드, 상태 확인
- AJAX API: 실시간 채팅, 추천 콘텐츠, 성격 검사
- 외부 API 통합: RunPod(Qwen3-8B), OpenAI(GPT-4o)
이와 같이 Django 기반으로 데이터 모델, 앱 구조, 다양한 API 연동을 통해 사용자 맞춤형 서비스를 안정적으로 제공할 수 있도록 설계하였으며, RESTful API와 AJAX, 외부 AI API 통합을 통해 실시간 상호작용과 확장성을 모두 확보할 수 있도록 하였습니다.
그런데 개발 포스팅을 위해 코드를 다시 확인해보니 당시에는 몰랐던 보완할 점들이 눈이 띕니다. 예를 들어 기존 코드는 비밀번호가 해시되지 않고 평문으로 저장되어 보안 이슈가 있습니다.
# user/views.py - 기존 코드(평문 저장)
user.password == password
위처럼 password를 암호화하지 않고 DB에 저장할 경우 해킹의 위험이 매우 높기 때문에 아래처럼 Django에서 제공하는 user.set_password() 메서드를 사용해 비밀번호를 안전하게 관리할 수 있습니다.
# 수정 코드(해시 적용)
user = User(email="a@b.com")
user.set_password("plain_password") # 내부적으로 salt + 해시 적용
user.save()
해시는 단방향 암호화와 비슷한 개념으로 사용자가 mypassword123을 입력하면, DB에는 $argon2id$v=19$m=65536,t=3,p=4$... 이런식으로 저장되며 다음과 같은 특징을 가지고 있습니다:
위와 같은 특징으로 비밀번호를 안전하게 저장 가능하니, 다음에 개발할 때는 해당 메서드를 꼭 활용해야겠습니다!
길고 긴 2개월 여정의 3/4을 막 지났습니다.
마지막인 4편에서는 프론트엔드와 배포의 과정을 담아서 돌아오겠습니다.
읽어주셔서 감사합니다! XD