A data context layer is a computed graph of grain, lineage, join safety, and metric definitions that an agent queries at runtime instead of re-reading a repository. At the AI Engineer conference on 2026-10-11, Typedef co-founder Yoni Michael and founding engineer Brandon Callender argued the model is not the bottleneck and the missing context is.
What a data context layer actually contains
A data context layer is a queryable graph of the four facts an agent needs and SQL never states: what one row represents, whether a join is safe, what a metric means, and which assets depend on which. Yoni Michael, co-founder of Typedef, described it at the AI Engineer conference on 2026-10-11 as the reasoning layer that lets an agent read and write to a data platform with the same working knowledge a data team built up over years.
Michael named the four facts directly. Each one answers a question the schema itself stays silent on:
| Fact | Question it answers | Failure when it is missing |
|---|---|---|
| Grain | What one row of a table represents | A grain that silently shifts from customer-by-month to customer-by-week makes every downstream sum wrong while the SQL still compiles |
| Join safety | Whether a join key is unique on the right side | An upstream column turns a one-to-one join into one-to-many, so a pipeline row count jumps 40 percent overnight |
| Metric meaning | The business definition embedded in transformation logic | The same metric name resolves to different logic in different tools |
| Dependencies | What breaks downstream when a definition changes | A definition change lands without anyone knowing which assets depend on it |
Those facts are spread across the warehouse, the transformation code, the BI tool, and tribal knowledge in people's heads. The agent sits in the middle without any of them, which is why a pipeline row count that jumps 40 percent overnight can be reported as more incoming data when the real cause is an upstream column turning a one-to-one join into one-to-many.
Typedef stores the result as a graph rather than a pile of markdown files so the agent pulls one subgraph per question instead of stuffing a whole repository into the prompt. Michael said the graph is computed once and refreshed atomically on every commit, which keeps it aligned with the current state of production data.
Why valid SQL still produces the wrong answer
Valid SQL produces the wrong answer whenever the query silently changes grain, drops rows, or redefines a metric, because none of those three things appear in the syntax an agent reads. Michael used a single equality join to explain this: the same written join can preserve rows, act as a dimension lookup, or replicate every row, and the agent cannot tell which outcome applies from the text alone.
The same ambiguity applies to BETWEEN clauses, which can be either a safe point-in-time lookup or a date spine that explodes the grain. Verification against real data is what settles the question, and that verification requires profiling the join key for uniqueness rather than guessing from column names.
A metric refactor is the third failure mode. Removing a predicate such as a paid filter keeps the SQL compiling while redefining the metric to include trial churn, and the change flows into every downstream dashboard that reads it. Michael's point is that the predicate was part of the business definition, not incidental syntax, and an agent has no way to know that from the code alone.
Michael gave the two obvious fixes and why each falls short. Handing an agent the dbt or Airflow project means re-deriving context on every prompt, bounded by the context window and rebuilt from scratch each session. Connecting an MCP server to Snowflake or Databricks shows the rows but not what each row means. Michael's summary: one can read the code without memory, the other sees the data without meaning.
How Typedef computes grain, lineage and join safety
Typedef computes what it can deterministically from transformation code, then uses an LLM only for the human-readable layer on top. Michael described parsing SQL down to the AST to derive grain and lineage, profiling warehouse tables to verify join keys, and reserving the model for naming assets, summarizing a model's purpose, and resolving ambiguity the first two layers leave open.
The separation is deliberate. Core facts stay tied to the implementation, so the agent cannot drift from what the transformation code actually does, while the LLM only labels nodes on the graph. Michael said the team spent significant effort using relational algebra to compute grain at each stage of the data lifecycle.
The graph carries provenance on its edges. Michael described edge types such as "is materialized by" and "has a semantic definition" connecting nodes that represent logical models, physical tables, and semantic views. That structure is what lets an agent walk downstream and ask each dependent node whether a proposed change breaks its grain.
Michael's claim is that this all happens pre-flight. The agent sees a blast radius before it writes a line of SQL, not at build time and not during a production incident. In his worked example, moving a monthly ARR measure to weekly grain would repeat the value across weekly rows and inflate a downstream ARR sum by roughly 4x, with the error landing on a board-level dashboard.
The workshop graph: five Qdrant crates in Neo4j
Brandon Callender, Typedef's founding engineer, built a smaller version of the same idea over Qdrant, the open-source vector search engine written in Rust. The workshop covered a sample of five crates, extracted symbols with tree-sitter, resolved them with rustdoc JSON, and loaded the result into Neo4j for traversal.
Callender framed the levels explicitly. Level one is grep and glob on raw strings with no structure. Level two is code RAG: embedding search and lexical search that return a ranked flat list of locations. Level three, his preferred level, is a traversible graph with real symbol identity and typed edges.
The motivating example is two Rust types both named PostingList in different files within Qdrant. Text search returns both plus a PostingListView and a PostingListIterator. Tree-sitter alone still collides them; rustdoc resolution gives each a canonical path and line. Callender was candid that Rust does some of this work for free through the compiler, and he picked it because it made a 90-minute workshop feasible.
The payoff shows up in one call. Callender demoed a blast-radius function that takes a fully qualified name and walks the graph to return every dependent symbol, which is the query an agent would otherwise answer by reading several files and inferring the links. Because the two PostingList types resolve separately, the tool returns different dependents for each.
Choosing a context graph, code RAG, or plain grep
A context graph earns its cost when the question depends on relationships between symbols or assets; grep and code RAG stay adequate when the question is text matching. Callender's three-level framing is the clearest available way to choose, and he was explicit that code RAG is not deficient, only flat.
Why the agent still runs grep instead of the graph
Agents keep reaching for grep because post-training made text search a reflex, and no amount of graph quality overrides it. Callender calls that reflex the main obstacle, not a tooling bug. So the fix is to meet the model halfway: rename the graph tool, match ripgrep's output shape, and make the first call pay off.
"We gave it amazing tools, a precomputed traversible model of the codebase, and it just ran grep anyway," he said during the workshop. His answer is to meet the model halfway rather than fight the reflex.
| Adoption lever | What to change | Why it works |
|---|---|---|
| Tool name | Call the graph tool search | A tool with that name gets multi-keyword queries with no training |
| Output format | Return results shaped like ripgrep | The model has handled that format thousands of times |
| First-call payoff | Make call one useful | A single empty result can convince the agent search is broken |
| Structure | Add call-graph edges from SCIP | More structure to extract, not a fix for adoption |
Callender's broader warning is about sunk cost. He described a loop where you keep improving the graph because the eval results were close, and he argued the honest reading of a tie is that grep already works well. Even his suggested upgrade path, adding call-graph edges from SCIP, is framed as more structure to extract rather than a fix for tool adoption.
The one structural exception is language. Callender said Python is harder than Rust because callers and types are not statically available, and that a code graph earns more of its keep there, where grepping for interface implementations returns an unusable pile of matches. He mentioned griffe, tree-sitter, and ty as pieces of a Python ingest path.
Eval results: pass@k versus consistency across runs
Two metrics told different stories about the same agent. Pass@k asks whether the agent answered correctly at least once across five attempts; the consistency metric asks whether it answered correctly every time. Callender's notebook shows the graph agent matching or slightly beating the file-probing control on pass@k, while running questions consistently across all five attempts about twice as often and using roughly 3.1 times fewer tokens. The consistency and token figures come from the talk rather than a published report.
The setup matters for reading those numbers. Both agents used the same model, the same 30-question corpus, and five attempts per question, with the run cached overnight one week before the talk so the notebook would not take 30 minutes live. The control agent used a file-system probing tool set maintained by Pydantic. Gold answers were pulled from the graph but cross-referenced against source code so the graph's own output did not contaminate them.
| Dimension | Graph agent | File-probing control |
|---|---|---|
| Model | Same | Same |
| Corpus and attempts | 30 questions, 5 attempts each | 30 questions, 5 attempts each |
| Pass@k | Matched or slightly better | Baseline |
| Consistency across all 5 runs | About 2x as often | Baseline |
| Tokens used | About 3.1x fewer | Baseline |
Callender drew the lesson from the flip between metrics. Pass@k showed the two agents close together; the consistency metric showed the graph agent roughly twice as reliable. For a task that has to run unattended, only the second number describes what you get in production.
Tool adoption is the number that gates everything else. Callender reported measuring tool usage in agent traces: a prompt with no instructions to use the graph tools produced 34 percent tool usage, and rewriting the prompt raised it to 72 percent. His blunt line: "an elegant tool that gets reached for a third of the time is just a third of a tool."
Typedef's production claim is larger and vendor-reported. Michael said task success rate was almost 35 points higher with the data context layer than without it, same models and same tasks, with the only variable being access to the layer. Other Typedef evals in the same session used the open-source Mattermost dbt project of roughly 300 to 350 models, loaded with simulated data.
Treat every number here as vendor and transcript evidence, not independent reproduction. Typedef staff also said they had tried NL2SQL benchmarks such as BIRD and Spider but framed the product goal as enabling data engineering workflows rather than writing better analytical SQL, so those benchmark results should not be read as a verdict on general text-to-SQL.
Running the workshop yourself
Callender published the workshop notebooks alongside the talk, and the setup is small enough to run on a laptop. The dependencies are Docker for Neo4j and an optional OpenRouter key if you want to run the LLM steps live; the deterministic parsing and graph steps run offline. His repository is a teaching artifact, not a product, and he said plainly that nobody should build a code-analysis graph from scratch as a product.
A reasonable order for the first pass:
Data Context Layer FAQ
- What is a data context layer? A data context layer is a computed graph of grain, lineage, join safety, and metric definitions built from transformation code and table profiles. Typedef's version refreshes on every commit so an agent queries current facts instead of re-reading a repository each session.
- Why do AI agents write correct SQL that returns wrong answers? Because grain, join cardinality, and business definitions live outside the query text. An upstream column that turns a one-to-one join into one-to-many inflates row counts while the SQL still compiles, and the agent reports the wrong root cause with full confidence.
- How is a context graph different from code RAG? Code RAG returns a ranked flat list of locations. A context graph links symbols with real identity, resolves re-exports to their original definitions, and adds typed edges so one traversal answers a dependency question instead of several file reads.
- Why does the agent ignore a graph tool in favor of grep? Post-training shaped a text-search reflex that a better tool does not automatically override. Naming the tool search, returning ripgrep-shaped output, and making the first call useful are the three tactics Callender recommends, and none of them require retraining.
- What did the Typedef workshop measure? The workshop measured consistency across repeated attempts, not just single-shot accuracy. Callender reported the graph agent was roughly twice as reliable across all five runs and used about 3.1 times fewer tokens on average, with those numbers coming from his own eval runs.
- What is the 35-point task success lift Typedef reported? Yoni Michael said task success rate was almost 35 points higher with the data context layer than without it, with identical models and tasks. The figure is vendor-reported from the presentation, reached on a corpus of dbt models based on the open-source Mattermost project, and has not been independently reproduced.
- Does a context graph replace a data catalog? No, the two coexist. A catalog describes what exists in the warehouse, while a context graph links a transformation model to the physical table it produces and pulls profile information from the catalog to verify join safety. Callender called the catalog a source for the graph, not a substitute.
- Can the same approach work for Python? Callender said yes, with more work. Python lacks Rust's compiler-provided resolution, so a Python ingest path uses tools such as griffe, tree-sitter, and ty to recover some type and caller information, and he treats the graph as more valuable where static analysis is weakest.
- When is incremental indexing necessary instead of a full rebuild? Callender said incremental indexing should be first-class from the start, because reindexing everything is the first cost that becomes unbearable as a codebase or data architecture grows. Most changes touch a small number of files, so the work is diffing and refreshing only what changed.
Fork this article
Start a new branch from the same video, shaped your way. You keep the credit; the original keeps the attribution.
A fork in another language is filed as a translation of this article, so the two pages point at each other. You can unlink it later from the editor.
0/240
You are creating
- Format
- For
- Language
- Source
- Your angle
You will be asked to sign in before it is generated.
Buy credits