CoolFace
Apppublic

astroknotsheep/meridian-api

sourceHugging Facemitupdated 4mo agoView on Hugging Face
0likes
App README

Meridian โ€” Clinical-Grade Mental Health AI

Meridian is a highly autonomous, agentic mental health platform designed to operate between the lines of passive symptom tracking and structured therapeutic intervention. The platform relies on a sophisticated LangGraph orchestrator to enforce rigorous deterministic safety protocols, alongside a MentalRoBERTa-based ONNX pipeline for quantitative depression screening and an OpenAI-backed conversational agent using ChromaDB RAG for persistent in-session memory.


๐Ÿ—๏ธ System Architecture & Stateful Orchestration

The core engine of Meridian is a directed cyclic graph (DCG) managed by LangGraph. This architecture ensures every message passes through mandatory, deterministic guardrails before an LLM or ML classifier is ever invoked.

State Schema (ClinicalState)

The global state passed between nodes is strongly typed using Python's TypedDict and utilizes custom LangGraph reducers to manage accumulation fields safely across turns.

python
class ClinicalState(TypedDict):
    # Core Communication
    messages: Annotated[Sequence, add_messages] # Full history (append-only)
    current_message: str                        # Latest input (post-redaction)
    session_id: str                             # Frontend-generated UUID

    # Guardrail & Safety Flags
    guardian_blocked: bool
    guardian_reason: str
    mode_suggestion: str
    crisis_detected: bool
    phi_redacted: bool

    # Routing & UI State
    mode: Literal["diagnosis", "therapy"]
    modality: Optional[str]

    # Analytics & Diagnosis Accumulators
    embedding_buffer: Annotated[List[List[float]], _append_embeddings]
    char_buffer_total: Annotated[int, _add_ints]
    diagnosis_ready: bool
    risk_scores: Dict[str, float]
    metrics: Dict[str, float]

Routing Logic

  1. 1.Guardian Node: Evaluates input against scope and abuse lists. If blocked, sets guardian_blocked = True and short-circuits to guardian_block_node -> END.
  2. 2.Security Node: Analyzes text for PHI and deterministic crisis keywords. Sets crisis_detected and current_message (redacted).
  3. 3.Supervisor Router:
  4. 4.If crisis_detected == True -> routes to crisis_response_node -> END
  5. 5.If mode == "therapy" AND every 5th AI turn -> routes to phq9_node -> END
  6. 6.If mode == "diagnosis" -> routes to diagnosis_node -> END
  7. 7.Else -> routes to therapy_node -> END

๐Ÿง  Core Technical Components

1. Guardian Agent (Outermost Gate)

The Guardian acts as an absolute perimeter defense to ensure the system is not utilized as a general-purpose LLM, maintaining strict clinical scope.

  • โ€”Off-Topic Classification: Checks input against a heuristic set of domain-specific stop words (e.g., coding, mathematics, business, entertainment).
  • โ€”Cumulative Drift Detection: Scans the messages history in the state. If โ‰ฅ 3 consecutive user inputs trigger the off-topic filter, it hard-blocks the session.
  • โ€”Vulgarity Moderation: Blocks slurs and sexual content, but utilizes an intentional exclusion list for emotional profanity (e.g., "I feel like shit"), recognizing this as valid therapeutic expression.
  • โ€”Mode Consistency Engine: If the user is operating in diagnosis mode but emits high-distress vectors (e.g., "I need help", "I feel lost"), it sets mode_suggestion = "therapy" to append a non-intrusive UI prompt suggesting a shift to active support.

2. Security Agent & PHI Redaction

To maintain HIPAA/GDPR conceptual compliance at the protocol level, no personally identifiable information (PHI) ever reaches the OpenAI API or ML classifier.

  • โ€”Presidio Engine: Uses presidio_analyzer and presidio_anonymizer running locally (via en_core_web_lg spaCy model).
  • โ€”Redaction Targets: PERSON, LOCATION, PHONE_NUMBER, EMAIL_ADDRESS, US_SSN, CREDIT_CARD.
  • โ€”Crisis Overrides: A purely deterministic text-matching array checks for 15+ acute crisis indicators. If matched, crisis_detected is set to True, triggering a hardcoded response containing verified crisis hotlines, bypassing all LLM generation.

3. Therapy Agent (LLM + RAG)

