PsyBot is an intelligent, memory-enabled chatbot system designed to interact with users, screen for common mental health conditions, maintain structured patient histories, and guide them with personalized psychoeducation and coping strategies at each stage of their journey.
- Auth Layer: Secure registration and user authentication via login credentials.
- Screening Layer: Conversational onboarding that administers validated screening instruments to assess the user's current mental health state across three conditions.
- Memory Layer: Long-term conversation and session history powered by LangChain with a relational database backend (PostgreSQL).
- Advising Layer: Context-aware dialogue during active sessions providing psychoeducation, evidence-based coping strategies, and referral triggers when severity thresholds are crossed.
- Reevaluation Layer: On subsequent logins, the system compares current screening scores against prior session history to track progression, improvement, or deterioration over time.
Important Boundary: PsyBot screens and monitors — it does not diagnose. All outputs are severity classifications based on validated instruments. Clinical diagnosis remains the responsibility of a licensed professional. When scores cross clinical thresholds, the system escalates to a referral prompt rather than a clinical recommendation.
PsyBot screens and monitors for three conditions, each measured by a validated, widely-used clinical instrument:
| Condition | Instrument | Items | Severity Bands |
|---|---|---|---|
| Stress | PSS-10 (Perceived Stress Scale) | 10 items | Low / Moderate / High |
| Anxiety | GAD-7 (Generalized Anxiety Disorder Scale) | 7 items | Minimal / Mild / Moderate / Severe |
| Depression | PHQ-9 (Patient Health Questionnaire) | 9 items | None / Mild / Moderate / Moderately Severe / Severe |
- Primary: Extended Mental Health Dataset for Anxiety, Stress, and Depression among University Students
- DOI: 10.5281/zenodo.17389336
- Base dataset: Syeed et al. (2024), DOI: 10.6084/m9.figshare.25771164.v1
- Extended with: DIU-collected responses (2025)
- License: CC BY 4.0
- Final size: ~2,038 records
note: University and Department columns were excluded from model features due to high cardinality and dataset-specific population bias. The model is scoped to individual symptom responses and aggregate scale scores, which are population-agnostic features of the validated instruments.
Data was collected from Bangladeshi university students aged primarily 18–25. This introduces a demographic scope limitation: the model is trained on a young, academically active population, which may not generalize to older adults or non-student populations. This limitation is explicitly acknowledged and should be stated in any deployment context.
The dataset contains 39 columns across three groups:
Demographics (7 columns) Age, Gender, University, Department, Academic Year, Current CGPA, Waiver/Scholarship status
PSS-10 Scale — Stress (12 columns) Individual item scores PSS1–PSS10, aggregate Stress Value, Stress Label
GAD-7 Scale — Anxiety (9 columns) Individual item scores GAD1–GAD7, aggregate Anxiety Value, Anxiety Label
PHQ-9 Scale — Depression (11 columns) Individual item scores PHQ1–PHQ9, aggregate Depression Value, Depression Label
Three separate supervised classification targets — one per condition:
Stress Label→ multiclass (Low Stress / Moderate Stress / High Perceived Stress)Anxiety Label→ multiclass (Minimal / Mild / Moderate / Severe Anxiety)Depression Label→ multiclass (No / Mild / Moderate / Moderately Severe / Severe Depression)
- Class distribution per target variable (check for imbalance)
- Missing value audit
- Severity band mapping confirmation per instrument
- Univariate: score distributions per scale (skewness, range)
- Bivariate: inter-scale correlation (Stress ↔ Anxiety ↔ Depression)
- Item-level: variance per PSS/GAD/PHQ item (identify low-signal items)
- Demographic splits: severity by Gender, Academic Year
- Ordinal encode ordered categoricals (CGPA range, Academic Year)
- Binary encode Gender and waiver status
- Handle high-cardinality categoricals (University, Department) via grouping or dropping
- Retain aggregate scale scores as features
- Engineer composite severity flag:
any_moderate_or_above(referral trigger feature)
Three separate classifiers — one per condition. Rationale: severity bands differ per instrument; a single multi-label model conflates clinically distinct outputs.
- Baseline: Logistic Regression
- Candidates: Random Forest, XGBoost
- Evaluation metric: Weighted F1 (preferred over accuracy due to class imbalance)
- Validation: Stratified K-Fold cross-validation
User Login (FastAPI + Auth)
↓
Intake Conversation (LangChain)
↓
Screening Engine → PSS-10 / GAD-7 / PHQ-9 administered conversationally
↓
ML Classifier → Severity classification per condition
↓
Advising Layer → Psychoeducation + Coping strategies
↓ (Referral trigger if threshold crossed)
Session Storage → PostgreSQL (scores + history per user)
↓
Return Session → Reassessment + trend comparison
| Layer | Technology |
|---|---|
| Backend API | FastAPI 0.136 + Uvicorn |
| Auth | JWT (python-jose) + bcrypt |
| Database ORM | SQLAlchemy 2.x async + asyncpg |
| Database | PostgreSQL 18 |
| LLM Engine | Groq API (llama-3.3-70b-versatile / llama-3.1-8b-instant) |
| ML Models | scikit-learn (MultiOutputClassifier + LogisticRegression) |
| Frontend | React 19 + Vite 8 + Tailwind CSS 4 |
| Language | Python 3.13 / JavaScript (ESModules) |
| Phase | Scope | Status |
|---|---|---|
| Phase 1 | PostgreSQL 18 + User Auth + 26-item ML assessment persistence (UPSERT) | ✅ Complete & Verified |
| Phase 2 | Groq LLM Consultation + 4-phase structured therapy + In-session Reassessment + Crisis Gate + Clinical Notes | ✅ Complete & Verified |
- Python 3.13+
- Node.js 18+ &
npm - PostgreSQL 18 with a database named
Psybotrunning onlocalhost:5432
# 1. Install backend dependencies
pip install -r backend/requirements.txt
# 2. Configure environment in backend/.env
# DATABASE_URL=postgresql+asyncpg://postgres:YOUR_PASSWORD@localhost:5432/Psybot
# SECRET_KEY=your_secure_random_key
# GROQ_API_KEY=your_groq_api_key
# 3. Start the FastAPI server (auto-creates DB tables on startup)
python -m uvicorn backend.main:app --reload --host 127.0.0.1 --port 8000- API Base URL:
http://127.0.0.1:8000 - Interactive Swagger Docs:
http://127.0.0.1:8000/docs - ReDoc:
http://127.0.0.1:8000/redoc
# 1. Navigate to frontend folder
cd frontend
# 2. Install dependencies
npm install
# 3. Start the Vite dev server
npm run dev- Frontend URL:
http://localhost:5173
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/ |
None | API health check & version info |
POST |
/assess |
None | Unprotected ML inference (legacy/demo) |
POST |
/auth/signup |
None | User registration (returns JWT token) |
POST |
/auth/login |
None | User login (returns JWT token) |
GET |
/auth/me |
JWT | Get current authenticated user profile |
POST |
/test/submit |
JWT | Submit 26-item assessment + ML inference + save to DB (UPSERT) |
GET |
/test/history |
JWT | Retrieve latest saved assessment result for user |
POST |
/consult/start |
JWT | Start/resume LLM consultation session (requires prior assessment) |
POST |
/consult/message |
JWT | Send chat message to AI therapist & receive response |
GET |
/consult/session/{id} |
JWT | Get session transcript, timestamps, and reassessments |
GET |
/consult/history |
JWT | List all past consultation sessions for user |
POST |
/consult/end |
JWT | End session & trigger LLM-generated clinical notes |
curl -X GET http://127.0.0.1:8000/curl -X POST http://127.0.0.1:8000/auth/signup \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"fathers_name": "Test Father",
"dob": "2000-01-01",
"phone": "+92-300-1234567",
"email": "testuser@example.com",
"username": "testuser1",
"password": "Password123!"
}'curl -X POST http://127.0.0.1:8000/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "testuser1",
"password": "Password123!"
}'curl -X POST http://127.0.0.1:8000/test/submit \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"pss1": 3, "pss2": 3, "pss3": 3, "pss4": 3, "pss5": 3,
"pss6": 3, "pss7": 3, "pss8": 3, "pss9": 3, "pss10": 3,
"gad1": 2, "gad2": 2, "gad3": 2, "gad4": 2,
"gad5": 2, "gad6": 2, "gad7": 2,
"phq1": 2, "phq2": 2, "phq3": 2, "phq4": 2,
"phq5": 2, "phq6": 2, "phq7": 2, "phq8": 2, "phq9": 0
}'curl -X GET http://127.0.0.1:8000/test/history \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"curl -X POST http://127.0.0.1:8000/consult/start \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"curl -X POST http://127.0.0.1:8000/consult/message \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"session_id": "<SESSION_ID>",
"message": "I feel constantly stressed about exams and cannot focus."
}'curl -X POST http://127.0.0.1:8000/consult/end \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
-d '{
"session_id": "<SESSION_ID>"
}'Complete Testing Guide: For detailed payload examples, edge cases, error codes, and PowerShell commands, see docs/api_testing_guide.md.
PsyBot includes an end-to-end automated audit test suite covering 29 distinct test cases (authentication, ML validation, UPSERT persistence, session scoping, cross-user isolation, and error handling):
python audit_tests.py