AI & Technology

Why Your AI Agent Needs a Typed Contract, Not a Blank API Key

BY SREEKANTH RAMAKRISHNAN

The biggest source of failure in production AI agents is often not the model. It is what happens after the model decides to act. The agent retrieves the wrong record, calls an operation that was never meant for it, or misreads a parameter. The uncomfortable result is that highly capable models fail at fairly simple operational tasks. 

Consider a customer support agent processing an order modification. The API accepts a discount as a decimal, so 0.05 means five percent. The agent, reading a user who said “5% off,” submits 5. The request is valid. It succeeds. It also applies a 500 percent discount. The model did not fail because it lacked reasoning. It failed because the contract between the model and the system left room for interpretation, and the model interpreted.

This is the layer most teams overlook. The conversation about agents tends to focus on model selection, prompting, and orchestration. A large share of production failures happen somewhere else: at the boundary between the model and the systems it touches. That boundary is a contract, and most agents are handed one that barely exists. Giving an agent a broadly defined API is like handing it a key to a building it has never visited, with no map and no list of rooms it is allowed to enter.  

GraphQL offers one clear illustration of the alternative, so I will use it as an example. But the argument is not about GraphQL. It is about what typed, self-describing contracts do for agent reliability, and why this layer deserves more attention than it gets.  

The contract problem hiding in plain sight 

An agent working with an API needs to know three things: what operations exist, what each one accepts, and what it returns. In a REST API, that lives in an OpenAPI spec, if someone wrote one, or in documentation, if someone kept it current. Neither is reliable at runtime. The API may have changed, the spec may lag behind, and the agent has no way to tell which.  

This is not theoretical. LangChain’s 2024 industry data found that average workflow complexity in production AI systems nearly tripled in a single year, from 2.8 steps per session to 7.7. As agents take on harder tasks, the number of API interactions grows, and every interaction is a place where a stale or underspecified contract can cause a failure. 

GraphQL’s core design idea, from Facebook’s engineering team in 2012, is that the schema is the contract. Not a document describing it, but the schema itself, embedded in the server, queryable at runtime, and derived from the implementation rather than from a file that might be out of date. An agent can ask “what can I do here?” and get a complete, typed answer. That property is what matters, and it is not unique to GraphQL. The question is what the agent is allowed to do with it. 

The danger of letting agents write their own queries 

The tempting next step is to let the agent read the schema and build its own queries. This is where things consistently go wrong. 

An agent that constructs its own queries will eventually produce an expensive one. GraphQL lets a caller traverse relationships: fetch orders, and for each order, the customer, and for each customer, their full order history. A naive query can trigger cascading database calls that would never survive code review. The agent is not being reckless. It is asking for the most convenient combination of data, and nothing tells it that the combination is too costly. 

There is a correctness problem too. A large schema exposes internal structure that was never meant to be a public surface: types that exist for backend coordination, fields that mirror database layout rather than domain meaning, deprecated operations that still validate but behave unpredictably. An agent draws inferences from that structure, and some will be wrong. The pattern teams report is consistent. Agents given broad schema access start out fine, then find corners of the schema they were not meant to use, and eventually call operations the system was not prepared for. 

Named operations as the actual contract 

The fix is simple to state and takes real discipline to hold. Instead of handing the agent the raw schema, give it a curated set of named operations. 

A named operation is a pre-approved query or mutation for a specific use case. It fixes which fields are returned, which arguments are required, and what the response contains. The agent calls the operation by name and passes arguments. It cannot change the field selection, traverse relationships that the operation did not expose, or discover capabilities beyond the defined set. 

The contrast is the whole point. In the open model, the agent receives the entire schema, full introspection, and unlimited query construction. In the named model, it receives a short list of operations, explicit inputs, approved outputs, and whatever authorization controls already exist. The first optimizes for the agent’s convenience. The second optimizes for the operator’s control. 

