AI agent schema: why agents should read it before they query
What an AI agent schema is, four ways to give one to an agent (DDL, sampling, planner statistics, a live catalog), and how they compare on invented filter values.
Contents
- TL;DR
- What is an AI agent schema?
- What can go wrong when an agent doesn't read the schema?
- How do you give an agent the schema?
- What do the measurements show?
- Why does freshness matter for an agent's schema?
- What does reading a RushDB catalog look like?
- How should an agent use the schema in practice?
- When is a catalog overkill?
- FAQ
- How do AI agents know the database schema?
- Is DDL enough for a text-to-SQL agent?
- Should the schema go in the system prompt or behind a tool?
- What is the difference between "agents schema" and a tool schema?
- Sources
An AI agent schema is the description of your data an agent reads before it writes a query: which tables or labels exist, which fields they have, their types, and which values are actually stored. Agents get it in four ways: DDL pasted into the prompt, sampling a few rows at runtime, the database's planner statistics, or a catalog the database keeps current. The differences show up in filter values, because a filter on a value the column doesn't store returns zero rows instead of an error.
TL;DR
- For an agent, "schema" means more than column names. It needs types, counts and the values a field actually holds.
- DDL tells the agent what was declared, sampling shows a few rows, planner statistics show the frequent values, and a catalog reports everything stored, with exact counts and value lists.
- In our benchmark runs, current models rarely invented a filter value on static questions (1.0–2.2% with plain sampling). After stored values changed, an agent reading a catalog snapshot gave stale answers on 28–55% of the changed questions, and the live catalog cut that by 41–89%.
- A tool that computed the same answers with plain SQL did as well as RushDB's catalog; a catalog maintained on write adds freshness without recomputation.
- Part 1 of the analytics series walks the schema-reading loop step by step on example data.
What is an AI agent schema?
An AI agent schema is the machine-readable map of a dataset that an agent consults to write valid queries: entities, fields, types, relationships, and the stored values of fields it will filter on. It is the agent's only knowledge of your data at the start of a session.
A human analyst builds this map over weeks. They learn that status uses paid, not Paid, that amount arrived as text from one service, and that customers link to invoices through account_id. An agent starts every session knowing only what you put in front of it.
"Agents schema" also gets used for the agent's own tool schema (the JSON Schema of its tool inputs). That is a different problem; this page is about the schema of the data the agent queries.
What can go wrong when an agent doesn't read the schema?
An agent that doesn't read the schema makes three kinds of error: names that don't exist, filter values that aren't stored, and queries that are valid but mean the wrong thing. The second kind is the most dangerous, because the query runs and returns an empty result that looks like an answer.
From easiest to hardest to spot:
- Schema errors. The query names a table or column that doesn't exist. The database rejects it, so at least you know.
- Value errors. The query filters on
country = 'United States'when the column storesUS. It runs, returns zero rows, and the agent says "no results". Nothing flags it. - Semantic errors. The query is valid and the values exist, but "active customer" means something else at your company.
A schema that lists stored values addresses value errors directly. Nothing in a schema addresses the third kind. A catalog tells the agent which fields and values exist, and your written definitions have to tell it what they mean.
How do you give an agent the schema?
You give an agent the schema in one of four ways: paste DDL into the prompt, give it sampling tools that list tables and read a few rows, expose the database's planner statistics, or let it read a live catalog of stored types, counts and values. They differ in what they reveal and how current they stay.
| Approach | What the agent sees | Strength | Weakness |
|---|---|---|---|
| DDL in the prompt | CREATE TABLE statements, declared types | Zero tool calls; cheap | Says what was declared, not what is stored; no values; stale once data moves |
| Sampling introspection | List tables, describe columns, first N rows | Works on any database | Five rows rarely contain the value you need; misses rare values |
Planner statistics (pg_stats) | Most common values, histograms | Already computed by Postgres | Approximate; refreshed by ANALYZE, not by writes |
| Live catalog | Exact counts, stored types, value lists and ranges, relationships | Reflects what is stored now | More tokens per question; needs a store that maintains it, or tools that compute it per call |
Generic database tools for agents (list tables, describe columns, sample rows) cover the first two. Planner statistics sit between sampling and a catalog, because their most-common-values list catches frequent spellings and misses the tail a question asks about (pg_stats docs).
The four approaches on the value error above:
What do the measurements show?
In our benchmark runs (BIRD Mini-Dev, 498 questions, no hints; Qwen3.5-9B, Qwen3.8-27B and a frontier hosted model), sampling introspection led to a query comparing an unstored value on 1.0–2.2% of questions. Optional catalog lookups with value search brought that to 0.4–1.0%, too few questions to be significant, and planner statistics changed little.
Grounding costs context. With the catalog and a check of the final query, tokens per question were 1.25–2.6× those of sampling, so don't expect it to save cost. The full table, the method and every condition are in How to evaluate a text-to-SQL agent beyond accuracy.
In our earlier exploratory runs, a control condition gave the agent the same tools, answered by exact SQL on the source database at call time, and matched the catalog. Any database can serve this information if you build the tools. The value search in that condition was a benchmark tool. The RushDB engine ships the same kind of lookup as propertyValues with a search and as query.searchValues (searching values), and MCP and the SDKs expose the catalog through getSchemaMarkdown and propertyValues.
On data that holds still, then, current models seldom need the catalog to get a value right. The difference shows once the data moves.
Why does freshness matter for an agent's schema?
A schema read once goes stale as soon as stored values change, and the agent then filters on spellings that no longer exist. On a drift set of 281 questions, 221 had a compared value renamed or newly written after a snapshot. An agent reading the snapshot gave stale answers on 28–55% of those questions, depending on the model, more than sampling the live data did. The live catalog cut that by 41–89% against the snapshot. Given the snapshot, the frontier model used a renamed value's old spelling on 64% of the renamed questions.
That is the argument for a catalog maintained on every write over a schema document generated once. The drift was built by us (values recoded to upper or snake case, or rows written after the snapshot), so don't stretch it to structural changes such as new or renamed columns.
What does reading a RushDB catalog look like?
RushDB keeps the catalog as part of the store instead of DDL. Every commit updates a schema catalog: labels with record counts, properties per type with how many records carry them, value dictionaries, and relationship shapes. Reading it does not scan records, and counts are exact.
The catalog docs use a small example tenant of Person and Company records (example data). One describe.schema call returns the whole map; detail: "catalog" keeps it to catalog facts and never reads records:
{"protocolVersion":1,"operation":{"kind":"describe","describe":{"kind":"schema","query":{},"detail":"catalog"}}}{
"protocolVersion": 1,
"response": {
"kind": "schema",
"schema": {
"labels": [
{ "name": "Person", "recordsCount": 3 },
{ "name": "Company", "recordsCount": 1 }
],
"properties": [
{ "id": "p…", "name": "born", "type": "number", "recordsCount": 3, "isArray": false }
],
"relationships": [
{ "sourceLabel": "Person", "targetLabel": "Person", "type": "INFLUENCED", "count": 2,
"properties": [ { "name": "via", "type": "string", "relationshipsCount": 2 } ] }
]
}
}
}That is DDL plus counts. A property's recordsCount says how many records carry it, which DDL cannot. For the stored values of a field the agent will filter on, propertyValues in topK mode returns the most frequent values with counts (facets docs):
{"kind":"propertyValues","property":"city","mode":"topK","limit":3,"query":{"labels":["Person"]}}{"kind":"propertyValues","property":"city","values":["Riga","Oslo"],"distinctCount":2,"counts":[2,1]}Both calls accept the same query document as a records search, so adding a predicate narrows every count to the matching records. Part 1 of the analytics series runs that full loop (guessed filter, stored values, the shape of the matches, the corrected query) on a refunds question.
Over MCP, the discovery-first workflow tells the agent to call getSchemaMarkdown at session start, then use discovered names exactly, since labels are case-sensitive. The Markdown form lists, per label, each property's type, sample values or range, and relationships, in a table a model reads well.
Trade-offs to know:
- The SDK's schema snapshot can be cached for up to an hour unless you pass
force: true, so very fresh writes may not appear in it; the engine'sdescribeandpropertyValuesread the live catalog. - The catalog reports type conflicts and leaves them in place: if one service sends
amountas text, you will seeamounttwice, once per type.
How should an agent use the schema in practice?
An agent should read a scoped schema once per session, look up stored values before filtering on text, use exact names from the schema, and run with read-only credentials. None of this depends on a particular database; it is a habit you build into the agent's tools and prompt.
- Read the schema once per session, scoped to the labels or tables in play. Full schemas waste tokens.
- Look up stored values before filtering on text, instead of trusting the model's guess at spelling or casing.
- Use exact names from the schema over names the model infers from the question.
- Keep credentials read-only and review the queries an agent writes, because a valid query can still answer the wrong question.
The analytics series goes deeper on step 2: grounding analytics agents checks a finished query against stored values before it runs.
When is a catalog overkill?
A catalog is overkill when the schema is small and stable. If the fields it filters on also have few values that never change, DDL in the prompt plus a short list of allowed values is enough. If you run Postgres, planner statistics are cheap to try, though they changed little in our runs. A live catalog earns its tokens when the data changes underneath the agent.
FAQ
How do AI agents know the database schema?
Only from what you give them, at session start or through tools they call. Without either, the model guesses names from the question and its training data, and guessed filter values are the errors that return zero rows without failing.
Is DDL enough for a text-to-SQL agent?
For small, stable schemas on strong models, often yes. DDL lacks stored values, though, so the agent still guesses filter literals such as status codes or country spellings. Add a value lookup tool for text columns the agent filters on, or a catalog that lists them.
Should the schema go in the system prompt or behind a tool?
Put a short, scoped summary in the prompt and keep value lists behind a tool. Value lists for large text columns can be long, and the agent needs them only for the fields a question filters on, so a lookup per field keeps the prompt short.
What is the difference between "agents schema" and a tool schema?
A tool schema is the JSON Schema of the inputs an agent's tools accept, so the model calls them correctly. A data schema describes the dataset the agent queries. Agents need both, but they fail differently. Tool schema errors are rejected, while data schema errors often return plausible empty results.
Sources
- RushDB engine: schema catalog
- RushDB engine: facets and propertyValues
- RushDB: MCP server and discovery-first workflow
- RushDB: discover your schema (SDK, caching)
- BIRD benchmark
- PostgreSQL documentation: pg_stats
- Benchmark figures: RushDB benchmark runs, November 2026, on the RushDB v3.0.1 release (method)
RushDB
Precision your agents can query.
RushDB is a self-describing, graph-native database that helps AI agents reason over data with confidence: progressively introspect what's queryable—without guesswork.
Start free →