이 프로젝트는 Claude API로 진로상담 챗봇을 만들어본 기록입니다. API를 호출하는 데서 끝내지 않고, 학생 정보를 어떻게 받고 프롬프트를 어떻게 짜고 상담 기록을 어떻게 저장할지까지 같이 고민해봤습니다.
1. 개발 환경 잡기
Python 설치
- Python 3.8 이상을 설치해요.
- 설치할 때 "Add Python to PATH" 옵션을 꼭 체크해주세요.
- 다 되면 터미널에서
python --version으로 확인하고요.
가상환경 설정
# 가상환경 생성
python -m venv venv
# 가상환경 활성화 (Windows)
venv\Scripts\activate
# 가상환경 활성화 (Mac/Linux)
source venv/bin/activate
필요한 라이브러리 설치
# Conda를 사용한 라이브러리 설치
conda install flask
conda install -c conda-forge anthropic
conda install python-dotenv
conda install -c conda-forge flask-sqlalchemy
의존성은 requirements.txt로 따로 관리했습니다.
Flask==2.0.1
anthropic==0.3.0
python-dotenv==0.19.0
Flask-SQLAlchemy==2.5.1
2. Claude API 설정하기

API 키 발급 과정
- Anthropic 공식 웹사이트에 들어갑니다.
- 회원가입하고 로그인합니다.
- Console이나 Dashboard에서 API 섹션으로 갑니다.
- "Create New API Key"를 눌러 새 키를 만듭니다.
- 만든 키는 안전한 데 보관하고요.
환경변수 설정
프로젝트 루트에 .env 파일을 만들고 API 키를 넣었습니다.
ANTHROPIC_API_KEY=your_api_key_here
FLASK_ENV=development
FLASK_APP=run.py
3. 프로젝트 구조 설정
디렉토리 구조
project/
├── app/
│ ├── __init__.py # Flask 애플리케이션 초기화
│ ├── templates/ # HTML 템플릿 파일들
│ │ ├── index.html # 메인 페이지
│ │ ├── chat.html # 채팅 인터페이스
│ │ └── base.html # 기본 템플릿
│ ├── static/ # 정적 파일들
│ │ ├── css/ # 스타일시트
│ │ └── js/ # 자바스크립트 파일들
│ └── utils.py # 유틸리티 함수들
├── config.py # 설정 파일
├── requirements.txt # 의존성 목록
└── run.py # 애플리케이션 실행 파일
주요 파일 설정
config.py
import os
from dotenv import load_dotenv
load_dotenv()
class Config:
SECRET_KEY = os.urandom(24)
ANTHROPIC_API_KEY = os.getenv('ANTHROPIC_API_KEY')
app/init.py
from flask import Flask
from config import Config
def create_app():
app = Flask(__name__)
app.config.from_object(Config)
from app.routes import main
app.register_blueprint(main)
return app
4. 웹 인터페이스 구현
메인 페이지

메인 페이지는 Bootstrap으로 빠르게 잡았습니다. 반응형까지 크게 무리 없이 맞춰졌고, 기본 구성은 이렇게 뒀고요.
- 환영 메시지와 서비스 소개
- 채팅 시작 버튼
- 사용 가이드
- 최근 상담 내역 (로그인 시)
채팅 인터페이스

