A production agent does not need a dramatic model failure to break. Sometimes the failure starts with something smaller: a tool argument is renamed, a default changes from draft to send, a field that used to mean “customer-visible note” now means “internal note,” or a required approval flag moves behind a new enum.

The JSON still validates. The tool still runs. The dashboard says the agent completed the task. But the workflow is now operating under a different contract than the one the prompt, evaluator, human approver, and incident runbook were written for.

That is the quiet risk in tool-using agents. Teams are starting to treat tools as real operating surfaces, but many still treat tool schemas like configuration text. They are not. For an agent, the tool name, description, arguments, defaults, return shape, and error behavior are part of the instruction layer. Change them casually and you have changed the agent.

The standards and frameworks are already pointing in this direction. The Model Context Protocol tools specification describes tools as model-controlled interfaces that servers expose for language models to discover and invoke. Each tool has a unique name and metadata describing its schema. MCP also includes a listChanged capability so clients can be notified when the available tool list changes. That is not a minor detail. It is an admission that the tool surface is dynamic.

Anthropic’s tool-use documentation makes the same point from the model side. Claude decides when to call a tool based on the user request and the tool’s description. For developer-defined tools, the application passes an input schema, Claude returns a structured tool_use block, and the application executes the call. In other words, the schema and description are not passive documentation. They shape behavior.

OpenAI’s Agents SDK frames an agent as a model configured with instructions, tools, and runtime behavior such as handoffs, guardrails, and structured outputs. Its agent configuration includes tools, MCP servers, guardrails, hooks, output types, tool-use behavior, and session handling. That is a broad control plane. If the tool contract shifts under it, every surrounding control can become stale.

So the practical question is not only “does this tool schema validate?” It is “which version of this contract did the agent understand when it acted?”

That version should cover more than the JSON shape. A production tool contract should include the tool name, description, input schema, required fields, defaults, units, permission scope, idempotency behavior, destructive-action class, output shape, error codes, retry rules, human approval copy, and guardrail expectations. If any of those change, the agent’s behavior can change even when the endpoint URL stays the same.

Consider a customer-support agent with a create_refund tool. Version one accepts amount_cents, reason, and draft_only. Version two adds refund_method and changes the default behavior so omitted draft_only means immediate submission. A normal backend API migration might handle that with a default and a release note. An agent migration needs more discipline. Old traces should be replayed against the new schema. New prompts should be tested against the old schema if rollback is possible. The human approval screen should show the same operational meaning the model saw. The evaluator should know whether a missing draft_only is safe, invalid, or a regression.

Without that discipline, teams end up debugging ghosts. Was the model careless? Did retrieval return stale policy? Did the user ask ambiguously? Or did the agent call a tool using a schema description that changed last Tuesday? If the trace only says create_refund was called, the answer is hard to reconstruct.

This is where telemetry becomes part of schema governance. OpenTelemetry’s GenAI semantic-convention work, now moved into a dedicated repository, reflects a broader industry push toward portable AI operation traces. For tool-using agents, those traces should include the tool contract version. Every important tool call receipt should record the tool name, schema version, server version if relevant, arguments after normalization, approval state, output schema version, and guardrail results. The goal is not bureaucracy. The goal is to make incidents explainable.

Versioning also changes how teams test. A good agent tool suite should include compatibility tests, not just happy-path examples. Run old successful traces against the new schema and confirm the agent still chooses safe arguments. Run new traces against the previous schema if rollback is part of the deployment plan. Test ambiguous fields, missing required arguments, changed units, enum expansions, removed values, permission-boundary changes, and destructive operations. If a tool can send money, update records, email customers, modify code, or trigger a vendor workflow, schema changes deserve release gates.

Deprecation needs the same seriousness. A retired tool version should not disappear silently from the model-facing list while old prompts, saved plans, or resumable sessions still reference it. There should be a migration window, a clear replacement, aliases only where safe, and explicit rejection receipts when an obsolete version is called. MCP’s listChanged pattern is useful here because it reminds implementers that tool availability can change and clients need to handle that change intentionally.

The hardest part is cultural. Engineers know how to version APIs for software clients. But agents blur the client boundary. The “client” is partly a model, partly a runtime, partly a human approval flow, partly an evaluator, and partly a set of old traces that might be replayed next week. That makes informal schema edits dangerous. A one-line description change can be equivalent to changing an endpoint contract if the model starts selecting the tool differently.

A small rollout is enough to start. Pick the ten tools with the highest business risk. Add an explicit contract_version to each tool descriptor and trace. Write a changelog for model-facing changes, not just backend changes. Create a compatibility test pack from real successful and failed runs. Require approval for changes to descriptions, defaults, permissions, and destructive-action behavior. Emit a receipt whenever an agent calls a tool through an alias or deprecated version. Make rollback expectations explicit.

Then connect schema versions to incidents. When a workflow fails, the postmortem should be able to say: this agent used create_refund contract 2.1.0, with approval template 4, output schema 3, and guardrail policy 7. The failure happened after the enum migration, before the evaluator update, and only in sessions resumed from the old planner. That is the level of detail that turns “the AI did something weird” into an engineering problem.

The next generation of reliable agents will not be separated only by model quality. It will be separated by interface discipline around the model-facing tool surface.

Prompts tell agents what to try. Tool schemas tell them what the world can do. If those schemas are unversioned, the agent is operating on vibes. If they are versioned, tested, traced, and deprecated with care, they become something better: a contract the whole system can trust.

Build AI Systems That Survive Contact With Real Work

We help teams turn AI research into practical automations, agent workflows, and operational systems that can be evaluated and improved.

Get the Field Guide — $10 →