Hamza Boughanim – AI/ML Engineer & Full-Stack Developer

I am an AI/ML Engineer specializing in Large Language Models (LLMs), Computer Vision, OCR pipelines, autonomous agents, and automation systems. I also work as a Full-Stack Developer using React.js, PHP Phalcon, Node.js, SQL Server, MySQL, and Python.

Based in Morocco, I help companies build intelligent software powered by modern AI architectures. My portfolio includes machine learning systems, web applications, APIs, automation tools, and advanced integration flows.

  • AI/ML Engineering
  • Computer Vision & OCR
  • Full-Stack Development
  • Robust backend architecture
  • Cloud and DevOps principles

The Agentic Loop: How AI Agents Reason and Act

By Hamza Boughanim · 2026-07-20 · 13 min read

The perceive-reason-act-remember loop behind Claude Code and every AI agent — explained with a working Python example and design patterns.

Key Takeaways

  • The agentic loop is a perceive-reason-act-remember cycle underlying every AI agent
  • Explicit reasoning steps (ReAct-style thoughts) measurably improve tool-use accuracy
  • Working, episodic, and semantic memory serve different roles and need different storage
  • Orchestrator-worker architectures scale the loop across multiple isolated agents
  • Step limits, scoped tool permissions, and human confirmation are essential guardrails

Introduction: What Is an Agentic Loop?

An agentic loop is the repeating cycle an AI agent runs through to get work done: it observes the current state of the world, reasons about what to do next, takes an action — usually by calling a tool — and updates its memory with the result. Then it does it again. And again. Until the task is finished or a stopping condition fires.

Perceive → Reason → Act → Remember. That four-word cycle is the entire idea. An agent doesn't just answer a prompt once — it perceives an observation, it reasons about what that observation means, it acts on that reasoning, and it remembers the outcome before the next iteration begins.

This is the architectural pattern underneath almost every AI agent you've heard of: Claude Code, AutoGPT, LangChain agents, OpenAI's function-calling assistants, and the countless "AI dev tool" repos on GitHub. A single chat completion — prompt in, text out — is not an agent. An agent is what you get when you wrap an LLM in a loop that lets it observe its own tool outputs and decide what to do next, autonomously, across multiple steps.

This article breaks the agentic loop down into its four core stages, shows a working Python implementation of one from scratch, explains how multi-agent "worker" architectures extend it, and looks at how it shows up in real systems like Claude Code and open-source GitHub projects.

The Core Cycle: Perceive → Reason → Act → Remember

Strip away the framework-specific jargon and every agentic loop reduces to four repeating stages. Different papers and libraries name them differently (ReAct calls it Thought/Action/Observation), but the underlying cycle is the same.

StageWhat happensTypical implementation
PerceptionThe agent observes the current state — a user message, a tool result, a file, an API responseTool outputs appended to the context window
ReasoningThe LLM decides what the observation means and what to do nextChain-of-thought / extended thinking before choosing an action
ActionThe agent executes a decision — calling a tool, writing a file, running codeStructured tool_use / function-calling API
MemoryThe outcome is recorded so future reasoning steps can use itConversation history, scratchpad files, or a vector store

The loop terminates when the agent reasons that the task is complete, when it hits a hard step limit, when a human intervenes, or when it fails in a way it can't recover from. That termination logic is just as important as the loop itself — an agentic loop without a reliable stopping condition is how you get infinite tool-calling and a very large bill.

Anatomy of a Minimal Agentic Loop

Before reaching for a framework, it's worth understanding that an agentic loop is only a few dozen lines of code. Here is a minimal but complete implementation using the Anthropic API's tool-use format.

import anthropic
import json

client = anthropic.Anthropic()

