A model, a loop and some tools
An agent is a language model that can ask your code to do things, in a loop, until it has an answer. Step through one call at a time, watch the context grow, and find out who actually decides when it stops.
This track is about building an agent: the moving parts, which part does what, and which of those parts you control.
Start with the uncomfortable fact. A language model can’t do anything. It reads text and writes text. It can’t open a file, look up an invoice or send an email. What it can write is a request: “please call find_invoice with 1042”. Your program reads that request, runs the real function, and pastes the result back into the conversation. Then it asks the model again.
Anthropic’s tool-use docs describe exactly that split. The model “determines when to call a tool based on the user’s request and the tool’s description”, and returns “a structured call that your application runs”. When the model wants a tool, the response says so with a stop reason of tool_use; your code runs the operation “and sends back a tool_result”.
So an agent is three things:
- A model, which only ever decides: call this tool with these arguments, or answer.
- Tools, which are ordinary functions you wrote, with a name and a description the model can read.
- A loop, also code you wrote, that runs the model, runs the tools it asks for, and decides when enough is enough.
- A person gives the model a task. The model reads it - plus its instructions and the descriptions of every tool it has.
- The model writes a tool call. That is all it can do: describe what it wants done.
- Your code runs the real function and adds the result to the conversation. The model keeps no memory, so its next call reads the whole conversation again.
- Eventually the model writes an answer instead of a call. Or the loop - your code again - stops it first.
Run one
The agent below has three tools and one question about an overdue invoice. Its “model” is a simulation: a short set of rules (listed in the next lesson’s widget, under “How this simulated model decides”), that picks tools the way a real model does, by reading their descriptions. No AI is called and nothing leaves your browser. What you see is the real shape of the loop, one model call at a time.
The pattern has a name
Write a run out as plain text and you get the shape the 2022 ReAct paper made famous. It had models write “reasoning traces and task-specific actions in an interleaved manner”, and letting them look things up (through a simple Wikipedia API) made them invent fewer facts. Most agents today still run some version of it:
- Think. The model writes what it’s trying to do next.
- Act. It writes a tool call in a fixed format.
- Observe. Your code runs the tool and pastes the result into the conversation.
- Repeat until the model answers, or the loop stops it.
An illustrative trace (the search result is written for the example, not real output):
GOAL: How tall can a bamboo plant get in a week?
THINK I need a growth rate. Let me search.
ACT search("fastest growing bamboo rate per day")
OBSERVE "...some species have been measured growing close to a metre a day..."
THINK Roughly a metre a day, times 7 days. I should say it's an upper bound.
ACT calculator("0.9 * 7")
OBSERVE 6.3
ANSWER Under ideal conditions, a fast species could grow around 6 m in a week -
an upper bound; most bamboo grows far more slowly.
Every THINK, ACT and ANSWER line is the model writing tokens. Every OBSERVE line is the outside world being pasted in - which is exactly where the tools lesson finds its biggest danger.
The context only grows
Look at the bars beside the trace. Every model call reads everything so far: the instructions, the tool definitions, the task, every tool call and every result. The model doesn’t remember the last call. It is handed the whole transcript again.
Two costs follow from that:
- Money. You pay for every token every call reads. Tool definitions count too: the docs list “tool names, descriptions, and schemas” as part of the input, plus a fixed tool-use instruction the API adds (286 tokens on Claude Opus 5.5). A ten-step run pays for its early steps ten times. The “tokens read in total” counter shows the sum.
- Attention. A long, cluttered context is harder for the model to use well, which is one more reason to give an agent fewer, clearer tools and shorter results. Text becomes tokens covers what a token is.
Who decides when it stops
The model ends a run only one way: by answering. Nothing in the model says “this is taking too long” or “I’ve spent enough”. A confused model can call tools forever.
So the loop needs its own limits, written in plain code the model can’t talk its way around: a maximum number of steps, a time limit, a spending cap. Anthropic’s guidance on building agents recommends “extensive testing in sandboxed environments, along with the appropriate guardrails”, and a step limit is the first of them.
Take away its tool for counting days, too. A good agent says what it couldn’t do instead of guessing. Real models don’t always manage that, which is why the next lessons put checks outside the model rather than trusting its final answer.
Your agent's model replies with stop_reason tool_use and a call to find_invoice. What happens next?
For tools you define, the model only writes the request. Your application runs the function and returns the result, and the model is called again with it. (Anthropic also offers server tools such as web search that run on its side, but your own functions always run in your code.)
A run takes 10 model calls. Roughly how many times do you pay to send the original task?
The model keeps no memory between calls. Each call is sent the full transcript, so early content is paid for on every turn. Prompt caching makes repeated content cheaper, but it is still read.
Which of these actually guarantees an agent stops?
Only code outside the model is guaranteed to run. A prompt instruction is advice the model may follow; the loop's limit is a fact.
Everything above ran in your browser. Now try it in a real terminal: any Linux machine, a Mac's Terminal app, or Windows with WSL. Nothing to install beyond that.
Build the same loop for real in a few lines. You need your own API key for a hosted model, or a local model through Ollama. With Anthropic’s Python SDK (pip install anthropic, key in ANTHROPIC_API_KEY), following the tool-use docs:
import json, anthropic
client = anthropic.Anthropic()
tools = [{
"name": "find_invoice",
"description": "Look up an invoice by its number: amount, customer and due date.",
"input_schema": {"type": "object", "properties": {"number": {"type": "string"}}, "required": ["number"]},
}]
def find_invoice(number): # your code, your data
return {"number": number, "customer": "Bamboo Bakery", "due": "2026-10-12", "status": "unpaid"}
messages = [{"role": "user", "content": "Is invoice 1042 overdue? Today is 2026-10-30."}]
for step in range(5): # the step limit lives here, in your code
reply = client.messages.create(model="claude-sonnet-5-5", max_tokens=1024, tools=tools, messages=messages)
messages.append({"role": "assistant", "content": reply.content})
if reply.stop_reason != "tool_use":
print([b.text for b in reply.content if b.type == "text"], reply.stop_reason)
break
results = [{"type": "tool_result", "tool_use_id": b.id, "content": json.dumps(find_invoice(**b.input))}
for b in reply.content if b.type == "tool_use"]
messages.append({"role": "user", "content": results})
else: # runs only if the loop never hit break
print("stopped by the step limit, not the model")Print reply.usage inside the loop and watch the input tokens grow each step. This costs money on your own account - a run like this is a fraction of a cent, but check current prices first.
Sources
Missions and quizzes above earn their own XP. This marks the lesson done.