Technical Field Guide

Context Graph

A decision-aware knowledge-graph system built on LightRAG. It extends triples (h, r, t) into contextual quadruples (h, r, t, rc) — attaching a full decision record to every edge — and adds CGR3 multi-hop reasoning, runtime decision capture, precedent search, a business rules engine, a typed ontology, web ingestion, a REST API, and an MCP server.

(h, r, t, rc) quadruples 11-field RelationContext CGR3 reasoning rules & ontology web ingester MCP + REST multi-tenant workspaces

01 Executive summary

What Context Graph is, and the one idea everything else hangs on.

Standard RAG retrieves text chunks; standard knowledge graphs store (subject, predicate, object) triples. Neither records why a relationship exists. Context Graph (CG) attaches a RelationContext (rc) to every edge — who approved it, why, via which channel, under which policy, for how long, with what evidence and confidence. The graph becomes a system of decision, not just a system of record, and you can query the lineage, not only the fact.

4th
element on every edge — the decision record
11
RelationContext fields
6
query modes + CGR3 multi-hop
REST+MCP
API surfaces, workspace-isolated
◆ The one idea
A triple says Sarah Chen — APPROVES → MegaCorp. A quadruple adds rc: "20% discount, in-person, valid through 2024-12-31, under DiscountPolicy_Standard, confidence 0.97." Now "who approved >15% discounts in Q3 and are they still valid?" is a query, not a research project.

02 Components at a glance

Nine moving parts, nine jobs.

ComponentJobWhere
ContextGraphOrchestrator — subclass of LightRAG; insert, query, emit, find precedents, CGR3.lightrag/context_graph.py
RelationContextThe 11-field decision record carried by each edge.lightrag/context_graph_types.py
CGR3Retrieve → Rank → Reason iterative multi-hop query loop.context_graph.py · operate.py
Decision captureRuntime emit_decision_trace + semantic precedent search.context_graph.py
Business Rules EnginePre-emit governance gate — DSL + semantic sim(), PASS/FLAG/REJECT, NL author. Guide →context_graph/rules/
OntologyPer-workspace typed schema; coercing extraction validation; NL author. Guide →context_graph/ontology/
Web ingesterPolite crawler + pluggable site connectors; pulls any site in with URL provenance. Guide →context_graph/webingest/
Action layerExecutable operations bound to object types; invoke → rules gate → audit edge. Guide →context_graph/actions/
LightRAG coreChunking, extraction, embeddings, storage, query modes (inherited).lightrag/lightrag.py · operate.py · kg/
◆ Feature field guides
Four subsystems have their own illustrated walkthroughs, in this same set: Web Ingester · Ontology · Business Rules Engine · Action Layer. The narrative intro is The Fourth Element.

03 End-to-end architecture

From document (or live decision) to a grounded, decision-aware answer.

Documentstranscripts · notes App / agentemit_decision_trace Chunk + Extractentities · relations · rc (LLM)1200-tok chunks RelationContextwritten directly Storage (4 layers) GRAPH — Neo4j (h,r,t,rc) VECTOR — entity/rel/chunk   + decision-trace index KV — docs · chunks · cache DOC_STATUS Query local·global·hybrid·mix·… + CGR3 (Retrieve→Rank→Reason) annotated context (rc inline) API REST + MCP workspace-isolated X-API-Key auth :9621 Grounded answer + decision lineage
Figure 1 — Two ingestion paths feed one graph + vector store; queries (modes or CGR3) read edges with their RelationContext; everything is exposed over REST and MCP, isolated per workspace.
Default LLM
OpenAI gpt-5-mini · embeddings text-embedding-3-large (dim 3072)
Default graph
Neo4j (label-per-workspace isolation)
Server
lightrag-server on port 9621
CG switch
USE_CONTEXT_GRAPH=true swaps LightRAGContextGraph

04 The quadruple & RelationContext

The data model that makes everything else possible.

