av / dives /Agents: Textbook
source about me

Core path - 6 of 8

Chapter 6: The Loop That Acts

This is the textbook chapter for the Agents deep dive. The README is the lab manual; this is the lecture. It covers what an agent actually is once the marketing evaporates, why the idea failed loudly in 2023 and quietly succeeded afterward, and the engineering judgment that separates a loop you would run unattended from one you would not.


6.1 A word with a marketing problem

Few words in technology have been stretched thinner than "agent." By 2024 it was being applied to everything from a chatbot with a nice interface to a scheduled cron job with an API call in it, and its main function in a sales deck was to raise the price. Underneath the stretch, though, there is a precise technical idea, and it fits in one sentence:

An agent is a loop: the model picks a tool, you run it, you feed the result back, until it's done.

That is the entire concept. A language model on its own can only emit text; it cannot check a database, run a calculation, or save a file. Give it a set of tools it may request, wrap it in a loop that executes each request and returns the result, and the model can now pursue a goal across multiple steps, observing what happened and deciding what to do next. Everything sold under the word "agent" that is not this is packaging.

The idea has a respectable intellectual lineage. Classical AI spent decades on the sense-think-act cycle in robotics and planning. The direct ancestor of the modern form is ReAct, a 2022 research paper showing that a model prompted to interleave reasoning ("I should look this up") with actions (a search query) and observations (the result) solved problems neither pure reasoning nor pure retrieval could. You met ReAct as a prompting pattern in Chapter 3, done by hand. Tool calling (Chapter 1) made it native: instead of parsing actions out of free text and hoping, the model emits structured requests your code can execute safely.

The recent history is a boom-bust-boom worth knowing, because it teaches the chapter's central judgment. In the spring of 2023, a project called AutoGPT became one of the fastest-starred repositories GitHub had ever seen. The pitch: give a model a goal and let it loop autonomously until done. Millions tried it. It mostly did not work: agents wandered, looped on failed steps, burned money reconsidering their own to-do lists, and rarely finished anything nontrivial. The word "agent" acquired a smirk. Then, over the following two years, agents quietly became some of the most-used AI products in existence, in one domain first: coding tools like Claude Code and Cursor run exactly this loop (read files, edit, run tests, read the failures, repeat). What changed was not the loop. It was better models, much better tools, tight feedback signals (a failing test is an unambiguous observation), and human checkpoints in the right places. The lesson to carry through this chapter: the loop is trivial; the engineering around it decides everything.

6.2 A tool has two faces

Before the loop, the thing it loops over. A tool, to your code, is a plain function. To the model, it is only three pieces of text: a name, a description, and a schema for its inputs. The model never sees your implementation and never executes anything. It reads the descriptions, decides one would help, and emits a request: call this name with these arguments.

Sit with that gap for a moment, because every bit of an agent's safety lives inside it. The model asks; your code decides. Between the ask and the run, you can validate arguments, check permissions, ask a human, log the attempt, or refuse. An agent is not a model that has been given power; it is a model that has been given a request channel, and you own the other end. When you read alarming headlines about an AI "doing" something, the engineering question is always about the other end of that channel: what was wired to it, and what checks stood in between?

The second thing worth sitting with: since the model chooses tools purely by reading their names, descriptions, and parameter names, those strings are prompt engineering, not documentation. A tool described as "search product information" gets used for questions its author never anticipated; one described tersely as "query db" gets ignored while the model guesses from memory. When an agent misbehaves, experienced builders check the tool descriptions before the system prompt, and the lab's troubleshooting table reflects that instinct. You are not writing docs for a colleague; you are writing the only evidence the model has about what its hands do.

6.3 The loop itself, and why it stays small

The lab's run_agent is about twenty lines, and the number is the message. Call the model with the conversation and the tool catalog. If it answers with text, done. If it requests tool calls, execute them, append the results to the conversation, and go again. That is a while loop around the API call you learned in Chapter 1, plus bookkeeping.

