AnyLearn
All lessons
AIbeginner

Loop engineering basics: the agent control loop

How LLM agents actually run: the iterative prompt-action-observation loop, the ReAct shape, the smallest tool-calling loop in twelve lines, why you always stack three termination layers, what the model sees on iteration N, and when a single prompt is the better answer.

Not signed in β€” your progress and quiz score won't be saved.
Lesson progress1 / 8

Why agents need a loop

A single LLM call answers one prompt. Many real tasks need information the model can't have until it acts β€” read a file, search a doc, run a calculation. The result of one action decides what to ask next. That's the loop: the model picks an action, the harness runs it, the result feeds into the next prompt, repeat.

The loop is the difference between a chatbot and an agent. A chatbot answers in one shot from prior knowledge. An agent gathers evidence, takes steps, and decides when it's done. If you can solve a task with a single prompt and no tools, skip the loop β€” it adds latency, cost, and failure modes for no gain.

Full lesson text

All 8 steps on one page β€” for reading, reference, and search.

Show

1. Why agents need a loop

A single LLM call answers one prompt. Many real tasks need information the model can't have until it acts β€” read a file, search a doc, run a calculation. The result of one action decides what to ask next. That's the loop: the model picks an action, the harness runs it, the result feeds into the next prompt, repeat.

The loop is the difference between a chatbot and an agent. A chatbot answers in one shot from prior knowledge. An agent gathers evidence, takes steps, and decides when it's done. If you can solve a task with a single prompt and no tools, skip the loop β€” it adds latency, cost, and failure modes for no gain.

2. The ReAct shape

ReAct stands for reason + act. Each iteration the model emits two things together: a brief thought ("I should check the price first") and an action (a tool call like get_price("BTC")). The harness runs the action, captures the observation, and feeds all three back into the next prompt.

You don't have to literally use the word "thought" β€” Claude's tool-use, OpenAI's function calling, and Google ADK's tool callbacks are all variants of this shape. The pattern is the same: a structured turn that combines reasoning and one action, external execution, then the result joins the conversation. Surfacing the thought is what makes mistakes and dead ends visible to the model next turn β€” without it, the model steers blind.

3. The cycle, drawn

Each box is the model's view; each edge is something the harness or the world does.

flowchart LR
  A["User request"] --> B["Model picks action"]
  B --> C["Harness runs tool"]
  C --> D["Observation"]
  D --> B
  B --> E["Model says done"]
  E --> F["Final answer"]

4. The smallest tool-calling loop

Here's the entire control flow in pseudo-Python. Production loops add error handling and caps; the spine is this:

messages = [{"role": "user", "content": user_request}]
for step in range(MAX_STEPS):
    reply = model(messages, tools=AVAILABLE_TOOLS)
    messages.append(reply)
    if reply.stop_reason == "end_turn":
        return reply.text
    for call in reply.tool_calls:
        result = TOOLS[call.name](**call.args)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": result,
        })

Three moving parts: messages (the running history), tools (the dispatch table), MAX_STEPS (the hard cap). Every other loop you'll see β€” plan-act-reflect, sub-agents, verification panels β€” is this with extras stapled on.

5. Termination: don't trust the model alone

The model signals "done" via a stop reason: end_turn for Anthropic, stop for OpenAI, or simply a turn with no tool call. That's the happy path. The unhappy path is a model that keeps calling tools forever β€” usually because the last observation didn't actually answer the question and it doesn't know what else to try.

Always stack three termination layers:

  • Model signal β€” exit when the model says it's done.
  • Iteration cap β€” MAX_STEPS = 20 (or 5, or 50; pick on purpose). Hard exit on hit.
  • Token or wallclock budget β€” exit if cumulative usage crosses a threshold.

Production loops also detect repeats β€” same tool, same args, twice in a row β€” and exit. "I'll just trust the stop reason" is how one stuck request bills four hundred dollars in tool calls overnight.

6. What the model sees on iteration N

On iteration 1 the prompt is the user's request and the tool list. On iteration N the prompt is every previous turn concatenated: assistant messages, tool calls, observations. This is the per-turn state, and it grows linearly with the number of steps.

That growth shapes the loop:

  • The model loses focus when iteration-1 context is buried ten turns deep.
  • Tokens add up. A 5KB observation across twelve iterations is 60KB of prompt before the model even thinks.
  • Mistakes from iteration 2 still influence iteration 12.

