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
sqlite-vec + FalkorDB
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.
| Dimension | Vector search only | GraphRAG |
|---|---|---|
| Matching basis | Semantic similarity | Semantic + relational |
| Misses | Entities connected to matching text | Nothing additionally missed |
| Result quality | Good for self-contained docs | Better for interconnected knowledge |
| Latency overhead | Baseline | +graph traversal (~10–30 ms) |
Supported Document Formats
Ingestion — Supported Formats
pdfplumber
pymupdf
.xlsx · .xls
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
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"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Natural language query text |
top_k | integer | No (default: 10) | Maximum number of chunks to return |
filters.source | string | No | Filter by source document filename or ID |
filters.entity_type | string | No | Restrict graph traversal to a specific entity type (e.g. "person", "repo") |
filters.date_from | string | No | ISO-8601 date — only return chunks ingested after this date |
filters.date_to | string | No | ISO-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
}
| Field | Type | Description |
|---|---|---|
chunks[].chunk_id | string | Unique identifier for this text chunk |
chunks[].score | float | Final RRF score (higher is more relevant) |
chunks[].text | string | Raw chunk text |
chunks[].source | string | Original document filename or URI |
chunks[].page | integer | Page number within the source document (1-indexed) |
chunks[].entities | array | Sagittarius graph nodes extracted from this chunk |
*_ms | integer | Per-stage latency breakdown in milliseconds |
Upload endpoint
POST /v1/documents/upload
Accepted MIME types:
| Format | MIME type |
|---|---|
application/pdf | |
| Word | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
| PowerPoint | application/vnd.openxmlformats-officedocument.presentationml.presentation |
| Excel (xlsx) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| Excel (xls) | application/vnd.ms-excel |
| PNG | image/png |
| JPEG | image/jpeg |
| TIFF | image/tiff |
Request: multipart/form-data with a file field.
Response body:
{
"document_id": "string",
"filename": "string",
"chunks_created": 42,
"entities_extracted": 17,
"status": "indexed"
}