A Retrieval-Augmented Generation (RAG) system with built-in security guardrails and audit logging — built to demonstrate production-aware AI system design, not just a demo chatbot.
Takes a user query, retrieves relevant context from a document knowledge base, generates a grounded answer, and validates every step of the pipeline before responding — logging the full decision trail for auditability.
User Query
│
▼
[API Key Auth] ──── reject if missing/invalid key
│
▼
[Input Guardrail] ── keyword filter + LLM classifier
│ (blocks prompt injection attempts)
▼
[Retrieval] ──────── pgvector cosine similarity search
│ (top-k relevant chunks from Postgres)
▼
[Generation] ──────── LLM answers using ONLY retrieved context
│
▼
[Output Guardrail] ── embedding similarity check
│ (blocks hallucinated/off-topic answers)
▼
[Audit Log] ──────── every query, decision, and result recorded
│
▼
Response
- Backend: Node.js, Express
- Vector DB: PostgreSQL + pgvector
- LLM: Groq (openai/gpt-oss-120b for generation, openai/gpt-oss-20b for input classification)
- Embeddings: Cohere (embed-english-v3.0)
- Infra: Docker (Postgres + pgvector container)
-
Input side — prompt injection defense
- Layer 1: keyword/pattern filter (fast, catches obvious attempts)
- Layer 2: LLM-based classifier (catches rephrased/sneaky attempts)
-
Output side — hallucination defense
- Cosine similarity check between generated answer and retrieved context
- Answers that don't semantically match the source material are blocked, not returned
-
Access control
- API key required on all
/queryrequests (x-api-keyheader)
- API key required on all
-
Audit trail
- Every request logged: query, input-check result, retrieved chunks, final answer, output-check result, blocked status, timestamp
git clone <your-repo-url>
cd rag-guard
npm installCopy .env.example to .env and fill in:
DATABASE_URL=postgresql://postgres:yourpassword@localhost:5432/ragguard
GROQ_API_KEY=your_groq_key
COHERE_API_KEY=your_cohere_key
API_SECRET_KEY=your_own_secret_string
PORT=3000
Start Postgres + pgvector via Docker:
docker run --name ragguard-db -e POSTGRES_PASSWORD=yourpassword -p 5432:5432 -d pgvector/pgvector:pg16
docker exec -it ragguard-db psql -U postgres -c "CREATE DATABASE ragguard;"Add source documents (.txt files) to data/docs/, then:
npm run ingest
npm startcurl -X POST http://localhost:3000/query \
-H "Content-Type: application/json" \
-H "x-api-key: your_own_secret_string" \
-d '{"query": "your question here"}'- Only
.txtdocument ingestion supported (no PDF/docx yet) - Fixed-size chunking (no semantic/sentence-aware splitting)
- Hallucination threshold (0.6 cosine similarity) is a tuned starting point, not exhaustively validated across all query types
- No rate limiting per API key (single shared key, no per-user throttling)
Most RAG demos stop at "retrieve and generate." This one treats the pipeline as something that has to be defended and observed — matching how RAG systems actually need to work before they touch real users or real data.