Building an agent loop
Under every agent framework is a simple loop. Build it yourself once and you'll understand — and debug — any agent.
Learning objectives
- Implement a bounded agent loop with error handling and tracing
- Distinguish working, scratchpad and long-term memory
- Manage context in long tasks
- Explain planning, sub-agents and skills
- Evaluate when to use a framework
4.1 The agent loop
At its core, an agent is a loop: the model looks at the goal and everything so far, chooses an action (usually a tool call), your code executes it, the result is added to the context, and the loop repeats — until the model produces a final answer or a limit is hit.
Python · a minimal, bounded agent loopTOOL_FUNCS = {"get_order_status": get_order_status} # name → Python function
def run_agent(goal, max_steps=10):
messages = [{"role": "user", "content": goal}]
for step in range(max_steps):
r = client.messages.create(model=MODEL, max_tokens=1000, tools=tools,
system="You are a careful support agent. "
"Use tools to check facts. Stop and ask if unsure.",
messages=messages)
messages.append({"role": "assistant", "content": r.content})
if r.stop_reason != "tool_use": # model gave a final answer
return "".join(b.text for b in r.content if b.type == "text")
results = []
for call in (b for b in r.content if b.type == "tool_use"):
try:
out = TOOL_FUNCS[call.name](**call.input)
except Exception as e: # errors go back to the model
out = {"error": str(e)}
print(f"step {step}: {call.name}({call.input}) -> {out}") # trace
results.append({"type": "tool_result", "tool_use_id": call.id,
"content": json.dumps(out)})
messages.append({"role": "user", "content": results})
return "Stopped: step limit reached — escalating to a human."
Three details matter: a step limit, errors returned to the model so it can recover, and a trace of every action.
4.2 State, memory and context
| Kind | What it holds | How |
|---|---|---|
| Working memory | The current task: goal, steps, tool results | The conversation context itself |
| Scratchpad / plan | A to-do list or notes the agent updates | A file or state object the agent reads and writes via tools |
| Long-term memory | Facts and preferences across sessions | A database or retrieval index, read and written deliberately |
Long tasks fill the context window. Techniques include summarising or trimming old tool results, storing details in files and re-reading them when needed, and handing sub-tasks to sub-agents with their own fresh context.
4.3 Planning
Asking an agent to write a short plan first — and update it as it goes — tends to improve long, multi-step work. Reasoning models do much of this internally. Either way, keep plans visible in traces so humans can understand what the agent intended.
4.4 Multi-agent systems
Some systems split work across several agents — for example an orchestrator that hands research, coding and review to specialised sub-agents, each with its own instructions, tools and context. This can help with large tasks and parallelism, but multiplies cost and makes failures harder to trace. Use it when a single agent demonstrably struggles, not by default.
4.5 Reusable skills and instructions
Agents perform better with good instructions about how to do recurring tasks. Several platforms now support packaged, reusable instructions — for example Anthropic's agent Skills, which an agent loads only when relevant. Treat them like code: version, review and test them.
4.6 Frameworks
You can build agents directly on a model API (as above) or use frameworks and platforms such as the OpenAI Agents SDK, Microsoft's agent frameworks, Google's Agent Development Kit, Amazon Bedrock's agent services, or open-source libraries. Frameworks speed up common plumbing — tool registration, tracing, hand-offs — but understand the underlying loop first so you can debug it.
Key takeaways
- The loop: decide → act → observe → repeat, until done or a limit.
- Step limits, errors returned to the model and traces are essential.
- Use files, summaries and sub-agents to manage context.
- Multi-agent systems add power and cost — use when one agent struggles.
- Learn the loop before relying on a framework.