Versioning and Deprecating Agent Tools Without Breaking Agents
Tool calls are a published contract consumed by models, prompts, evals, and saved agent graphs.
Search across all documentation pages
Tool calls are a published contract consumed by models, prompts, evals, and saved agent graphs.
A silent schema change looks like a model regression. Use this cheatsheet when you rename fields, tighten validation, or retire a tool.
| Change | Break risk | Safe pattern |
|---|---|---|
| Add optional parameter | Low | Document default; keep old callers valid |
| Add required parameter | High | New tool name or long dual-support with default |
| Remove / rename parameter | High | Accept both names, then new tool |
| Tighten types (string → enum) | Medium-high | Expand enums carefully; dual-parse |
| Rename tool | High | Alias old name to handler; deprecate |
| Change result field names | High | Return both shapes or version results |
| Change side-effect semantics | High | New tool (create_ticket_v2) |
| Narrow auth / permissions | Medium | Expect more AUTH errors; update prompts |
| Raise stricter validation | Medium | Better errors; watch failure rate |
| Strategy | How | When |
|---|---|---|
| Name suffix | get_order → get_order_v2 | Clear breaks; multi-agent fleets |
| Date stamp | search_docs_202603 | Infrequent freezes |
| Namespace | billing.create_invoice vs billing.create_invoice.v2 | Large catalogs |
| Schema version field | schema_version: 2 inside args | Only if runtime routes carefully |
| Facade stability | External name stable; internal rewrite | Best for minor evolutions |
Rule of thumb: models key off the tool name string. Renaming is a hard break even if the handler is identical.
currency added next to total_cents) without removing old keys.| Phase | Actions | Agents see |
|---|---|---|
| Announce | Mark deprecated in description; registry + Slack/docs | Old + new tools |
| Dual serve | Both names call compatible handlers | Prefer new in prompts |
| Steer | Prompts/system instructions mention new tool only | Old still works |
| Monitor | Metrics: call counts of old vs new | Traffic should shift |
| Remove | Drop old tool from catalog after idle threshold | New only |
| Clean | Delete dead aliases; archive schema fixtures | - |
Minimum dual-serve window: long enough to cover your slowest deployed agent config (often weeks, not hours).
DEPRECATED: prefer get_order_v2. get_order remains until 2026-09-01.
Returns legacy shape without line_items.Accept old and new argument names temporarily:
def get_order_args(raw: dict) -> int:
# Compatibility shim during deprecation
if "order_id" in raw:
return int(raw["order_id"])
if "id" in raw: # legacy
return int(raw["id"])
raise ValueError("order_id required")Alias registration:
HANDLERS = {
"get_order": get_order_v2_handler, # legacy name
"get_order_v2": get_order_v2_handler, # current
}Return dual result keys only briefly; long dual shapes bloat tokens.
Do not delete a tool until:
| Gate | Signal |
|---|---|
| Traffic | Old tool calls ≈ 0 for N days (per env) |
| Evals | Full suite green with new tool only |
| Config | No prod prompt/graph references old name (search repo + prompt store) |
| External | MCP clients / partner agents notified |
| Rollback | Re-add path documented if you must hot-fix |
Not necessarily. Version the agent contract. A backend v3 can still back get_order_v2 if the tool shape is stable.
Usually non-breaking for callers. Removing or renaming an enum value is breaking for models that still emit the old token.
Publish clear names and changelogs; clients cache catalogs. Bump names or use explicit version metadata your clients understand; verify client refresh behavior at build.
version argument?Possible but models often omit it. Prefer explicit names for majors; use version only for negotiated advanced clients.
Reintroduce the old schema under the old name, dual-serve, and hot-fix prompts. Add contract tests so it cannot recur.
Yes if agents parse fields or later tools depend on keys. Additive keys are safer than renames.
Central tool registry with owners, schemas, deprecation dates, and consumers. No ad-hoc edits on shared tools.
Yes. Text protocols break just as hard; pin protocol version strings in the system prompt and parsers.
Related: What Makes an Internal API a Good Agent Tool
Related: Wrapping a REST API as an Agent Tool
Related: Custom Tools Basics
Related: Custom Tools Best Practices
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026