The Agent Loop
7 min read
Understand the perceive-think-act cycle that drives every LLM agent and why it differs from a single model call.
A language model call is stateless: you hand it a prompt and it returns a response. An agent is different — it runs in a loop, using each model output to decide what to do next, taking actions, observing results, and continuing until it reaches a stopping condition. This loop is the foundation of all agentic systems.
The perceive-think-act cycle
Each iteration of the loop follows three steps. First, the agent perceives its current state — the task description, prior observations, and any new information from the environment. Second, it thinks — the model reasons about what action to take next. Third, it acts — it executes the chosen action (calling a tool, writing a file, querying a database) and observes the result, which becomes input to the next iteration.
- Perceive: gather current context — task, memory, tool results, and observations
- Think: model reasons and selects the next action to take
- Act: execute the action and capture its output as a new observation
- Repeat: feed the observation back in; check stopping condition
A minimal agent loop
def run_agent(task: str, tools: dict, max_steps: int = 10) -> str:
messages = [{"role": "user", "content": task}]
for _ in range(max_steps):
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
)
msg = response.choices[0].message
messages.append(msg)
if msg.tool_calls:
for call in msg.tool_calls:
result = dispatch_tool(call.function.name, call.function.arguments)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result,
})
else:
return msg.content # no tool call means the agent is done
return "max steps reached"Stopping conditions
Without a reliable stopping condition, an agent can loop indefinitely. The most common approach is to treat a model response without a tool call as a signal that the agent believes the task is complete. Additional guards include a hard step limit, a time budget, and an explicit 'done' tool the agent can invoke when it is confident the objective is satisfied.
Never run an agent loop without a maximum step limit. Models can get stuck in tool-call cycles — for example, if a tool keeps returning errors — and without a ceiling you will exhaust your budget or block indefinitely.
Log the full message list at each iteration during development. Seeing exactly what the model received and returned at each step is the single most useful debugging tool for agent systems.