Hybrid RAG over Security Assets
A production module inside a Security Command Center (SCC) platform that lets analysts ask natural-language questions over a sprawling estate of asset documents — server inventories, app registries, user lists, logs, PDFs — and get a cited, grounded answer powered by hybrid vector + keyword retrieval and an LLM whose prompt was machine-optimized offline.
What it does. A SOC sits on a mountain of asset documentation — spreadsheets of servers, app inventories, user directories, logs, PDFs — spread across formats and storage. Finding "which internet-facing servers run service X and who owns them" normally means hunting through files by hand. This module turns that estate into a question-answering surface: an analyst types a natural-language query and gets a synthesized answer with source citations, drawn from both the meaning of documents (semantic search) and exact terms (keyword search). It handles both unstructured docs (PDF/MD/TXT/LOG/JSON/HTML) and structured tabular data (CSV/XLSX), and can also return raw ranked hits when an analyst wants the evidence without the prose.
// Background
Asset knowledge exists but can't be queried quickly.
Finding 'who owns this server?' costs minutes.
Scattered, multi-format data
Critical context lived across spreadsheets, PDFs,
logs, and JSON in object storage.
No unified query surface over the asset estate
Keyword search wasn't enough
Exact-match missed semantically-phrased questions;
pure vector missed exact IDs (hostnames, IPs).
Every retrieval mode had a blind spot
Manual lookup slow mid-incident
Paging through files to answer 'who owns this,
what runs here' cost precious minutes.
Incident response slowed to a file hunt
Answers needed to be trustworthy
A free-floating LLM answer is useless to a SOC
without sources — analysts must verify every claim.
Citations aren't optional in a security context
Net effect
A mountain of asset docs across formats, no single
question surface, and answer quality that couldn't be
measured meant analysts hunted files by hand.
// Solution
Data sources
Asset documents
PDF · MD · JSON · CSV · XLSX
object storage (S3-compatible)
Analyst NL query
natural-language question
→ hybrid retrieve → LLM answer
Pipeline
Ingest
chunk + embed
split by type
Ingest
Index
Qdrant (dense+sparse)
Typesense (full-text)
Index
Retrieve
hybrid fan-out
merge + rerank
Retrieve
Generate
LLM + citations
champion prompt
Generate
Portal
Vue 3 + FastAPI
asset search UI
Serve
Dual index (Qdrant + Typesense) · hybrid merge + rerank · champion prompt via DSPy + LLM-as-Judge versioned in MLflow
// Impact
Lookup: files → instant answer
Before · by hand
hunt files · slow · no citationsAfter · hybrid RAG
NL query → cited LLM answer7
7-axis LLM-as-Judge optimization
Operational impact
Higher recall, both ways
dense+sparse+keyword: semantic + exact
Trustworthy by construction
answers cited · retrieval-only mode
Quality is measured, not guessed
DSPy + LLM-as-Judge optimization
Prompt versioned in MLflow
champion prompt auto-loaded, safe
Format-agnostic
one interface: PDF, sheets, logs, JSON
No schema knowledge required
ask in plain language, any asset type
Results
LLM judge axes
7
Index backends
2
Answers cited
100%
Query latency
~sec
Champion prompt auto-loaded at startup ·
collections aliased + versioned.
| Layer | Technologies |
|---|---|
| Ingestion | Object storage (S3-compatible), Papermill notebook (on-demand), Python, pandas |
| Retrieval | Qdrant (dense sentence-transformer + sparse BM25, alias/version tags), Typesense (full-text), hybrid merge + rerank |
| Generation | LLM answer synthesis with citations, retrieval-only mode |
| Prompt MLOps | DSPy MIPROv2, LLM-as-Judge (7 eval axes), MLflow champion prompt registry, startup load |
| Observability | Laminar tracing (optional Langfuse backup) |
| Backend API | FastAPI (Tools API + portal proxy with auth injection) |
| Frontend | Vue 3, Quasar, Vite, TypeScript |
Disclaimer: sample visuals may contain anonymized, simulated, or non-production values for presentation purposes.