Causality-Aware Retrieval-Augmented Generation
Find what keyword search can't β by understanding why things are connected.
Problem β’ Solution β’ Quick Start β’ Search Modes β’ API β’ Benchmarks
Research Context: In June 2025, researchers at the University of Illinois Urbana-Champaign published "CC-RAG: Structured Multi-Hop Reasoning via Theme-Based Causal Graphs" β a breakthrough paper that brought causal reasoning into RAG systems. The academic world was excited: RAG could finally "understand and connect," not just "find and fetch."
We had already been doing this for two months. NeuroCausal RAG v5.0 was deployed to production in April 2025. The causal engine, multi-hop retrieval, and chain injection were already running in real enterprise environments.
This is how we work: we build for real clients first, battle-test in production, then open-source. Our personal AI system JARVIS has been alive for 5 years and operating as an autonomous agent for 3 years β months before platforms like OpenClaw existed. We plan to open-source that too.
Read more: Our 2025 AI R&D: NeuroCausal RAG, DSGMv2, and 100+ SaaS Projects
Classic RAG systems retrieve documents by keyword similarity. Search for "stress" and you get documents containing the word "stress."
But real-world knowledge doesn't work that way:
Stress β Cortisol rises β Sleep disrupted β Attention drops β Workplace accident risk increases
If your system can't see this chain, it misses critical connections.
The academic world noticed this in June 2025 when UIUC researchers published CC-RAG, introducing causal graphs into RAG.
We deployed this to production in April 2025. Two months earlier.
NeuroCausal RAG builds a causal knowledge graph on top of your documents and retrieves information by understanding why things are connected β not just what words they share.
| Classic RAG | NeuroCausal RAG | |
|---|---|---|
| Retrieval | Keyword similarity | Cause-effect relationships |
| Search for "stress" | Documents about stress | + Cortisol, sleep, workplace accidents |
| Hops | Single (1-hop) | N-degree (multi-hop) |
| Scoring | Vector distance | Hybrid: Similarity + Causal + PageRank |
| Memory | None | Persistent feedback loop |
| Contradictions | Ignored | Detected and flagged |
NeuroCausal RAG v6.0
βββ Core Layer
β βββ Causal Knowledge Graph (NetworkX / Neo4j)
β βββ Multilingual Embeddings (Sentence-BERT)
β βββ Vector Index (BruteForce / FAISS / Milvus)
β
βββ Search & Retrieval
β βββ Hybrid Retriever (Similarity + Causal + Importance)
β βββ Multi-Hop Search (N-hop path finding + bridge docs)
β βββ Search Optimizer (6 adaptive modes)
β βββ Query Decomposer (complex β sub-queries)
β
βββ Reasoning
β βββ Contradiction Detector
β βββ Temporal Reasoner
β βββ Entity Linker (alias resolution)
β
βββ Learning
β βββ Causal Discovery (semantic + NLI + funnel)
β βββ Feedback Loop (RLHF)
β βββ Persistent Memory (SQLite)
β
βββ Agentic RAG
β βββ LangGraph Self-Correcting Agent
β
βββ API & UI
βββ FastAPI REST API
βββ Streamlit Dashboard
Final Score = Ξ± Γ Similarity + Ξ² Γ Causal + Ξ³ Γ Importance
Multi-Hop Decay: hop_score = base_score Γ (0.7 ^ hop_distance)
git clone https://github.com/ertugrulakben/NeuroCausal-RAG.git
cd NeuroCausal-RAG
pip install -r requirements.txtfrom neurocausal_rag import NeuroCausalRAG
rag = NeuroCausalRAG()
# Add documents
rag.add_document("cement", "Cement production is responsible for 8% of global CO2 emissions.")
rag.add_document("co2", "CO2 is the primary greenhouse gas driving climate change.")
rag.add_document("warming", "Global warming causes sea level rise and extreme weather.")
# Add causal links
rag.add_causal_link("cement", "co2", "causes")
rag.add_causal_link("co2", "warming", "causes")
# Search β finds cement even though query doesn't mention it
results = rag.search("What causes global warming?")
# β Returns: co2, warming, AND cement (via causal chain)from neurocausal_rag.search import create_multi_hop_retriever
retriever = create_multi_hop_retriever(graph, embedding, max_hops=3)
results = retriever.search("How does cement affect sea levels?")
# Discovered chain:
# Cement Production β CO2 Emissions β Global Warming β Sea Level Rise
explanation = retriever.explain_connection("cement", "warming")docker-compose up -d
# API: http://localhost:8000
# UI: http://localhost:85016 preset modes for different retrieval strategies:
| Mode | Ξ± (Similarity) | Ξ² (Causal) | Ξ³ (Importance) | Best For |
|---|---|---|---|---|
| BALANCED | 0.5 | 0.3 | 0.2 | General purpose |
| ENCYCLOPEDIA | 0.7 | 0.2 | 0.1 | Factual queries |
| DETECTIVE | 0.3 | 0.5 | 0.2 | Cause-effect investigation |
| HUB | 0.3 | 0.2 | 0.5 | Finding central documents |
| EXPLORER | 0.4 | 0.3 | 0.3 | Open-ended research |
| FACT_CHECKER | 0.6 | 0.3 | 0.1 | Verification tasks |
from neurocausal_rag.search import create_optimizer
optimizer = create_optimizer(graph, embedding)
results = optimizer.search("Why did the bridge collapse?", mode="DETECTIVE")Full REST API via FastAPI:
uvicorn neurocausal_rag.api.app:create_app --factory --host 0.0.0.0 --port 8000| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/search |
Search with causal reasoning |
POST |
/api/v1/documents |
Add documents |
GET |
/api/v1/documents |
List documents |
POST |
/api/v1/documents/links |
Add causal links |
POST |
/api/v1/agent/query |
Agentic RAG query |
POST |
/api/v1/feedback |
Submit feedback |
POST |
/api/v1/discovery |
Auto-discover causal links |
GET |
/api/v1/graph/stats |
Graph statistics |
POST |
/api/v1/graph/chain |
Get causal chain |
GET |
/api/v1/health |
Health check |
curl -X POST http://localhost:8000/api/v1/search \
-H "Content-Type: application/json" \
-d '{"query": "What causes global warming?", "top_k": 5, "mode": "DETECTIVE"}'Query: "How do greenhouse gases cause global warming?"
| Metric | Classic RAG | NeuroCausal RAG |
|---|---|---|
| Search Time | 37 ms | 22 ms |
| Documents Found | Greenhouse effect, Gases | + Cement Production |
| Causal Score | 0.00 | 1.00 |
| Multi-Hop | None | 3-hop chain |
Discovered chain:
Cement Production β CO2 Emissions β Greenhouse Gas β Global Warming
The word "cement" appears nowhere in the query β but the causal chain reveals the connection.
| Feature | CC-RAG (June 2025) | NeuroCausal RAG (April 2025) |
|---|---|---|
| Causal Graph | DAG structure | NetworkX + Neo4j |
| Multi-Hop | Theme-based chaining | N-hop + bridge documents |
| Bidirectional Search | Yes | Yes |
| Memory System | No | Persistent (SQLite) |
| Query Decomposition | No | Sub-query system |
| Contradiction Detection | No | Yes |
| Temporal Reasoning | No | Yes |
| Entity Linking | No | Yes (alias resolution) |
| Enterprise Ready | Academic | Production deployed |
| Published | June 2025 | April 2025 |
pytest tests/ -v
# With coverage
pytest tests/ --cov=neurocausal_rag --cov-report=htmlTest Distribution (v6.1)
βββ Core (graph, node, edge): 35 tests
βββ Search (retriever, multi_hop, optimizer, decomposer): 66 tests
βββ Learning (discovery, entity, temporal, contradiction): 42 tests
βββ Memory: 24 tests
βββ Integration: 20 tests
βββ API Routes: 58 tests
βββ Config Validation: 70 tests
βββ LLM Client: 34 tests
βββ Imports & Exports: 33 tests
βββββββββββββββββββββββββββββ
Total: 382 tests, 0 failures
neurocausal_rag/
βββ core/ # Graph engine, nodes, edges
βββ embedding/ # Sentence-BERT multilingual
βββ search/ # Retriever, multi-hop, optimizer, decomposer
βββ learning/ # Causal discovery, feedback, pipeline
βββ entity/ # Entity linking, NER
βββ reasoning/ # Contradiction detection, temporal reasoning
βββ memory/ # Persistent memory store
βββ agents/ # LangGraph agentic RAG
βββ api/ # FastAPI REST endpoints
βββ llm/ # LLM client (OpenAI)
βββ visualization/ # Graph visualization (PyVis)
βββ ui/ # Streamlit components
cp .env.example .env
# Set your API keys in .env- Causal knowledge graph
- Multi-hop retrieval
- 6 search modes
- Contradiction detection
- Temporal reasoning
- Entity linking
- Persistent memory (RLHF)
- REST API (FastAPI)
- Agentic RAG (LangGraph)
- Enterprise backends (Neo4j, Milvus)
- 187 tests
- Batch processing
- Advanced UI
- PyPI package
Ertugrul Akben β AI & Systems Strategist
Because knowing "what" is not enough β you need to know "why."