def run_agent(user_task: str, tools: list, tool_executor, max_steps: int = 15):
    """
    A minimal agentic loop: perceive -> reason -> act -> remember, repeated
    until the model stops requesting tools or max_steps is hit.
    """
    messages = [{"role": "user", "content": user_task}]

    for step in range(max_steps):
        # --- REASON: the model sees the full history and decides what's next
        response = client.messages.create(
            model="claude-sonnet-4-6",
            max_tokens=2048,
            tools=tools,
            messages=messages,
        )

        # No tool calls left -> the agent believes the task is done
        if response.stop_reason != "tool_use":
            final_text = "".join(
                block.text for block in response.content if block.type == "text"
            )
            return final_text

        # --- ACT: execute every tool call the model requested this turn
        messages.append({"role": "assistant", "content": response.content})
        tool_results = []

        for block in response.content:
            if block.type == "tool_use":
                result = tool_executor(block.name, block.input)  # runs the real tool
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": json.dumps(result),
                })

        # --- REMEMBER: fold the observation back into the conversation
        messages.append({"role": "user", "content": tool_results})

    return "Stopped: max_steps reached without completion."

Notice what this loop is doing structurally: the messages list is the agent's short-term memory. Each iteration perceives by reading that list, reasons by calling the model, acts by executing whatever tool the model requested, and remembers by appending the result — which becomes the next iteration's perception. Every production agent framework is a more elaborate version of this same cycle.

Reasoning: The Step That Decides Everything Else

The reasoning stage is where an agent's quality is won or lost. Two dominant patterns show up across agentic systems:

ReAct: Interleaved Thought and Action

The ReAct pattern (Reason + Act) asks the model to produce an explicit "thought" before each tool call — verbalizing why it's taking an action, not just what the action is. This intermediate reasoning step consistently improves task success because it forces the model to commit to a plan before acting, rather than pattern-matching straight to a tool call.

Extended Thinking / Planning

More recent agentic systems give the model a dedicated reasoning phase — an extended-thinking block or a planning step — before it ever touches a tool. For long-horizon tasks, some agents also maintain an explicit plan or todo list as part of their memory, updating it as steps complete rather than re-deriving strategy from scratch on every loop iteration.

Thought: The user wants the failing test fixed. I should first read the
         test file to understand what it expects, then look at the
         implementation it's testing.
Action:  read_file("tests/test_auth.py")
Observation: [test file contents]
Thought: The test expects a 401 on expired tokens, but the auth module
         doesn't check expiry. I need to look at the auth module next.
Action:  read_file("app/auth.py")
...

Perception: What the Agent Actually "Sees"

Perception in an agentic loop is not vision in the robotics sense — it's whatever gets fed back into the context window after an action. This includes:

  • Tool outputs — file contents, command stdout/stderr, API responses
  • Environment state — a directory listing, a database schema, a running process's status
  • Errors — a stack trace or a failed tool call, which is itself valuable signal
  • User interjections — a person correcting or redirecting the agent mid-task

A common failure mode is feeding the model too much raw perception — a 10,000-line log file dumped verbatim — which burns context and buries the signal. Well-designed agentic loops summarize, truncate, or paginate large tool outputs before they re-enter the loop.

Memory: Short-Term Context vs. Long-Term Storage

"Memory" in an agentic loop operates at two very different timescales, and conflating them is a common design mistake.

Memory typeScopeTypical storage
Working memoryCurrent task, current sessionThe message list / context window itself
Episodic memoryPast sessions, past tasksA database or transcript log the agent can search
Semantic memoryFacts and preferences learned over timeA vector store or key-value memory the agent writes to explicitly
Procedural memoryReusable strategies or skillsSaved scripts, prompts, or "skill" files the agent can invoke

Because context windows are finite, long-running agentic loops need a strategy for what to keep in working memory versus what to externalize. Common techniques include periodically summarizing older turns, writing intermediate findings to a scratchpad file instead of keeping them in the message list, and retrieving only the relevant slice of long-term memory for the current step rather than loading everything. If the agent's long-term memory is backed by a vector store, the retrieval mechanics are the same ones covered in this guide to building a production RAG pipeline — chunking, embeddings, and similarity search apply just as well to an agent's memory as to a document knowledge base.