Two practical rules: be terse in observations β€” don't dump a 50KB file when one line answers the question β€” and exit if the loop drifts (iteration 5 looks like iteration 3, you're not making progress).

7. A worked trace

Task: "What's the capital of France, in Spanish?" Available tools: lookup_capital(country) and translate(text, target_lang).

IterModel thoughtActionObservation
1Need the capital first.lookup_capital("France")"Paris"
2Translate it to Spanish.translate("Paris", "es")"ParΓ­s"
3Have the answer.(no tool call, final text)β€”

Three iterations, two tool calls, then a stop. The order is decided by the model β€” it could equally have used a single combined tool, or asked the user to clarify. The loop just runs whatever the model picks next. That flexibility is the agent's power, and the reason every termination layer above exists.

8. When not to use a loop

A loop is for tasks where step N depends on the result of step N-1. If one prompt answers the question, use one prompt. If one tool call answers it, use the model's native tool-use without looping.

Common false positives where people reach for a loop they don't need:

  • Retrieval-augmented prompts β€” one search, one synthesis, no loop.
  • Form filling / extraction β€” call the model once with a JSON schema, validate, done.
  • Chat β€” the user's next message is the next iteration; you don't loop programmatically.
  • Single-tool answers β€” "fetch this row" doesn't need a harness; just call the tool.

The loop adds latency, token cost, three new failure modes (drift, runaway, repeat), and an evaluation burden. Pay that cost only when the task structurally needs it.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. What distinguishes an agent loop from a single LLM call?
    • The agent loop uses a larger model.
    • Each iteration's prompt includes the result of the previous action.
    • The agent loop always streams its output.
    • Agent loops require a fine-tuned model.
  2. Why is relying only on the model's stop signal to end the loop risky?
    • Models can't emit stop reasons reliably.
    • The model may keep calling tools indefinitely when it can't reach an answer, with no cap to halt it.
    • The stop reason is hidden in the API and unreadable.
    • The stop signal is only available on streaming responses.
  3. A tool returns a 50KB file dump on every call. What's the best move inside the loop?
    • Forward the raw dump so the model sees every detail.
    • Trim or summarize before appending so per-turn state stays small.
    • Append it to a separate channel the model never reads.
    • Always spawn a sub-agent to handle the file.
  4. Which task does NOT need a loop?
    • Read a CSV, find anomalies, then fetch context for each one.
    • Translate one sentence to German.
    • Debug a failing test by reading files and running it.
    • Plan a five-stop itinerary and check each stop's opening hours.
  5. On iteration 12 your loop has just re-sent the exact same tool call it sent on iteration 10, with the same args and the same result. What's the most direct fix?
    • Raise MAX_STEPS so the model has more chances to recover.
    • Detect the repeat in the harness and exit early with a clear failure.
    • Switch to a smaller, faster model so each iteration costs less.
    • Disable the model's stop reason and let the harness decide.

Related lessons

AI
advanced

Loop engineering: verification, orchestration, and anti-patterns

Make loops trustworthy. Adversarial verification panels, sub-agent orchestration, loop-until-dry for unbounded discovery, loop-until-budget for paid depth, multi-modal sweeps with diverse prompts, eval-driven cap selection, and the five anti-patterns β€” silent caps, infinite plans, drift, premature termination, thrashing β€” that ship to prod more than they should.

9 stepsΒ·~14 min
AI
intermediate

Loop engineering in production: state, errors, and budgets

Once an agent loop runs past a few iterations the failure surface shifts: state bloats, tool calls fail in three distinct ways, retries multiply if you stack them wrong, and unbounded budgets rack up four-figure bills overnight. The state, errors, and budgets you need to make the loop survive contact with reality.

8 stepsΒ·~12 min
AI
intermediate

LLM Observability with OpenTelemetry: GenAI Semantic Conventions

Master the OTel GenAI semantic conventions β€” gen_ai.* attributes, span structure for prompts/completions/tools, sampling strategies, and cost attribution β€” and understand why standardizing across LangSmith, Phoenix, Datadog, and Grafana matters for production AI systems.

13 stepsΒ·~20 minΒ·audio
AI
intermediate

RAG Evaluation in Production: Metrics, Tools, and Cadence

Learn how to systematically evaluate Retrieval-Augmented Generation systems in production using RAGAS, TruLens, and Phoenix β€” covering golden sets, retrieval drift, embedding drift, and cost-aware eval scheduling.

12 stepsΒ·~18 minΒ·audio