ChromaDB + LangChain RAG 기반 유재석 AI 챗봇 서비스
이 프로젝트는 유재석의 성격과 말투를 모방한 AI 챗봇 서비스입니다. ChromaDB를 벡터 데이터베이스로 사용하고, LangChain RAG(Retrieval-Augmented Generation) 방식으로 구현되었습니다.
- FastAPI: 고성능 웹 API 프레임워크
- ChromaDB: 로컬 벡터 데이터베이스로 유재석 관련 지식 저장
- LangChain RAG: 검색 증강 생성으로 정확한 답변 제공
- Upstage Solar API: 한국어 특화 LLM 및 임베딩 모델 사용
- 유재석 페르소나: 친근하고 유머러스한 국민MC 스타일
- Backend: FastAPI, Python 3.11
- Vector DB: ChromaDB (로컬 저장)
- AI Models: Upstage Solar Pro (LLM), Solar Embedding (임베딩)
- Framework: LangChain
- Deployment: AWS EC2 (계획)
중요: langchain_upstage와 langchain_chroma 패키지는 Python 3.13.x에서 호환성 문제가 있습니다.
반드시 Python 3.11 버전을 사용해야 합니다.
- Python: 3.11.x (필수)
- 메모리: 최소 4GB RAM
- 저장공간: 최소 2GB (ChromaDB 포함)
- 네트워크: Upstage API 접근을 위한 인터넷 연결
# 1. venv311이라는 이름으로 가상환경 생성
py -3.11 -m venv venv311
# 2. 가상환경 활성화
.\venv311\Scripts\activate
# 3. pip 업그레이드 및 의존성 설치
pip install --upgrade pip
pip install -r requirements.txt.env 파일을 생성하고 다음 내용을 추가:
# Upstage API 키 (필수)
UPSTAGE_API_KEY=your_upstage_api_key_here
# ChromaDB 설정
CHROMA_PERSIST_DIR=./chroma_db
# FastAPI 서버 설정
HOST=0.0.0.0
PORT=8000
LOG_LEVEL=info
# 환경 설정
ENVIRONMENT=developmentbackend/
├── 📄 main.py # FastAPI 메인 애플리케이션
├── 📄 chatbot.py # 유재석 RAG 챗봇 클래스
├── 📄 run.py # 서버 실행 스크립트
├── 📄 test_chatbot.py # 챗봇 단독 테스트 스크립트
├── 📄 requirements.txt # Python 의존성 패키지
├── 📄 .env # 환경변수 설정 파일
├── 📄 README.md # 프로젝트 문서 (이 파일)
├── 📄 Dockerfile # Docker 컨테이너 설정
├── 📁 chroma_db/ # ChromaDB 벡터 데이터베이스 (팀원 제공 예정)
├── 📁 venv311/ # Python 3.11 가상환경
├── 📁 .git/ # Git 버전 관리
├── 📁 .github/ # GitHub Actions 워크플로우
├── 📁 events/ # 테스트용 이벤트 파일
├── 📁 tests/ # 단위 테스트 파일들
└── 📁 __pycache__/ # Python 캐시 파일
역할: 웹 API 서버의 진입점
주요 기능:
- FastAPI 애플리케이션 설정 및 CORS 처리
- 생명주기 관리 (lifespan 이벤트)
- API 엔드포인트 정의 (
/answer,/health,/) - 요청/응답 모델 정의 (Pydantic)
- 예외 처리 및 로깅
핵심 클래스:
ChatRequest: 사용자 요청 모델ChatResponse: 챗봇 응답 모델HealthResponse: 헬스체크 응답 모델
역할: 유재석 AI 챗봇의 핵심 로직
주요 기능:
- Upstage Solar API 연동 (LLM + 임베딩)
- ChromaDB 벡터 데이터베이스 연결
- LangChain RAG 파이프라인 구성
- 유재석 페르소나 프롬프트 관리
- 답변 생성 및 품질 관리
핵심 메서드:
_setup_models(): AI 모델 초기화_load_chromadb(): 벡터 DB 로드_setup_rag_chain(): RAG 체인 구성get_answer(): 답변 생성health_check(): 상태 확인
역할: FastAPI 서버 실행 및 환경 관리
주요 기능:
- 환경변수 검증 및 설정
- 개발/운영 환경 구분
- 서버 설정 최적화
- AWS EC2 배포 지원
역할: 챗봇 기능 단독 테스트
주요 기능:
- 챗봇 초기화 테스트
- 헬스체크 검증
- 대화 기능 테스트
- 대화형 테스트 모드
http://localhost:8000
GET /응답 예시:
{
"service": "유재석 AI 챗봇",
"version": "1.0.0",
"description": "ChromaDB + LangChain RAG 기반",
"endpoints": {
"POST /answer": "챗봇과 대화",
"GET /health": "서비스 상태 확인"
},
"example": {
"request": {"prompt": "안녕하세요!"},
"response": {"answer": "안녕하세요! 유재석입니다! 하하하!"}
}
}POST /answer
Content-Type: application/json요청 본문:
{
"prompt": "유재석님의 대표 프로그램은 뭐예요?"
}응답 본문:
{
"answer": "아! 제 대표 프로그램이라고 하면 무한도전과 런닝맨이 있죠! 무한도전은 2006년부터 2018년까지 정말 즐겁게 했고, 런닝맨은 2010년부터 지금까지 계속하고 있어요! 하하하!"
}오류 응답:
// 400 Bad Request - 빈 프롬프트
{
"detail": "빈 메시지는 보낼 수 없습니다."
}
// 503 Service Unavailable - 챗봇 미초기화
{
"detail": "챗봇이 초기화되지 않았습니다. 잠시 후 다시 시도해주세요."
}
// 500 Internal Server Error - 서버 오류
{
"detail": "답변 생성 중 오류가 발생했습니다. 다시 시도해주세요."
}GET /health응답 예시:
{
"status": "healthy",
"message": "서비스가 정상 작동 중입니다.",
"vectorstore_status": "connected",
"documents_count": 1247
}| 코드 | 설명 |
|---|---|
| 200 | 성공 |
| 400 | 잘못된 요청 (빈 프롬프트 등) |
| 405 | 지원하지 않는 HTTP 메서드 |
| 500 | 서버 내부 오류 |
| 503 | 서비스 사용 불가 (챗봇 미초기화) |
graph LR
A[사용자 질문] --> B[임베딩 변환]
B --> C[ChromaDB 검색]
C --> D[관련 문서 추출]
D --> E[프롬프트 구성]
E --> F[Solar Pro LLM]
F --> G[유재석 답변]
embeddings = UpstageEmbeddings(
model="solar-embedding-1-large",
api_key=upstage_api_key
)- 역할: 텍스트를 벡터로 변환
- 사용 시점: 질문 검색 시, 데이터 저장 시
llm = ChatUpstage(
model="solar-pro",
api_key=upstage_api_key
)- 역할: 최종 답변 생성
- 특징: 한국어 특화, 대화 형태
vectorstore = Chroma(
client=client,
embedding_function=embeddings,
collection_name="yujaeseuk_knowledge"
)- 역할: 유재석 관련 지식 저장 및 검색
- 검색 알고리즘: MMR (Maximal Marginal Relevance)
retriever = vectorstore.as_retriever(
search_type="mmr",
search_kwargs={"k": 3}
)- 역할: 질문과 관련된 상위 3개 문서 검색
- 알고리즘: MMR (관련성과 다양성 고려)
prompt = ChatPromptTemplate.from_messages([
("system", "당신은 유재석입니다. 성격: 밝고 긍정적..."),
("human", "{question}")
])- 역할: 유재석 페르소나 정의
- 구성: 시스템 프롬프트 + 사용자 질문
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)- 역할: 전체 파이프라인 연결
- 흐름: 검색 → 프롬프트 → LLM → 파싱
sequenceDiagram
participant User as 사용자
participant FastAPI as FastAPI 서버
participant ChatBot as YuJaeSukRAGBot
participant Upstage as Upstage API
participant ChromaDB as ChromaDB
User->>FastAPI: python run.py
FastAPI->>ChatBot: 챗봇 초기화
ChatBot->>Upstage: API 키 검증
ChatBot->>ChromaDB: 벡터 DB 연결
ChatBot->>ChatBot: RAG 체인 구성
ChatBot-->>FastAPI: 초기화 완료
FastAPI-->>User: 서버 실행 준비
sequenceDiagram
participant User as 사용자
participant FastAPI as FastAPI
participant ChatBot as 챗봇
participant Embeddings as 임베딩 모델
participant ChromaDB as ChromaDB
participant LLM as Solar Pro
User->>FastAPI: POST /answer {"prompt": "질문"}
FastAPI->>ChatBot: get_answer("질문")
ChatBot->>Embeddings: 질문 벡터화
Embeddings-->>ChatBot: 질문 벡터
ChatBot->>ChromaDB: 유사 문서 검색
ChromaDB-->>ChatBot: 관련 문서 3개
ChatBot->>LLM: 프롬프트 + 검색 결과
LLM-->>ChatBot: 유재석 스타일 답변
ChatBot-->>FastAPI: 최종 답변
FastAPI-->>User: {"answer": "답변"}
# 사용자 질문: "유재석 프로그램은?"
question_vector = embeddings.embed_query("유재석 프로그램은?")
# 결과: [0.1, 0.5, -0.3, 0.8, ...]# ChromaDB에서 MMR 알고리즘으로 검색
similar_docs = vectorstore.similarity_search(
query="유재석 프로그램은?",
k=3
)
# 결과: ["무한도전은...", "런닝맨은...", "해피투게더..."]system_prompt = "당신은 유재석입니다..."
context = "무한도전은... 런닝맨은... 해피투게더..."
user_question = "유재석 프로그램은?"
final_prompt = f"{system_prompt}\n참고정보: {context}\n질문: {user_question}"response = llm.invoke(final_prompt)
# 결과: "아! 제 대표 프로그램이라고 하면 무한도전과 런닝맨이 있죠!"📝 사용자 입력
↓ (FastAPI 검증)
🔍 질문 벡터화 (Solar Embedding)
↓ (MMR 검색)
📚 ChromaDB 문서 검색
↓ (컨텍스트 구성)
🎭 유재석 프롬프트 + 검색 결과
↓ (Solar Pro LLM)
💬 유재석 스타일 답변 생성
↓ (FastAPI 응답)
✅ JSON 형태로 반환
# 프로젝트 클론
git clone <repository-url>
cd backend
# Python 3.11 가상환경 생성
py -3.11 -m venv venv311
# 가상환경 활성화
.\venv311\Scripts\activate
# 의존성 설치
pip install --upgrade pip
pip install -r requirements.txt.env 파일 생성:
UPSTAGE_API_KEY=your_api_key_here
CHROMA_PERSIST_DIR=./chroma_db
HOST=0.0.0.0
PORT=8000
LOG_LEVEL=info
ENVIRONMENT=development현재 상황: 팀원으로부터 chroma_db/ 폴더를 받아야 함
# 팀원으로부터 받은 chroma_db/ 폴더를 프로젝트 루트에 배치
# 폴더 구조:
# backend/
# ├── chroma_db/
# │ ├── chroma.sqlite3
# │ ├── [collection-id]/
# │ └── ...# 서버 시작 전 반드시 데이터 임베딩 필요
python setup_data.py
# 방법 1: run.py 사용 (권장)
python run.py
# 방법 2: uvicorn 직접 사용
uvicorn main:app --reload --host 0.0.0.0 --port 8000
# 방법 3: main.py 직접 실행
python main.py# 기본 테스트 실행
python test_chatbot.py테스트 내용:
- 챗봇 임포트 및 초기화
- 헬스체크 검증
- 5개 질문 대화 테스트
- 대화형 테스트 모드
# 서버 실행 후 다른 터미널에서
curl -X POST "http://localhost:8000/answer" \
-H "Content-Type: application/json" \
-d '{"prompt":"안녕하세요!"}'서버 실행 후 브라우저에서 접속:
- API 문서: http://localhost:8000/docs
- 서비스 정보: http://localhost:8000
- 헬스체크: http://localhost:8000/health
| 테스트 | 입력 | 기대 결과 |
|---|---|---|
| 기본 인사 | "안녕하세요!" | 유재석 스타일 인사 |
| 프로그램 질문 | "대표 프로그램은?" | 무한도전, 런닝맨 언급 |
| 성격 질문 | "어떤 성격이세요?" | 밝고 긍정적 등 언급 |
| 빈 입력 | "" | 400 에러 |
| 잘못된 형식 | 잘못된 JSON | 400 에러 |
- AMI: Ubuntu 22.04 LTS
- 인스턴스 타입: t3.medium (최소 t3.small)
- 보안그룹: 22(SSH), 8000(FastAPI) 포트 오픈
# 시스템 업데이트
sudo apt update && sudo apt upgrade -y
# Python 3.11 설치
sudo apt install python3.11 python3.11-venv python3-pip -y
# 프로젝트 배포
git clone <repository>
cd backend
# 가상환경 설정
python3.11 -m venv venv311
source venv311/bin/activate
pip install -r requirements.txt# .env 파일 생성
nano .env
# UPSTAGE_API_KEY 등 설정# systemd 서비스 파일 생성
sudo nano /etc/systemd/system/yujaeseuk-chatbot.service
# 서비스 내용:
[Unit]
Description=YuJaeSuk AI Chatbot
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/backend
Environment=PATH=/home/ubuntu/backend/venv311/bin
ExecStart=/home/ubuntu/backend/venv311/bin/python run.py
Restart=always
[Install]
WantedBy=multi-user.target
# 서비스 등록 및 시작
sudo systemctl daemon-reload
sudo systemctl enable yujaeseuk-chatbot
sudo systemctl start yujaeseuk-chatbot# 서비스 상태 확인
sudo systemctl status yujaeseuk-chatbot
# 브라우저에서 접속
http://<EC2-PUBLIC-IP>:8000# 오류: langchain_upstage import 실패
❌ ImportError: cannot import name 'UpstageEmbeddings'
# 해결: Python 3.11 사용 확인
python --version # Python 3.11.x 여야 함# 오류: ChromaDB 디렉토리 없음
❌ FileNotFoundError: ChromaDB 디렉토리가 없습니다
# 해결: 팀원으로부터 chroma_db/ 폴더 받기
# 또는 임시 더미 데이터 생성# 오류: API 키 없음
❌ ValueError: UPSTAGE_API_KEY가 설정되지 않았습니다
# 해결: .env 파일 확인
cat .env | grep UPSTAGE_API_KEY# 오류: 포트 8000 이미 사용 중
❌ OSError: [Errno 98] Address already in use
# 해결: 다른 포트 사용 또는 기존 프로세스 종료
lsof -ti:8000 | xargs kill -9# 오류: ChromaDB 로딩 중 메모리 부족
❌ MemoryError
# 해결: 더 큰 인스턴스 타입 사용
# 또는 Swap 메모리 설정# 애플리케이션 로그
tail -f app.log
# systemd 서비스 로그
sudo journalctl -u yujaeseuk-chatbot -f
# FastAPI 개발 서버 로그
python run.py # 콘솔에 직접 출력- 적절한 chunk_size 설정 (현재: 1000)
- MMR 알고리즘의 k 값 조정 (현재: 3)
- 운영 환경에서 멀티워커 사용
- 적절한 인스턴스 타입 선택
- 프롬프트 길이 최적화
- 캐싱 전략 고려