Graph construction quality and canonicalization

Enforcing graph hygiene through entity resolution and alias deduping — because a fractured graph can't be traversed.

0/4 done

Overview

Enforcing graph hygiene through entity resolution and alias deduping — because a fractured graph can't be traversed.

Why it matters

The golden rule of GraphRAG is: garbage indexed, garbage retrieved — and graphs fail in a way chunk-based RAG doesn't, because a graph's value comes entirely from its connectivity, not just its content.

Canonicalization is the process of recognising that 'AI', 'Artificial Intelligence', and 'A.I.' are the same real-world entity and merging them into a single node. Skip this step and your extraction pipeline creates three separate nodes, each with only a fraction of the true edges — the graph fractures into isolated islands that traversal can't cross. A two-hop query that should find 'companies that invested in AI' now silently misses two-thirds of the relevant edges, because they were attached to the wrong alias node.

But there's an opposite, more dangerous failure: false merges. If entity resolution is too aggressive and collapses 'Java' the programming language and 'Java' the island into a single node, every edge from both real-world entities now lives on one node — a query about 'population of Java' can return facts about JVM garbage collection. Under-merging just loses recall (annoying); over-merging actively poisons the graph with wrong answers presented confidently (far worse, and much harder to detect after the fact, because nothing looks broken).

This is why production GraphRAG pipelines invest heavily in entity resolution that considers context (surrounding text, entity type, co-occurring relations), not just string similarity — and why false merges, not missed aliases, are treated as the higher-severity defect to catch in QA.

How it actually works

GraphRAG's golden rule: garbage indexed, garbage retrieved. Retrieval quality is capped by graph-build quality, and the highest-leverage build step is canonicalisation — making sure AI, Artificial Intelligence and A.I. resolve to one node, not three.

canonicalization:
  person_alias_merge_rate: 0.87        # good aliases merged
  org_alias_false_merge_rate: 0.04     # distinct orgs wrongly merged
gate:
  fail_if_precision_below: 0.88
  fail_if_false_merge_above: 0.06

False merges are the dangerous defect. A missed merge leaves a node slightly fragmented — annoying but recoverable. A false merge collapses two distinct identities (two different 'John Smith's, two different 'Apple's) into one node, and now every traversal produces confidently wrong multi-hop answers that are almost impossible to debug because the graph 'looks' clean. So watch false-merge rate even more closely than merge recall.

Validate domain/range. An edge Atlas-worksFor-P12 (a product 'working for' a policy) violates the schema's domain/range and should be dropped at build time, not discovered at answer time. Track invalid_domain_range_edges and dropped_edges as build metrics.

Make build quality a gate. Precision, false-merge rate and dropped-edge counts belong in the same CI gate as your retrieval metrics. A graph that silently degrades upstream will degrade every answer downstream.

Analogy

Graph construction is merging two companies' customer lists. Missing a duplicate is a minor annoyance; wrongly merging two different customers mails one person's invoices to another and corrupts every report built on the list. Guard hardest against the false merge.

Pitfalls & how to avoid them

  • Optimising merge recall over precision. Symptom: false merges → wrong paths. Fix: precision/false-merge first.
  • No domain/range validation. Symptom: nonsensical edges. Fix: drop schema-violating edges at build.
  • Build quality untracked. Fix: gate releases on extraction precision + false-merge rate.
  • Ignoring stale entities. Symptom: deleted things linger. Fix: reconcile on source updates.

Apply it to your system

Think about identity in your data.

  • Which entities in your domain share names but are genuinely different (people, orgs, products)?
  • What false-merge rate would you consider a release blocker?
  • How would you detect a canonicalisation regression after a resolver-model change?

Reading in progress · 0 of 4 activities done