Inside the Agent Loop: Perceive, Reason, Act, Observe
Most agent systems look complex from the outside: tools, prompts, memory, frameworks, retries. Underneath, almost all of them run the same cycle again and again.
Search across all documentation pages
Most agent systems look complex from the outside: tools, prompts, memory, frameworks, retries. Underneath, almost all of them run the same cycle again and again.
That cycle is the agent loop: the model sees the current situation, decides what to do next, does it (often via a tool), then folds the result back into the situation before deciding again.
Agent Loop Basics walks a single turn in code-shaped terms. This page is the mental model underneath that walkthrough: what each phase is, how phases hand off, and why the loop (not a single prompt) is the real unit of agent behavior.
A plain chatbot answers once. An agent keeps going until a stop rule says it is done.
The difference is not "smarter model." The difference is a control loop around the model that can call tools and re-prompt with new evidence.
Think of one iteration as four jobs:
| Phase | Job | Typical inputs | Typical outputs |
|---|---|---|---|
| Perceive | Assemble what the model is allowed to "see" | User goal, prior messages, tool results, system policy | A context package (messages / prompt state) |
| Reason | Decide the next move | Context package + tool schemas | Plan fragment, tool call(s), or final answer |
| Act | Execute side effects or pure lookups | Structured tool call | Tool result, error, or text reply |
| Observe | Record what happened for the next pass | Tool result / environment feedback | Updated trajectory in context |
Nothing magical happens between phases. Each one is software you own (or a framework owns for you).
A useful analogy: a human researcher reading a ticket, thinking, running a query, reading the output, then deciding again. The agent loop is that same rhythm, automated with an LLM as the decision maker.
goal / user message
│
v
┌──────────┐
│ Perceive │ build context for this turn
└────┬─────┘
v
┌──────────┐
│ Reason │ model chooses tool call or final answer
└────┬─────┘
│
final? ──yes──> stop (return answer)
│ no
v
┌──────────┐
│ Act │ run tool / API / shell / retrieval
└────┬─────┘
v
┌──────────┐
│ Observe │ append result to trajectory
└────┬─────┘
│
└──> back to Perceive (next iteration)Perceive is context assembly, not sensors in the robotics sense.
On turn 1, the package usually includes system instructions, tool definitions, and the user goal. On later turns, it also includes the conversation so far and prior tool results.
What you put in (and what you omit) shapes the next decision. If a critical tool error is truncated out of context, the model may retry blindly. If policy says "never refund without approval" and that line is missing, the model cannot honor it.
Reason is the model call that chooses the next step.
That choice is usually one of:
Some stacks expose intermediate "thinking" or chain-of-thought-style traces before the structured decision. Others only show the final tool call or text. See Reasoning Traces: How Agents "Think" Before Acting.
Reasoning is bounded by the model and by the context you assembled. It is not free-floating intelligence outside that window.
Act is where side effects happen: search, database read, ticket update, code edit, browser click.
The host runtime (not the model) should execute tools. The model proposes a call; your code validates, runs, and returns a result string or structured payload.
Good act-phase design includes:
A weak act phase makes the reason phase look worse than it is. Garbage tool errors produce garbage next decisions.
Observe is writing the environment's feedback into the trajectory.
The model does not magically remember the tool call. Your loop must append something like: "tool X was called with Y; result was Z" (or the framework's equivalent message roles).
That observation becomes part of the next perceive package. This is the feedback arrow that turns a single LLM call into an agent.
Goal: "What's the open ticket count for acme-corp?"
lookup_org, count_open_tickets + user goal.lookup_org(name="acme-corp").{ "org_id": "org_9f2" }.count_open_tickets(org_id="org_9f2").14.That is one short multi-turn agent run: two tool steps plus a final answer.
Teams overload the word turn.
| Meaning | What it counts |
|---|---|
| User turn | One human message |
| Model turn | One completion from the LLM |
| Agent iteration | One pass through perceive→reason→act→observe |
| Tool turn | One tool execution inside an iteration |
When someone says "max 8 turns," ask which definition they mean. Production budgets usually cap model turns or tool calls, not human messages.
Some models can request multiple tools in one reason step. Act then fans out, observe concatenates results, and the next reason step sees the batch.
This speeds independent lookups. It complicates error handling when one of three tools fails.
LangGraph-style systems and multi-agent handoffs still implement the same feedback idea. They may split "reason" across nodes or agents, but each specialist still consumes context, acts, and returns observations.
For architecture patterns built on this loop, see the Agent Architectures section, especially ReAct and plan-and-execute pages under ../agent-architectures/.
Every iteration re-sends growing context (unless you trim or cache). Long loops burn tokens on repeated system prompts and history, not just on the "smart" new reasoning.
Design the loop for the shortest path that still gets evidence. Do not celebrate long trajectories as "more agentic."
| Loop style | Strength | Weakness | Best fit |
|---|---|---|---|
| Single model call, no tools | Cheap, simple | Cannot fetch live facts or act | Pure drafting |
| One tool then answer | Bounded cost | Fails when step order is unknown | Known lookup patterns |
| Full agent loop | Flexible multi-step work | Cost, latency, runaway risk | Ambiguous goals needing evidence |
| Plan then execute loop | Fewer wasted steps on long tasks | Bad plans need replan logic | Multi-stage workflows |
Without stops, the diagram's back-edge is infinite. Max turns, goal checks, timeouts, and user cancel are first-class design, not afterthoughts.
See Stopping Conditions: How an Agent Knows When It's Done.
A controlled cycle that lets a model repeatedly see state, decide, use tools, and incorporate results until a stop condition ends the run.
A chatbot typically produces one model response per user message. An agent may perform many model and tool steps for a single user goal before answering.
The host runtime executes tools. The model only proposes structured calls; your code must validate and run them.
No. Many frameworks fold them into one orchestrator. The four labels are for reasoning about failures and design, not mandatory package layout.
Short-term memory is mostly the trajectory in context (perceive/observe). Long-term memory is extra retrieval injected during perceive before reason.
Log each model decision, tool name and args, tool result summary, latency, token counts, and the stop reason. That is the trajectory.
Yes. If the model already has enough context, it should emit a final answer. Forcing tools on every turn wastes cost.
Observe should capture a clear error payload, not crash the whole process silently. The next reason step can retry, choose another tool, or stop with a partial answer depending on policy.
ReAct is a popular way to interleave reasoning and acting inside this loop shape. The loop is the general control pattern; ReAct is one policy for how reason and act alternate.
Because observe appends new tool results and messages. Without trimming or summarization, the perceive package gets longer and more expensive each turn.
Use a fixed workflow when step order is known and stable. Use a loop when the next action depends on intermediate evidence you cannot hardcode.
A typical shape is while not stopped: context = build(); decision = llm(context); if final: break; result = run_tool(decision); append(result). Frameworks hide the while, not the idea.
The ordered record of messages, tool calls, and tool results for one agent run. It is the primary artifact for debugging and evaluation.
Multi-agent systems often give each agent its own loop and pass messages between them. Handoff is observe-for-the-other-agent, not a different physics of agency.
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026