Apollo’s MCP Server takes this approach directly: each operation file becomes a tool definition, so the agent sees named tools with descriptions and input schemas. The agent calls “get order status” and receives the fields that operation defines, nothing more. Apollo noted a useful consequence. Field-level authorization, rate limiting, and query complexity analysis apply to agent requests exactly as they do to application traffic. There are no special agent endpoints and no separate trust model. That uniformity matters, because most teams building agent integrations end up creating parallel infrastructure, and parallel infrastructure is where inconsistencies and security gaps appear. 

When contract ambiguity becomes a business problem 

Once an agent operates in production, a malformed API call is rarely just a technical issue. The order that applied a 500 percent discount is a financial event, not a log line. Depending on what the agent touches, a loose contract can produce incomplete workflows, failed customer transactions, inaccurate reporting, or a compliance question someone has to answer later. 

These costs are easy to underweight during a prototype and hard to ignore once agents move into real processes. Every ambiguous failure tends to land on a human: a support escalation, a manual correction, a reconciliation at month end. As organizations push agents into more critical work, contract quality stops being an engineering preference and becomes an operating concern. 

Typed contracts also draw boundaries that can be audited and enforced. A named operation answers the questions anyone responsible for an AI system has to answer: which actions can the agent take, who approved that list, and can a given action be traced and reproduced. A raw schema answers none of these, because the set of possible actions is whatever the agent can compose. That gap widens as agents move from advisory roles into ones that execute actions on their own. An agent that recommends a refund and an agent that issues one are governed differently, and the second only stays governable if the operations it can call are a known, reviewed set. 

Common failure patterns 

A few patterns recur when agents meet underspecified contracts. Contract drift: the API changes and the agent’s understanding of it does not. Unit ambiguity: the 5 versus 0.05 problem, where the type is right but the convention is undocumented. Over-permissioning: the agent reaches operations it was never meant to. Query explosion: the agent composes a request that is valid but far too expensive. Hidden dependencies: the agent relies on undocumented behavior that quietly changes. Each is a gap between what the agent assumes and what the contract actually guarantees. 

The broader principle: typed contracts reduce variance 

GraphQL is a case study, not a prescription. The same logic applies to any schema-first layer: OpenAPI-specified REST endpoints, gRPC services defined with Protocol Buffers, and the tool schemas that protocols like Anthropic’s Model Context Protocol and OpenAI’s function calling expose to a model. What these share is the property that helps an agent. They narrow the gap between what the model might send and what the system will accept. 

The model is probabilistic. The API boundary can be deterministic. The Berkeley Function Calling Leaderboard, a benchmark for how accurately models make real API calls, found a telling case: models failed when a user said “5% interest rate” and the parameter expected 0.05. The type was correct. The unit convention was not documented. The model guessed, and the guess was wrong. Add an example to the field description showing the expected value, and the failure goes away. That is what a good contract does. It shrinks the space the model has to guess in, and a smaller space means a more reliable agent. 

The likely direction from here is APIs designed with machine consumers in mind from the start: contracts optimized not only for a developer reading docs but for an agent reading a schema, with policy-aware operations and runtime validation built in rather than bolted on. The named-operation pattern is an early version of that idea. It treats the interface, not the prompt, as the place where an agent’s behavior is constrained. 

What this means for teams building agents today

The teams that get agent reliability right are usually not the ones that found the best model. They are the ones who treated the boundary between the model and their systems as a contract to be designed on purpose. If you use GraphQL, audit what your agents actually need, define named operations, and turn off raw schema access for agent traffic. If you use REST, keep your OpenAPI spec current, keep operation IDs stable, and write error messages that tell the agent what went wrong in terms it can act on.  

The industry has spent the last few years making models smarter. The next phase of progress may depend less on that and more on making the systems around them easier to understand. Reliability shows up when a probabilistic model meets a deterministic interface. Typed contracts are one of the mechanisms that make that meeting work, and the agents that succeed in production are built on them rather than on assumptions. 

Author

Related Articles

Back to top button