What's an Agentic Loop?
In the realm of AI Agents an Agentic Loop in simple terms is a model call inside a while loop. In each iteration of the loop the model says either "run this tool for me" or "I'm done", and your code either calls the tool or exits. You can think of it like a turn based game between you and the model.
The model never executes anything, it asks. Your tool/code decides what actually runs, not the model. This is where sandboxing and permissions live.
The final answer is the response that broke the loop. You don't make a closing call to ask for a summary. The turn that came back without tool use already is the final answer.
Anthropic SDK Example
# /// script
# requires-python = ">=3.10"
# dependencies = ["anthropic"]
# ///
import anthropic
client = anthropic.Anthropic()
# Tool Declaration
tools = [{
"name": "add",
"description": "Add two numbers",
"input_schema": {
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"},
},
"required": ["a", "b"],
},
}]
# Tool Implementation
def run_tool(name, args):
if name == "add":
return str(args["a"] + args["b"])
# Initial Prompt
messages = [{"role": "user", "content": "What is 5 + 10?"}]
# The Agentic Loop
while True:
# Initial call with the prompt
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
tools=tools,
messages=messages,
)
# Agent's response (agent's turn) appended to the messages array.
messages.append({"role": "assistant", "content": response.content})
# Done: model gave a final answer instead of calling a tool
if response.stop_reason != "tool_use":
print(response.content[0].text)
break
# Otherwise: run each requested tool and send the results back
results = []
for block in response.content:
if block.type == "tool_use":
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": run_tool(block.name, block.input),
})
# The tool results are appended to messages as role: user (user's turn)
messages.append({"role": "user", "content": results})Logic Breakdown
In the above example, a total of 8 steps happen across 2 model calls and 1 tool call. Here's the run, step by step.
Setup: before the loop
- Declare the tools. tools is what the model sees. Each tool has a name, a description and a JSON schema for the input.
- Seed the conversation. messages starts with a single prompt: the user's question, "What is 5 + 10?".
Iteration 1: the model asks for a tool
- Call the model. We send the tools and the initial messages array. The model decides it needs add tool and replies with a stop_reason as "tool_use". The response from the model has a tool_use block with tool name, input & a unique id.
- Record the model's turn. The reply from the model goes onto messages as role: "assistant", unchanged. This matters because the model is stateless, it doesn't remember anything between the calls. So every call resends everthing in the messages (the conversation).
- Check the exit condition. stop_reason is "tool_use", so we don't break.
- Run the tool and send the result back. For every tool_use block, our code calls run_tool, gets the result, and wraps it in a tool_result whose tool_use_id matches the tool block's id. The tool_use_id is how the model correlates the tool call request and the result. The tool results go onto messages as role: "user". From the model's point of view, the tool result is the user's next turn because the user runs it for the model.
Iteration 2: the model answers
- Call the model again with the whole conversation so far (with tool results from the previous iteration). This time it has what it needs and replies with plain text, "5 + 10 = 15". stop_reason is "end_turn".
- Exit. The reply is appended, and since stop_reason is no longer "tool_use", we print the text and break. That reply is the final answer.
By the time the loop exits, messages holds four entries:
| # | role | content |
|---|---|---|
| 1 | user | "What is 5 + 10?" |
| 2 | assistant | tool_use: add(a=5, b=10) |
| 3 | user | tool_result: "15" |
| 4 | assistant | "5 + 10 = 15" |
The roles alternate user, assistant, user, assistant: the turn based game from the diagram.
To Summarize
An agentic loop is a model call inside a while loop:
- The model asks, your code acts. Sandboxing and permissions live in your code.
- stop_reason drives the loop. "tool_use" means run the tools and go again; anything else means done.
- The model is stateless. Every call resends the whole conversation.
- Tool results are the user's turn, matched to their request by tool_use_id.
- The reply that breaks the loop is the final answer.
Swap add for real tools and the loop stays the same.