Watch the trace on a multi-step question and you see why this small thing is a genuinely new capability rather than a convenience. Asked what a year of a subscription costs, the agent searches for the price, reads the result, and only then can it multiply by twelve, because the second step's input did not exist until the first step returned. A single API call, however clever, cannot do that; it must produce its whole answer before observing anything. The loop gives the model what programmers would call intermediate state and what the rest of us would call the ability to find things out before deciding.

Give it several tools and a second capability appears without any new code: routing. The model decomposes the task and sends each part to the right tool, chaining them, guided by nothing but those descriptions. No dispatcher was written. This is also the moment to name what the loop really is beneath the surface: a conversation that grows. Every tool result is appended to the message list, the whole list is re-sent each turn (the statelessness of Chapter 1, now with consequences), and a long-running agent is therefore an eating contest against the context window. That pressure, and what to do about it, gets its own chapter (Context Engineering); here you just need to see where it comes from.

6.4 The multiplication problem, and the guardrails it forces

Now the judgment section. A model that is right 95% of the time sounds fine until it must be right ten times in a row: the chain succeeds only about six times in ten. Twenty steps, about a third. Errors in a loop compound geometrically, which is the arithmetic behind AutoGPT's flailing, and it dictates the engineering posture for everything an agent does unattended. You do not get reliable agents from optimism; you get them from designing every layer around the assumption that some step will go wrong.

Step limits are the first layer. An unsupervised loop needs a hard ceiling so a confused agent stops and says so rather than orbiting forever, and in production the ceiling comes paired with a cost budget, because a stuck loop is a machine that converts confusion into invoices at several cents per orbit.

Error recovery is the second, and it contains this chapter's most elegant idea. When a tool raises an exception, the naive loop crashes. The right loop catches the error and feeds the error text back to the model as the tool's result. The model reads "error: division by zero" or "error: no such file" the way it reads any observation, and it adapts: retries differently, picks another tool, or reports honestly that it is stuck. The failure becomes information. This trick, almost insultingly simple, is a large part of why modern coding agents feel robust: a failing test or a stack trace is not a crash, it is the next observation in the loop.

Human-in-the-loop approval is the third, and it encodes a policy question in code. Some actions are safe to let the model take freely (a calculation, a read-only search); some have consequences (writing files, sending email, moving money). The lab's pattern marks consequential tools as dangerous and requires an approval callback before they run, and there is a detail here that deserves attention: a denial is delivered to the model as just another tool result, so the agent adapts to "no" the same way it adapts to an error. The human is not an exception handler bolted on; the human is part of the environment the agent operates in. Which tools require approval is not a technical fact, it is your policy, and declaring it explicitly on the tool is what makes the policy auditable.

Observability closes the set. An agent makes its own decisions, so when it misbehaves, "it gave a weird answer" is not debuggable; you need the trace, which tool, what arguments, what result, at each step. The structured record the lab keeps is the same object you would log in production, and, closing a loop with Chapter 5, it is exactly what a trajectory eval grades: right tools, sensible order, no forbidden calls, within budget. An agent you cannot trace is an agent you cannot evaluate, debug, or trust.

6.5 Do you even need an agent?

The most valuable pattern in the lab may be the one that argues against the repo's own title. If you can draw the flowchart for a task (classify the ticket, then route by category, then draft from the template), build a workflow: fixed steps orchestrated by your code, with model calls inside the boxes where language ability is needed. It is cheaper, faster, predictable, and testable, precisely because the path is not decided at runtime. Reach for an agent, where the model drives the control flow, only when the path genuinely cannot be known up front, as in debugging, open-ended research, or "make this test pass."

Anthropic's widely circulated engineering guidance says the same thing bluntly: most "agent" use cases in the wild are workflows wearing a costume, and the composed-workflow patterns (chaining, routing, parallelization) cover most needs at a fraction of the complexity. The ladder from CHOOSING.md puts agents on the top rung for a reason, and the reason is cost, not prestige. There is a seductive counterargument you will hear: "everyone uses agents, they can't be that expensive." Notice that almost everyone uses agents someone else built and hardened; the complexity was paid once, by the tool's author, then hidden. Building the loop into your own product is the decision the ladder prices, and there it is rarely the cheapest thing that works. Prove the lower rungs fail first, with the evals you now know how to run.

