Every tool-calling system, regardless of provider, runs the same loop. Memorize the steps once and the rest of this quest is a series of decorations on top.
- You define tools. Each tool has a name, a one-sentence description, and a JSON Schema describing its arguments.
- You call the model with a user message and the tool list. The model sees both the question and the menu of actions available.
- The model decides. It either answers in text (no tool needed) or returns a structured tool-call object specifying name and arguments.
- You execute the tool in your code (the model never runs anything itself), then send the result back as a new message in the conversation.
- You call the model again. It either calls another tool, calls the same tool with different arguments, or finishes with a text answer.
Step five is where new builders get tripped up. The loop continues until the model emits a "I'm done" stop reason — usually end_turn for Anthropic, stop for OpenAI, STOP for Gemini. You do not decide when to stop; you read the stop reason and react. Hard-coding "always loop three times" or "stop after the first tool call" produces agents that either finish too early or hang forever.
The other gotcha is conversation construction. Tool results are first-class messages in the transcript — the model sees them on the next turn the same way it sees user messages. If you forget to append the assistant's tool-call message and the tool result, the next call looks like the question never had a tool call attached, and the model will happily call the same tool again. Round-trip discipline matters.