Cortex / ARCHITECTURE_EXPLANATION.md
aditya-joshi-05's picture
Add conversational memory
a2f2da3
|
Raw
History Blame Contribute Delete
6.38 kB
# Cortex RAG β€” Architecture & Implementation Guide
This document provides a deep dive into the architecture of **Cortex**, a production-grade Retrieval-Augmented Generation (RAG) system. This guide is structured to help you explain the "what", "how", and "why" of each layer during your GenAI Engineer interview.
---
## πŸ—οΈ 1. High-Level Architecture Overview
Cortex follows a modular, multi-layer RAG architecture designed for high precision, scalability, and reliability. It moves beyond "naive RAG" by implementing:
- **Semantic Data Ingestion** (instead of fixed-size chunking)
- **Hybrid Multi-Strategy Retrieval** (Dense + Sparse + Knowledge Graph)
- **Corrective Gating (CRAG)** (to handle retrieval failures)
- **Reference-Free Evaluation** (using RAGAS)
---
## πŸ“₯ 2. Ingestion Layer: "Context-Aware Processing"
### **Document Loading**
- Supports multiple formats: PDF, HTML, and TXT.
- **Implementation:** `DocumentLoader` handles parsing and basic cleaning.
### **Semantic Chunker (`ingestion/chunker.py`)**
- **The Problem:** Fixed-size chunking (e.g., 512 tokens) often splits mid-sentence or mid-concept, losing semantic coherence.
- **The Solution:** We use **Sentence-Level Semantic Boundary Detection**.
- **How it works:**
1. Split text into individual sentences.
2. Embed each sentence using `BAAI/bge-small-en-v1.5`.
3. Compute the **cosine similarity** between consecutive sentence embeddings.
4. Insert a chunk boundary whenever the similarity drops below a certain threshold (e.g., 0.82) or the token limit is reached.
- **Why?** This ensures each chunk contains a single, coherent topic.
### **Parent-Child Hierarchy**
- **The Problem:** Small chunks are better for retrieval precision, but large chunks provide better context for generation.
- **The Implementation:**
- **Child Chunks (~256 tokens):** These are the units indexed in the vector database. They represent a specific "nugget" of information.
- **Parent Chunks (~1024 tokens):** A wider window of text centered on the child. When a child is retrieved, its **parent text** is what gets sent to the LLM.
- **Why?** It decouples **retrieval granularity** (find exactly what you need) from **context width** (give the LLM enough room to understand).
---
## πŸ” 3. Retrieval Layer: "Multi-Strategy Orchestration"
Cortex doesn't just rely on vector search; it uses a `MultiStrategyRetriever` to combine different search paradigms.
### **A. Dense Retrieval (Milvus)**
- **Embeddings:** `bge-small-en-v1.5` (384-dim).
- **Vector DB:** Milvus (Dockerized).
- **Indexing:** `IVF_FLAT` with `COSINE` similarity metric.
- **Why?** Captures semantic meaning (e.g., "puppy" matches "dog").
### **B. Sparse Retrieval (BM25)**
- **Implementation:** `rank_bm25` library.
- **Why?** Essential for exact keyword matching, acronyms, and specific names (e.g., "Project Cortex-X1") where vector search might be too "fuzzy".
### **C. Knowledge Graph (GraphRAG)**
- **Extraction:** During ingestion, we use **spaCy** for Named Entity Recognition (NER) and **REBEL** (or LLM) for relation extraction.
- **Storage:** A NetworkX graph storing triples: `(Subject) --[Predicate]--> (Object)`.
- **Retrieval:**
1. Extract entities from the user query.
2. Traverse the graph to find related nodes (multi-hop traversal).
3. Retrieve the chunks associated with those nodes.
- **Why?** Solves "multi-hop" queries where the answer requires connecting disparate pieces of information across the document.
### **D. Fusion & Reranking (`retrieval/fusion.py`)**
- **RRF (Reciprocal Rank Fusion):** Combines the ranked lists from Milvus, BM25, and the Graph into one unified list.
- **Cross-Encoder Reranker:** We take the top-15 fused candidates and run them through a Cross-Encoder (e.g., `BAAI/bge-reranker-base`).
- **Why?** Cross-encoders are much more accurate (but slower) than vector search because they look at the query and chunk simultaneously. Using them as a final "filter" boosts precision significantly.
---
## 🧠 4. Generation Layer: "Corrective RAG (CRAG)"
The `CRAGGate` (`generation/crag.py`) acts as a "quality control" layer between retrieval and the LLM.
### **The CRAG Workflow**
1. **Grading:** An LLM-as-judge assesses if the retrieved chunks are relevant to the query.
2. **Action Categories:**
- **GOOD:** Chunks are relevant. Proceed to generation.
- **POOR:** Chunks are partially relevant. **Rewrite the query** (using CoT) and re-retrieve to find better results.
- **ABSENT:** Knowledge base doesn't have the answer. **Fallback to Web Search** (Tavily/DuckDuckGo).
3. **LLM Generation:** Uses Groq (Llama 3), OpenAI, or NVIDIA NIM to generate the final answer with **inline citations** (e.g., "The sky is blue [1].").
---
## πŸ“Š 5. Evaluation Layer: "Reference-Free Metrics"
Since production RAG systems often lack "ground truth" answers, we use the **RAGAS** framework (`evaluation/ragas_eval.py`).
### **Key Metrics**
- **Faithfulness:** Does the answer stay true to the retrieved context? (Prevents hallucinations).
- **Answer Relevancy:** Does the answer actually address the user's question?
- **Context Precision:** Were the retrieved chunks actually useful?
- **Context Utilisation:** What % of retrieved chunks were actually cited?
### **Implementation**
- Evaluations run **asynchronously** in background threads so they don't slow down the user's response time.
- Results are stored in a local SQLite DB for monitoring.
---
## πŸ› οΈ 6. System & Infrastructure
- **API:** FastAPI for high-performance, asynchronous endpoints.
- **UI:** Streamlit for a clean, interactive dashboard (Ask, Ingest, Monitor).
- **Cache:** Redis for caching query results (TTL-based) to save LLM costs and latency.
- **Deployment:** Full **Docker Compose** setup for Milvus, Redis, API, and UI.
---
## πŸ’‘ Interview Tip: "Why this architecture?"
If asked why you built it this way, emphasize these three points:
1. **Precision:** By using **Semantic Chunking** and **Cross-Encoder Reranking**, we ensure only the most relevant context reaches the LLM.
2. **Reliability:** **CRAG** ensures the system doesn't hallucinate when the knowledge base is missing information.
3. **Observability:** By integrating **RAGAS**, we have an automated way to track performance and catch regressions.
Good luck with your interview! πŸš€