Addaly is in open beta. Things will change, and AI answers can be wrong — check anything that matters.

A tool call is a request, not an action

Agents and Automation · lesson 2 of 8 · 7 min

The model does not do anything

This is the single most useful thing to internalise, and it is not obvious from the marketing. When you "give a model a tool," the model gains no new powers. It gains the ability to *ask*.

You send the model a list of tool definitions. The model replies with a structured block that names one and supplies arguments. Your code then runs whatever that name maps to — an HTTP call, a SQL query, a shell command — and sends the result back as another message. The model never reaches the network. It only ever produces text and reads text.

A tool definition looks like this. The exact JSON differs slightly between providers; the shape does not.

json
{
  "name": "get_order",
  "description": "Look up one order by its ID. Returns status, items, amount paid and refund eligibility. Use only when you have an order ID like ORD-48213. If you only have a customer email, call find_orders_by_email first.",
  "input_schema": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "Format ORD- followed by five digits. Not an email, not an invoice number."
      }
    },
    "required": ["order_id"]
  }
}

The description is the interface

Engineers treat the schema as the important part and the description as a comment. It is the other way round. The schema constrains the shape of the arguments. The description is the only thing that tells the model *when* to reach for this and when not to.

Compare:

  • Weak: "Gets an order."
  • Strong: the version above, which says what comes back, what identifier it needs, and what to do instead when you have the wrong identifier.

Tool descriptions are prompt. They are read on every single call. Writing a good one is the cheapest quality improvement available to you, and it takes ten minutes.

Errors are feedback, and they must be readable

When a tool fails, the model sees exactly one thing: whatever string you put in the result. That string is its entire understanding of what went wrong.

python
# Useless. The model learns nothing and will try again.
return "Error: 500"
return "[]"

# Useful. The model can act on this.
return "No order found with id 'arjun@example.com'. That looks like an \
        email address. Order IDs look like ORD-48213. Try find_orders_by_email."
return "No rows matched status='pending'. 412 orders exist with other statuses."

Never let an exception propagate as an opaque failure, and never return an empty result that is indistinguishable from a successful empty result. An agent stuck in a retry loop is almost always an agent being handed uninformative errors.

Fewer tools, wider tools

Every tool definition sits in the context window on every request. Twelve well-chosen tools beat forty narrow ones, for two reasons: cost, and selection accuracy. Past roughly twenty tools in one context, teams routinely watch the model start picking plausible-but-wrong tools, and the failure is quiet — it calls something reasonable and returns a confident, incorrect answer.

So design coarse. search_orders(query, status=None, since=None) is better than list_orders, filter_orders_by_status, filter_orders_by_date and sort_orders as four separate entries. You are designing an interface for a reader with limited attention, not an API for a compiler.

One last practical note: make tools that are safe to call twice. Models retry. If send_invoice is not idempotent, a retry becomes a duplicate invoice, and duplicate invoices become a phone call from a supplier in Karachi asking why he was billed twice.

Before you move on

A support agent has a `refund_order` tool. When it is called on an order that was already refunded, the underlying code raises, and the harness returns HTTP 500 with an empty body as the tool result. The agent then calls `refund_order` with identical arguments four more times. What most directly explains the repetition?

Pick the one you would defend. Nobody sees your answer.

No ads. No data sale. No public scores on people. Ever.

© 2026 Addaly