The active intervention pipeline utilizes the OpenAI Chat Completions API, constrained by modality-specific prompts and session-persistent memory.

  • โ€”LLM: Defaults to gpt-4o-mini (configurable via THERAPY_MODEL).
  • โ€”Modality Injectors: System prompts dynamically adjust based on the selected modality (CBT, ACT, DBT, Mindfulness, SFBT), modifying the assistant's analytical framework (e.g., Cognitive Restructuring vs. Defusion).
  • โ€”ChromaDB RAG Memory:
  • โ€”Each session_id instantiates a unique, isolated Chroma collection using cosine similarity {"hnsw:space": "cosine"}.
  • โ€”Previous exchanges (User + AI) are embedded using sentence-transformers via Chroma's DefaultEmbeddingFunction.
  • โ€”The agent retrieves the top n_results=2 similar past exchanges and injects them into the system prompt to prevent repetitive advice and maintain deep thematic context across long sessions.
  • โ€”Output Guardrails: Post-generation regex filters ensure the LLM does not hallucinate diagnoses or prescribe medication (e.g., blocking phrases like "you have depression", "take this medication").

4. Diagnosis Agent (ML Screening Pipeline)

Instead of relying on LLM self-analysis for diagnostics, Meridian uses a robust, deterministic Machine Learning pipeline.

The ML Pipeline Architecture
  1. 1.Accumulation & Progressive Probing:
  2. 2.A single message lacks statistical significance. The node requires char_buffer_total โ‰ฅ 800 characters.
  3. 3.While accumulating, the agent dynamically generates empathetic follow-up questions focused on PHQ-9 clinical domains (Sleep, Energy, Appetite, Anhedonia) using a secondary LLM call to draw out highly relevant linguistic data.
  4. 4.Tokenization: Input is processed via HuggingFace AutoTokenizer (max length 96 tokens, matches original training topology).
  5. 5.Inference (MentalRoBERTa ONNX):
  6. 6.The tokenized text is passed to an onnxruntime.InferenceSession utilizing the CPUExecutionProvider.
  7. 7.The engine handles dynamic input graphs (determining if token_type_ids are required by the specific export).
  8. 8.Mean Pooling:
  9. 9.Extracted token embeddings of shape (1, SequenceLength, 768) are multiplied against the attention_mask.
  10. 10.The masked embeddings are summed and divided by the clamped mask sum to generate a single, dense semantic vector of shape (1, 768).
  11. 11.Turn Aggregation: Mean-pooled vectors from every turn in the active session are stored in embedding_buffer and vertically stacked (np.vstack) to compute the final, session-wide average embedding.
  12. 12.Classification & Calibration:
  13. 13.The aggregated vector is normalized using a pre-fitted StandardScaler (scaler.joblib).
  14. 14.The scaled vector is passed to a CalibratedLinearSVC (svm_depression.joblib), which outputs a bounded probability [0.0, 1.0].
  15. 15.The probability is mapped to risk tiers (Low < 30%, Moderate < 60%, Elevated โ‰ฅ 60%).

๐Ÿš€ Setup & Installation

Prerequisites

  • โ€”Python 3.11+
  • โ€”OpenAI API Key
  • โ€”ONNX Runtime and Joblib (for ML pipeline)

Local Development

  1. 1.Clone and setup virtual environment:
bash
   git clone <repository_url>
   cd Prod
   python -m venv .venv
   source .venv/bin/activate
  1. 1.Install dependencies:
bash
   pip install -r requirements.txt
   python -m spacy download en_core_web_lg
  1. 1.Configure Environment Variables:
bash
   cp .env.example .env
   # Edit .env and set OPENAI_API_KEY
  1. 1.Verify Models: Ensure models/mentalroberta_onnx/model.onnx, models/svm_depression.joblib, and models/scaler.joblib are present. (Run Colab notebook train_classifiers.ipynb to generate them if missing).
  1. 1.Start the Application:
bash
   uvicorn backend.main:app --reload --host 0.0.0.0 --port 8000

Navigate to `http://localhost:8000` to interact with the platform.


๐Ÿ”’ Ephemeral Execution & Privacy

Traditional clinical intake relies on permanent records, exposing vulnerable populations to data breaches. Meridian is intentionally ephemeral. The platform operates statelessly beyond the immediate browser session, requiring zero account creation and retaining zero long-term data. In-memory ChromaDB collections and LangGraph states are instantly discarded upon server restart or session expiration.