Skip to content

One prompt, many requests

In the last lesson you watched a toy agent work through a task step by step. Nobody typed anything between those steps, and yet the model was called again at every one of them. This lesson slows the loop down to single calls. You follow one prompt through every call it caused and see what is sent to the model each time and what comes back. Then you learn why the model needs the whole history again on every call. By the end you can read an agent’s log and count the calls a prompt cost.

Here is the first transcript from the last lesson again.

task: Which meeting note mentions the June delivery?
1. model: call list_dir with path "notes"
loop: ran list_dir, result: 2026-03-14-lantern.txt, 2026-03-21-budget.txt, 2026-03-28-lantern.txt
2. model: call read_file with path "notes/2026-03-14-lantern.txt"
loop: ran read_file, result: Project Lantern, 14 March. Sensor boards moved from April to June. Ana confirms the date by Friday.
3. model: done. The note of 14 March: the sensor boards moved from April to June.
loop: stopped, the model said it is done after 3 steps

A person asked one question. Behind it, the software around the model called the model three times, once for each model: line. Each of those calls is a model request: the software sends the model one package of text, and the model sends back one reply [1]. A request ends when its reply comes back. If the reply asks for a tool, the software runs it, and the result goes to the model in the next request. If the reply asks for nothing, the run is over [2].

Each request, with its reply and the tool run that follows, is one turn of the loop, the same turn you labeled observe, think and act in the last lesson. Step 3 had no act, but it was still a request, because the model had to be asked before it could write its answer.

The software that sends the requests and runs the tools is called the harness. The last lesson called it the loop. The next lesson shows what else it holds, and in this lesson it does two jobs: it sends each request, and it carries out the tool requests that come back.

A reply can ask for more than one tool at once [2]. A model that needs three files can ask for all three in one reply. The harness then runs all three and sends the three results back together, in one new request. So the number of tool calls and the number of requests are often different.

In a log, the rule for counting is this: after the first request, a new request starts only when the harness has something new to send, which is the results of the tools it just ran. Model lines with no harness line between them came in the same reply. Count the replies, and you have counted the requests.

Checkpoint · choice

How many model requests did this prompt cause?

prompt: What did we spend on travel in September?
model: call search_files with query "travel invoice September"
harness: ran search_files, result: inv-0912-train.txt, inv-0918-hotel.txt, inv-0925-taxi.txt
model: call read_file with path "inv-0912-train.txt"
model: call read_file with path "inv-0918-hotel.txt"
model: call read_file with path "inv-0925-taxi.txt"
harness: ran read_file three times, results: train EUR 84.00, hotel EUR 236.50, taxi EUR 31.20
model: done. Travel in September came to EUR 351.70 over three invoices.

A transcript shows what the model wrote and what the tools returned. It doesn’t show what was in each request. Here is the same toy run again, written as the harness’s own log of what it sent. This log was written for this lesson to show the contents, and a real harness records more detail, such as the exact text of every part.

prompt: Which meeting note mentions the June delivery?
request 1
harness sent: instructions, tool descriptions (list_dir, read_file),
history: the prompt
model replied: call list_dir with path "notes"
harness ran list_dir, and the folder returned 3 file names
request 2
harness sent: instructions, tool descriptions (list_dir, read_file),
history: the prompt, reply 1, result 1
model replied: call read_file with path "notes/2026-03-14-lantern.txt"
harness ran read_file, and the folder returned the text of the note
request 3
harness sent: instructions, tool descriptions (list_dir, read_file),
history: the prompt, reply 1, result 1, reply 2, result 2
model replied: done. The note of 14 March: the sensor boards moved from April to June.
no tool was asked for, so the harness stopped the run

Each request holds the instructions, the tool descriptions and the history [2]:

  • The instructions. The standing text the model reads before the task, the system prompt from earlier in this course. It is the same in every request.
  • The tool descriptions. The name, purpose and parameters of each tool, as in the last lesson. They are also the same every time.
  • The history. The prompt, followed by every reply the model wrote and every result that came back, in order. This is the part that grows. Request 1 has one item in its history, request 2 has three, and request 3 has five.

In the Messages documentation, the history is a list of messages that alternate between the person’s side and the model’s side, and a tool result goes back on the person’s side, in the message after the reply that asked for it [1]. The harness writes that list. The person typed only the first item in it.

Look at request 3 again. To write its answer, the model needs the text of the 14 March note. It read that note in request 2. So why does the harness send the note again?

Because the model keeps nothing from one request to the next. It is a stateless model: each request is answered from what is in that request and from what the model learned in training, and from nothing else. The Messages documentation calls a conversation of many messages stateless, and the caller passes the earlier messages in again with each new request [1]. In request 3 the model “remembers” the note only because the note is in the history the harness sent.

