A novel Retrieval-Augmented Generation mechanism for code assistants that uses dependency graph traversal instead of pure vector similarity — enabling true multi-hop reasoning across codebases.
Standard RAG retrieves code chunks by cosine similarity alone. But code is a graph:
- Functions call other functions
- Classes inherit from other classes
- Modules import other modules
When you ask "Why does UserService.save() fail when DB disconnects?", vanilla RAG retrieves only UserService.save() — missing DatabasePool, RetryHandler, and the config it depends on.
GAC-RAG solves this with 3-layer retrieval:
Query → [Semantic Anchor] → [Graph Expansion] → [LLM Reranker] → Answer
┌─────────────────────────────────────────────────────────┐
│ GAC-RAG │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Layer 1 │ │ Layer 2 │ │ Layer 3 │ │
│ │ Semantic │───▶│ Graph │───▶│ LLM │ │
│ │ Anchor │ │ Expansion │ │ Reranker │ │
│ │(ChromaDB)│ │ (Neo4j) │ │ (Claude) │ │
│ └──────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ Vector search Hop traversal Prune noise │
│ top-k nodes calls/imports/ keep relevant │
│ inherits edges nodes only │
└─────────────────────────────────────────────────────────┘
- 🔎 Multi-language support — parses Python, JS/TS, Java, Go, C++ via
tree-sitter - 🕸️ Dependency graph — builds call graph, import graph, inheritance graph in Neo4j
- 🔢 Semantic anchoring — ChromaDB stores function/class embeddings
- 🔁 N-hop traversal — configurable depth with relevance decay scoring
- 🤖 LLM reranking — Claude prunes irrelevant nodes before final generation
- 📓 Jupyter demo — interactive notebook with a real sample codebase
- 🧪 Test suite — unit tests for graph builder, retriever, and reranker
- Python 3.10+
- Neo4j Desktop or Docker
- Anthropic API key
git clone https://github.com/YOUR_USERNAME/gac-rag.git
cd gac-rag
pip install -r requirements.txtdocker run \
--name neo4j-gac \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/password \
neo4j:5cp .env.example .env
# Edit .env with your API key and Neo4j credentialsjupyter notebook notebooks/demo.ipynbgac-rag/
├── src/
│ ├── indexer.py # Parses code → builds graph + embeddings
│ ├── graph_store.py # Neo4j interface (nodes, edges, traversal)
│ ├── vector_store.py # ChromaDB interface (embed, search)
│ ├── retriever.py # 3-layer retrieval pipeline
│ ├── reranker.py # LLM-based context pruning
│ └── assistant.py # Final answer generation
├── notebooks/
│ └── demo.ipynb # Full interactive walkthrough
├── tests/
│ ├── test_indexer.py
│ ├── test_retriever.py
│ └── test_reranker.py
├── sample_repo/ # Example codebase to query against
│ ├── services/
│ ├── models/
│ └── utils/
├── docs/
│ └── architecture.md
├── requirements.txt
├── .env.example
└── README.md
from src.assistant import CodeAssistant
assistant = CodeAssistant(repo_path="./sample_repo")
assistant.index() # Build graph + embeddings
answer = assistant.ask(
"Why does payment processing fail silently when the database is down?"
)
print(answer)Standard RAG retrieves: PaymentService.process() only
GAC-RAG retrieves:
PaymentService.process()← semantic anchorDatabasePool.getConnection()← 1 hop (called)RetryHandler.attempt()← 1 hop (called)EventBus.emit()← 2 hopsconfig.db_timeout← 2 hops (imported)
| Metric | Standard RAG | GAC-RAG |
|---|---|---|
| Single-function questions | ✅ Good | ✅ Good |
| Cross-file reasoning | ❌ Poor | ✅ Excellent |
| Multi-hop (3+ steps) | ❌ Fails | ✅ Strong |
| Retrieval precision | ~0.61 | ~0.84 |
| Context relevance | ~0.58 | ~0.81 |
Tested on the included sample repo with 20 multi-hop questions.
PRs welcome! See CONTRIBUTING.md for guidelines.
MIT — see LICENSE