Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 3

The Agent Loop: LLMs, Tools, and Memory

Recommended resources

Welcome to the third lesson in our exploration of LLM agents. In our previous session, we developed a taxonomy to classify agents along the axes of autonomy, tool access, planning horizon, and the number of actors. This high-level framework allows us to profile and compare different agent systems.

Today, we will move from this external classification to the internal mechanics. We will dissect the fundamental operational cycle that powers nearly every agent you will encounter: the canonical perceive → reason → act → observe loop. Your learning outcome for this lesson is to describe this loop and identify precisely where the core components—the LLM, the controller, tools, and memory—reside within this architecture. Mastering this model is the key to understanding all advanced agentic patterns, as they are extensions or sophisticated implementations of this core engine.

The Canonical Agent Loop: An Architectural Blueprint

At its heart, an agent is a system that continuously interacts with its environment to achieve a goal. This process is formalized into a four-stage loop. Let's look at a high-level visualization of this architecture.

This diagram illustrates the core architecture of an AI agent. The Foundation Model/LLM acts as the central reasoning engine, operating within a closed loop of Perception → Reasoning → Planning → Action → Observation. It interacts with modules for Memory, Tool Use, and more detailed Reasoning/Planning.

As the diagram shows, the agent operates in a continuous cycle:

  1. Perception: The agent receives an input or stimulus. This could be the initial query from a user, the output from a tool it just ran (e.g., an API response), or a change detected in its environment.
  2. Reasoning/Planning: This is the "thinking" phase. The agent's core intelligence, the LLM, processes the perception. It analyzes the current state, its long-term goal, and the information at hand to decide on the next course of action. This might involve decomposing a large goal into smaller steps (planning) or simply determining the single best next action (reasoning).
  3. Action: The agent executes the chosen action. This action is not limited to generating text. Critically, it can involve calling external tools, running code, querying a database, or interacting with other systems.
  4. Observation: The agent takes in the result of its action. A successful tool call might return data; a failed one might return an error message. This new information becomes the perception for the next iteration of the loop, closing the cycle.

This loop continues until the agent determines that its goal has been achieved, at which point it produces a final output. This iterative process allows the agent to handle complex, multi-step tasks that would be impossible with a single, non-agentic LLM call.


Locating the Components within the Loop

Now, let's map the essential components of an agent system—the controller, the LLM, tools, and memory—onto this operational loop. Understanding their placement and interaction is fundamental to agent engineering.

The following article, "The Anatomy of an Agent Loop," provides a remarkably clear and technically grounded explanation of how these pieces fit together. It argues that virtually all agent frameworks converge on the same core architecture.

The Anatomy of an Agent Loop | Steve Kinney

This article breaks down the canonical agent loop into simple pseudocode and explains the underlying mechanics of tool calling, which drives the loop's continuation.

Begin by reading the introduction, which makes the bold claim that all major agent frameworks implement the same fundamental loop. Then, study the section "The loop every framework converges on". Pay close attention to the pseudocode and the explanation of how tool_calls act as a continuation signal, while a text-only response signals termination. This section directly introduces the ReAct (Reasoning and Acting) pattern, which formalizes this cycle.

As you've just read, the entire agentic process can be distilled into a surprisingly simple structure. Let's analyze it piece by piece.

The Controller: The while Loop

The controller is the heart of the agent, the process that orchestrates the entire cycle. In its most common implementation, it is a while loop that runs until a termination condition is met.

From the article's pseudocode:
while (!done) { ... }

This loop is the embodiment of the perceive-reason-act-observe cycle. It continuously drives the agent forward, turn by turn. The controller's logic decides when to call the LLM, when to execute tools, and when to stop. While simple in concept, sophisticated controllers, like those in LangGraph, may replace the while loop with a more complex stateful graph, but the principle of iterative execution remains.

The LLM: The Reasoning Engine

The LLM is the brain of the operation, responsible for the Reasoning and Planning stages. It resides inside the controller's loop. On each iteration, the controller packages the current state (the memory) and passes it to the LLM.

const response = await callLLM(messages);

The LLM's task is to analyze the context and decide what to do next. Crucially, its output is not just content; it's a control signal.

  • If the LLM returns a tool_calls object, it's instructing the controller to Act by executing a specific function. The loop continues.
  • If the LLM returns only plain text, it's signaling that it has a final answer. The controller sees this as a termination condition and breaks the loop.

This dynamic, where the LLM directs the control flow of the application, is the defining characteristic of an agent.

