MyProjects

MindDomain The Power Of Hybrid RAG

How to implement a RAG(retrival augmentation generation) with Knowledge Graph (kuzu DB), vector DB, Feedback System

What I Built

Most RAG systems retrieve the same five chunks for the same question every time, forever. MindDomain doesn't work that way. It's a hybrid retrieval engine that pairs a vector database with a graph database, then gets smarter every time someone rates an answer.

The idea was simple: dense embeddings are great at "these two things sound similar," but they're bad at "these two things are connected." A knowledge graph is the opposite. So instead of picking one, MindDomain runs both searches in parallel and merges what comes back — better recall on factual comparisons, entity relationships, and the multi-hop questions that trip up plain vector search.

Why Hybrid Retrieval Beats Vector-Only RAG

Vector search alone answers "what sounds like this" well and "how are these connected" poorly. Graph search is the reverse — strong on relationships, weak on fuzzy similarity. MindDomain runs ChromaDB and KuzuDB side by side instead of betting on one:

  • Cosine similarity search over embeddings (ChromaDB) catches semantic overlap
  • Structured entity and relationship traversal (KuzuDB) catches connections vector search misses
  • Results get merged and deduplicated before they ever reach the LLM If the combined context still falls short of a confidence threshold, the engine doesn't guess — it asks permission to fall back to a live web search.

The Stack

Layer Tool
Vector DB ChromaDB (cosine similarity)
Graph DB KuzuDB (embedded, disk + in-memory)
Embeddings BAAI/bge-small-en-v1.5, runs on CPU
LLM routing Nvidia NIM → OpenRouter → Groq (auto-fallback by key precedence)
Web fallback DuckDuckGo HTML search
Feedback log SQLite
Terminal UI prompt_toolkit + rich
Language Python

How the Retrieval Loop Actually Works

A query goes in, and here's the path it takes:

User query → extract entities + embed
           → vector search (Chroma) + graph search (Kuzu), run in parallel
           → merge and deduplicate context
           → confident enough? → answer from local context
           → not confident (or answer = NOT_FOUND)? → ask to search the web
           → web search → synthesize answer with citations
           → user rates the answer (thumbs up/down)
           → thumbs up → embed the Q&A, extract entities, write back to both DBs
           → either way → log the interaction to SQLite

That last step is the part that makes this "self-improving" rather than just "RAG with extra steps." A thumbs-up doesn't just log satisfaction — it writes the question and answer straight back into both the vector store and the graph store. Ask the same thing again later and the engine answers from memory instead of hitting the web a second time.

Key Learnings

  • Merging vector and graph context before generation catches queries that either method alone would fumble — particularly multi-hop and comparison questions.
  • A confidence threshold that gates web fallback keeps the system from making things up when local knowledge is thin, without hitting the network on every single query.
  • Treating user feedback as a write path, not just a log, turns a static knowledge base into one that compounds — every thumbs-up makes the next similar query cheaper and faster to answer.
  • Routing across multiple LLM providers by key precedence (Nvidia NIM, then OpenRouter, then Groq) is a cheap way to avoid getting stuck when one provider is down or rate-limited.

Share this article if it helped you!