def compact_history(messages: list, keep_last_n: int = 10) -> list:
    """
    A simple context-management strategy: summarize everything except
    the most recent N messages, so the loop can run indefinitely without
    exceeding the context window.
    """
    if len(messages) <= keep_last_n:
        return messages

    old_messages = messages[:-keep_last_n]
    recent_messages = messages[-keep_last_n:]

    summary = summarize_with_llm(old_messages)  # a smaller/cheaper model call
    return [{"role": "user", "content": f"[Earlier context summary]\n{summary}"}] + recent_messages

Worker Agents: Scaling the Loop Beyond One Agent

A single agentic loop works well for tasks that fit within one context window and one line of reasoning. Complex tasks — a large codebase migration, a multi-source research report — often split across multiple agents instead, in what's usually called an orchestrator–worker pattern.

  • Orchestrator agent — runs its own agentic loop, but its "tools" are other agents. It decomposes the task and delegates subtasks.
  • Worker agents — each runs an independent agentic loop scoped to a narrow subtask, with its own context window, and reports a result back to the orchestrator.
def orchestrator_loop(task: str, worker_pool: dict):
    subtasks = plan_subtasks(task)  # LLM call: break task into independent pieces
    results = {}

    for subtask in subtasks:
        worker_name = route_to_worker(subtask, worker_pool)
        # Each worker runs its OWN full agentic loop, isolated from the others
        results[subtask.id] = run_agent(subtask.description, worker_pool[worker_name].tools,
                                         worker_pool[worker_name].executor)

    return synthesize_final_answer(task, results)  # LLM call: merge worker outputs

This pattern matters for two reasons beyond raw parallelism. First, isolating each worker's context prevents an unrelated subtask's tool output from polluting another subtask's reasoning. Second, it lets different workers use different tools, models, or even different system prompts tuned to their specific job — a research worker with web search, a code worker with a sandboxed shell, a review worker with read-only access.

Agentic Loops in Practice: Claude Code and Coding Agents

Coding agents like Claude Code are one of the clearest real-world examples of the agentic loop in action, because the loop's stages map directly onto observable developer actions:

Loop stageIn a coding agent
PerceiveRead a file, run a linter, run the test suite, view a diff
ReasonDecide which file to edit, or whether the last change fixed the failing test
ActEdit a file, run a shell command, create a new file
RememberTrack what's been tried, what failed, and what the remaining plan is

What distinguishes a good coding agentic loop from a bad one is usually the feedback tightness: an agent that runs the test suite after every edit and reads the actual failure output corrects course far faster than one that edits blindly and only checks its work at the very end. The loop is only as good as the quality of the perception it gets back from its own actions. Once an agent like this is ready to run as a hosted service rather than a local CLI tool, it needs the same serving layer as any other model-backed API — see this guide to deploying AI models with Docker and FastAPI for the production patterns.

Open-Source Agentic Loop Examples on GitHub

If you want to study working implementations rather than just pseudocode, a few families of open-source projects are worth knowing about — each takes a different stance on how much structure to impose on the loop:

  • ReAct-style single-agent loops — minimal implementations that closely mirror the ReAct paper: thought, action, observation, repeat, with little extra scaffolding.
  • Autonomous "auto-GPT" style agents — early open-source projects that gave an LLM a goal and let it self-direct across many tool calls with persistent memory, popularizing the idea of a fully autonomous agentic loop.
  • Graph-based agent frameworks — represent the loop as a state graph rather than a flat while-loop, making branching, retries, and human-in-the-loop checkpoints explicit nodes in the graph instead of implicit logic.
  • Multi-agent orchestration frameworks — implement the orchestrator–worker pattern directly, with built-in message-passing between agents and role-based prompt templates.

Reading a few of these side by side is one of the fastest ways to understand the design space: they all implement the same four-stage cycle, but differ sharply in how much control flow is left to the LLM's own judgment versus hard-coded by the developer.

Guardrails: Keeping the Loop From Running Away