The requests get bigger as the run goes on. The history in each request holds everything so far. A long session sends a long history on every call. The context keeps growing over the turns of a session, and nothing clears it between turns [2]. The token-cost lessons later in this course build on this point.

The harness decides what the model knows. If the harness leaves something out of the history, the model has never seen it, as far as that request goes. When a session gets too long, a harness may replace the oldest part of the history with a short summary, and a detail from early on can be lost in that summary [2].

What looks like the agent’s memory is text that the harness keeps and sends again. Clear the conversation, and from the next request on the model knows nothing of it.

Checkpoint · choice

In its third request the agent wrote “Travel in September came to EUR 351.70”, which includes the EUR 236.50 hotel invoice it read in the second request. How did the model have that amount when it wrote the total?

Every step of a run is done by the model, the harness or the environment. The model chooses: it writes a reply, which is either a request for a tool or an answer. The harness carries out: it sends the requests, checks whether a tool call is allowed, and runs the tool. The environment is what the tools act on: the files, programs, services and data within the agent’s reach. When a tool runs, the change happens in the environment, and what the environment returns is the tool’s result.

In the toy run, the model chose to list the folder and then to read one note. The harness sent three requests and ran two tools. The environment was the folder of notes, which returned three file names and then the text of one note.

The permission check is part of the harness. When the harness refuses a tool call, nothing reaches the environment, and the harness sends the refusal back to the model as that tool’s result [2]. The model reads the refusal like any other result. It usually tries something else, or tells the person the step could not be done.

The three parts go wrong in different ways, so naming the part tells you where to look. A poor choice of file is the model’s. A tool call that should have been refused and wasn’t is the harness’s. A file that was missing or out of date is the environment’s. The environment is also where a mistake does its damage, which is why a copy of a folder is a safer place for an agent than the folder itself.

Checkpoint · sort

Exercise

Here is the log of one prompt to an agent with three tools: list_dir, move_file and send_message. The harness asks the person before it sends a message, and the person said no. On paper or in a note, write how many model requests the prompt caused. Then write one line per request: what the harness sent, what the model replied, and what came back from the environment, or “nothing” when nothing did. Ten minutes is enough.

prompt: Put the October newsletter draft in the shared folder and tell Mia it is there.
request 1
harness sent: instructions, tool descriptions (list_dir, move_file, send_message),
history: the prompt
model replied: call list_dir with path "drafts"
harness ran list_dir, result: newsletter-oct.txt, newsletter-sep.txt
request 2
harness sent: instructions, tool descriptions (list_dir, move_file, send_message),
history: the prompt, reply 1, result 1
model replied: call move_file from "drafts/newsletter-oct.txt" to "shared/newsletter-oct.txt"
harness ran move_file, result: moved
request 3
harness sent: instructions, tool descriptions (list_dir, move_file, send_message),
history: the prompt, reply 1, result 1, reply 2, result 2
model replied: call send_message to "Mia" with text "The October newsletter draft is in the shared folder."
harness asked the person, the person said no, result: the person declined this message
request 4
harness sent: instructions, tool descriptions (list_dir, move_file, send_message),
history: the prompt, reply 1, result 1, reply 2, result 2, reply 3, result 3
model replied: done. The draft is now in shared/newsletter-oct.txt. I did not message Mia, because you declined it.
no tool was asked for, so the harness stopped the run

A good result says the prompt caused four requests. In request 1 the drafts folder returned two file names, and in request 2 the file moved and the folder reported it. In request 3 nothing came back from the environment: the harness refused the call, and the “declined” result is the harness’s own text. In request 4 nothing came back either, because the model asked for no tool. Each line also notes that the instructions and the tool descriptions were the same every time, and that the history grew by one reply and one result per request. When you are done, ask yourself: the model wrote “because you declined it” in request 4, so where did it learn that, if it keeps nothing between requests?

Stretch: Rewrite request 4 as it would be if the harness had sent only the prompt and the last reply and result as its history. What would the model know, and what could its answer say?

Recap

  1. One prompt to an agent usually causes several model requests. Each request is one call to the model and gets one reply, and a new request follows each batch of tool results until a reply asks for no tool [2].
  2. A reply can ask for several tools at once, so count requests by the replies, not by the tool calls.
  3. Every request carries the instructions, the tool descriptions and the whole history so far, and only the history grows.
  4. The model is stateless. It keeps nothing between requests, so it knows an earlier step only because the harness sent it again [1].
  5. The model chooses, the harness sends the requests and checks and runs the tools, and the environment is what the tools act on. Name the part to know where to look when a step goes wrong.

You can now

  • Follows one prompt through its model requests and names the part of the agent behind each step

  1. Anthropic. Messages. Claude Platform documentation. Reference. Claude docs messages
  2. Anthropic. How the agent loop works. Claude Code documentation. Reference. Claude Code agent loop