Defensive Programming with AI Agents: Write Data Contracts Before Prompts
Document contracts BEFORE letting AI touch your pipelines
Defensive programming with AI agents is the practice of writing explicit data contracts and schemas before you write a single prompt — defining what data looks like, what invariants must hold, and what happens when they are violated. Agents armed with contracts operate within known boundaries; agents without them are guessing in the dark.
The concept is simple but counterintuitive: before you configure any agent, document your data contracts and schemas explicitly. Define the shape, the meaning, the invariants, and the failure modes. Only then let AI agents interact with your data. This approach has become a best practice on r/dataengineering, and it is the foundation of how Data Workers deploys its 15-agent swarm safely in production environments.
The term 'defensive programming' comes from software engineering — writing code that anticipates and handles unexpected inputs, edge cases, and failure modes. Applied to AI agents in data engineering, it means building the guardrails and constraints before the automation, not after. It means treating data contracts as the interface definition between human intentions and AI execution.
What Are Data Contracts?
A data contract is a formal agreement between a data producer and its consumers about the structure, semantics, quality, and behavior of a dataset. It specifies: what columns exist and their types, what values are valid, what business rules apply, what freshness guarantees are made, and what happens when the contract is violated.
| Contract Element | What It Defines | How Agents Use It |
|---|---|---|
| Schema specification | Column names, types, nullability, uniqueness constraints | Agents validate queries against the schema before execution |
| Semantic definitions | Business meaning of each column and metric | Agents disambiguate terms like 'revenue' or 'active user' |
| Quality expectations | Acceptable null rates, value ranges, freshness SLAs | Agents check quality before using a table as a source |
| Relationship rules | Valid join paths, cardinality constraints, referential integrity | Agents construct correct joins without guessing |
| Change policies | Who can modify, what changes require review, versioning rules | Agents know when to request approval vs act autonomously |
Why Contracts Before Prompts
The Reddit consensus is clear: teams that deploy AI agents without data contracts inevitably experience one of three failure modes. The agent uses the wrong table because there is no authoritative mapping of business concepts to technical assets. The agent applies incorrect business logic because the rules are not documented anywhere machine-readable. Or the agent makes a change that breaks a downstream consumer because there is no contract defining the interface between them.
Data contracts prevent all three. When an agent has access to a contract that says 'revenue means SUM(net_amount) from finance_metrics.revenue WHERE is_recognized = true,' it cannot accidentally query gross revenue. When a contract says 'the orders table has a NOT NULL constraint on customer_id and a freshness SLA of 1 hour,' the agent knows not to use the table if customer_id contains nulls or the last refresh was 4 hours ago.
How to Write Data Contracts for AI Agents
Data contracts for human consumers can be informal — a wiki page, a README, a Slack message. Data contracts for AI agents must be structured and machine-readable. Agents cannot interpret prose reliably. They need explicit, unambiguous specifications that they can evaluate programmatically.
- •Use schema definition languages. YAML, JSON Schema, or Protobuf definitions that agents can parse directly. Tools like Soda Core, dbt contracts, and Great Expectations provide schema definition frameworks that agents can consume.
- •Define every metric explicitly. Do not rely on column names to convey meaning.
amountcould mean gross, net, or recognized revenue. The contract should specify the exact calculation:SUM(orders.amount) WHERE status = 'completed' AND is_deleted = false. - •Specify valid join paths. Do not let agents discover joins by matching column names. Explicitly define which tables can be joined, on which keys, with which join types. This prevents the class of errors where an agent joins on a name collision that is not a real relationship.
- •Include negative constraints. Tell agents what NOT to do: 'Never join users directly to transactions — use the bridge table.' 'Never aggregate this column — it is already a pre-computed aggregate.' Negative constraints prevent the most dangerous category of plausible-but-wrong agent actions.
- •Version your contracts. Contracts change as schemas evolve. Version them alongside your code so that agents always reference the current version. Data Workers' MCP integration allows agents to pull the latest contract version automatically.
Data Contracts as Agent Guardrails
Once data contracts exist, they serve as runtime guardrails for every agent action. Data Workers' agents validate every query, transformation, and modification against the relevant data contracts before execution. This is not a best-effort check — it is a hard gate. If an agent-generated query violates a contract constraint, it does not execute. The agent either corrects its approach or escalates to a human.
This fundamentally changes the risk profile of AI agent deployment. Without contracts, you are relying on the agent's judgment — which is fallible. With contracts, the agent's judgment is bounded by explicit constraints — and violations are caught before they cause damage. The contract becomes the source of truth that the agent cannot override.
Implementing Contract-First AI in Practice
The practical challenge is that most organizations do not have comprehensive data contracts. Starting from zero, the recommendation is to build contracts incrementally, starting with your most critical data assets — the ones where agent mistakes would cause the most damage.
- •Start with your top 10 tables. Identify the 10 tables that appear most frequently in stakeholder questions and executive dashboards. Write contracts for these first.
- •Use AI to draft contracts. Ironically, AI agents are excellent at drafting initial data contracts by analyzing schemas, query patterns, and existing documentation. Data Workers' Catalog Agent can generate draft contracts that humans then review and refine.
- •Integrate contracts into CI/CD. When a contract changes, automatically validate that all dependent queries, models, and agent configurations still comply. Treat contract violations like failing tests — they block deployment.
- •Evolve contracts with feedback. When an agent makes a mistake, add the constraint that would have prevented it to the relevant contract. Over time, your contracts become a comprehensive encoding of your data team's hard-won operational knowledge.
The Contract-Agent Virtuous Cycle
The most powerful aspect of defensive programming with AI agents is the feedback loop. Agents that operate within contracts generate structured data about contract violations, edge cases, and constraint gaps. This data feeds back into contract refinement, which makes agents more reliable, which generates more structured feedback. Over time, the system converges on a comprehensive, battle-tested set of data contracts that encode your organization's complete data knowledge.
This is the inverse of the typical AI deployment pattern, where teams start with prompts and add guardrails reactively after incidents. Defensive programming starts with guardrails and lets agents operate freely within them. The result is faster time to value, fewer incidents, and a monotonically improving system. Teams using this approach with Data Workers report 60-70% auto-resolution rates within weeks of deployment, not months, because the contracts give agents the boundaries they need to act confidently and correctly.
Defensive programming for AI data agents is not about limiting what agents can do — it is about ensuring they do it correctly. Write your data contracts before your prompts. Define the boundaries before you deploy the automation. The investment in contracts pays for itself immediately in reduced incidents, faster debugging, and higher agent accuracy. Book a demo to see how Data Workers uses data contracts as guardrails across its 15-agent swarm. Read more about production-safe AI deployment on the Blog.
Go from data platform to
agentic platform.
With autonomous AI agents working across your entire data stack — MCP-native, open-source, deployed in minutes.
Book a Demo →Related Resources
- How to Use Claude Code with dbt for Enhanced Data Engineering — Learn how to integrate Claude Code with dbt to enhance your data engineering workflows. Follow ou…
- Using Claude Code for Automated Data Lineage Tracking — Learn how to implement automated data lineage tracking using Claude Code, an essential skill for…
- Claude Code Data Quality Management Tutorial — Learn how to use Claude Code for data quality management in this step-by-step tutorial, focusing…
- Claude Code Data Observability Tutorial — Learn how to use Claude Code for improved data observability in this comprehensive tutorial, enha…
- Using Claude Code for Data Cataloging: A Step-by-Step Guide — Learn how to use Claude Code for data cataloging with our step-by-step guide, enhancing your data…