Evidence supporting_sentences[]provenanceconfidence_score Authority approved_byapproved_viapolicy_ref Time valid_fromvalid_untiltemporal_info Rationale decision_tracequantitative_data
Figure 2 — The 11 RelationContext fields grouped by what they answer. Each is independently filterable in queries and decision search.
FieldTypeMeaning
supporting_sentencesList[str]Verbatim quotes from source documents
temporal_infostr?Free-form validity ("Q4 2026", "since 2020")
quantitative_datastr?Numbers — discount %, budget, counts
decision_tracestr?The why — rationale / exception / override / approval
approved_bystr?Approver entity name
approved_viastr?Channel: slack · zoom · email · in_person · jira · system
valid_from / valid_untilstr?ISO-8601 effective / expiry dates
policy_refstr?Policy name/ID followed or overridden
provenancestr?Source reference — thread ID, doc section, timestamp
confidence_scorefloatExtraction reliability 0.0–1.0 (default 1.0)

A 5-field relation (no rc) gets relation_context = null — full backward compatibility with standard LightRAG extraction.

05 Ingestion: extract & emit

Two paths in; one graph.

Documents → ainsert()LLM extracts entities + rc App → emit_decision_trace()rc written atomically 6-field extraction…|description|{rc json} Graph + vectorsedge.relation_context
Figure 3 — Extraction mines rc from prose (6-field relation format); emission writes rc directly from application code. Both land on the same edges and vector indexes.

Extraction format (6-field relation)

# standard LightRAG (5 fields)
relation<|#|>source<|#|>target<|#|>keywords<|#|>description
# Context Graph adds a 6th — a compact RelationContext JSON
relation<|#|>source<|#|>target<|#|>keywords<|#|>description<|#|>{"decision_trace":"…","approved_by":"…","confidence_score":0.95}

Emission (runtime, no document)

from lightrag.context_graph_types import RelationContext
rc = RelationContext(
    decision_trace="VP approved 20% discount; 5-yr relationship + competitive pressure",
    approved_by="Sarah Chen", approved_via="in_person",
    valid_until="2024-12-31", policy_ref="DiscountPolicy_Standard",
    quantitative_data="20% discount", confidence_score=0.97)
await cg.emit_decision_trace("Sarah Chen", "MegaCorp", "discount_approval", rc)

06 Querying & CGR3

Six retrieval modes for single-shot, CGR3 for multi-hop.

ModeStrategy
localLow-level keywords → entities → connected relations → chunks
globalHigh-level keywords → relations → connected entities → chunks
hybridlocal + global combined
naivePure vector similarity over chunks (no graph)
mixKG retrieval + vector chunks + reranking (recommended)
bypassSkip retrieval; query straight to the LLM
1 · Retrieveentities + edges + rc 2 · RankLLM orders by relevance 3 · Reasonsufficient to answer? if not: seed follow_up_entities, repeat (≤ 3 iterations, context deduped)
Figure 4 — CGR3 loops up to 3 times; each pass can surface new entities that seed the next retrieval. Edges return with rc, so answers cite the decision lineage.
from lightrag import QueryParam
# standard query — rc enriches retrieved edges; annotated context by default
res    = await cg.aquery("Who approved discounts above 15% in Q3?", param=QueryParam(mode="hybrid"))
# CGR3 multi-hop
answer = await cg.cgr3_query("Are there precedents for waiving payment terms for a renewal?")
◆ Annotated context
CG renders RelationContext inline in the prompt (the annotated context format, the default for CGR3) rather than hiding it — a comparative benchmark found annotated answers stronger on completeness, usefulness, and grounding than the legacy format.

07 Decisions & precedents

The capabilities a flat graph can't offer.

Emit

emit_decision_trace(h, t, relation, rc) records a decision the instant it's made — webhooks, approval bots, workflows. No ingestion.

Find precedents

