← Back to portfolio
local_healthcare_rag · Guardrail Design · July 2026

Building Guardrails That Don't Rely on the Model Behaving

Abhinandan Pandey — LLM Security Researcher

I built local_healthcare_rag as a 48-hour AI Engineer assignment: a fully local, offline healthcare chatbot that answers questions on symptoms, diseases, nutrition, lifestyle, preventive care, and first aid — while never, under any circumstance, giving an actual diagnosis.

The chatbot itself was the easy part. Streamlit UI, FastAPI backend, Phi3 running locally via Ollama, a RAG pipeline over a curated medical knowledge base using FAISS and sentence-transformers. No API key, no cloud dependency, zero cost per query. Standard stack for this kind of project.

The interesting part — the part that actually matters if you've spent time doing LLM security research — was designing guardrails that don't collapse the moment the model does something you didn't expect.

The naive approach fails silently

The obvious first move is a system prompt: "You are a helpful medical assistant. Never provide a diagnosis. Always recommend consulting a doctor." This works most of the time. It also fails in exactly the situations where failure matters most — edge-case phrasing, multi-turn context where the instruction gets diluted, or just the model deciding to be unusually helpful at the wrong moment.

If your only defense is "hope the LLM follows instructions," you don't have a safety layer. You have a suggestion.

Two-layer defense

I split the guardrail into two independent layers that don't rely on each other to work:

The critical design decision: the emergency/self-harm detection layer runs before the LLM is even called. If a message matches emergency criteria, the system responds with a fixed, pre-written safety response — the model never gets a chance to generate something unpredictable in a situation where unpredictability is dangerous.

Why this matters beyond one project

This is the same principle that shows up throughout my actual security research: prompt injection and jailbreak vulnerabilities exist precisely because systems trust the model's output as if it were sanitized input. A model instruction is not a security boundary. If a behavior is genuinely non-negotiable — no diagnosis, no leaking a system prompt, no executing a destructive tool call — it needs to be enforced by code that runs independently of whether the model "listened."

Prompting is a UX layer. Deterministic checks are the security layer. Conflating the two is how agentic AI systems end up with vulnerabilities that look obvious in hindsight.

RAG LLM Safety Ollama / Phi3 Guardrail Design