
Welcome to AIEdTalks’ Newsletter!
In today's edition:
What Is Loop Engineering?
Let’s dive in.
Today’s Edition
AI TOPIC
What Is Loop Engineering?

Welcome back. This one is a foundations issue. If the word "agent" still feels a little hand-wavy, this is the issue that makes it concrete — using the most familiar tool in your toolbox: the humble while loop.
Here's what's inside:
What the "agent loop" actually is — and why it's a while-loop you've already written a hundred times
The one-tool agent that ran until it ran out of money
The five ways a loop should stop, and the four most people forget
Two checks tonight to see if your loop is quietly running away
AI SYSTEMS: An agent is a while-loop
Loop engineering is taking that loop seriously — especially the part that decides when it stops.
In The Model Is 20% of Your Agent, the orchestration loop was the first of six harness components. This issue zooms all the way in on that one box — because it's the foundation the other five sit on, and it's the most familiar thing in all of AI to a backend engineer. You've written this loop before. You just didn't call it an agent.
Here's the story that teaches the whole issue.
A developer gave their agent exactly one tool — a search function — and one clear instruction: call the search tool only once. The agent called it anyway. Then again. Slightly different arguments each time, burning a model call on every attempt, until it hit the turn limit and gave up with no answer. So the developer raised the limit — from the default all the way to 100. It got worse. More budget, more loops, same non-answer.
That's a real, public bug (OpenAI's Agents SDK, issue #191). And it's the entire lesson in one paragraph: the agent never decided it was done, and nothing made it stop.
What the loop actually is
Simon Willison spent months collecting definitions of "agent" and landed on the one that stuck: an LLM that runs tools in a loop to reach a goal. Anthropic says nearly the same — an agent is an LLM "using tools in a loop."
That's not a metaphor. It's close to the literal code.
A plain model call is one-shot: text in, text out. It can't run a command, hit an error and react, or look up something it doesn't already know. The loop closes that gap. Three beats, repeated:
Thought — the model reasons about what to do next.
Action — it asks to call a tool (an API, a query, a file edit).
Observation — you run the tool and feed the result back.

Then it reasons again, this time with the new fact in hand. That cadence — Thought, Action, Observation — comes from a 2022 paper called ReAct. Every agent framework runs some version of it.
Here it is in code you'd recognize in your sleep:
python
def run_agent(task, tools, max_iters=10):
messages = [{"role": "user", "content": task}]
for _ in range(max_iters): # a stop condition
reply = model.call(messages, tools)
if not reply.tool_calls: # no action left -> done
return reply.content
for call in reply.tool_calls:
result = run_tool(tools[call.name], call.args)
messages.append(observation(call, result)) # feed the result BACK
return "hit max iterations" # the backstopThat's an agent. The model is the decision-maker; the loop is the runtime that keeps calling it. One line matters more than it looks: messages.append(observation(...)). Forget to feed the result back, and the model re-decides against stale context and re-issues the same call — a loop you built by accident.
A quick honesty note: "loop engineering" is a young phrase — people only started using it in mid-2026. Don't over-index on the term. Index on the thing under it: the agent loop, which has been around since ReAct.
Where beginners get burned: stopping
A naive loop has exactly one way out — the model volunteers a final answer with no tool call — and no backstop. That's the issue-#191 bug. When the model never volunteers "done," the loop runs until your wallet does.
A well-engineered loop has five ways to stop, and you set all of them on purpose:
No more tool calls — the natural exit. The model returns plain text. Necessary, never sufficient.
Max iterations — a hard cap on turns. A backstop, not a fix. Raising it doesn't unstick a stuck loop; ask the #191 developer.
A budget — tokens, time, or dollars per run. Your circuit-breaker against the invoice. (When a runaway spans multiple agents and you need real kill switches, that's a bigger pattern — see Your Multi-Agent System Needs a Circuit Breaker. Here we're on the single loop.)
No-progress detection — if the agent calls the same tool with the same arguments two or three times, stop it. It isn't thinking; it's spinning.
A verification gate — the strongest exit. The loop ends when the work actually passes a check (tests green, JSON validates), not when the model says it's finished.
That last one is why coding agents feel like magic: the test suite is the verifier. "The model said it's done" is not a stop condition. "The criteria are met" is.
Two ways this hides
One: it works in the demo. Short tasks finish in two or three turns and exit cleanly. The runaway only shows up on the messier real task that needs eight turns — the one you didn't test.
Two: it fails silently and expensively. No crash, no stack trace. Just an agent quietly looping, re-sending a growing history every turn, until someone notices the bill. Gartner expects over 40% of agentic AI projects to be cancelled by the end of 2027 — cost and weak controls near the top of the list. An unbounded loop is exactly that failure, one agent at a time.
Find out if you have this problem tonight
Check one — find your caps. Open your agent's loop. Can you point at the line that limits iterations, and the line that limits tokens or dollars? If either is missing or set to "none," you don't have a loop — you have an open tab on your API bill.
Check two — force a repeat. Give the agent a task where a tool comes back useless: an empty result, a vague error. Watch what it does. If it calls the same tool with the same arguments more than twice, you have no progress detection. Add this and run it again:
python
seen = {}
# inside the loop, before executing each tool call:
key = (call.name, canonical(call.args))
seen[key] = seen.get(key, 0) + 1
if seen[key] >= 3:
return "stuck: repeated the same call" # stop spinningIf that one guard ends the spin, you just did loop engineering.
Closing
Your agent was never as smart, or as dumb, as it looked on any single turn. It's a loop. And a loop you don't bound is a loop that ends when your budget does.
Engineer the loop, or let it run until the invoice stops it. There is no third option.
Sources: the origin of the Thought–Action–Observation loop is the ReAct paper (Yao et al., 2022). "An LLM using tools in a loop" is Anthropic's framing in "Building Effective Agents"; the goal-directed phrasing is Simon Willison's. The one-tool runaway is OpenAI Agents SDK issue #191. The 40% figure is Gartner (June 2025). "Loop engineering" as a named term is recent (mid-2026) — treat the phrase as a lens and the agent loop as the durable idea underneath.
👋 That’s All Folks!
Before you go, just a few public service announcements:
See you soon,
AIEdTalks’ Newsletter Team