find_precedents(...) — semantic search over decision traces: "have we done something like this, and how did it go?"

Validity & authority

valid_from/until answer "still in force?"; approved_by + policy_ref reconstruct the approval chain.

These map to dedicated REST endpoints (§8): /graph/decision/emit, /graph/decisions/search, and /graph/decisions (filter by approver, channel, policy, confidence, date).

08 REST API reference

All endpoints are workspace-aware. CG-specific endpoints return 503 when USE_CONTEXT_GRAPH=false.

Standard (inherited from LightRAG)

MethodPathPurpose
POST/documents/uploadUpload & ingest a document
POST/queryQuery with mode selection
POST/query/streamStreaming query
POST/query/dataRaw retrieved data (no synthesis)
POST/graph/entity/create · /graph/relation/createGraph CRUD (and update/delete variants)
GET/healthHealth check

Context Graph-specific CG

MethodPathPurpose
POST/cgr3/queryIterative multi-hop reasoning (Retrieve→Rank→Reason)
GET/graph/edge/contextRelationContext for a specific edge
GET/graph/entity/edges-with-contextAll context-enriched edges for an entity
POST/graph/decision/emitRecord a decision trace at runtime
GET/graph/decisions/searchSemantic precedent search over decision traces
GET/graph/decisionsFilter decisions by approver · channel · policy · confidence · date

Governance & ingestion CG

MethodPathPurpose
POST/scrapeCrawl a website into the graph (async job) · GET /scrape/{id} to poll. Guide →
GET · POST · DELETE/rulesGet, save, or delete the workspace rules policy
POST/rules/evaluate · /rules/toggle · /rules/generateDry-run · enable/disable · author from plain English. Guide →
GET · POST · DELETE/ontologyGet, save, or delete the workspace ontology
POST/ontology/generate · /ontology/validateAuthor a schema from a description · validate extractions. Guide →
GET · POST · DELETE/actionsGet, save, or delete the workspace action catalog
POST/actions/invokeInvoke an action: validate → rules gate → side effect → audit. Guide →

Auth & workspace

Authenticate with X-API-Key; select the tenant with the LIGHTRAG-WORKSPACE header.

# query a specific workspace
curl -X POST http://localhost:9621/query \
  -H "X-API-Key: $LIGHTRAG_API_KEY" \
  -H "LIGHTRAG-WORKSPACE: company_acme" \
  -H "Content-Type: application/json" \
  -d '{"query": "Who approved the MegaCorp discount?", "mode": "hybrid"}'

# CGR3 multi-hop reasoning
curl -X POST http://localhost:9621/cgr3/query \
  -H "X-API-Key: $LIGHTRAG_API_KEY" -H "LIGHTRAG-WORKSPACE: company_acme" \
  -d '{"query": "Precedents for waiving payment terms on a renewal?"}'

# filter decisions (illustrative params)
curl "http://localhost:9621/graph/decisions?approved_via=slack&min_confidence=0.8" \
  -H "X-API-Key: $LIGHTRAG_API_KEY" -H "LIGHTRAG-WORKSPACE: company_acme"

Exact request/response schemas live in lightrag/api/routers/context_graph_routes.py; payloads above are illustrative.

09 MCP server

The same capabilities as tools for MCP-speaking agents.

When enabled (ENABLE_MCP=true, default), the server mounts a Model Context Protocol sub-app exposing 8 tools, each wrapping one rag method. It uses FastMCP(stateless_http=True), validates the X-API-Key header on the MCP sub-app, and tools that require CG mode raise an MCP error (not HTTP 503) when USE_CONTEXT_GRAPH=false. Workspace isolation is automatic via the parent app's middleware.

▲ Mount order
The MCP app is mounted last (after /webui and /static) so it doesn't shadow named mounts.

10 Storage & LLM providers

Four pluggable storage layers; multiple LLM/embedding backends.

Storage layers

