What Is the Knowledge Graph Schema in Code-Graph-RAG?
The knowledge graph schema in Code-Graph-RAG is defined as a Protocol Buffers (protobuf) specification where the GraphCodeIndex message serves as the top-level container for strongly-typed Node entities and directed Relationship edges, creating a flattened, ID-based graph representation of codebases.
The vitali87/code-graph-rag project transforms raw source code into a queryable knowledge graph to support retrieval-augmented generation (RAG) systems. At its core, the system relies on a rigorous protobuf schema that standardizes how code entities—from high-level projects down to individual function calls—are encoded and interconnected. This schema ensures that language-specific abstract syntax trees (ASTs) can be unified into a common format for graph traversal and semantic search.
Core Schema Architecture
The knowledge graph schema centers on the GraphCodeIndex message defined in codec/schema.proto. This message acts as the root container for an entire codebase representation and contains two primary repeated fields:
nodes– A list of genericNodeobjects that wrap strongly-typed entity messages.relationships– A list ofRelationshipobjects that encode directed edges between nodes.
This design creates a flattened graph structure where nodes are referenced by unique identifiers rather than nested hierarchies, enabling efficient storage and traversal of large codebases.
Node Structure and Payloads
Each Node message utilizes a oneof payload field (lines 81–107 of codec/schema.proto) that can hold exactly one of several concrete entity types. This polymorphic approach allows the graph to store heterogeneous code elements—such as Project, Package, Folder, Module, Class, Function, and Method—within a uniform container.
The wrapper pattern decouples the graph topology from entity specifics, enabling the ingestion pipeline to handle new language constructs without altering the core graph structure.
Relationship Definitions
Relationships are defined by the Relationship message (lines 114–139 of codec/schema.proto), which establishes directed edges using source_id and target_id fields that reference node identifiers. Each relationship carries:
- A
RelationshipTypeenum value specifying the semantic nature of the edge - Optional
propertiesstored as a protobufStructfor metadata - Textual labels (
source_label,target_label) denoting the entity types involved
Entity Types and Primary Keys
The schema defines distinct protobuf messages for various code artifacts, each utilizing specific fields as primary identifiers:
| Entity | Primary Key | Key Fields |
|---|---|---|
| Project | name |
– |
| Package | qualified_name |
name, path |
| Folder | path |
name |
| File | path |
name, extension |
| Module | qualified_name |
name, path, decorators, flow_covered |
| ExternalModule | qualified_name |
name, path |
| ModuleImplementation | qualified_name |
name, path, implements_module (C++20) |
| ModuleInterface | qualified_name |
name, path (C++20) |
| Function | qualified_name |
name, docstring, line range, decorators, is_exported |
| Method | qualified_name |
name, docstring, line range, decorators |
| Class | qualified_name |
name, docstring, line range, decorators, is_exported |
| Interface | qualified_name |
name, path, absolute_path |
| Enum | qualified_name |
name, path, absolute_path |
| Type | qualified_name |
name |
| Union | qualified_name |
name |
The consistent use of qualified_name for code elements and path for filesystem entities ensures reliable cross-referencing throughout the graph.
Relationship Types and Semantic Edges
The RelationshipType enum (lines 118–136 of codec/schema.proto) enumerates all supported edge semantics:
- Containment:
CONTAINS_PACKAGE,CONTAINS_FOLDER,CONTAINS_FILE,CONTAINS_MODULE - Definition:
DEFINES(module to function/class/enum),DEFINES_METHOD(class to method) - Invocation:
CALLS(function/method to function/method) - Inheritance:
INHERITS,OVERRIDES - Dependencies:
IMPORTS,DEPENDS_ON_EXTERNAL
These relationship types enable precise graph traversals for use cases like "find all callers of this function" or "identify classes that inherit from a given base class."
Building and Serializing Graphs in Python
The generated Python bindings in codec/schema_pb2.py provide classes for constructing and manipulating graph instances programmatically.
Creating a Basic Graph Structure
from codec import schema_pb2 as sb
# Create nodes
project = sb.Node(project=sb.Project(name="my_project"))
folder = sb.Node(folder=sb.Folder(path="src/", name="src"))
file_node = sb.Node(
file=sb.File(path="src/main.py", name="main.py", extension=".py")
)
# Create relationships
rel_proj_folder = sb.Relationship(
type=sb.Relationship.CONTAINS_FOLDER,
source_id=project.project.name,
target_id=folder.folder.path,
source_label="Project",
target_label="Folder",
)
rel_folder_file = sb.Relationship(
type=sb.Relationship.CONTAINS_FILE,
source_id=folder.folder.path,
target_id=file_node.file.path,
source_label="Folder",
target_label="File",
)
# Assemble the graph
graph = sb.GraphCodeIndex(
nodes=[project, folder, file_node],
relationships=[rel_proj_folder, rel_folder_file],
)
# Serialize to protobuf binary
with open("graph_index.pb", "wb") as f:
f.write(graph.SerializeToString())
Adding Functions and Call Relationships
# Create a function node
func = sb.Node(
function=sb.Function(
qualified_name="src.main.main",
name="main",
docstring="Entry point",
start_line=1,
end_line=10,
decorators=[],
is_exported=True,
)
)
# Create a CALLS relationship
call_rel = sb.Relationship(
type=sb.Relationship.CALLS,
source_id="src.main.main", # caller
target_id="src.utils.helper", # callee
source_label="Function",
target_label="Function",
)
# Append to existing graph
graph.nodes.append(func)
graph.relationships.append(call_rel)
Schema Implementation and Consumption
Several modules interact with the knowledge graph schema during the ingestion and query pipeline:
codec/schema.proto– The canonical protobuf definition specifying all messages, enums, and fields.codec/schema_pb2.py– Auto-generated Python classes providing serialization and deserialization capabilities.codebase_rag/graph_loader.py– Handles loading serializedGraphCodeIndexprotobuf files from disk into memory.codebase_rag/graph_updater.py– Implements logic for mutating the graph, including node addition and relationship updates during incremental indexing.codebase_rag/schema_builder.py– Contains utility functions that translate language-specific AST nodes into the standardized protobuf entity messages.
Summary
- The knowledge graph schema in Code-Graph-RAG is implemented in
codec/schema.protousing Protocol Buffers. - The
GraphCodeIndexmessage serves as the root container for lists ofNodeandRelationshipobjects. - Nodes use a oneof payload pattern to wrap specific entity types (Project, Function, Class, etc.), each identified by
qualified_nameorpath. - Relationships are directed edges with typed enums (
CONTAINS_*,DEFINES,CALLS,INHERITS) connecting nodes by ID. - The generated
schema_pb2.pybindings enable Python code to construct, serialize, and deserialize graph indices for storage and retrieval.
Frequently Asked Questions
What file format defines the knowledge graph schema in Code-Graph-RAG?
The schema is defined in codec/schema.proto as a Protocol Buffers (protobuf) specification. This file declares all entity messages, the GraphCodeIndex container, and the RelationshipType enum. The Python implementation uses auto-generated bindings from this file located at codec/schema_pb2.py.
How does the schema handle different programming language constructs uniformly?
The schema employs a polymorphic node wrapper where the generic Node message contains a oneof field that can hold any specific entity type (Function, Class, Module, etc.). This allows the graph to store heterogeneous code elements from multiple languages within a single, uniform structure while preserving type safety through the protobuf definition.
What fields are used to identify nodes uniquely in the graph?
Nodes are identified by primary key fields specific to their entity type: qualified_name for code symbols (functions, classes, modules) and path for filesystem elements (files, folders). These identifiers populate the source_id and target_id fields in Relationship messages to create edges without data duplication.
Which modules are responsible for building and loading the knowledge graph?
The graph construction and persistence pipeline relies on codebase_rag/schema_builder.py for AST-to-protobuf translation, codebase_rag/graph_updater.py for incremental graph modifications, and codebase_rag/graph_loader.py for deserializing stored GraphCodeIndex protobuf files into queryable in-memory structures.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →