DEV Community

Cover image for Stop Pasting Your Database Schema Into Every AI Prompt
Siddharth Pandey
Siddharth Pandey

Posted on

Stop Pasting Your Database Schema Into Every AI Prompt

Your team builds an internal agent that answers questions like "revenue by product category last quarter." It generates SQL against a Postgres database with 240 tables. The first version does the obvious thing: dump the entire schema into the system prompt. It mostly works, and it is quietly terrible — every single question pays the token cost of 240 table definitions, the agent confuses users.name with the actual column full_name because the real signal is buried in noise, and the schema snapshot in the prompt drifts out of date the moment someone runs a migration.

The fix is not a bigger context window. It is giving the agent the same thing a human analyst has: a way to look up the tables it needs, when it needs them.

This is a use case I did not originally design Infrawise for — it started as infrastructure context for AI coding assistants — but as of v0.15.0 it handles this pattern end to end, for SQL and NoSQL databases. (GitHub · npm)

The schema dump is the problem, not the model

When a query-writing agent gets the whole schema up front, three things go wrong:

Token cost scales with your database, not your question. A 240-table schema rendered as DDL is tens of thousands of tokens. You pay that on every request, forever, even when the question touches two tables.

Irrelevant schema actively hurts accuracy. Models pick columns from tables that merely look plausible. The more near-duplicate tables in context (orders, orders_archive, orders_v2), the more confidently wrong the generated SQL gets.

The dump goes stale. Someone pastes the schema into the prompt template in March. In May a column is renamed. The agent keeps generating SQL against the March schema, and the failures look like model errors instead of what they are: stale context.

The alternative is progressive disclosure — a small inventory up front, full detail on demand. Infrawise exposes exactly that over MCP, the protocol most agent SDKs can already speak.

Inventory first, schema on demand

Infrawise runs a read-only analysis of your infrastructure — Postgres, MySQL, and MongoDB via schema introspection, DynamoDB via the AWS API — and serves the result through an MCP server. It never reads row data, only metadata.

The agent flow is two calls.

Call 1, once per session: get_infra_overview. This returns a compact inventory — every table name with its database type, plus counts and high-severity findings. For a 240-table database this is a fraction of the tokens of a full dump, because it is names, not definitions. The response also carries a freshness object with analyzedAt, ageSeconds, and a stale flag that flips after 24 hours, so the agent knows whether the analysis is current or should be refreshed with infrawise analyze. That freshness contract means you can cache the inventory for the session and trust the server to tell you when it has gone stale.

Call 2, per question: get_table_schema. When the agent decides the question needs orders and payments, it asks for exactly those (up to 20 names per call):

{
  "name": "get_table_schema",
  "arguments": { "tables": ["orders", "payments"] }
}
Enter fullscreen mode Exit fullscreen mode

Names are matched case-insensitively, and short names work — orders matches public.orders, so the agent does not need to know your schema-qualification convention. The response is the full picture for just those tables:

{
  "note": "Row data is never included.",
  "tables": [
    {
      "requested": "orders",
      "found": true,
      "matches": [
        {
          "name": "public.orders",
          "databaseType": "postgres",
          "columns": [
            { "name": "id", "dataType": "integer", "nullable": false },
            { "name": "user_id", "dataType": "integer", "nullable": false },
            { "name": "status", "dataType": "character varying", "nullable": false },
            { "name": "total", "dataType": "numeric", "nullable": false }
          ],
          "primaryKeys": ["id"],
          "indexes": ["orders_pkey"]
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Column names, data types, nullability, primary keys, indexes. If the agent asks for a table that does not exist — a hallucinated name, a typo — it gets found: false, and when near matches exist, up to five suggestions from the real inventory. That turns a silent wrong-table failure into a correctable one.

The prompt for any given question now contains the inventory plus two or three real schemas instead of 240 speculative ones. Costs drop, and the model stops choosing columns from tables that were never relevant.

Foreign keys are the context your agent actually needed

Column lists get you valid syntax. Join paths get you correct queries — and join paths are exactly what schema dumps usually omit, because people paste \d output or ORM models without constraint details.

Infrawise extracts foreign keys directly from information_schema (Postgres and MySQL) during analysis, and get_table_schema returns them per table:

"foreignKeys": [
  {
    "column": "order_id",
    "referencesTable": "public.orders",
    "referencesColumn": "id"
  }
]
Enter fullscreen mode Exit fullscreen mode

When the agent fetches payments and sees order_id → public.orders.id, the join is no longer a guess. Chains compose the same way: fetch the tables the question mentions, follow the referencesTable values one hop out, and the agent has the join graph for the query without ever seeing the other 230 tables.

The same flow works for NoSQL

The tool is polymorphic across database types, because "what does my agent need to know before writing this query" differs by engine:

  • DynamoDB — the response carries partitionKey and sortKey, which decide whether the access pattern is a cheap Query or an expensive Scan. Index names cover the GSIs.
  • MongoDB — collections return their indexes and an estimated document count, so the agent can tell a 100-row lookup table from a 50M-document collection before choosing a filter strategy.

One inventory call, one schema tool, four database engines.

Wiring it into an agent

Setup is one command in the project that has your infrawise.yaml (or lets start generate one):

npx infrawise start    # analyze + write .mcp.json for stdio-based editors/agents
Enter fullscreen mode Exit fullscreen mode

For agents that speak HTTP instead of stdio:

infrawise serve        # MCP server at http://localhost:3000/mcp
Enter fullscreen mode Exit fullscreen mode

Any MCP-capable agent framework can then list the tools and call them. The system prompt shrinks to a policy instead of a schema:

Call get_infra_overview once to learn what tables exist. Before writing a query, call get_table_schema with only the tables the question needs. Use the returned foreign keys for joins. Never guess column names.

Two cautions from building this. First, the server has no authentication — it is designed to run locally or inside a private network, next to the agent. Keep it off the public internet; it exposes schema metadata (never data, never secrets, but your table names are your business). Second, the analysis is a snapshot: honor the stale flag rather than assuming the graph is live.

Conclusion

"Text-to-SQL accuracy" problems are very often context problems wearing a trench coat. An agent that receives 240 table definitions is being asked to find a needle in a haystack it paid for by the token. An agent that can look up exactly the three tables a question touches — with types, primary keys, and foreign-key join paths — is doing what a competent analyst does with a schema browser open.

Infrawise was built to stop AI coding assistants from guessing about infrastructure. It turns out the same deterministic extraction, served over MCP, is a schema context provider for any query-writing agent. That flow shipped in v0.15.0: GitHub · npm.

Key Takeaways

  • Full-schema prompts scale cost with database size, not question size — and the irrelevant 95% of the schema makes column hallucination worse, not better.
  • Use progressive disclosure: get_infra_overview once per session for the table inventory, get_table_schema for only the tables each question needs.
  • Foreign keys are the highest-value schema context for SQL generation — they turn joins from guesses into lookups. Infrawise extracts them from information_schema automatically.
  • Unknown table names return suggestions instead of silent failure, catching hallucinated tables before they become broken SQL.
  • Respect the built-in freshness contract: the overview reports analysis age and flips a stale flag at 24 hours, so agents know when to trigger a re-analysis instead of trusting old schema.

Top comments (0)