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.
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.
| Component | Job | Where |
|---|---|---|
| ContextGraph | Orchestrator — subclass of LightRAG; insert, query, emit, find precedents, CGR3. | lightrag/context_graph.py |
| RelationContext | The 11-field decision record carried by each edge. | lightrag/context_graph_types.py |
| CGR3 | Retrieve → Rank → Reason iterative multi-hop query loop. | context_graph.py · operate.py |
| Decision capture | Runtime emit_decision_trace + semantic precedent search. | context_graph.py |
| Business Rules Engine | Pre-emit governance gate — DSL + semantic sim(), PASS/FLAG/REJECT, NL author. Guide → | context_graph/rules/ |
| Ontology | Per-workspace typed schema; coercing extraction validation; NL author. Guide → | context_graph/ontology/ |
| Web ingester | Polite crawler + pluggable site connectors; pulls any site in with URL provenance. Guide → | context_graph/webingest/ |
| Action layer | Executable operations bound to object types; invoke → rules gate → audit edge. Guide → | context_graph/actions/ |
| LightRAG core | Chunking, extraction, embeddings, storage, query modes (inherited). | lightrag/lightrag.py · operate.py · kg/ |
03 End-to-end architecture
From document (or live decision) to a grounded, decision-aware answer.
- Default LLM
- OpenAI
gpt-5-mini· embeddingstext-embedding-3-large(dim 3072) - Default graph
- Neo4j (label-per-workspace isolation)
- Server
lightrag-serveron port9621- CG switch
USE_CONTEXT_GRAPH=trueswapsLightRAG→ContextGraph
04 The quadruple & RelationContext
The data model that makes everything else possible.
| Field | Type | Meaning |
|---|---|---|
| supporting_sentences | List[str] | Verbatim quotes from source documents |
| temporal_info | str? | Free-form validity ("Q4 2026", "since 2020") |
| quantitative_data | str? | Numbers — discount %, budget, counts |
| decision_trace | str? | The why — rationale / exception / override / approval |
| approved_by | str? | Approver entity name |
| approved_via | str? | Channel: slack · zoom · email · in_person · jira · system |
| valid_from / valid_until | str? | ISO-8601 effective / expiry dates |
| policy_ref | str? | Policy name/ID followed or overridden |
| provenance | str? | Source reference — thread ID, doc section, timestamp |
| confidence_score | float | Extraction 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.
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.
| Mode | Strategy |
|---|---|
| local | Low-level keywords → entities → connected relations → chunks |
| global | High-level keywords → relations → connected entities → chunks |
| hybrid | local + global combined |
| naive | Pure vector similarity over chunks (no graph) |
| mix | KG retrieval + vector chunks + reranking (recommended) |
| bypass | Skip retrieval; query straight to the LLM |
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 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)
| Method | Path | Purpose |
|---|---|---|
| POST | /documents/upload | Upload & ingest a document |
| POST | /query | Query with mode selection |
| POST | /query/stream | Streaming query |
| POST | /query/data | Raw retrieved data (no synthesis) |
| POST | /graph/entity/create · /graph/relation/create | Graph CRUD (and update/delete variants) |
| GET | /health | Health check |
Context Graph-specific CG
| Method | Path | Purpose |
|---|---|---|
| POST | /cgr3/query | Iterative multi-hop reasoning (Retrieve→Rank→Reason) |
| GET | /graph/edge/context | RelationContext for a specific edge |
| GET | /graph/entity/edges-with-context | All context-enriched edges for an entity |
| POST | /graph/decision/emit | Record a decision trace at runtime |
| GET | /graph/decisions/search | Semantic precedent search over decision traces |
| GET | /graph/decisions | Filter decisions by approver · channel · policy · confidence · date |
Governance & ingestion CG
| Method | Path | Purpose |
|---|---|---|
| POST | /scrape | Crawl a website into the graph (async job) · GET /scrape/{id} to poll. Guide → |
| GET · POST · DELETE | /rules | Get, save, or delete the workspace rules policy |
| POST | /rules/evaluate · /rules/toggle · /rules/generate | Dry-run · enable/disable · author from plain English. Guide → |
| GET · POST · DELETE | /ontology | Get, save, or delete the workspace ontology |
| POST | /ontology/generate · /ontology/validate | Author a schema from a description · validate extractions. Guide → |
| GET · POST · DELETE | /actions | Get, save, or delete the workspace action catalog |
| POST | /actions/invoke | Invoke 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.
/webui and /static) so it doesn't shadow named mounts.10 Storage & LLM providers
Four pluggable storage layers; multiple LLM/embedding backends.
Storage layers
| KV | docs, chunks, entities, relations, LLM cache |
| VECTOR | entity / relation / chunk / decision embeddings |
| GRAPH | entity-relation graph (Neo4j in default config) |
| DOC_STATUS | document 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.
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).
| Variable | Default | Purpose |
|---|---|---|
| USE_CONTEXT_GRAPH | true | Use ContextGraph instead of base LightRAG |
| ENABLE_MCP | true | Mount the MCP server |
| LIGHTRAG_GRAPH_STORAGE | Neo4JStorage | Graph backend |
| LLM_BINDING / LLM_MODEL | openai / gpt-5-mini | LLM provider + model |
| EMBEDDING_MODEL | text-embedding-3-large | Embedding model (dim 3072) |
| NEO4J_URI / _USERNAME / _PASSWORD | — | Neo4j 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.
├─ 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
| Term | Meaning |
|---|---|
Quadruple (h,r,t,rc) | A graph edge plus its RelationContext |
RelationContext (rc) | The 11-field decision record on an edge |
| CGR3 | Retrieve → Rank → Reason iterative multi-hop reasoning |
| Decision trace | The rationale/approval recorded for a relationship |
| Precedent | A prior decision retrieved by semantic similarity |
| Annotated context | Prompt format that renders rc inline for the LLM |
| Workspace | An isolated per-tenant namespace selected by header |