채팅 화면은 실제 상담처럼 보이게 기본 기능 몇 개를 넣었죠.
- 실시간 메시지 표시
- 사용자/AI 응답 구분을 위한 다른 스타일 적용
- 입력창과 전송 버튼
- 대화 내역 자동 스크롤
- 로딩 인디케이터
HTML/CSS 구현
<!-- index.html 주요 부분 -->
<div class="chat-container">
<div class="chat-messages" id="messageArea">
<!-- 메시지들이 여기에 동적으로 추가됨 -->
</div>
<div class="input-area">
<input type="text" id="userInput" placeholder="질문을 입력하세요..." />
<button onclick="sendMessage()">전송</button>
</div>
</div>
5. Claude API 연동
API 호출 구현
# app/utils.py
import anthropic
def get_claude_response(message):
client = anthropic.Client(api_key=os.getenv('ANTHROPIC_API_KEY'))
try:
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1000,
messages=[{
"role": "user",
"content": message
}]
)
return response.content[0].text
except Exception as e:
return f"Error: {str(e)}"
프롬프트 설계
진로 상담에 맞춘 프롬프트도 따로 짰습니다. 그냥 "상담해줘"라고 보내면 답이 너무 넓어져서, 학생 정보랑 상담 기준을 같이 넘기는 방식으로 갔고요.
def engineer_prompt(user_info, user_message):
system_prompt = """당신은 전문적인 고등학생 진로 상담 AI입니다.
상담 시 고려해야 할 핵심 영역:
1. 학업 역량 분석
- 교과목별 성취도와 선호도 파악
- 학습 스타일과 학업 태도 분석
- 교과 외 학습 활동 및 자기주도학습 능력
- 특정 분야에 대한 심화학습 경험
2. 적성 및 흥미 분석
- MBTI 성격유형과 직업 적합성
- 취미와 관심사의 진로 연계 가능성
- 동아리 활동과 교내외 활동 경험
- 봉사활동과 사회참여 경험
3. 진로 탐색 및 설계
- 희망 직업군에 대한 상세 정보 제공
- 필요한 역량과 자격요건 안내
- 관련 학과 및 커리큘럼 소개
- 진학 전략 및 준비 방법 제시
4. 역량 개발 계획
- 학업 성취도 향상을 위한 학습 전략
- 필요한 자격증 및 스펙 준비 계획
- 외국어 및 컴퓨터 활용능력 향상 방안
- 독서 및 교양 함양 방법
5. 심리적 지원
- 학업 스트레스 관리 방안
- 진로 불안 해소를 위한 조언
- 자신감과 동기부여 강화
- 긍정적 자아상 형성 지원
6. 미래 전망 분석
- 관심 분야의 산업 동향
- 미래 유망 직종 정보
- 기술 발전에 따른 직업 변화
- 사회 변화와 진로 적응력
7. 실천적 행동 계획
- 단기 목표(6개월-1년)
- 중기 목표(1-3년)
- 장기 목표(3-5년)
- 구체적 실천 방안과 타임라인"""
user_context = f"""
# 학생 기본 정보
- 이름: {user_info['name']}
- 나이: {user_info['age']}
- 학년: {user_info['grade']}
- 계열: {user_info['academic_track']}
# 학업 현황
- 학업 성취도: {user_info['academic_performance']}
- 좋아하는 과목: {user_info['favorite_subject']}
- 싫어하는 과목: {user_info['disliked_subject']}
- 학습 스타일: {user_info.get('learning_style', '정보 없음')}
# 진로 탐색
- 관심사: {user_info['interests']}
- 희망 진로: {user_info['career_interests']}
- 장래 희망: {user_info['future_job']}
- 롤모델: {user_info['role_model']}"""
return system_prompt + "\n\n" + user_context + "\n\n학생 메시지: " + user_message
프롬프트 구성
프롬프트는 두 덩어리입니다. 앞쪽 시스템 프롬프트가 "고등학생 진로 상담가"라는 역할이랑 다룰 영역을 정하고, 뒤쪽 유저 컨텍스트가 그 학생의 이름, 학년, 계열, 성적, 관심사, 희망 진로, 롤모델을 붙입니다. 마지막에 학생이 방금 친 메시지를 붙입니다.
응답은 HTML 헤딩으로 네 칸을 미리 정해뒀습니다. 종합 분석, 진로 적합성, 발전 계획, 추천 자료. 이렇게 안 하면 답변 길이랑 순서가 매번 달라져서 화면에 붙이기가 애매했죠.
프롬프트를 다듬을 때 본 것
제일 효과가 컸던 건 학생 정보를 문장으로 풀어 쓰지 않고 항목으로 끊어서 넣은 겁니다. "2학년 이과이고 수학을 좋아하는 학생입니다" 같은 문장보다 학년: 2, 계열: 이과처럼 줄을 나눠 주는 쪽이 답변에서 정보를 덜 흘리더라고요.
MBTI를 넣어봤는데 이건 애매했습니다. 답변 말투가 약간 달라지긴 하는데 내용이 나아지는 느낌은 아니어서, 있으면 넣고 없으면 말고 정도로 뒀습니다.
반대로 확실히 나빴던 건 "구체적으로 조언해줘" 같은 지시를 프롬프트에 넣는 것이었습니다. 그러면 오히려 일반론이 길어지더라고요. 대신 출력 칸을 미리 정해두니까 알아서 구체적으로 채웠고요.
6. 데이터베이스 연동
SQLAlchemy 모델 정의
from app import db
class ChatHistory(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_message = db.Column(db.Text, nullable=False)
ai_response = db.Column(db.Text, nullable=False)
timestamp = db.Column(db.DateTime, default=datetime.utcnow)
대화 내역 저장과 조회
def save_chat(user_message, ai_response):
chat = ChatHistory(
user_message=user_message,
ai_response=ai_response
)
db.session.add(chat)
db.session.commit()
7. 보안과 에러 처리
API 키 보안
- 환경 변수 사용
- .gitignore 파일에 .env 추가
- 프로덕션 환경에서의 보안 설정
에러 핸들링
@app.errorhandler(500)
def internal_error(error):
return jsonify({
'error': 'Internal server error',
'message': str(error)
}), 500
8. 배포 준비
프로덕션 설정
# config.py
class ProductionConfig(Config):
DEBUG = False
# 프로덕션 데이터베이스 설정
SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL')
서버 실행
gunicorn run:app
마무리
만들면서 "챗봇 하나 붙이기"가 생각보다 많은 구조를 필요로 한다는 걸 느꼈습니다. API 키 관리, 프롬프트 설계, 대화 저장, 에러 처리까지 하나씩 챙겨야 실제로 쓸 수 있는 형태가 되더라고요.
이 과정에서 특히 많이 배운 건 이렇습니다.
- Flask 웹 프레임워크 활용
- API 연동 및 비동기 처리
- 데이터베이스 설계 및 구현
- 프론트엔드 인터페이스 구현
- 보안 및 에러 처리
나중에 더 손본다면 이런 방향이 있을 것 같아요.
- 사용자 인증 시스템 추가
- 상담 내역 분석 및 리포트 기능
- 다국어 지원
- 음성 인터페이스 추가
- 모바일 앱 버전 개발
전체 소스는 깃허브에 올려뒀습니다. 지금 보면 더 깔끔하게 고칠 데도 많은데, Claude API를 실제 서비스 형태로 붙여본 게 좋은 연습이었죠.
