DEV Community

Cover image for Building an AI-Based Student Stress Management System with Python, ML, and RAG
HydraBytes
HydraBytes

Posted on

Building an AI-Based Student Stress Management System with Python, ML, and RAG

Student mental health has become a genuine crisis in universities worldwide. Stress, anxiety, and depression are among the leading causes of academic dropout — yet most campuses lack accessible, real-time tools to help students recognize and address what they're experiencing.

We built the AI-Based Student Stress Management System to tackle exactly that. It's a full-stack web platform that uses machine learning to detect stress, anxiety, and depression from questionnaire inputs, then provides instant severity scoring, personalized coping recommendations, and a conversational AI chatbot — all in one place.

This post walks through the architecture, the ML pipeline, and the design decisions we made building it.

Repo: TheHydraBytes/AI-based-student-stress-mangement


The Problem

The standard approach to student mental health support is: fill out a form, wait for a counselor to follow up, get an appointment weeks later. By that point, a student in mild-to-moderate distress may have already spiraled.

We wanted something that:

  1. Gave students an immediate, private assessment of where they stood
  2. Offered actionable coping tools they could use right now
  3. Connected them to a professional when needed

Architecture Overview

React Frontend
     |
  Flask Backend (Python)
     |          |           |
   SQL Server   ML Models   AI Chatbot
  (pyodbc)    (scikit-learn) (LangChain + Groq + Qdrant)
Enter fullscreen mode Exit fullscreen mode

The backend is a Flask application. The ML models (three separate classifiers) run as in-process Python objects. The chatbot uses a RAG (Retrieval-Augmented Generation) pipeline backed by Qdrant as the vector store and Groq (LLaMA 3.1) as the LLM.


The ML Pipeline

Three Separate Models

We trained three independent classifiers, one each for stress, anxiety, and depression. Each model:

  • Takes a questionnaire response as input (Likert-scale answers covering behavioral, cognitive, and physiological symptoms)
  • Outputs a severity label: Minimal / Mild / Moderate / Severe
  • Was trained on a labeled clinical survey dataset (PSS, GAD-7, PHQ-9 style)

All three follow the same training pattern:

from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split
import joblib

df = pd.read_csv("stress.csv")

label_encoder = LabelEncoder()
df["Stress Label"] = label_encoder.fit_transform(df["Stress Label"])

X = df.drop(["Stress Value", "Stress Label"], axis=1)
y = df["Stress Label"]

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

model = LogisticRegression(max_iter=500, random_state=42)
model.fit(X_train, y_train)

joblib.dump(model, "logistic_regression_stress.pkl")
joblib.dump(scaler, "scaler.pkl")
joblib.dump(label_encoder, "label_encoder.pkl")
Enter fullscreen mode Exit fullscreen mode

We chose Logistic Regression deliberately. For clinical classification tasks where interpretability and reliability matter more than marginal accuracy gains, it outperforms black-box alternatives like neural networks. We can understand exactly why a sample was classified the way it was.

Real-Time Prediction

When a student submits the questionnaire, all three models run simultaneously and the results are bundled into a single response object:

results_data = {
    'stress_score': stress_score,
    'stress_prediction': stress_label,
    'anxiety_score': anxiety_score,
    'anxiety_prediction': anxiety_label,
    'depression_score': depression_score,
    'depression_prediction': depression_label,
    'demographic_info': demographic_info,
}
Enter fullscreen mode Exit fullscreen mode

The results page shows all three severity scores at once, letting students see the full picture rather than a single-dimension reading.


The RAG Chatbot

The conversational layer is where the system goes beyond a static form. Students can ask the chatbot anything related to their mental health — and it responds using actual clinical knowledge, not just generic LLM hallucinations.

Stack

  • Embeddings: sentence-transformers/all-mpnet-base-v2 via HuggingFace
  • Vector store: Qdrant (cloud-hosted)
  • LLM: LLaMA 3.1 8B Instant via Groq API (fast, low-latency)
  • Orchestration: LangChain

