Live

Agentic RAG Portfolio Assistant

A production-grade Agentic RAG system with LangGraph agent, Docling extraction, OpenSearch hybrid search, Cohere reranking, Redis caching, and RAGAS evaluation.

System Architecture

Agentic RAG Architecture

Overview

A recruiter visits my portfolio, clicks the AI assistant, and asks questions about my projects, skills, and experience. The system retrieves relevant information from my documents and generates accurate, grounded answers in seconds.

Unlike linear RAG pipelines, this system uses a LangGraph agent that reasons about which tools to call. The agent can search all documents, focus on specific categories, or look up a single file — then decide if it needs to retrieve again before generating an answer.

System Components

1

Input Guardrails

Custom Regex + LLM

Prompt injection detection, harmful content filter, length validation

2

Portfolio Classifier

Keyword + LLM Fallback

Blocks general knowledge — only answers questions about Adeesha's work

3

LangGraph Agent

StateGraph + 5 Tools

LLM decides which tools to call based on query intent. Max 2 retrieval rounds.

4

Hybrid Retrieval

OpenSearch (BM25 + k-NN)

BM25 keyword search + k-NN dense vector search with RRF fusion

5

Reranking

Cohere rerank-v3.5

Top 10 results narrowed to top 3 most relevant

6

Generation

Groq gpt-oss-120b + Gemini Fallback

Primary LLM with automatic fallback to Gemini 2.5 Flash on rate limits

7

Caching

Upstash Redis

LLM response cache (1hr TTL) + conversation memory (24hr TTL)

8

Observability

Langfuse

Full execution tracing, prompt versioning, grading scores

Agent Tools

ToolDescription
search_allSearch all documents — default for most queries
search_projectsFocus on project documents only
search_skillsFocus on skills/resume documents
search_sourceSearch a specific file by name
list_documentsShow what's available in the index

Key Features

Agentic RAG

LangGraph StateGraph with tool routing and multi-step retrieval

Parent-Child Chunking

2000 char parents (LLM context) + 500 char children (search precision)

Query Expansion

Synonym-based expansion for better BM25 recall

API Key Auth

X-API-Key header on all endpoints (health check open)

Rate Limiting

5 requests/min per IP

Gemini Fallback

Groq primary, Gemini 2.5 Flash on rate limit/connection errors

Tenacity Retry

3 attempts, exponential backoff on all external APIs

Tool Result Caching

In-memory 5min TTL avoids redundant search + rerank calls

Chunk Deduplication

Delete existing chunks before re-indexing

Structured Logging

logging module with per-module loggers (rag.graph, rag.tools, etc.)

API Endpoints

GET/Health check (OpenSearch, MinIO, Redis)
POST/queryAsk a question (body: {question, source_filter?})
POST/upload?folder=Upload file to MinIO (max 20MB)
GET/files?folder=List files (optional folder filter)
DELETE/files/{folder}/{filename}Delete file + reindex
POST/reindexFull reindex from MinIO
POST/clear-memoryClear conversation history
POST/clear-cacheClear LLM response cache

Evaluation Metrics (RAGAS)

Faithfulness

Is the answer grounded in context (no hallucination)?

Answer Relevancy

Does the answer address the question?

Context Precision

Are retrieved docs focused and relevant?

Context Recall

Did we retrieve all needed information?

Factual Correctness

Is answer factually accurate vs ground truth?

Tech Stack

Python 3.13FastAPILangGraphLangChainGroq gpt-oss-120bGemini 2.5 FlashGemini EmbeddingCohere rerank-v3.5OpenSearch 2.19BM25 + k-NNMinIODoclingUpstash RedisLangfuseRAGASDocker ComposeCoolify