Guide

Treat tool descriptions as prompts. Vague names and one-line descriptions are the most common cause of wrong tool choice. The model does not see your source code. It sees the name, the description, the parameter schema and prior turns.

Concept

Before you start: a tool definition is a contract. Write it the way you would write a CLI README for someone who is literal and has never opened your repo.

Name, description, parameters

Name. Prefer verbs that say what happens: get_order, search_help_docs, create_refund. Avoid synonyms that overlap (fetch_order vs get_order).

Description. Several sentences: when to use it, when not to use it, what it returns, and known limits. Models are surprisingly literal.

Parameters. Use JSON Schema with types, required fields, enums where values are closed, and per-property descriptions. Put format hints in the description ("Order ID, e.g. ORD-12345"), not only in the type.

TypeScript
const getOrder = {
  name: "get_order",
  description:
    "Look up a single order by ID. Returns status, line items, tracking URL and " +
    "estimated delivery. Use when the user mentions a specific order ID. " +
    "Do not use for browsing history—use search_orders instead. " +
    "Returns {error: 'not_found'} if the ID does not exist.",
  input_schema: {
    type: "object",
    properties: {
      order_id: {
        type: "string",
        description: "Order ID shaped like ORD-12345",
      },
    },
    required: ["order_id"],
  },
}

Keep the tool set small and distinct. Five sharp tools beat fifteen overlapping ones. If two tools differ only by a flag, make it one tool with a parameter.

Example

A support bot had both get_customer and lookup_user. On "What's Jane's email?", the model flipped between them across runs. Merging into one get_customer with clear filters cut wrong-tool rate from ~18% to under 3% on a 200-case eval set.

A 200-token tool definition × 8 tools is 1,600 tokens on every request before the user message. Descriptions that ramble cost money. Descriptions that omit "when not to use" cost wrong calls. Budget both.

When you change a description, treat it like an API change: bump a prompt/tool version, run the trajectory suite, and only then roll out. Silent edits to production tool text are a classic "who broke tool selection?" incident.

Common mistakes

  • Synonym pairs. fetch_order and get_order will be flipped at random.
  • One-line descriptions with no "when not to use."
  • Optional fields that are actually required, so the model invents parameter names it saw in training.

Check yourself

  1. Why did merging get_customer and lookup_user cut the wrong-tool rate? The model no longer had two overlapping names to flip between.
  2. Where does "ORD-12345" belong — type or description? In the description. The type only says string.

Key takeaways

  • Tool descriptions are prompts. Write when, when-not, formats and limits.
  • Prefer a small set of distinct names. Merge synonyms.
  • Schema fields need types, required lists and per-property descriptions.
  • Version tool text the way you version an API.

Further learning

Writing effective tools for agents (Anthropic)Writing effective tools for AI agents—using AI agentsanthropic.com

Next, how those tools should behave at the interface: designing tools.