A metadata layer needs the same duality, and this is where the analogy to a context graph is exact rather than loose. Each entity in a context graph (a customer, a deal, an article) carries both halves of the contract. The semantic half says what the entity is and how it relates to neighboring entities (a deal belongs to an account, an account has a health score, and so on). The schema half says what’s structurally valid: which fields exist, what types they hold, which relationships are legal to traverse, which values are out of range. An agent querying that entity doesn’t just get a definition; it gets boundaries. It can’t hallucinate a field that isn’t in the schema, and it can’t misinterpret a metric because the entity already declares what that metric means and how it’s derived.
Skip the constraint half, and you’ve only built documentation, not an interface. Agents can still read what a field is supposed to mean, but nothing stops a new use case from bending that meaning, querying a relationship that doesn’t exist, or returning a shape the next consumer wasn’t expecting. The semantic layer without the schema layer is a description you hope people follow. With both halves, you get something a second agent can build against without ever talking to the first.
That distinction sounds small. It isn’t. Hard-coded context works for a single run because it’s fast to build and immediately useful, which is exactly why it’s most people’s first instinct. But every new use case means writing new context, and now you’re maintaining multiple versions that drift out of sync. A layer that describes the types of information available, how to retrieve them, and the boundaries on both ends lets you pull exactly the context a task needs without rewriting the underlying definition every time. Three effects follow, and I see all three constantly with engineering teams: