Skip to main content

GraphRAG

GraphRAG

Hybrid retrieval combining semantic vector search with knowledge graph traversal.

Full Pipeline

Phase 1 — Ingestion

Document Upload
POST /v1/documents/upload

Extraction
pypdf · pdfplumber · pymupdf · python-docx · python-pptx · openpyxl · pytesseract

Text Chunking
Sliding window · configurable size & overlap

Embedding Generation
sentence-transformers

Entity Extraction
Linked to Sagittarius graph nodes

Vector Store
Redis DB 1
sqlite-vec + FalkorDB
Knowledge Graph
Sagittarius
Entity nodes & edges

Phase 2 — Retrieval

Query Text
POST /v1/graphrag/query

Query Embedding
sentence-transformers (same model)

Vector Search
Cosine similarity

Graph Traversal
Related entities

RRF Rank Fusion
Vector score + Graph proximity

Top-K Results
Chunks with score, source, page, entities


What is GraphRAG?

Standard RAG (Retrieval-Augmented Generation) uses vector similarity alone: it finds chunks of text whose embedding is close to the query embedding. This works well for semantic matching but misses relational context — the fact that a document mentions "Pedro" tells you nothing about Pedro's open issues, the repositories he owns, or his team's recent incidents.

GraphRAG adds a second retrieval channel: after vector search identifies candidate chunks, the system traverses the Sagittarius knowledge graph starting from the entities mentioned in those chunks. This surfaces related nodes — people, issues, repos, calendar events — that would never appear in a pure vector search.

The two ranked lists (vector results, graph results) are then combined using Reciprocal Rank Fusion (RRF) into a single re-ranked output. The result is more relevant and contextually grounded than either source alone.

DimensionVector search onlyGraphRAG
Matching basisSemantic similaritySemantic + relational
MissesEntities connected to matching textNothing additionally missed
Result qualityGood for self-contained docsBetter for interconnected knowledge
Latency overheadBaseline+graph traversal (~10–30 ms)

Supported Document Formats

Ingestion — Supported Formats

📄
PDF
pypdf
pdfplumber
pymupdf
📝
DOCX
python-docx
📊
PPTX
python-pptx
📈
Excel
openpyxl
.xlsx · .xls
🖼️
Images / Scanned
pytesseract OCR
via pdf2image
PNG · JPG · TIFF

Rank Fusion Formula

Reciprocal Rank Fusion (RRF)

final_score(d) = Σ 1 / (k + ranki(d))

where k = 60 (rank smoothing constant) · sum over all retrieval lists i

Vector Results
#1chunk_42 · 0.93
#2chunk_07 · 0.87
#3chunk_19 · 0.81
#4chunk_55 · 0.74
Graph Results
#1chunk_19 · hop 1
#2chunk_42 · hop 1
#3chunk_88 · hop 2
#4chunk_03 · hop 3
Fused Output
#1chunk_420.0328
#2chunk_190.0311
#3chunk_070.0161
#4chunk_880.0159

chunk_42 ranks #1 in vector and #2 in graph → combined RRF score pushes it to final #1.
chunk_19 ranks #3 in vector but #1 in graph → graph boost elevates it to final #2.


API Reference

Query endpoint

POST /v1/graphrag/query

Request body:

{
"query": "string",
"top_k": 10,
"filters": {
"source": "string | null",
"entity_type": "string | null",
"date_from": "ISO-8601 | null",
"date_to": "ISO-8601 | null"
}
}
FieldTypeRequiredDescription
querystringYesNatural language query text
top_kintegerNo (default: 10)Maximum number of chunks to return
filters.sourcestringNoFilter by source document filename or ID
filters.entity_typestringNoRestrict graph traversal to a specific entity type (e.g. "person", "repo")
filters.date_fromstringNoISO-8601 date — only return chunks ingested after this date
filters.date_tostringNoISO-8601 date — only return chunks ingested before this date

Response body:

{
"chunks": [
{
"chunk_id": "string",
"score": 0.0328,
"text": "string",
"source": "string",
"page": 4,
"entities": [
{
"id": "string",
"type": "person | repo | issue | event | ...",
"label": "string"
}
]
}
],
"query_embedding_ms": 12,
"vector_search_ms": 8,
"graph_traversal_ms": 24,
"rrf_ms": 2
}
FieldTypeDescription
chunks[].chunk_idstringUnique identifier for this text chunk
chunks[].scorefloatFinal RRF score (higher is more relevant)
chunks[].textstringRaw chunk text
chunks[].sourcestringOriginal document filename or URI
chunks[].pageintegerPage number within the source document (1-indexed)
chunks[].entitiesarraySagittarius graph nodes extracted from this chunk
*_msintegerPer-stage latency breakdown in milliseconds

Upload endpoint

POST /v1/documents/upload

Accepted MIME types:

FormatMIME type
PDFapplication/pdf
Wordapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
PowerPointapplication/vnd.openxmlformats-officedocument.presentationml.presentation
Excel (xlsx)application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Excel (xls)application/vnd.ms-excel
PNGimage/png
JPEGimage/jpeg
TIFFimage/tiff

Request: multipart/form-data with a file field.

Response body:

{
"document_id": "string",
"filename": "string",
"chunks_created": 42,
"entities_extracted": 17,
"status": "indexed"
}