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

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, which parses subcommands and delegates to specialized handlers.

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 specifies this API.

For the example above, the LLM returns:

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】.

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 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 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 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 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 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:

cgr callers utils.parse_config

Behind the scenes, 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:

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

The system:

  1. Resolves config.py and target line via 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:

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】 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
  • 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. 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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →