Hybrid retrieval — vectors + graph traversal

Blending semantic similarity search with structural graph traversal — using each for what it's actually good at.

0/4 done

Overview

Blending semantic similarity search with structural graph traversal — using each for what it's actually good at.

Why it matters

Vector search and graph traversal solve different problems, and hybrid retrieval uses each for its strength instead of forcing one to do the other's job:

  • Vector search finds needles: given a fuzzy natural-language query, it's excellent at locating the specific entities or facts that are semantically closest to what the user asked, even if they phrase it very differently from the source text.
  • Graph traversal pulls threads: once you know which entity node the query is 'about', traversal follows the typed edges outward — one hop, two hops, three hops — to assemble facts that are connected but never appear near each other in any single chunk of text.

A hybrid pipeline chains them: (1) embed the query and use vector search to land on the best entry-point node(s) in the graph — e.g. the query 'who did Acme's biggest acquisition compete with?' lands on the Acme node; (2) from there, traverse acquired -> competesWith edges to assemble the multi-hop answer that no single chunk contains. Vector search alone would return text about Acme but couldn't compose the two-hop relationship; graph traversal alone has no way to find the right starting node from a vague natural-language query in the first place. Neither half works without the other — that's the actual meaning of 'hybrid'.

How it actually works

Hybrid retrieval combines the two strengths: vectors find the right entry points; the graph assembles the relationships around them. Vector search lands you on the seed entities semantically closest to the query; a bounded graph traversal then pulls the connected facts that no single chunk contained.

WITH ['Atlas', 'Policy P-12'] AS seeds              // from vector search
MATCH (s:Entity) WHERE s.name IN seeds
MATCH path = (s)-[:MENTIONS|GOVERNED_BY|OWNED_BY*1..2]-(n)  // bounded expansion
RETURN s.name, collect(DISTINCT n.name)[0..10] AS context, count(path) AS evidence
ORDER BY evidence DESC;

The make-or-break parameter is hop depth. *1..2 is a contract: expand at most two hops. Leave it unbounded and traversal explodes — a popular node connects to thousands of others and your 'context' becomes the whole graph, drowning the relevant vector hits in noise. Each extra hop multiplies neighbours and the share that is irrelevant.

Then re-rank the blend. After you have vector hits and graph-expanded neighbours, score candidates on a mix of (text relevance, path support, recency) and keep the top few. Without re-ranking, graph noise can outvote the precise vector match. The whole point of 'hybrid' is that neither signal wins by default — you combine and re-score them.

Analogy

Hybrid retrieval is GPS plus a local guide. The GPS (vector search) drops you at the right neighbourhood; the local guide (graph traversal) walks you the last two blocks to the connected places that aren't on the map. Let the guide wander unbounded, though, and you'll tour the whole city instead of the two streets you needed.

Pitfalls & how to avoid them

  • Unbounded traversal. Symptom: huge noisy context, latency spikes. Fix: explicit hop cap (*1..2).
  • No re-ranking of the blend. Symptom: graph noise outvotes precise vector hits. Fix: score on relevance+path+recency.
  • Expanding from low-confidence seeds. Fix: filter seed entities by extraction confidence.
  • Ignoring hub nodes. Symptom: one celebrity node connects everything. Fix: cap degree or down-weight hubs.

Apply it to your system

Picture a real multi-hop question from your domain.

  • Which entities would vector search seed, and which relationships must the graph add?
  • What hop budget keeps the answer complete without flooding it with noise?
  • What re-ranking features would you combine to score the blended candidates?

Reading in progress · 0 of 4 activities done