Ask a retrieval system who signed off on the vendor contract that governs the integration your incident just took down, and it will hand you five plausible documents. Ask it whether any of them contradict each other, and it has no opinion. Vector search retrieves things that sound like your question. A knowledge graph knows what things are, how they connect, and which connections are load-bearing. As agents move from answering questions to taking actions, that difference stops being academic.
The question retrieval cannot answer
Here is a request that sounds trivial and is not: list every customer in the enterprise tier whose account is owned by someone who left the company in the last quarter, and tell me which of them have an open escalation. A capable model with a good retrieval layer will produce something confident and wrong. It will find documents about enterprise customers, documents about departures, documents about escalations, and it will attempt to weave them into an answer. The weave is the problem. The information required to answer correctly is not contained in any single passage. It lives in the joins between records, and joins are exactly what similarity search does not do.
This is not a flaw in embeddings. It is a category error about what embeddings are for. Vector retrieval is a superb tool for the question what does the corpus say about X. It is structurally incapable of answering the question what is connected to what, because it never represented the connections in the first place. It represented meaning as proximity in a continuous space, which is a lossy and deliberately fuzzy encoding. Fuzziness is a feature when you are matching a badly-worded question to a well-worded paragraph. It is a defect when you are trying to establish that this specific person owns that specific account.
Agents make this defect expensive. A chatbot that gives a fuzzy answer to a relational question produces a mildly unsatisfying conversation. An agent that acts on a fuzzy answer to a relational question sends the escalation to the wrong owner, applies the discount to the wrong contract, or revokes access for the wrong employee. The cost of ambiguity scales with the authority you grant the system, and we have spent two years steadily granting more.
What a knowledge graph actually is
Strip away the vendor language and a knowledge graph is a very old idea wearing new clothes. You have entities, which are the things that exist in your domain: people, accounts, contracts, incidents, products, servers, policies. You have relations, which are the named, directed connections between them: owns, reports to, supersedes, depends on, was caused by. And you have attributes hanging off both. That is it. A graph is a set of assertions of the form subject, predicate, object, accumulated until the shape of a domain emerges from them.
The elegance is that this representation is closed under composition. If you know that Priya manages Daniel and Daniel owns the Acme account, you can derive that Priya is in the ownership chain for Acme without anyone ever having written that sentence down. Relational databases can do this too, of course, through joins, but they do it under a schema fixed in advance and with a rigidity that makes adding a new kind of relationship a migration. Graphs treat relationships as data rather than as structure, which means the shape can grow sideways as your understanding of the domain grows.
What makes this newly interesting is not the data model, which has existed in one form or another since the semantic web era and arguably since Aristotle. It is that language models finally made graph construction tractable. The historical blocker on knowledge graphs was never querying them. It was populating them. Turning ten thousand contracts into a set of clean entity-relation triples used to require either a small army of analysts or a brittle pipeline of regular expressions and hand-tuned parsers that broke every time a document template changed. Models can now read a contract and emit structured assertions about it with accuracy that is imperfect but genuinely useful. The bottleneck moved, and a technique that was always theoretically appealing became practically available.
Why embeddings blur exactly what agents need sharp
Picture an embedding space as a night sky. Every chunk of text is a star, and semantically similar chunks sit near each other. It is a beautiful representation, and looking up at it you can immediately see clusters, regions, and neighbourhoods of meaning. What you cannot see are lines. Nothing in that sky tells you that this star and that one are the same object seen from different angles, or that this one orbits that one. Proximity encodes resemblance, and resemblance is not a relationship.
This produces a specific and recurring failure. Two documents that describe the same entity in different vocabularies land far apart, so retrieval finds one and misses the other. Two documents that describe different entities in similar vocabularies land close together, so retrieval finds both and the model conflates them. The invoice from Northwind Traders and the invoice from Northwind Trading Company are, in embedding space, nearly the same point, and a model reading both will happily produce a total that belongs to neither company. There is no amount of reranking that fixes this, because the ambiguity is not in the ranking. It is in the representation.
Graphs make the sharp things sharp. An entity has an identity, and that identity is a decision the system made explicitly rather than an accident of cosine distance. When two records refer to the same real-world thing, they resolve to the same node, and everything known about that thing accumulates in one place. When they refer to different things, they stay separate no matter how similar their names look. The correctness of that decision becomes an auditable, testable property of your pipeline instead of an emergent behaviour of a similarity threshold.
Entities, not documents
The most important shift in perspective is deciding that the unit of knowledge is the entity rather than the document. In a retrieval system, the world is made of passages, and an entity is whatever the passages happen to mention. In a graph, the world is made of entities, and documents are demoted to evidence: sources that support assertions about entities.
This inversion has consequences that reach further than they first appear. Under a document-centric model, everything you know about a customer is scattered across the contract, the support tickets, the CRM export, and the meeting notes, and assembling a complete picture requires retrieving all of them and hoping the model integrates them faithfully. Under an entity-centric model, the integration happened at write time. There is one node for that customer, and it carries the contract terms, the ticket history, the renewal date, and the account owner, each with a pointer back to where it came from.
Write-time integration is more expensive than read-time integration, and that is the trade you are making. You pay once, carefully, in a pipeline you can test, rather than every time, hopefully, in a context window you cannot inspect. For a corpus that is queried more often than it changes, which describes most enterprise knowledge, this is straightforwardly the better bargain. For a corpus that changes constantly and is queried rarely, it is the worse one. Knowing which situation you are in is most of the architectural decision.
The ontology problem: deciding what exists
Before you can populate a graph you have to decide what kinds of things it contains, and this is where most projects go quietly wrong. The failure is not usually building a bad ontology. It is building an ambitious one. Some team sits in a room for six weeks producing a taxonomy of two hundred entity types with careful inheritance hierarchies, and by the time it is finished nobody remembers what question it was supposed to answer.
An ontology is not a description of reality. It is a description of the distinctions your system needs to make in order to do its job. If nothing downstream ever treats a Contractor differently from an Employee, you do not need both types. If your agent needs to know whether an approval came from someone with budget authority, then budget authority needs to be representable, and no amount of elegance elsewhere compensates for its absence. The right way to derive an ontology is backward, from the queries you intend to serve, and the right size is the smallest one that serves them.
The second discipline is naming. Relations in particular attract vagueness. A relation called related to carries no information and cannot be reasoned over. A relation called reports to has a direction, a cardinality, and an implication. When you find yourself reaching for a generic predicate, it usually means you have not yet decided what you actually believe about the connection, and writing it down vaguely is a way of deferring the decision into a place where it will be much more expensive to fix.
Schema first, or schema last
There are two honest philosophies here and both work. Schema-first means you fix the entity and relation types up front, and extraction is constrained to produce only those. You get consistency, easy validation, and queries that never encounter surprises. You also get brittleness: anything the world contains that your schema did not anticipate is silently discarded, and you will not find out for months.
Schema-last, sometimes called open extraction, lets the model emit whatever entities and predicates it finds, and you impose structure afterward by clustering and canonicalizing the results. You capture more of the domain and discover distinctions you would not have thought to specify. You also get a graph in which the same relationship appears as employed by, works at, works for, and is staff of, which is not one graph but four graphs interleaved, and queries against it return a quarter of the truth.
The pragmatic answer is a hybrid that most mature systems converge on independently. Define a core schema covering the entities and relations your product genuinely depends on, and enforce it strictly. Allow open extraction into a staging area for everything else. Periodically review what accumulated there, and promote the patterns that recur into the core schema. The graph grows in a controlled way, and the open channel functions as a research instrument telling you what your ontology is missing.
Building the graph from unstructured text
Extraction is where the model earns its place. You feed it a document and a schema, and you ask for assertions. The naive version of this works surprisingly well in a demo and disappoints reliably in production, for reasons worth enumerating.
The first is context starvation. A model shown a single paragraph in isolation will extract assertions that are locally true and globally misleading. A clause reading the Provider shall indemnify the Client is meaningless unless you know who the Provider is, and that definition appeared on page one, forty pages earlier. Extraction needs the document-level context that establishes referents, which in practice means either a preliminary pass that builds a glossary of defined terms and carries it into every chunk, or a long-context pass over the whole document accepting the cost.
The second is the pull toward paraphrase. Models are trained to be helpful, and helpfulness in this setting manifests as smoothing. Asked to extract the relationship between two parties, a model will happily produce a reasonable-sounding relation that the text does not actually assert. The countermeasure is to require every assertion to carry the exact span of source text that supports it, verified programmatically to appear verbatim in the document. Assertions that fail that check are discarded. This single constraint eliminates a large fraction of extraction hallucination, because it converts a generative task into something closer to a selection task.
The third is inconsistency across runs. Two chunks describing the same fact will produce two slightly different triples, and both will land in the graph. This is not a bug you fix at extraction time. It is the reason the next stage exists.
Entity resolution, the hardest easy problem
Every knowledge graph project eventually discovers that its real difficulty is deciding when two names refer to the same thing. It sounds like a preprocessing detail. It is the load-bearing wall.
The problem has a deceptive surface. Yes, Bob Smith and Robert Smith are probably the same person, and yes, string similarity gets you some distance. But the interesting cases are not typos. They are two genuinely different people named Robert Smith in the same organization. They are a company that was acquired and now appears under both its old and new name, where the correct answer is that these are the same commercial relationship but different legal entities, and which one you mean depends on whether the question is about revenue or about liability. They are a server that was decommissioned and had its hostname reassigned, so that identical identifiers in two log files refer to different machines separated by eighteen months.
Good resolution uses evidence beyond the name. Two mentions of Robert Smith that both connect to the same department and the same manager are likely one person. Two that connect to different offices in different countries are likely not. This is where the graph helps resolve itself: structure is evidence, and the more edges you have, the better your resolution decisions become, which produces more reliable edges. Handled well this is a virtuous cycle. Handled badly it is contamination that compounds, because a single incorrect merge fuses two entities permanently and every subsequent assertion about either lands on the same corrupted node.
Which is why merges should be reversible. Store the resolution decision as its own record, with the evidence that motivated it, rather than destructively rewriting the underlying assertions. When you discover that two entities were merged in error, you want to unmerge them, not rebuild the graph. Systems that treat resolution as an irreversible write step end up rebuilding from scratch, repeatedly, and the rebuild is never cheap.
Relations, and the trouble with verbs
Entities get most of the attention and relations cause most of the pain. A relation is a claim about how the world is arranged, and claims have qualifiers that a bare triple cannot express. Priya manages Daniel, but since when, and in what capacity, and according to which source. The subject-predicate-object form is clean precisely because it discards this, and discarding it is often unacceptable.
The standard remedy is to promote important relations into entities of their own. Instead of an edge from Priya to Daniel labelled manages, you create an Employment Relationship node connecting both, carrying a start date, an end date, a role, and a source. This is called reification, it is verbose, and it is almost always the right call for any relation your business logic actually depends on. Reserve bare edges for relations that are genuinely timeless and unqualified, which is a smaller set than it first appears.
The second trouble with verbs is directionality and its implications. If A depends on B, then an outage in B threatens A, and the reverse is not true. Getting the direction backwards in a dependency graph does not produce a slightly worse answer. It produces a confidently inverted one, and an agent reasoning over it will restart precisely the wrong service. Direction deserves the same test coverage you would give a permission check.
Provenance: every edge knows where it came from
An assertion in a graph with no provenance is a rumour with good formatting. The moment an agent takes consequential action on graph content, someone will ask why it believed that, and the only acceptable answer is a pointer to a specific sentence in a specific version of a specific document, with a timestamp and an extraction method.
Provenance is not only for audits. It is the mechanism by which you repair the graph. When a source document is superseded, you need to find every assertion derived from it and re-evaluate. When you discover that a particular extraction prompt was producing a systematic error, you need to find everything it wrote and quarantine it. Without provenance, both of these operations degrade into rebuilding the entire graph, which is how organizations end up with knowledge bases they are afraid to touch.
It also enables the most useful trust primitive available: agreement counting. An assertion supported by one offhand mention in a meeting transcript is different from one supported by a contract clause, an invoice, and a database record that all agree. Both are edges in the graph. Only one should be allowed to authorize a payment.
Time, and graphs that remember when things were true
Most knowledge graphs are built as though facts are permanent, and most facts are not. People change roles. Contracts get amended. Prices change. Services are deprecated. A graph that overwrites the old value with the new one loses the ability to answer any historical question, and historical questions are a large fraction of the interesting ones. Why did we apply that discount in March. Who approved this when it was approved. What did we believe about this customer before the acquisition.
The discipline is bitemporality, which sounds academic and is not. Every assertion carries two timeframes: when it was true in the world, and when your system came to believe it. These diverge constantly. You learn on Friday that someone left the company on Tuesday. A query about Wednesday should say they had left; a query about what the system knew on Wednesday should say it did not know yet. Systems that collapse these two axes cannot explain their own past behaviour, which is the exact capability you need when investigating why an agent did something surprising.
You do not need this everywhere. Applying bitemporality to every attribute in a large graph is a significant cost in storage and query complexity. Apply it to the relations that drive decisions, which are usually a small and identifiable subset: ownership, authority, status, and price.
Confidence and contradiction
Real sources disagree. The CRM says the account owner is one person, the signed order form says another, and the support system has a third. A graph that silently picks one is lying by omission. A graph that stores all three without comment is passing an unresolved conflict to a model that will choose arbitrarily, which is worse, because now the arbitrariness is invisible.
The workable approach is to represent conflict explicitly and to encode a resolution policy separately from the data. Source precedence handles most cases: the signed document beats the CRM, the CRM beats the transcript. Recency handles many of the rest. What remains after both is a genuine conflict, and genuine conflicts should be surfaced rather than resolved. An agent that reports the sources disagree about who owns this account, here are both claims, is behaving correctly. An agent that picks the more recent one and proceeds to send a contract to the wrong signatory has been failed by its knowledge layer.
Calibration matters here in the same way it matters everywhere in this field. A confidence score attached to an edge is only useful if it means something empirically, which requires measuring extraction accuracy against a labelled sample rather than passing through whatever number the model produced when asked how sure it was. Uncalibrated confidence is decoration.
Querying: traversal as a first-class operation
The payoff for all this construction is a class of query that similarity search cannot express. Find everything within three hops of this incident. Find the shortest path between this policy and this customer complaint. Find all nodes that would become orphaned if this service were removed. Find every contract whose counterparty is a subsidiary of a company on the restricted list, including subsidiaries of subsidiaries.
That last one is worth dwelling on, because it is the shape of query that separates graph reasoning from everything else. Ownership hierarchies are recursive and of unknown depth. There is no fixed number of joins that answers the question, and no amount of semantic similarity approximates it. Either your system can traverse a variable-length path, or it can only answer a weaker version of the question and hope nobody notices the difference. In compliance settings, someone notices.
Neighbourhood retrieval is the workhorse pattern in practice. Given an entity, pull the subgraph around it to a bounded depth, serialize it into readable text, and hand it to the model as context. This is dramatically more information-dense than passages. A well-constructed two-hop neighbourhood might be four hundred tokens and contain every relevant fact about an entity, where the equivalent document retrieval would be six thousand tokens of prose that mentions those facts in passing among a great deal of boilerplate.
Giving an agent graph tools, not a query language
There is a persistent temptation to hand the model a graph query language and let it write its own queries. It is elegant, it is flexible, and it fails in ways that are annoying to debug. Generated queries fail on syntax, on schema assumptions that do not hold, and most insidiously on silent semantic errors that return an empty result which the model then reports as there is no such relationship. Empty results are indistinguishable from absence of fact, and models are not skeptical enough about them.
Constrained traversal tools work far better. Give the agent operations like get neighbours of this node filtered by relation type, find paths between these two nodes up to a given length, and list entities of this type matching these attributes. Each is parameterized rather than free-form, each validates its inputs, and each returns a structured result the agent can reason about. You lose some expressiveness. You gain a system whose failure modes are legible, and you can add specific tools for the specific complex queries that turn out to matter, which is a much better use of engineering effort than debugging generated query syntax.
When you do allow generated queries, treat them exactly as you would treat generated SQL against production: read-only credentials, a strict timeout, a row limit, a cost estimate checked before execution, and results validated against expectations. An unbounded traversal on a well-connected graph can touch a substantial fraction of the database, and the model has no intuition whatsoever about that.
The hybrid that actually works
Nothing above argues for abandoning vector search, and any system that does will be worse than the one it replaced. Graphs are precise about things you modelled. They are silent about everything else, and everything else is most of a corpus. The nuance in a customer complaint, the reasoning in a design document, the tone of a negotiation: none of that becomes triples without violence, and it is often exactly what the question needs.
The productive architecture uses each for what it is good at. Vectors find the entry point, because natural-language questions rarely name their subject cleanly and semantic search is excellent at getting from a vague question to a probable entity. The graph then expands from that entry point, pulling in the structured neighbourhood: the related parties, the governing agreements, the current status, the chain of authority. Documents come back into play at the end, when the agent has identified which specific sources it needs to read closely, and retrieves their full text rather than an arbitrary chunk of it.
Entry point, expansion, evidence. Vectors handle the first, the graph handles the second, document retrieval handles the third. Each stage is independently testable, and when the answer is wrong you can tell which stage failed, which is not a property that emerges from a monolithic retrieval pipeline.
Community detection deserves a mention as the interesting middle case. Running clustering over the graph structure to identify densely connected groups, then generating a summary of each cluster, produces a hierarchy of abstractions that supports the broad questions neither approach handles well on its own. What are the main themes in our incident history is a question with no single answer document and no single relevant node. It is a question about the shape of a region of the graph, and having pre-computed summaries of those regions is the only efficient way to answer it.
Aggregation and the questions vectors cannot answer at all
Some questions are not hard for vector search, they are impossible. How many active contracts do we have with counterparties in a given jurisdiction is a counting question. Similarity search returns a ranked list of ten things, not a count, and a model asked to count from a ranked list will produce a number that is confidently derived from an arbitrary sample. It will not tell you it sampled. It will just say forty-three.
Any question involving counts, sums, coverage, or absence requires a representation with complete membership semantics. A graph provides that: the set of nodes of type Contract with an edge to a Jurisdiction node is a well-defined set, and its cardinality is a fact rather than an estimate. The same applies to negative questions, which are the ones that embarrass systems most publicly. Are there any customers without an assigned account manager is unanswerable by retrieval, because the evidence is the absence of an edge, and absence has no embedding.
Keeping the graph fresh
A stale graph is more dangerous than no graph, because it is authoritative-looking. The freshness strategy has to match the change rate of each part of the domain, and those rates differ by orders of magnitude. Organizational structure changes weekly. Contract terms change on renewal. Product catalogues change daily. Historical incidents never change at all.
Incremental update is the goal and event-driven update is the mechanism. When a source system emits a change, re-extract only what that change touches and reconcile the affected subgraph. This is more work to build than a nightly full rebuild and it is the only thing that scales past a certain corpus size. It also introduces the reconciliation problem: when re-extraction of an updated document produces assertions that conflict with existing ones, you need a policy that distinguishes a genuine change in the world from an extraction difference caused by a model update. Tagging assertions with the extraction version makes this tractable.
Whatever the mechanism, expose freshness in the output. An agent that reports this reflects data as of a stated time is giving its user the information needed to calibrate trust. One that presents six-week-old organizational structure as current fact is quietly setting up the failure that eventually destroys confidence in the whole system.
Scale, and what breaks when the graph gets big
Graphs degrade in a characteristic way. The first problem is supernodes: a handful of entities connected to an enormous number of others. A company node in a graph built from internal documents might connect to every employee, every contract, and every incident. Traversing two hops from anything reaches it, and from there reaches everything. Neighbourhood queries that were fast on the test set take thirty seconds in production and return the entire database. The fix is unglamorous: identify high-degree nodes, exclude them from generic traversal, and require queries that involve them to be explicit and filtered.
The second is the density of weak edges. Open extraction over a large corpus generates enormous numbers of low-confidence relationships, most of which are coincidental co-occurrence rather than meaningful connection. They inflate storage, slow traversal, and dilute results. Pruning by confidence and by support count is necessary maintenance, not a compromise.
The third is serialization cost. Converting a subgraph into text the model can read is not free, and a naive serializer that emits every attribute of every node in a neighbourhood produces context that is both expensive and mostly irrelevant. Serialization should be query-aware, including the attributes that bear on the question and eliding the rest. This is context engineering applied to graph output, and it has the same leverage there as anywhere else.
Permissions on a graph
Access control is harder on a graph than on documents, and it is routinely underestimated. In a document store, permission is a property of the document, and filtering is straightforward. In a graph, knowledge leaks through structure. A user who cannot see the compensation record can still learn a great deal from the existence of an edge between an employee node and a salary band node. Path queries are especially leaky: revealing that a two-hop path exists between a person and a confidential project discloses the association even if both endpoints are individually visible and the intermediate node is not.
Filtering must therefore happen during traversal, not after it. A post-filter that removes forbidden nodes from a result set has already allowed those nodes to influence which paths were found, and the shape of the result betrays what was removed. Traversal that never expands into unauthorized regions is the only construction that holds up. It is slower, it complicates caching, and it is not optional in any environment with real confidentiality requirements.
The related trap is caching. A cached neighbourhood computed for a user with broad access, served to a user with narrow access, is a data breach with excellent latency. Permission context has to be part of the cache key, which substantially reduces hit rates, which is a cost worth paying without argument.
Evaluating a knowledge graph
Graph quality is measurable, and the fact that many teams do not measure it is the main reason graph projects stall in a state of vague dissatisfaction. Three layers deserve separate measurement.
Extraction quality is precision and recall of assertions against a human-labelled sample of source documents. Take fifty documents, have a person write down what should have been extracted, and compare. This is tedious and it is the only way to know whether the graph reflects the corpus.
Resolution quality is measured on pairs. Sample pairs of entities, label whether each pair refers to the same thing, and measure how often the system agrees. Report over-merging and under-merging separately, because they have different costs and different fixes, and a single accuracy number hides which one is happening.
End-to-end quality is answer accuracy on questions that require the graph, which is the only number that matters to anyone outside the team. Build a question set weighted toward multi-hop, aggregation, and negative questions, since those are the ones you built the graph for. If graph-augmented answers are not measurably better than the vector baseline on that set, the graph is not earning its maintenance cost, and it is better to learn that in month two than in year two.
Failure modes worth naming
The ontology that never ships. Six months of modelling produces a beautiful schema and no data. The countermeasure is a hard rule that the graph must answer a real question in week two, with whatever crude schema that requires.
The merge that ate the graph. One aggressive resolution rule fuses two common entities and the contamination propagates through every query touching them. The countermeasure is reversible merges, plus alerting on any node whose degree grows anomalously fast.
The graph nobody queries. It gets built, it sits alongside the existing retrieval system, and the agent never actually uses it because the tools are awkward or the results are hard to read. The countermeasure is to instrument tool usage from the first day and treat low graph tool invocation as a product defect rather than a curiosity.
Confident traversal over stale edges. The agent finds a clean path, reports the conclusion with certainty, and every edge on that path is nine months old. The countermeasure is propagating freshness through traversal, so a path is only as fresh as its stalest edge, and surfacing that in the answer.
Schema drift between extraction and query. Extraction starts emitting a new relation name after a prompt change, queries continue looking for the old one, and results quietly thin out over weeks. The countermeasure is treating the schema as a versioned contract with tests on both sides, exactly as you would treat an API.
When you do not need a graph
Plenty of systems should not build one. If your questions are consistently answerable from a single document, vector retrieval is simpler, cheaper, and better. If your data already lives in a well-normalized relational database, you have a graph, you are just calling the edges foreign keys, and the right move is usually to give the agent good query tools over that database rather than to construct a parallel representation that will drift from it.
If your domain has few entity types and shallow relationships, the graph overhead buys nothing. If your corpus changes faster than you can extract from it, write-time integration is the wrong bargain. And if you cannot name three questions that fail today and would succeed with a graph, that is the clearest possible signal to wait until you can.
The honest summary is that graphs are worth it when relationships are the product. Compliance, security, finance, supply chain, healthcare, and operations all share the property that the connections between entities carry as much meaning as the entities do. Consumer question answering over a help centre generally does not, and building a knowledge graph for it is an expensive way to arrive at the same answers.
Getting started without an ontology committee
Start with one question your current system answers badly and that clearly requires structure. Write down the three or four entity types and the two or three relations that question needs, and refuse to add more. Extract them from a bounded corpus, a few hundred documents, not the whole archive. Build the crudest possible resolution, probably normalized name plus one distinguishing attribute. Wire up a single traversal tool. Measure whether answers improve.
This gets you to a working system in weeks rather than quarters, and more importantly it puts you in contact with the specific difficulties of your domain, which are never the ones you predicted. You will discover that your entity names collide in some particular way, or that a relation you thought was one-to-many is many-to-many, or that half your corpus refers to entities by internal codes that appear nowhere in any document. None of that is discoverable through design. It is only discoverable through extraction.
Expand along the direction of demonstrated need. Each new entity type should be justified by a query it enables, each new relation by a question it answers. A graph grown this way stays comprehensible, stays maintainable, and never becomes the thing that everyone is afraid to modify.
The bottom line
The industry spent two years learning to retrieve, and retrieval got very good at the question what does the corpus say about this. Agents keep asking a different question: how is this connected to that, and what follows from the connection. Those questions have structural answers, and structure has to be represented before it can be reasoned over. Similarity does not represent structure. It was never trying to.
A knowledge graph is the deliberate act of writing down what your organization believes about the entities it deals with and the relationships between them, with sources attached and timestamps recorded. Language models made that act affordable for the first time. What they did not do is make it automatic. The construction is still engineering: schemas chosen for a purpose, extraction constrained by evidence, resolution that can be undone, provenance on every edge, permissions enforced in traversal, and evaluation at every layer.
The measure of whether it was worth building is simple and worth returning to often. Ask your system a question whose answer lives in the joins, and see whether it answers confidently, correctly, and with a path you can follow. If it does, the structure earned its keep. If it answers confidently and wrong, you did not build a knowledge graph. You built a more expensive way to guess.