# How the RAG System Works in Code‑Graph‑RAG: Architecture and Data Flow Explained

> Discover how the RAG system in Code-Graph-RAG transforms queries into Cypher, queries a Memgraph knowledge graph, and generates context-aware answers or AST patches. Explore the architecture and data flow.

- Repository: [Vitali Avagyan/code-graph-rag](https://github.com/vitali87/code-graph-rag)
- Tags: architecture
- Published: 2026-09-06

---

**The RAG system in Code‑Graph‑RAG converts natural‑language queries into LLM‑generated Cypher statements, executes them against a Memgraph knowledge graph, and synthesizes context‑aware answers or AST patches.**

Code‑Graph‑RAG implements a two‑component architecture where the **Retrieval‑Augmented Generation (RAG) system** serves as the interactive, AI‑driven query layer. After the Multi‑Language Parser builds a language‑agnostic knowledge graph in Memgraph using Tree‑sitter, the RAG system enables developers to explore and modify that graph through natural language. This article breaks down the exact data flow, key source files, and practical usage patterns.

## RAG System Architecture Overview

The RAG system follows a deterministic six‑stage pipeline that bridges user intent and graph data:

1. **User query entry** – Input via `cgr` CLI or MCP request
2. **LLM‑driven Cypher generation** – Prompt expansion with few‑shot examples
3. **Cypher execution** – Query against Memgraph via `pymgclient`
4. **Result post‑processing** – Typed dictionaries with guaranteed sort order
5. **LLM‑driven response synthesis** – Human‑readable answers with source citations
6. **Optional side‑effects** – Code optimization suggestions or AST patch application

This pipeline is orchestrated within the `codebase_rag/` package, a self‑contained CLI built with **Typer**, **Rich**, and **Prompt‑Toolkit**.

## Core Data Flow: From Query to Answer

Understanding how the RAG system works requires tracing a single request through the codebase.

### Step 1: Natural‑Language Query Input

Users interact through the `cgr` command. The entry point resides in [`codebase_rag/graph_cli.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_cli.py), which parses subcommands and delegates to specialized handlers.

```bash
cgr ask "Where is the `UserService` class defined?"

```

### Step 2: Cypher Generation via LLM

The query routes through the *pydantic‑ai* agent framework. The model receives an expanded prompt containing few‑shot examples of natural language mapped to Cypher patterns. Documentation in [`docs/sdk/cypher-generator.md`](https://github.com/vitali87/code-graph-rag/blob/main/docs/sdk/cypher-generator.md) specifies this API.

For the example above, the LLM returns:

```cypher
MATCH (c:Class {qualified_name: "myapp.services.UserService"})
RETURN c.path, c.start_line, c.end_line

```

### Step 3: Graph Execution in Memgraph

The generated Cypher executes through `pymgclient` against the Memgraph database. The deterministic query logic lives in [`codebase_rag/graph_query.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_query.py)【https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_query.py】.

### Step 4: Result Transformation

Raw rows convert to typed dictionaries—`SymbolRow`, `DefinitionRow`, `CallSiteRow`—with explicit sorting to ensure repeatable output. Functions `resolve` and `source_root_for` in [`graph_query.py`](https://github.com/vitali87/code-graph-rag/blob/main/graph_query.py) handle navigation‑style queries like "go‑to‑definition" and "find callers".

### Step 5: Response Synthesis

Retrieved snippets return to the LLM, which produces human‑readable answers citing exact source locations: file paths, line ranges, and qualified names.

### Step 6: Optional Code Modification

For editing workflows, the LLM generates AST‑level patches shown as diffs for user confirmation. Approved patches apply via the `diff‑match‑patch` library.

## Key Source Files in the RAG Pipeline

| File | Role |
|------|------|
| [`codebase_rag/graph_query.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_query.py) | Core deterministic query builder and result transformers (`resolve`, `source_root_for`)【https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_query.py】 |
| [`codebase_rag/graph_cli.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_cli.py) | CLI entry point (`cgr`) parsing commands and orchestrating LLM calls【https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_cli.py】 |
| [`codebase_rag/graph_updater.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_updater.py) | Pipeline controller handling parsing, graph ingestion, and incremental updates【https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_updater.py】 |
| [`docs/architecture/overview.md`](https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/overview.md) | High‑level two‑component design documentation【https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/overview.md】 |

## Practical Usage Examples

### Finding Function Callers

The `callers` command demonstrates deterministic query construction without LLM involvement for common patterns:

```bash
cgr callers utils.parse_config

```

Behind the scenes, [`graph_query.py`](https://github.com/vitali87/code-graph-rag/blob/main/graph_query.py) constructs a Cypher query walking `CALLS` edges to return each call‑site with precise location data.

### AI‑Assisted Code Editing

The `edit` command exercises the full RAG system with side‑effects:

```bash
cgr edit "Replace the hard‑coded API key in `config.py` with a call to `get_secret()`"

```

The system:
1. Resolves [`config.py`](https://github.com/vitali87/code-graph-rag/blob/main/config.py) and target line via [`graph_query.py`](https://github.com/vitali87/code-graph-rag/blob/main/graph_query.py)
2. Sends context to LLM for AST‑level patch generation
3. Displays diff for user confirmation
4. Applies patch via `diff‑match‑patch` on approval

### Programmatic SDK Access

The Python SDK mirrors CLI behavior for integration into external tooling:

```python
from cgr import GraphLoader, CypherGenerator

loader = GraphLoader.load_graph("graph.json")
cypher = CypherGenerator()
query = cypher.from_natural("List all public functions in the `auth` module")
rows = loader.run_cypher(query)

```

## Visualization of the Complete Data Flow

```

Source Code → Tree‑sitter Parser → AST Analysis → Memgraph Knowledge Graph
                                                             ↓
User Query → AI Model (Cypher Gen) → Cypher Query → Graph Results → Response

```

See [`docs/architecture/overview.md`](https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/overview.md)【https://github.com/vitali87/code-graph-rag/blob/main/docs/architecture/overview.md】 for the official diagram.

## Summary

- **Code‑Graph‑RAG's RAG system** operates as the query‑and‑response layer atop a Memgraph knowledge graph generated by Tree‑sitter parsing
- **LLM involvement** occurs at two points: Cypher generation from natural language, and response synthesis from retrieved graph data
- **Deterministic queries** for common navigation patterns bypass the LLM for speed and reliability, implemented in [`codebase_rag/graph_query.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_query.py)
- **Code modification** workflows generate AST patches with user‑controlled approval before application
- **Both CLI and SDK** expose identical pipeline behavior, enabling interactive and programmatic usage

## Frequently Asked Questions

### Does the RAG system require an LLM for every query?

No. Simple navigation commands like `cgr callers` and `cgr resolve` use deterministic Cypher templates in [`codebase_rag/graph_query.py`](https://github.com/vitali87/code-graph-rag/blob/main/codebase_rag/graph_query.py). The LLM is invoked only for natural‑language `ask` queries, complex filtering, or code‑generation tasks.

### What database does Code‑Graph‑RAG use for the knowledge graph?

**Memgraph** via the `pymgclient` driver. The graph stores nodes for classes, functions, files, and call sites with properties including qualified names, source paths, and line ranges.

### How does the system ensure reproducible query results?

All result transformers in [`graph_query.py`](https://github.com/vitali87/code-graph-rag/blob/main/graph_query.py) apply explicit sorting to returned rows. Typed dictionaries (`SymbolRow`, `DefinitionRow`, etc.) guarantee schema consistency across query types.

### Can the RAG system modify source code automatically?

Only with explicit user approval. The `edit` command generates AST patches via LLM, displays a diff through **Rich**, and applies changes via `diff‑match‑patch` only after confirmation. This prevents unintended modifications.