KVdocs, chunks, entities, relations, LLM cache
VECTORentity / relation / chunk / decision embeddings
GRAPHentity-relation graph (Neo4j in default config)
DOC_STATUSdocument processing status

Backends: JSON, NetworkX, Neo4j, PostgreSQL, MongoDB, Redis, Milvus, Qdrant, Faiss.

LLM & embeddings

Bindings for OpenAI, Ollama, Azure, Gemini, Bedrock. Default: gpt-5-mini + text-embedding-3-large (3072-dim). Optional reranker via Cohere binding.

▲ Embedding consistency
The embedding model must stay fixed after ingestion — changing it invalidates the vector indexes.

11 Multi-tenancy (workspaces)

Per-request isolation — one deployment, many tenants.

Each company gets an isolated workspace selected by the LIGHTRAG-WORKSPACE request header. Isolation spans Neo4j nodes/edges (label-based), per-workspace indexes, vector collections, KV stores, doc status, LLM cache, and the decision-trace index.

# Neo4j: nodes carry a workspace label; queries + drops are workspace-scoped
MERGE (n:`company_acme` {entity_id: $id})
MATCH (n) WHERE n:`company_acme` …
MATCH (n:`company_acme`) DETACH DELETE n

Workspace names allow a-z A-Z 0-9 _ only.

12 Configuration

Key environment variables (full list in env.example / config.ini.example).

VariableDefaultPurpose
USE_CONTEXT_GRAPHtrueUse ContextGraph instead of base LightRAG
ENABLE_MCPtrueMount the MCP server
LIGHTRAG_GRAPH_STORAGENeo4JStorageGraph backend
LLM_BINDING / LLM_MODELopenai / gpt-5-miniLLM provider + model
EMBEDDING_MODELtext-embedding-3-largeEmbedding model (dim 3072)
NEO4J_URI / _USERNAME / _PASSWORDNeo4j credentials

Run it

# server (port 9621)
lightrag-server
# dev with auto-reload
uvicorn lightrag.api.lightrag_server:app --reload
# tests
python -m pytest tests

13 Repository map

The Context-Graph surface on top of the LightRAG tree.

lightrag/
 ├─ context_graph.py # ContextGraph: insert/query, emit_decision_trace, find_precedents, CGR3
 ├─ context_graph_types.py # RelationContext, ContextNode, ContextEdge
 ├─ operate.py # extraction, merge, annotated-context assembly
 ├─ prompt.py # CG extraction + annotated-response prompts
 ├─ lightrag.py · base.py # base orchestrator + storage interfaces
 ├─ kg/ # storage backends (Neo4j, PG, Milvus, Qdrant, Faiss, …)
 ├─ llm/ # OpenAI · Ollama · Azure · Gemini · Bedrock
 └─ api/
   ├─ lightrag_server.py # FastAPI app, routes, workspace middleware
   ├─ mcp_server.py # MCP server (8 tools, X-API-Key)
   └─ routers/ # context_graph · rules · ontology · webingest · actions routes
context_graph/ # governance & ingestion packages
 ├─ rules/ # Business Rules Engine — DSL, gate, sim(), NL author
 ├─ ontology/ # typed schema, coercing validation, NL author
 ├─ webingest/ # polite crawler + pluggable site connectors
 └─ actions/ # executable operations bound to object types, governed by the gate
docs/ # this guide, the blog, per-feature guides, the paper, deployment
tests/ # test_context_graph · test_context_graph_api · test_mcp_server

14 Glossary

TermMeaning
Quadruple (h,r,t,rc)A graph edge plus its RelationContext
RelationContext (rc)The 11-field decision record on an edge
CGR3Retrieve → Rank → Reason iterative multi-hop reasoning
Decision traceThe rationale/approval recorded for a relationship
PrecedentA prior decision retrieved by semantic similarity
Annotated contextPrompt format that renders rc inline for the LLM
WorkspaceAn isolated per-tenant namespace selected by header
↑ Top