Skip to main content

The Deprecation Notice Your Agent Can't Read

· 9 min read
Tian Pan
Software Engineer

When you deprecate an API for human developers, you have a whole ceremony for it. You bump the version, add deprecated: true to the OpenAPI spec, ship a Sunset HTTP header, send an email to the developer mailing list, post to the changelog, and give people six months to migrate. The signal reaches a human who reads it, files a ticket, and updates their client before the old path disappears.

Now point that same deprecation at an agent. The model calling your tool does not read your changelog. It does not subscribe to your mailing list. It never sees the Sunset header unless you deliberately put it somewhere the model looks, and even then it has no reliable habit of acting on it. The deprecation notice you so carefully authored lands in a mailbox with no reader. The agent keeps calling the old shape of the tool until the shape is gone, and then it fails — often silently, often in production, often at 2 a.m.

This is the quiet asymmetry of building tools for agents instead of people. Every discipline we built over two decades of API evolution assumes a human sits between the deprecation and the migration. Take the human out, and the entire mechanism goes dark.

The stakes are not theoretical. Practitioner surveys of production agent incidents keep landing on the same uncomfortable number: a large share of agent failures — some teams put it as high as 60% — trace back to tool and schema changes rather than the model itself. The model was fine. The tool moved, and nothing told the model.

Why the Model Genuinely Cannot Read the Notice

There are two separate failures hiding under "the agent can't read the deprecation," and they need to be untangled because they call for different fixes.

The first is a training-cutoff problem. A model's weights encode a snapshot of the world up to some date. If you deprecate a function, rename a parameter, or change a field's meaning after that date, the model has no posterior knowledge of it. An empirical study of LLMs generating code against evolving libraries found that models confidently emit deprecated API calls precisely because the deprecated version is what dominated their training data. The model isn't ignoring your notice — it never contained your notice, and it has a strong prior toward the old way of doing things.

The second failure is a context problem, and it's the one you actually control. Even a model with a perfectly current tool schema in its context window has no durable memory across sessions and no instinct to treat a deprecated annotation the way an engineer treats a compiler warning. You can hand the model a tool definition that says deprecated: true in a metadata field, and unless that deprecation is surfaced somewhere the model is forced to reckon with — the description text, the tool result, an explicit instruction — it will cheerfully keep calling the tool. A flag the model never renders into its reasoning is a flag that does not exist.

Put those together and you get the core design constraint: deprecation for agents has to travel in-band, inside the payload the model actually processes, not out-of-band in headers, docs, or dashboards a human would consult. The notice has to be part of the conversation, or it isn't a notice at all.

The Tool Schema Is a Public API Contract — Treat It Like One

Here is the reframe that fixes most of the damage. The interface your agent sees — the function name, the description prose, the input JSON Schema, and the shape of the output payload — is a public API contract. Every word of it is load-bearing, because every word of it conditions the model's behavior.

REST and gRPC teams learned this lesson the hard way over a decade: you never change the meaning of a field without changing its name or bumping the contract version. Additive changes are safe. Adding a new endpoint, a new optional parameter, a new response field — none of these break existing callers. Removing a field, renaming a parameter, changing a type, or quietly altering what a field means: those are breaking changes, and they detonate on contact.

Tool authors, being new to this, mostly haven't internalized it yet. Worse, a tool contract has a larger blast radius than a REST contract, because the description text is part of the interface. Rewording a parameter description from "the user's email" to "the user's primary contact" is a semantic change the model can act on, even though not a single byte of the JSON Schema changed. For a REST API that edit is documentation. For an agent it's a behavior change with no version bump attached.

Loading…
References:Let's stay in touch and Follow me for more thoughts and updates