Most retrieval stacks start with a vector index, and for good reason: "find me things that look like this" is the single most common question an agent asks. But a meaningful slice of agent questions aren't about similarity at all. They're about connection — what depends on this, who touched it, how did we get from A to B. Cosine distance has no concept of an edge, so it cannot answer those. A relational store can, but you pay for it with a join per relationship type and a recursive CTE tuned per query.
This post is about that second class of question, and what changes when you model it as a graph.
Depth as a parameter
Suppose an agent has to answer "what depends on service X?" You don't know the depth in advance. It might be two hops today and five after the next deploy. In Cypher the depth is just part of the pattern:
MATCH path = (s:Service {name: $name})<-[:DEPENDS_ON*1..5]-(dependent)
RETURN DISTINCT dependent.name AS name, length(path) AS hops
ORDER BY hops
The same question in SQL means a recursive CTE, a termination condition you have to get right, and a rewrite every time someone adds a new kind of relationship. The graph version doesn't change shape when the schema grows — typed edges are the data model, so a new relationship type is data, not a migration.
Retrieval bounded by neighbourhood, not by corpus
The usual RAG failure mode is stuffing everything plausibly relevant into the prompt and hoping the model sorts it out. Graph retrieval inverts that: resolve the entities in the question, walk out a couple of hops, and send only that.
The difference is easy to underestimate. On a 3,700-entity knowledge base, dumping every node and edge rendered to 202,285 tokens per query; fetching the two-hop neighbourhood around the query entities rendered to 2,668. Same text, same tokenizer (GPT-4 cl100k_base). The gap widens with scale, and that's the actual point — baseline tokens grow with the corpus, while neighbourhood retrieval stays bounded by the neighbourhood.
The path is the explanation
The part I find most underrated: when you traverse for the answer, you get the justification in the same result set. A vector hit gives you a score and no account of itself. A graph query returns the route it took, and provenance can live on the edge as a property, so "why do you believe this?" is answerable without a separate audit table.
That matters a lot once an agent is allowed to act on what it retrieved.
Where this doesn't apply
It's not graph versus vectors. Similarity search is still the right tool for fuzzy recall over unstructured text, and most real systems end up using both: embeddings to find the entry points, traversal to assemble grounded context around them. If your data has no meaningful relationships, a graph buys you nothing but a new thing to operate.
Trying it without standing up a cluster
This is the part that used to stop me from prototyping graph ideas. CognoDB is a managed graph database that speaks Bolt 5.0–5.4 and Cypher, so the official Neo4j drivers connect unchanged — migration is a one-line URI change:
from neo4j import GraphDatabase
driver = GraphDatabase.driver(
"bolt+s://db-7f3a2c1e.databases.cognodb.cloud",
auth=("cognodb", DB_PASSWORD),
)
with driver.session() as session:
result = session.run(
"MATCH (p:Person)-[:FOLLOWS]->(f) "
"WHERE p.name = $name RETURN f.name AS name",
name="Ada",
)
for record in result:
print(record["name"])
There's a free tier with no card, plus a built-in MCP server if you want an agent querying the graph directly. Published benchmark numbers (0.27 ms two-hop p95, ~74K read queries/s, ~80 bytes per edge on disk) come with full methodology on the site rather than as round marketing figures — worth reading the footnotes before you trust any vendor's graph benchmark, including ours.
If you're new to this, the concepts explainers on graphs, Cypher and GraphRAG are short and run on the free tier.
Over to you
What are you using for agent memory right now — vectors, a relational store, something hand-rolled? And if you've tried traversal-based retrieval, did the token savings hold up in production or did prompt-stuffing creep back in? I'd genuinely like to hear where this breaks.
We'll be posting more under #cognodb: Cypher patterns, GraphRAG walkthroughs, and honest benchmark write-ups. Questions welcome in the comments.
Top comments (0)