# The tool-use loop

> The model asks for a tool call, your code runs it and sends the result back, and the loop repeats until it answers.

Concept · Models & prompting · https://levelcode.org/concepts/tool-use-loop

A model can't query your database or call an API. It can only produce text. **Tool use**, also called function calling, lets it *request* an action: you describe tools with a name, a description and a JSON Schema for the input. When the model decides it needs one, it stops and returns a structured tool call instead of a final answer. **Your code** runs the tool and sends back the result.

```text
user: "Is order 1042 shipped?"
  → model:  tool_use get_order({"id": 1042})          (stop_reason: tool_use)
  → you:    run get_order → {"status": "shipped", "carrier": "UPS"}
  → send:   tool_result for that call
  → model:  "Yes — order 1042 shipped via UPS."         (stop_reason: end_turn)
```

## The loop

```python
messages = [{"role": "user", "content": question}]
for _ in range(10):                                   # always cap the steps
    response = client.messages.create(model=MODEL, max_tokens=1024, tools=TOOLS, messages=messages)
    messages.append({"role": "assistant", "content": response.content})
    if response.stop_reason != "tool_use":
        break                                         # final answer
    results = [
        {"type": "tool_result", "tool_use_id": block.id, "content": run_tool(block.name, block.input)}
        for block in response.content if block.type == "tool_use"
    ]
    messages.append({"role": "user", "content": results})
```

The model may ask for several tools in one turn. Run them, in parallel if they're independent, and return every result. That loop, given a goal and run until it finishes, is an [agent](https://levelcode.org/roadmaps/ai-engineer/agents).

## Designing tools

- **Descriptions are prompts.** Say what the tool does, when to use it, what each parameter means, and what it returns. Most "the model picked the wrong tool" bugs are description bugs.
- **Make tools few and task-shaped.** `search_orders(customer_email, status)` beats exposing raw SQL, and five clear tools beat thirty overlapping ones.
- **Return compact, useful results.** Large payloads fill the [context window](https://levelcode.org/concepts/context-windows). Return what the model needs plus an ID it can use to fetch more.
- **Return errors as results.** "No order with id 1042" lets the model recover. Throwing ends the loop.

## Safety

- **Validate tool input like any untrusted input.** The model's arguments are only well-formed if you check them; [structured outputs](https://levelcode.org/concepts/structured-outputs) can enforce the schema.
- **Apply [least privilege](https://levelcode.org/concepts/least-privilege).** Use read-only tools by default, scoped to the current user's data.
- **Require confirmation for anything irreversible**, like sending, paying or deleting, because text the model reads can carry instructions. See [prompt injection](https://levelcode.org/concepts/prompt-injection).
- **Cap steps, tokens and time,** and log every call.