Tools: The Actuators

Tools are the agent's connection to the outside world, enabling the Action phase. They are simply functions that the controller can execute based on the LLM's commands. These can range from a simple get_weather API call to a complex code interpreter.

const results = await executeTools(response.toolCalls);

The controller parses the tool_calls from the LLM's response and invokes the corresponding functions with the specified arguments. The output of these tools—the data, the success message, or the error—is then captured in the Observation phase.

Memory: The Conversation State

Memory is the context or state that persists across iterations of the loop. It's the agent's record of what has happened so far: the initial prompt, its own thoughts, the actions it has taken, and the observations it has made.

In the simple pseudocode, memory is the messages array:
messages.push(...results);

The controller is responsible for managing this memory, appending the LLM's reasoning (message) and the results of tool calls (results) to the history before the next iteration. This growing context is what allows the agent to maintain a coherent strategy over multiple steps.

This diagram offers another view of these interactions, emphasizing the flow of information.

This diagram shows the flow of data within an agent. The central **Model** (LLM) receives **Context Injection** (perception/memory), decides on an **Action** (tool calls), and then **Observes** the results. It also interacts with a **Persist** layer (memory) and is governed by a **Control** layer (the controller/loop).

Production Architectures: Separation of Concerns

While the simple while loop is a powerful mental model, production systems often introduce more explicit separation of concerns. An agent is rarely the entire backend; it's a capability within a larger, mostly deterministic system.

This video from AWS provides an excellent overview of architecting production-grade agents, emphasizing where different components should live.

We Need to Talk About AI Agent Architectures

This video discusses practical agent architectures, focusing on separating the agent's core logic from the surrounding deterministic system and showing how memory is integrated in a production setting.

First, watch the introduction from separation of concerns. It makes a critical distinction: upstream components like API gateways and business logic should be separate from the agent runtime, which contains the LLM, loop, tools, and memory access. Next, see a concrete example of this in the segment on adding memory from add a feature. Notice how the agent itself manages storing and retrieving conversation history, but a separate, deterministic endpoint is used to simply display that history in a UI. Finally, watch the code walkthrough from Let's take a look. This demonstrates a real-world implementation using LangGraph's AgentCoreMemorySaver. The checkpointer object here is a sophisticated memory manager that persists the agent's state between turns. This is a production-grade version of the simple messages.push() we saw earlier.

The video reinforces that in a real system, the controller and memory management might be handled by robust frameworks (like LangGraph's checkpointer) and external services (like DynamoDB), while the core loop of calling the LLM and executing tools remains intact within the agent's dedicated runtime.


From Theory to Practice: A Minimal Viable Agent

To solidify your understanding, let's look at the code for a minimal, working agent. The same article you read earlier provides a concise implementation.

The Anatomy of an Agent Loop | Steve Kinney

This section provides complete, runnable code for a minimal agent, translating the pseudocode into a practical implementation using a standard LLM API.

Now, read the section "Building one from scratch". Walk through the run function line by line. Identify: The messages array, which serves as the Memory. The while (true) loop, which is the Controller. The client.chat.completions.create call, which invokes the LLM for the Reasoning phase. The executeTool call, which performs the Action. The messages.push calls that append the assistant's response and the tool results, representing the Observation phase and updating the memory.

This code makes the abstract loop concrete. You can see how each part of the four-stage cycle maps directly to a few lines of code, all orchestrated by the controller's simple while loop.


Conclusion

In this lesson, we have dissected the canonical agent loop: perceive → reason → act → observe. You have learned that this is the fundamental engine driving agentic behavior. We identified the precise roles and locations of the core components:

  • The Controller: The orchestrator, typically a while loop or a state graph, that executes the cycle.
  • The LLM: The reasoning engine, situated inside the loop, which analyzes the current state and decides the next action.
  • Tools: The actuators, called by the controller based on the LLM's decision, which allow the agent to interact with the world.
  • Memory: The persistent state, usually a list of messages, that is passed to the LLM on each iteration and updated by the controller.

Understanding this architecture is not just academic; it is the prerequisite for building, debugging, and scaling agentic systems. Every complex pattern you will learn about next, from ReAct to multi-agent collaboration, is built upon this foundation.

In our next lesson, we will compare 'agentic workflows' with 'autonomous agents' and begin to explore the common failure modes of this loop, such as hallucinated tool calls, infinite loops, and goal drift. This will equip you with the knowledge to design more robust and reliable agents.