Tool calling, also known as function calling, is the mechanism by which a language model requests that an external action be performed instead of just generating text, and it works in three steps. First, the application sends the model a list of available tools, each described with a name, a natural-language description and a JSON Schema defining its expected arguments, alongside the user's message. Second, if the model decides a tool is needed to answer the request, it returns a structured object naming the tool and the arguments to use, rather than calling the API itself; the model never has direct network access. Third, the application code executes the actual API call, database query or function, and sends the result back to the model in a follow-up message, which the model then uses to compose its final answer to the user. This loop can repeat multiple times for multi-step tasks such as looking something up, then acting on it. Nanobase AI builds this tool-calling integration and the surrounding execution, validation and logging layer for enterprise LLM deployments.

Narrow tools beat clever ones

The single biggest factor in reliable tool calling is not the model, it is how the tools are designed. A tool named manage_customer that accepts an action parameter with ten possible values and different required fields per action forces the model to make two decisions at once, which action and which fields, and errors compound. Splitting that into ten narrow tools, each with one clear purpose and a fixed set of required fields, consistently produces fewer wrong calls than one flexible tool with branching behavior, even though it means more tool definitions to maintain.

Handling multiple tool calls in one turn

Modern tool-calling models can request more than one tool call in a single response when a question naturally decomposes into independent lookups, for example checking both inventory and pricing before answering "can we fulfill this order at this price." Two practical details matter here: independent calls can usually execute concurrently to reduce total latency, while calls that depend on each other's output, such as looking up a customer ID before fetching that customer's orders, need to run sequentially with the first result fed back to the model before it issues the second call. Getting this ordering wrong either serializes calls that could have run in parallel, wasting time, or attempts to parallelize calls that actually depend on each other, producing errors.

What a good error response looks like

Response typeWhat the model receivesWhat the model can do next
Silent failure or crashNothing, or a raw stack traceNothing useful; often invents an answer
Generic error string"An error occurred"Apologize, but cannot self-correct
Structured error with reasonField-level validation message, e.g. "order_id not found"Ask the user to confirm the ID or try a corrected value
Structured error with suggestionValidation message plus a hint, e.g. "did you mean order 10234?"Retry with the corrected argument directly

Returning a structured, specific error is what turns a failed tool call into a recoverable conversation turn instead of a dead end or a hallucinated answer.

A full multi-step tool-calling loop

  1. The application sends the user's message plus the list of available tools to the model.
  2. The model responds with either a direct text answer or one or more structured tool calls.
  3. The application executes each call against the real system and collects results, including any errors.
  4. Those results are appended to the conversation and sent back to the model.
  5. The model either issues another round of tool calls, if the first results revealed a new need, or produces a final answer.
  6. The application enforces a maximum number of loop iterations to prevent an agent from looping indefinitely on a task it cannot complete.

Step 6 is easy to skip in a prototype and expensive to skip in production, since a model stuck retrying a failing tool call with slightly different arguments each time can run up inference costs quickly without a hard iteration cap.

Frequently asked questions

Does forcing the model to use a specific tool help reliability?

Yes, most tool-calling APIs support constraining the model to call a particular tool or to choose from a restricted subset, which is useful when the application already knows, from prior context or a menu selection, which category of tool is relevant, removing an entire class of wrong-tool-selection errors.

How many tools can a model reliably choose between?

This degrades gradually rather than at a hard cutoff, but past roughly fifteen to twenty tools with overlapping purposes, selection accuracy tends to drop noticeably. Grouping related tools under a single entry point with sub-parameters, or splitting them across separate agents with narrower toolsets, both help at that scale.

Should tool results be shown to the user or only to the model?

Typically both, but not identically. The raw structured result goes to the model to reason over, while the user usually sees the model's synthesized explanation rather than raw JSON, unless the product specifically benefits from showing the underlying data, such as a table result.

How Nanobase AI helps

Nanobase AI builds the full tool-calling loop described here, including schema design, parallel and sequential call handling, structured error responses and iteration limits, as part of every enterprise LLM integration it delivers rather than leaving these details to a first prototype. The transport layer that often carries these calls in multi-client deployments is covered in how-does-mcp-server-work.

Ready to discuss your project? Contact Nanobase AI or email hello@bumu.tech.