Skip to content
Naveen Raj

Building AI Agents from Scratch with Python · Building the Core Loop

Implementing the Agent Loop

The core of an agent is a while loop around a single LLM call, where the model's response tells you whether to keep looping or stop.

# agent.py
import os
from dotenv import load_dotenv
from anthropic import Anthropic

load_dotenv()
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
MODEL = "claude-sonnet-4-5"


def run_agent(user_input: str, messages: list[dict]) -> list[dict]:
    messages.append({"role": "user", "content": user_input})

    while True:
        response = client.messages.create(
            model=MODEL,
            max_tokens=1024,
            messages=messages,
        )
        messages.append({"role": "assistant", "content": response.content})

        # No tool call in this minimal version yet — Chapter 3 adds one.
        # For now, the loop always terminates after one turn.
        return messages


if __name__ == "__main__":
    history: list[dict] = []
    while True:
        user_input = input("You: ")
        if user_input.lower() in {"exit", "quit"}:
            break
        history = run_agent(user_input, history)
        print("Agent:", history[-1]["content"][0].text)

This isn't a real agent yet — there's no branching decision, so it's really just a chat loop. The important structural piece is already there though: messages is the agent's entire world. Every perceive/think/act cycle reads from it and appends to it. Chapter 3 adds the piece that makes this an agent: letting response contain a tool call instead of a plain reply, and looping again when it does.