Query-first GraphRAG how it works
Back to the demo

Cut the graph first, then summarise it

GraphRAG answers questions by reading summaries of a knowledge graph. We make it read only the part of the graph that the question is about.

The idea

Microsoft's GraphRAG splits a whole graph into communities and has a language model write a report about each one. Questions are answered by reading those reports. It works well for broad questions, but on a biomedical graph with more than a hundred thousand genes, diseases and drugs, the reports have to be written for everything, once, before anyone asks anything.

We turn the order around. The question comes first. We find the entities it names, grow a small subgraph around them with tools from network medicine, and only then run GraphRAG on that subgraph. Every question gets its own small set of reports.

What happens when you ask

  1. Read the question. Qwen 2.5 7B lists the genes, diseases and drugs the question names, with their type and standard English name. That is all the model decides.
  2. Find them in the graph. Each mention is looked up in a dictionary of node names and synonyms from UMLS, DisGeNET, HGNC and MeSH. Matches are exact after normalising case, punctuation and word order, so every link can be traced back to the name that produced it.
  3. Grow a subgraph. From each entity we take its direct neighbours, then let DIAMOnD and C3 add the nodes that are significantly connected to them: the disease module. A random walk from the whole selection adds a last handful of close nodes.
  4. Communities and reports. GraphRAG splits the subgraph into communities with Leiden, and Qwen3 30B writes a short report for each one, from the nodes, their edges and the definitions PrimeKG gives for them. This index is built on demand, for this question only.
  5. Answer. The question is put to every report, the useful points are scored, and the best ones are merged into a single paragraph that cites the reports it relies on. Searching these few reports takes fewer tokens than searching an index of the whole graph.

Because each node remembers why it entered the subgraph, one selection gives four nested subgraphs: neighbours only, plus DIAMOnD, plus C3, and the full one with the random walk. The recorded runs in the demo keep all four, so you can compare them.

Under the hood

Entity linker: an LLM finds the mentions, then a dictionary links them to nodes.
Subgraph selection: DIAMOnD and C3 run inside each homogeneous layer of the graph, the genes, the diseases and the drugs, followed by a heterogeneous random walk with restart. Selection uses no model and runs with a fixed seed, so the same question gives the same subgraph.
Bring Your Own Graph converter: turns any subgraph into the tables GraphRAG expects, so a curated graph can be indexed without extracting it from text.
Search with its context: every answer is stored together with the reports it read and the scored points of the map step. That record is what the demo shows.

The graph

PrimeKG, integrated in an earlier thesis of the lab with gene and disease associations from DisGeNET, plus a drug layer of bioactivity and chemical similarity built in the lab. It is served from Neo4j.

Code

Work in progress :) This is not the final version of the demo. The thesis will be published soon, together with its code. The demo is built from the pipeline's own outputs: a local version answers new questions, and the recorded runs are real runs from the BioASQ evaluation, packed so they can be replayed in any browser, without a GPU. The online version only has some examples.

Ezequiel González Grenat, Bioinformatics Lab, Leloir Institute. Thesis work on query-first subgraph selection for biomedical GraphRAG.

Leloir Institute