An agentic loop that can call tools autonomously needs explicit boundaries, or it will eventually do something expensive, destructive, or simply wrong. The essentials:

  • Step limits. Always cap the number of loop iterations — an agent stuck in a retry cycle will otherwise run until the context window or your budget is exhausted.
  • Confirmation for irreversible actions. Sending an email, deleting a file, or making a payment should pause the loop for human approval rather than executing automatically.
  • Scoped tool permissions. A worker agent doing research shouldn't have filesystem write access; a coding agent shouldn't have network access it doesn't need. This is the same least-privilege principle behind scoped, short-lived credentials in a Zero-Trust AI backend — an agent's tool permissions should expire and narrow just as aggressively as an API token does.
  • Failure detection, not just success detection. A robust loop recognizes when it's repeating the same failing action and escalates or stops, instead of looping indefinitely.

Common Pitfalls

  • No termination condition beyond "the model says it's done." Models can be wrong about task completion; pair this with an external check (tests passing, a validator) where possible.
  • Unbounded context growth. Without compaction or summarization, long loops eventually exceed the context window or degrade in quality as irrelevant history piles up.
  • Too many tools at once. Giving an agent 40 tools when 5 are relevant increases the chance of the wrong tool being selected at each reasoning step.
  • Treating memory as a monolith. Dumping everything into one long conversation history instead of separating working memory from long-term storage makes both slower and less reliable.

Takeaways for Builders

  • An agentic loop is perceive → reason → act → remember, repeated. Every agent framework, however elaborate, is built on this cycle.
  • Reasoning quality drives loop quality. Explicit thought steps (ReAct-style) before tool calls measurably improve task success.
  • Memory has layers. Working memory, episodic memory, and long-term semantic memory serve different purposes and shouldn't be conflated.
  • Worker agents scale the pattern. Orchestrator–worker architectures isolate context and specialize tools per subtask for complex, multi-part work.
  • Guardrails are not optional. Step limits, scoped permissions, and human confirmation for irreversible actions are what make an agentic loop safe to run autonomously.

Final Thought

The agentic loop is a deceptively simple idea — observe, think, act, remember, repeat — but that simplicity is exactly what makes it general-purpose. The same four-stage cycle powers a coding assistant fixing a failing test, a research agent synthesizing sources, and an orchestrator coordinating a dozen worker agents. Understanding the loop itself, rather than any single framework's abstraction over it, is what lets you debug an agent that's stuck, design one that scales, and reason about what "autonomous" actually means in practice.

Further Reading

A few related deep dives if you're building agentic or LLM-backed systems:

  • Building a Production RAG Pipeline — the retrieval mechanics behind an agent's long-term memory
  • MLOps in Practice: Deploying AI Models with Docker and FastAPI — turning an agent into a hosted service
  • Building a Zero-Trust AI Backend with Argon2 — scoping and securing the tools an agent can call
  • More AI engineering projects on this site

Frequently Asked Questions

What is an agentic loop in AI?

It's the repeating cycle an AI agent uses to complete a task: it perceives the current state (a tool result or observation), reasons about what to do next, takes an action such as a tool call, and stores the outcome in memory before repeating. This loop is what turns a single LLM call into an autonomous, multi-step agent.

How is an agentic loop different from a chatbot?

A chatbot produces one response per user message. An agentic loop lets the model take an action, observe the result, and decide on its own what to do next — repeating that cycle multiple times without a person in between each step — until the task is complete or a stopping condition is reached.

What is the role of memory in an agentic loop?

Memory carries information across loop iterations so reasoning can build on prior steps rather than starting from scratch. Working memory (the current conversation) handles the immediate task, while episodic and semantic memory — usually a database or vector store — let an agent recall past sessions or learned facts.

What are worker agents in agentic AI?

Worker agents are subordinate agents that each run their own agentic loop on a narrow subtask, with an orchestrator agent decomposing the overall task and delegating pieces to them. This orchestrator-worker pattern isolates context per subtask and lets each worker use tools suited to its specific job.

How does Claude Code use an agentic loop?

Claude Code repeatedly reads files, runs commands like tests or linters, reasons about the results, and edits code based on what it observes — looping until the task is verified complete. The tightness of that perceive-and-correct feedback cycle is a major factor in how reliably it solves a coding task.