Knowledge Graph Retrieval#
RAGFlow implements a dual-path retrieval architecture that keeps knowledge graph (KG) data and ordinary document chunks in the same backing store (Elasticsearch or Infinity), but routes them through entirely separate retrieval classes. The two paths are:
Dealer.retrieval()— standard hybrid BM25+KNN search for normal document chunksKGSearch.retrieval()— graph-aware retrieval that synthesizes entities, relations, and community reports into a single prepended result block
KGSearch extends Dealer , so it inherits the base vector-search machinery while adding graph-specific query logic.
Isolation via available_int=0#
All KG chunks—entities, relations, community reports, graph snapshots, and subgraphs—are written to the doc store with available_int=0 at index time. Dealer.retrieval() hardcodes "available_int": 1 in every search request , so KG chunks are invisible to normal document search without any runtime branching.
The flag is set by the two indexing helpers in rag/graphrag/utils.py:
graph_node_to_chunk()— sets"available_int": 0on entity chunks and also storesrank_flt(PageRank) andn_hop_with_weight(pre-computed 2-hop neighbor paths)graph_edge_to_chunk()— sets"available_int": 0on relation chunks
Graph snapshot and subgraph chunks written inside set_graph() also carry "available_int": 0.
Each KG chunk additionally carries a knowledge_graph_kwd field ("entity", "relation", "community_report", "graph", or "subgraph") that KGSearch uses as a targeted filter during retrieval.
KGSearch Retrieval Pipeline#
KGSearch.retrieval() is an async method that executes in five stages:
-
Query rewrite — Calls an LLM via
query_rewrite()to extract entity type keywords (ty_kwds) and entity names (ents) from the question. LLM responses are cached in Redis viaget_llm_cache/set_llm_cache. -
Parallel graph lookups — Three concurrent store searches (each filtered by
knowledge_graph_kwd):get_relevant_ents_by_keywords()— KNN on entity embeddings, filtered byknowledge_graph_kwd=entityget_relevant_ents_by_types()— ordered byrank_fltDESC, filtered by entity typeget_relevant_relations_by_txt()— KNN on relation embeddings, filtered byknowledge_graph_kwd=relation
-
N-hop expansion — Each entity chunk stores pre-computed 2-hop neighbor paths in
n_hop_with_weight. KGSearch reads this field to add multi-hop relation scores without additional store queries . -
Scoring — Entities are ranked by
sim * pagerank(P(E|Q) ≈ pagerank × similarity). Relations get boosted by n-hop path overlap and entity-type membership . -
Result assembly — Top entities and relations are serialized to CSV tables, then community reports are appended via
_community_retrieval_()(ordered byweight_fltDESC, filtered byknowledge_graph_kwd=community_report). The final chunk is returned withdocnm_kwd="Related content in Knowledge Graph"andsimilarity=1.0.
The use_kg Option and Call Site#
use_kg is a boolean flag on the retrieval API. When set, the retrieval handler in chunk_api.py:
- Resolves the tenant's default chat LLM
- Calls
settings.kg_retriever.retrieval(question, tenant_ids, kb_ids, embd_mdl, llm) - Inserts the returned KG chunk at index 0 of
ranks["chunks"]if itscontent_with_weightis non-empty
kg_retriever is a module-level KGSearch singleton initialized at startup in common/settings.py . It shares the same docStoreConn as the standard retriever but is a distinct object.
The KG injection happens after Dealer.retrieval(), child-chunk expansion, and optional ToC re-ranking, so the KG block is always the first result the LLM sees regardless of its vector score.
The same use_kg injection pattern appears in the Dify external knowledge integration handler at api/apps/restful_apis/dify_retrieval_api.py .
Key Source Files#
| File | Purpose |
|---|---|
rag/graphrag/search.py | KGSearch class — full KG retrieval pipeline |
rag/nlp/search.py | Dealer class — standard retrieval, available_int=1 filter |
rag/graphrag/utils.py | graph_node_to_chunk(), graph_edge_to_chunk(), set_graph() — where available_int=0 is set |
rag/graphrag/general/index.py | KG extraction orchestration; extraction classes (GeneralKGExt, LightKGExt, NerKGExt) |
api/apps/restful_apis/chunk_api.py | use_kg call site and result injection |
Status note: As of v0.27.0, the GraphRAG system is superseded by the Knowledge Compilation Engine (
rag/advanced_rag/knowlege_compile/). TheKGSearch/Dealerdual-path architecture remains active for datasets created before the migration. See PR #16515 for the new engine.