The chatbot was trained on a curated mental health knowledge base (embedded as a PDF via embed_documents.py). When a user sends a message, the system retrieves the top relevant chunks from Qdrant, then passes them as context to the LLM.

Crisis Detection

One design decision we're particularly careful about: if a student types something that suggests a suicidal crisis, the chatbot does not attempt to respond as a therapist. It immediately surfaces emergency contact information.

crisis_triggers = [
    "i want to die", "i want to end it all", "i don't want to live",
    "i'm done with everything", "ending my life",
    "i think about suicide", "i have no reason to live"
]
Enter fullscreen mode Exit fullscreen mode

The system detects these triggers before the RAG pipeline even runs. Automated AI responses should never substitute for human intervention in a genuine crisis.


Features Beyond Assessment

A questionnaire and a chatbot are the core, but the system includes several additional tools students can use day-to-day.

Mindfulness Games

Two browser-based games built to reduce acute stress:

  • Bubble Pop Game: Timed focus exercise. Simple, but effective for grounding.
  • Puzzle Game: Cognitive engagement that shifts attention away from anxiety spirals.

Game session data is stored and shown in the user's progress dashboard.

Guided Breathing Exercises

An animated breathing guide with session tracking. The /breathing route stores per-session stats so students can track consistency over time.

Progress Dashboard

Every student gets a personal dashboard showing:

  • Historical assessment results (trend over time)
  • Breathing and game session stats
  • Upcoming counselor appointments

Doctor Appointment Booking

Students can browse available counselors, check open slots via the /api/available_slots endpoint, and book appointments directly through the platform. Admins can accept, reschedule, or cancel bookings through a separate admin dashboard.


Admin Panel

The /admin_dashboard gives university mental health staff a full view of the system:

  • User management: view/delete student accounts
  • Assessment history: aggregate submissions across all students
  • Chatbot ratings: feedback on response quality
  • Appointment management: approve, reschedule, cancel appointments

This matters because the platform is designed to integrate with, not replace, existing campus counseling infrastructure.


Security Decisions

A mental health platform handles particularly sensitive data. A few things we made sure to get right:

Security headers on every response:

@app.after_request
def after_request(response):
    response.headers['X-Frame-Options'] = 'DENY'
    response.headers['X-Content-Type-Options'] = 'nosniff'
    response.headers['X-XSS-Protection'] = '1; mode=block'
    response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
    return response
Enter fullscreen mode Exit fullscreen mode

Cache prevention on protected routes: The @require_login decorator adds no-cache, no-store, must-revalidate headers so assessment results cannot be retrieved from browser cache by a shared device user.

Password reset via security questions instead of email-only, reducing dependency on email deliverability for account recovery.


What We'd Do Differently

Switch to PostgreSQL properly. The app currently uses SQL Server via pyodbc with a local SSMS connection string hardcoded for development. Moving to PostgreSQL on a hosted provider (Supabase, Neon) would make deployment portable.

Add model versioning. The .pkl files are committed directly to the repo. As the training data grows, we'd want MLflow or a similar registry to track model versions alongside accuracy metrics.

Upgrade the chatbot to streaming. The current Groq integration waits for the full response before sending it. Streaming tokens to the frontend would make the chatbot feel significantly more responsive.


Try It Yourself

The full source is on GitHub under the HydraBytes organization:

github.com/TheHydraBytes/AI-based-student-stress-mangement

git clone https://github.com/TheHydraBytes/AI-based-student-stress-mangement.git
cd AI-based-student-stress-mangement
pip install flask scikit-learn pandas numpy langchain-huggingface langchain-groq langchain-qdrant
npm install
cd flask_app && python app.py
Enter fullscreen mode Exit fullscreen mode

You'll need to set QDRANT_HOST, QDRANT_API_KEY, and GROQ_API_KEY environment variables for the chatbot to work. The ML models and Flask routes function independently without them.


Built by HydraBytes — a digital solutions agency based in Pakistan.

If you're building something in the mental health tech space and want to talk architecture, drop a comment below.

Top comments (0)