agent loops — tool_use and the request/tool/respond cycle3 / 9
stop_reason, tool_use, tool_result — the loop every agent runs
The tool_result reply has to match the tool_use it answers
Once the model returns a tool_use block, your loop runs the actual
tool, then sends the answer back as a new user turn — with a
tool_result block inside.
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_01", # must equal the tool_use id
"content": "72F, partly cloudy",
}
],
}
Three things to lock in:
- The role flips back to
user. Even though you are responding to the model, the protocol says your turn is the user turn. The model never directly emits its own tool results. tool_use_idis a hard link. It must exactly equal theidfrom the tool_use block. If you call the model again with a missing or wrong id, the API returns 400.- Multiple tool calls in parallel are common. The model can emit several tool_use blocks in one assistant turn (e.g. "read these three files"). Your reply must include one tool_result per tool_use_id, in any order.
What the model sees on the next round
The model now has the full transcript: the user question, its own
tool_use, and your tool_result. With that context, it usually returns a
plain text response with stop_reason == "end_turn" — "It's 72°F and
partly cloudy in Tokyo."
That's the round trip. One iteration of the agent loop.
Run the editor. We print the role of each turn so you can see the
user → assistant → user (with tool_result) shape.
⌘↵ runs the editor.
Booting Python…
Output
[promptdojo:~]$ _