The Deska blog

An Agent Loop From Scratch in 200 Lines

Learn how to build an agent loop from scratch using Python to understand the core architecture of modern AI coding assistants and autonomous developer tools.

· 11 min read

Building an agent loop from scratch is the most effective way to understand how modern AI coding assistants actually operate. While high-level frameworks offer convenience, they often obscure the fundamental cycle of observation, reasoning, and action that defines an autonomous system. By stripping away the abstractions, we can see that a functional agent is essentially a controlled loop where an LLM is given access to specific tools and a mechanism to interpret the results of its own actions.

The Anatomy of an Agent Loop

At its core, an agent loop is a state machine. It begins with a prompt, enters a cycle of processing, and exits once a specific condition is met or a final answer is generated. The process follows a predictable pattern often referred to as ReAct (Reason and Act).

  1. Input: The user provides a task.
  2. Thought: The model analyzes the task and decides which tool to use.
  3. Action: The model generates a structured call for a tool.
  4. Observation: The system executes the tool and returns the output to the model.
  5. Evaluation: The model assesses the output and decides if it needs more steps.

This cycle continues until the model determines it has sufficient information to complete the request. The complexity lies not in the loop itself, but in how you manage the history and handle errors when a tool fails or the model hallucination leads to an invalid command.

Minimal Python Implementation

To build an agent loop from scratch, you need a way to manage the conversation history and a registry of functions the model can call. Below is a conceptual structure for a 200 line implementation. We use a simple while loop and a list of dictionaries to track the messages.

import json

class SimpleAgent:
    def __init__(self, model_client, tools):
        self.client = model_client
        self.tools = {t.__name__: t for t in tools}
        self.messages = []

    def run(self, prompt):
        self.messages.append({"role": "user", "content": prompt})
        
        while True:
            response = self.client.chat(messages=self.messages)
            message = response.message
            self.messages.append(message)

            if not message.tool_calls:
                return message.content

            for tool_call in message.tool_calls:
                result = self.execute_tool(tool_call)
                self.messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": str(result)
                })

    def execute_tool(self, tool_call):
        func = self.tools[tool_call.function.name]
        args = json.loads(tool_call.function.arguments)
        return func(**args)

This snippet demonstrates the core logic. You must define your tools as standard Python functions and provide their schemas to the model. The loop handles the handoff between the model thinking and the local execution of code or shell commands.

Tooling and Environment Considerations

An agent is only as useful as the tools it can access. For developers, this typically means a terminal, a file system, and perhaps a web browser. When building your own loop, safety is a primary concern. Running arbitrary shell commands on your host machine is risky. This is why many developers prefer local-first environments where the agent operates within a controlled context.

ComponentResponsibilityRecommended Approach
LLMReasoning and planningGPT-4o or Claude 3.5 Sonnet
Context WindowManaging long conversationsSummarization or sliding window
Tool RegistryMapping names to functionsJSON Schema validation
SandboxExecuting dangerous codeDocker or restricted local folders

Visualizing the Workspace with Deska

Once you have a functional agent loop from scratch, the next challenge is monitoring it. Watching a stream of JSON logs in a standard terminal makes it difficult to debug complex multi-step tasks. This is where a specialized workspace becomes valuable.

Deska provides an infinite canvas workspace designed for this exact purpose. Instead of a single window, you can place multiple panels anywhere on a zoomable plane. When you are running AI coding agents like Claude Code or OpenCode, you can see them operating side by side.

The canvas allows you to arrange a terminal panel, a code editor using Monaco, and a browser panel in a single view. This layout helps you track the agent loop in real time. If the agent modifies a file, you see it in the editor. If it starts a local server, you can view the output in the browser panel. This visibility is crucial when your agent loop is performing complex operations like refactoring a repository or debugging a test suite.

Local-first Development and Privacy

A major hurdle in agent engineering is data privacy. Many developers are hesitant to send their entire codebase to a cloud service. Deska addresses this by being local-first. Your code, files, and even the agent session data stay on your machine.

If you use the lifetime tier, you can use your own API keys. This means the workspace itself does not act as a middleman for your data. For those who prefer a managed experience, Deska also offers managed inference for subscribers. In both cases, the logic of the panels and the coordination of the terminals happen locally on Mac, Windows, or Linux.

Advanced Features: Ask Deska and Mobile

Building a basic loop is just the start. Sophisticated systems often require a way to drive the workspace itself. Deska includes a feature called Ask Deska, which is a voice and chat assistant. Unlike a standard agent loop that only talks to an LLM, Ask Deska can actually manipulate the environment. It can open new panels, run specific commands, and check the status of active sessions.

Furthermore, monitoring a long running agent loop from a desk is not always practical. The Deska mobile app allows you to monitor and continue your work through a secure relay. The devices pair directly, meaning no ports are exposed to the public internet. This is a significant advantage over DIY setups that require complex VPNs or SSH tunnels to check on a running process.

Comparing Frameworks and Custom Loops

When deciding whether to use a framework like LangChain or build an agent loop from scratch, consider the trade-offs.

  • Custom Loops: Offer total control, no hidden overhead, and easier debugging of the core logic. They are ideal for learning and specialized tasks.
  • Frameworks: Provide pre-built integrations for hundreds of tools and databases. They are better for enterprise applications where rapid integration with legacy systems is required.
  • Deska Approach: Deska sits in the middle by providing the environment where both custom and standard coding agents can run. It does not force a specific library on you, but gives you the visual tools to manage the agents you choose to use.

FAQ

How to prevent infinite agent loops?

To prevent an agent from running indefinitely, you must implement a maximum iteration counter in your code. Once the loop exceeds a set number (for example, 10 or 20 steps), the system should force a stop and ask the user for intervention. You should also monitor API costs if you are not using a local LLM.

What is the best LLM for agent tool calling?

Currently, models like Claude 3.5 Sonnet and GPT-4o are considered the leaders for tool calling. They have been specifically trained to output valid JSON and follow complex instructions. If you are working locally, high-parameter models like Llama 3 70B can also perform well, provided you have the hardware to run them.

Can an agent loop run in a terminal?

Yes, most agent loops are designed to run in a terminal environment. In Deska, you can run these agents inside dedicated terminals while seeing the file changes reflected instantly in the side-by-side code editor. This makes the terminal output much easier to interpret.

Build Your Environment

Building the logic of an agent is only half the battle. The other half is creating an environment where that agent can be productive without compromising your security or productivity. By focusing on a local-first approach and using a visual workspace, you can bridge the gap between a simple Python script and a professional development workflow.

To start building and running your own agents in a flexible, infinite canvas, download Deska for your platform today.

💡 Ideas+🐛 BugsSuggest a feature or report a bug