Two cheap wrappers blur the middle ground and are worth knowing. Planning asks the model to write a short plan before acting, which keeps long tasks on track and gives you a checkpoint where a human can veto a bad approach at the cost of one extra call. Reflection runs a critic pass after, catching half-answers before the user sees them, and it echoes a lesson from Chapter 3 worth repeating because it generalizes: self-correction works far better against a real external check (a test, a validator, a search result) than against the model's own feelings about its work.

6.6 Scaling the shape: sub-agents, parallelism, hosted tools

Three extensions carry the loop from demo to system, and the pleasing thing about all three is that none introduces a new concept.

Multi-agent systems sound exotic and are, mechanically, a pun. A sub-agent is a tool whose implementation happens to run its own loop, with its own prompt and its own narrower toolset. The orchestrator calls research the way it calls calculator; underneath, research is a whole second agent. Why bother? Focus. One agent with twenty tools gets noticeably worse at choosing among them (a crowded tool catalog is a crowded prompt), and a specialist with three relevant tools and a specialist's system prompt outperforms a generalist with everything. There is also a context benefit with real consequences: the sub-agent's lengthy intermediate work stays in its own conversation, and only its conclusion returns to the orchestrator, which keeps the parent's window lean. Large agent products, including the coding tools, are built exactly this way, focused agents calling each other through the same tool interface you already know.

Parallel tool calls and streaming are the user-experience half. When the model requests several independent calls in one turn, run them concurrently; the turn costs the slowest call rather than the sum. And stream everything, not just the final answer but the narration between tool calls ("let me look that up..."), because an agent that works silently for thirty seconds reads as broken while one that narrates reads as working. This is not cosmetics; visible progress is what makes multi-step latency tolerable, and it is the pattern every production assistant uses.

Hosted tools are the one genuine architectural fork in the chapter. Everything so far was client-executed: the model asks, your loop runs the function, your code sits in the middle of every action. Providers now also offer tools they execute themselves, inside the turn, on their infrastructure: web search, code execution, and, at the frontier, computer use, where the model operates a real GUI through screenshots and clicks. You declare the tool, send one request, get one final answer, and your loop handles zero rounds. The trade is control for plumbing: a hosted tool cannot be gated behind your approval callback, logged by your tracer, or sandboxed by your policy, because your code never sees the call. Real systems mix both, and the decision rule falls out of everything above: convenience is fine for actions you would have auto-approved anyway; anything you would want to gate, inspect, or audit belongs on your side of the channel.

The lab's MCP bonus belongs in this list as a preview: the Model Context Protocol takes "a tool is a name, a description, and a schema" and speaks it over a wire, so an agent can discover and call tools it never shipped with, served by other processes, other teams, other companies. The lab builds the protocol by hand, JSON-RPC and all, so that when Chapter 14 treats it fully, it reads as familiar plumbing rather than a new religion.

6.7 What you should now see through

The stated goal of this dive is x-ray vision, so let it be explicit about what you can now see through.

Agent frameworks, first. LangChain, CrewAI, the SDK tool-runners: having written the loop, you can now read any of them as the twenty lines you wrote plus opinions about configuration. Some of the opinions are good. But you can now evaluate them as engineering rather than accept them as magic, and when one misbehaves you know the loop underneath is inspectable, because you have inspected yours.

Agent products, second. When a coding assistant fixes your bug, you can narrate what happened: tools for reading and editing files and running commands, a loop feeding results back, error text becoming the next observation, approval gates on the dangerous parts, a trace behind it all. The demystification is not cynicism; the products are genuinely good. It is the difference between a user and an engineer.

And the risk conversation, third. An agent's danger is not mystical autonomy; it is a request channel wired to consequential tools with insufficient checks between. That framing tells you exactly where to look in any agent system you are asked to assess: what tools exist, which are gated, what the arguments are validated against, what gets logged, and what happens when a step fails. It also tells you what is coming next in this course. An agent that reads documents and acts on what it reads is a machine whose instructions can arrive hidden in its inputs. You have built the loop; the next chapter attacks it.


Lab manual: README.md · Exercises: EXERCISES.md · Previous: Evals · Next: Prompt Injection & Guardrails