# The Agent Loop: Think, Act, Observe

> An agent loop repeats a cycle until it finishes: evaluate, request a tool, receive the result and decide again. How it is limited and what to design per pass.

*Tags: ai, agents, fundamentals, api*

---


> [!info] Quick Definition
> The **agent loop** is the cycle an agent repeats until a task is finished: the model evaluates the situation, decides whether to respond or request a tool, the application runs that tool, and the result goes back to the model for the next decision.


## What happens in each pass?

According to the Claude Agent SDK documentation, every session follows five steps. First, the model receives the prompt along with the system instructions, the tool definitions and the history. Second, it evaluates the current state and responds with text, with one or more tool calls, or with both. Third, the SDK runs each requested tool and collects the results; those results go back to the model for the next decision. Fourth, steps two and three repeat until the model produces a response with no tool calls. Fifth, the SDK delivers that final response together with the result text, token usage, cost and session ID.

Each full pass is called a **turn**. A turn is not a message: it can contain several tool calls. A simple question such as "what files are here?" may take one or two turns. A task such as "refactor the auth module and update the tests" can chain dozens.

The documentation itself walks through "fix the failing tests in auth.ts". In turn one the agent runs `npm test` and sees three failures. In turn two it reads `auth.ts` and its test file. In turn three it edits `auth.ts` and reruns the tests, which now pass. In the final turn it answers with text only, no tools, and the loop ends. That is four turns: three with tools and one final text-only response.

In the Anthropic API the same cycle looks like this: when Claude wants a tool it responds with `stop_reason: "tool_use"` and a `tool_use` block. Your application runs the operation and sends back a `tool_result` block, and Claude uses that result to answer or to request another tool. More detail in [[tool-use|tool use]].

## Why is it called a loop?

Because the result of each action feeds the next decision. It is the same idea as the [[what-is-an-ai-agent|definition of an agent]]: Anthropic describes agents, essentially, as language models using tools in a loop, guided by feedback from the environment. The model does not follow a fixed script; it observes what happened and adjusts. That is why the loop is what separates an agent from a predefined chain of calls.

A simple way to think about it is in three verbs: the model **thinks** about what to do, **acts** by requesting a tool, and **observes** the result. Those verbs are a teaching simplification, not step names in the SDK. What matters is that the observation enters the context and conditions what comes next.

## What does the loop consume?

Everything that happens in the loop accumulates in the [[context-window|context window]]: instructions, history, tool calls and results. The SDK documentation notes that large tool results, such as a full file or a command with verbose output, can consume thousands of [[tokens|tokens]] in a single turn.

The context does not reset between turns: long sessions with many tool calls build up far more context than short ones. What stays the same from turn to turn (system instructions, tool definitions, CLAUDE.md) is stored with [[prompt-caching|prompt caching]], which reduces the cost and latency of those repeated prefixes.

When the context nears its limit, the SDK compacts the conversation automatically: it summarizes older history and keeps the most recent exchanges and key decisions. Compaction replaces older messages with a summary, so specific instructions from the start may not be preserved. That is why rules that must survive belong in the instructions file (CLAUDE.md, see [[claude-md-and-agents-md|CLAUDE.md and AGENTS.md]]), whose content is re-injected on every request.

## How do you control a loop?

Without limits, the loop runs until the model finishes on its own. The SDK documentation considers that fine for well-scoped tasks, but warns that it can run long on open-ended requests such as "improve this codebase," and recommends setting a budget as a default for production agents. The usual controls are:

| Control | What it limits |
|---|---|
| Maximum turns (`max_turns`) | How many tool-use rounds it can make; the final text-only turn is not counted |
| Dollar budget (`max_budget_usd`) | The estimated spend at which the loop stops |
| Per-tool permissions | Which tools are auto-approved, which are blocked and which ask for confirmation |
| Hooks before execution | Intercept, modify or block a call before it happens |
| Reasoning effort (`effort`) | How much the model reasons in each response |

When a permission or a hook rejects a call, the model receives the rejection as the tool result and usually tries a different approach or reports that it could not continue. For approvals designed as an experience, see [[action-approval|action approval]] and [[human-in-the-loop|human-in-the-loop]].

The budget cap is not exact: the SDK compares spend after each response arrives, so the response that crosses the limit still completes and is billed. Leave some headroom.

The SDK reports how the loop ended with a subtype on the final result: `success`, `error_max_turns`, `error_max_budget_usd`, `error_during_execution` (for example, a cancelled request) and `error_max_structured_output_retries`. Only the success case carries the final text. Checking that subtype is part of designing the experience well.

## Why does it matter to a designer?

Because the loop defines the moments of the experience. There is a start (the person describes the task), one or more progress moments (what the agent has already done), a decision point (approving an action) and an end (the result or the reason it stopped). Each one needs a screen or a message.

A common mistake is designing only the end. If the loop stops because of a turn limit and the interface says "error," the person does not know whether they can continue. A good design distinguishes "finished," "stopped at a limit" and "failed."

## When is a loop NOT a good idea?

- When the steps are fixed and known. A predefined flow is cheaper and more predictable.
- When each pass costs more than it contributes. A long loop on a trivial task wastes money.
- When there is no way to stop it in time. Without limits or approval points, an error repeats.

Anthropic recommends starting with the simplest solution and adding complexity only when it improves the result.

## Example

Illustrative example: an agent is asked to fix a disabled button in a form. In turn one it finds the component. In turn two it reads the file. In turn three it proposes the change, and the system blocks it because the hook on the components folder requires approval. The agent receives the rejection as a result, explains the proposed change and stops. The person approves from the review screen, and the agent runs the loop again with permission to edit that file.

## Common mistakes

- Confusing a turn with a message. A turn can contain several tools.
- Leaving a loop without turn or budget limits on open-ended tasks.
- Designing only the final state and not the progress states.
- Believing the model remembers the whole loop. It only sees what remains in the context.
- Trusting that compaction keeps the important instructions.

## Sources

- [How the agent loop works, Claude Code Agent SDK](https://code.claude.com/docs/en/agent-sdk/agent-loop)
- [Tool use with Claude, Anthropic API documentation](https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview)
- [Building effective agents, Anthropic](https://www.anthropic.com/engineering/building-effective-agents)


---

Source: https://www.fernandoux.com/en/wiki/ai/agent-loop/
