What it does

Anyone who feels unwell faces the same question before they reach a clinician: how urgent is this, and where should I go? Search engines and generic chatbots answer this inconsistently and with no accountability — they'll wave off a heart attack as "probably stress," or send a common cold to the ER.

AI Symptom-Triage Assistant takes a patient's free-text complaint and returns a calibrated urgency level (emergency / urgent / routine / self-care), the specific red flags it detected, a recommended specialist, its step-by-step reasoning, and plain-language next steps — with each assessment citing the clinical guidance it relied on.

This is a triage navigation aid, not a diagnostic tool. Every response carries that disclaimer and defers to emergency services.

How I built it

The system is three deliberate layers, not a single model call:

1. Grounded reasoning (RAG). Each complaint is embedded (sentence-transformers, all-MiniLM-L6-v2) and matched against a curated 40-entry knowledge base of public triage guidance (NHS, CDC, WHO, MedlinePlus) using FAISS. Retrieved snippets are injected into the model's context, and every assessment cites the specific sources it used — so guidance is traceable, not conjured.

2. A deterministic safety layer. Because an LLM is probabilistic and can under-triage, a rule-based checker runs independently of the model. If it detects hard emergency patterns — cardiac chest pain with breathlessness, FAST stroke signs, anaphylaxis, severe bleeding, seizure, unresponsiveness — it forces an emergency classification regardless of what the model said. Critical symptoms can never be silently downgraded.

3. A measured evaluation. I built a 45-case labeled test set and an evaluation harness computing accuracy, a confusion matrix, and safety recall (the fraction of true emergencies correctly caught).

The backend is FastAPI serving one /triage endpoint (Groq, openai/gpt-oss-120b, JSON mode, schema-validated with Pydantic). The frontend is React + Vite + Tailwind.

What I learned

The evaluation surfaced a real failure I wouldn't have caught otherwise. An early version of my RAG corpus used alarm-heavy wording, which biased the model toward over-triage and actually lowered accuracy (83.3% grounded vs 91.7% ungrounded). Rather than hide it, I diagnosed the cause — retrieved snippets lexically priming the emergency cluster — rewrote the corpus to be tier-neutral, and re-measured. Grounding is now accuracy-neutral (91.7%, matching ungrounded) while adding source transparency, with 100% safety recall and zero dangerous under-triages.

The lesson: RAG isn't automatically an improvement, and without an eval I'd have shipped a version that made the system worse. Measuring your own work honestly is the feature.

Challenges

Getting the safety layer to fire on real emergencies without false-positiving on negated or mild cases ("no chest pain, just a cold") took careful combination-based rules rather than keyword matching. And free-tier API quotas forced a disciplined, batched evaluation approach.

Limitations

The only consistent errors are at the routine/self-care boundary — genuinely borderline cases the model rated one tier lower than my gold label. Notably, no error was a dangerous under-triage: safety recall on true emergencies stayed at 100%, and mistakes clustered at the lowest-stakes boundary, never near emergencies.

AI tools disclosure

Built solo, with AI tooling disclosed in full:

  • Claude Code (Anthropic) — used as a pair-programming tool to implement the FastAPI backend, React frontend, retrieval module, safety-rule layer, and evaluation harness under my direction. The architecture, the RAG/safety/eval design, the corpus curation, the test-set labels, and all engineering decisions (including diagnosing and fixing the over-triage bias) were mine.
  • Groq API — openai/gpt-oss-120b — the runtime LLM performing triage reasoning (substitute for the decommissioned llama-3.3-70b-versatile).
  • sentence-transformers (all-MiniLM-L6-v2) and FAISS — local embeddings and vector search.
  • The clinical knowledge base is my own concise summaries of publicly documented triage guidance, with source URLs — not reproduced verbatim.

Built With

Share this project:

Updates

Submission history