Back to Blog

Building a Career Counseling Chatbot with Claude API

Build Log8 min

Sungbin Kim

This project records how I built a career counseling chatbot with Claude API. I did not stop at making one API call. I also thought about how to collect student information, structure prompts, and store counseling records.

1. Setting Up the Development Environment

Installing Python

  • Install Python 3.8 or later.
  • Check Add Python to PATH during installation.
  • Confirm the installation with python --version in a terminal.

Creating a virtual environment

# Create a virtual environment
python -m venv venv

# Activate on Windows
venv\Scripts\activate

# Activate on macOS/Linux
source venv/bin/activate

Installing libraries

conda install flask
conda install -c conda-forge anthropic
conda install python-dotenv
conda install -c conda-forge flask-sqlalchemy

I managed the dependencies in requirements.txt:

Flask==2.0.1
anthropic==0.3.0
python-dotenv==0.19.0
Flask-SQLAlchemy==2.5.1

2. Configuring Claude API

API configuration

Creating an API key

  1. Open the Anthropic website.
  2. Sign up and log in.
  3. Open the API section in Console or Dashboard.
  4. Click Create New API Key.
  5. Store the generated key somewhere safe.

I created a .env file in the project root:

ANTHROPIC_API_KEY=your_api_key_here
FLASK_ENV=development
FLASK_APP=run.py

3. Setting Up the Project Structure

Directory structure

project/
├── app/
│   ├── __init__.py         # Flask application initialization
│   ├── templates/          # HTML templates
│   │   ├── index.html      # Main page
│   │   ├── chat.html       # Chat interface
│   │   └── base.html       # Base template
│   ├── static/             # Static files
│   │   ├── css/            # Stylesheets
│   │   └── js/             # JavaScript
│   └── utils.py            # Utility functions
├── config.py               # Configuration
├── requirements.txt        # Dependencies
└── run.py                  # Application entry point

Main configuration files

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. Building the Web Interface

Main page

The first page

I built the main page quickly with Bootstrap. It was easy to make it responsive, and I included a welcome message and service introduction, a button to start chatting, a usage guide, and recent counseling history for logged-in users.

Chat interface

The second page

The chat screen included several features so it felt like an actual counseling session:

  1. Live message display
  2. Different styles for user and AI responses
  3. An input field and send button
  4. Automatic scrolling through the conversation
  5. A loading indicator
<!-- Main section of index.html -->
<div class="chat-container">
  <div class="chat-messages" id="messageArea">
    <!-- Messages are added here dynamically -->
  </div>
  <div class="input-area">
    <input type="text" id="userInput" placeholder="Enter your question..." />
    <button onclick="sendMessage()">Send</button>
  </div>
</div>

5. Connecting Claude API

API call

# 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)}"

Prompt design

I designed a separate prompt for career counseling. Sending only “give me counseling” produced an answer that was too broad, so I passed student information and counseling criteria together.

def engineer_prompt(user_info, user_message):
    system_prompt = """You are an experienced career-counseling AI for high-school students.

Consider these areas during counseling:

1. Academic ability
- Analyze achievement and preferences by subject
- Analyze learning style and study attitude
- Consider activities outside class and self-directed learning
- Consider experience with advanced study in a specific field

2. Aptitude and interests
- Use MBTI and job-fit as one input, not a diagnosis
- Connect hobbies and interests to possible careers
- Consider club and school activities
- Consider volunteer work and civic participation

3. Career exploration and planning
- Provide information about desired job families
- Explain required skills and qualifications
- Introduce related majors and curricula
- Suggest admissions and preparation strategies

4. Skills-development plan
- Suggest study strategies
- Plan relevant certificates and preparation
- Improve foreign-language and computer skills
- Suggest reading and general-education activities

5. Psychological support
- Suggest ways to manage academic stress
- Give advice for career anxiety
- Strengthen confidence and motivation
- Support a positive self-image

6. Future outlook
- Explain industry trends in the field of interest
- Discuss promising future occupations
- Explain how technology may change work
- Connect social change with career adaptability

7. Practical action plan
- Short-term goals (6 months to 1 year)
- Mid-term goals (1 to 3 years)
- Long-term goals (3 to 5 years)
- Concrete actions and a timeline"""

    user_context = f"""
# Basic student information
- Name: {user_info['name']}
- Age: {user_info['age']}
- Grade: {user_info['grade']}
- Academic track: {user_info['academic_track']}

# Academic status
- Performance: {user_info['academic_performance']}
- Favorite subject: {user_info['favorite_subject']}
- Disliked subject: {user_info['disliked_subject']}
- Learning style: {user_info.get('learning_style', 'No information')}

# Career exploration
- Interests: {user_info['interests']}
- Career interests: {user_info['career_interests']}
- Desired future job: {user_info['future_job']}
- Role model: {user_info['role_model']}"""

    return system_prompt + "\n\n" + user_context + "\n\nStudent message: " + user_message

Response structure

<h2>Overall analysis</h2>
[Professional analysis of the student's traits and situation]

<h2>Career-fit assessment</h2>
[How the desired path matches current abilities]

<h2>Personal development plan</h2>
[Step-by-step goals and actions]

<h2>Recommended materials</h2>
[Personalized learning materials and activities]

What I changed while refining the prompt

  1. Stronger context: structured student information, connected related facts, and placed information in a useful timeline.
  2. Better responses: added concrete guidelines, a consistent response structure, and an emphasis on actionable advice.
  3. More personalization: considered MBTI, learning style, and individual strengths and weaknesses.
  4. Practicality: added concrete actions, time-based goals, and achievable steps.

6. Connecting the Database

SQLAlchemy model

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)

Saving and loading conversations

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. Security and Error Handling

API-key security

  • Use environment variables.
  • Add .env to .gitignore.
  • Keep production security settings separate.

Error handling

@app.errorhandler(500)
def internal_error(error):
    return jsonify({
        'error': 'Internal server error',
        'message': str(error)
    }), 500

8. Preparing for Deployment

Production settings

# config.py
class ProductionConfig(Config):
    DEBUG = False
    SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL')

Running the server

gunicorn run:app

Closing Thoughts

Building this project taught me that simply “adding a chatbot” requires more structure than I expected. API-key management, prompt design, conversation storage, and error handling all have to be handled before the result is actually usable.

The areas I practiced were Flask, API integration and asynchronous handling, database design, frontend interfaces, and security and error handling.

If I improved it further, I would add:

  • User authentication
  • Counseling-history analysis and reports
  • Multilingual support
  • A voice interface
  • A mobile-app version

The full source is available on GitHub. There are still many things I would clean up, but connecting Claude API to a real service was valuable practice.