QRefAI
Contents
Custom AI Agents

Part 1 — What is an agent, really?

What is an agent, really — and does my problem even need one?

5 min · Updated June 2026

Strip away the hype and an agent is a loop around a language model that can take actions in the world and decide what to do next based on what happened.

That’s it. A model receives some context, decides to call a tool — search a database, file a claim, send an email — sees the result, and loops again, continuing until the task is done or it hits a stopping condition. The “agentic” quality comes from the model controlling the loop: it chooses which action to take, in what order, and when to stop. Compare that to a traditional workflow, where a human engineer hard-codes those decisions in advance.

1.1

Everyone keeps saying “agent” — but what am I actually building?

Workflow

Predefined paths

LLMs and tools orchestrated through code paths you write in advance. You, the engineer, decide the steps.

Agent

Dynamic control

The LLM dynamically directs its own process — deciding which tools to use and in what order. The model controls the loop.

Most Common Mistake

Both are useful. The confusion between them is the most common and expensive mistake teams make — building a fully autonomous multi-agent system for a problem that a routing workflow would solve.

What “the model controls the loop” looks like in code. The whole definition collapses into about fifteen lines. There’s no framework here — just the model provider’s SDK — and that’s the point: the loop is the agent, not any library on top of it.

from anthropic import Anthropic

client = Anthropic()

def run_agent(user_input, tools, tool_functions):
    messages = [{"role": "user", "content": user_input}]

    while True:  # the loop that makes it an "agent"
        response = client.messages.create(
            model="claude-sonnet-4-5-20250929",
            max_tokens=1024,
            tools=tools,
            messages=messages,
        )
        messages.append({"role": "assistant", "content": response.content})

        # The model decided it's done — natural stopping condition.
        if response.stop_reason != "tool_use":
            return response

        # The model chose a tool. We run it and feed the result back.
        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                result = tool_functions[block.name](**block.input)  # engineer supplies the "how"
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": str(result),
                })
        messages.append({"role": "user", "content": tool_results})

Read the three decisions the model is making, not the engineer: which tool to call (block.name), with what arguments (block.input), and when to stop (stop_reason != “tool_use”). In a workflow, all three would be lines of your code instead. That single shift in who owns the control flow is the entire distinction.

Most SDKs now ship a helper that hides this boilerplate — the Anthropic SDK’s tool_runner iterates the same loop for you:

runner = client.beta.messages.tool_runner(
    model="claude-sonnet-4-5-20250929",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": user_input}],
)
for message in runner:  # same loop, managed for you
    ...

Convenient — but worth writing the loop by hand once. Every agent framework in this series is, underneath, a more elaborate version of those fifteen lines.

1.2

My stakeholders want “an autonomous agent” — do we actually need one?

This framing comes from Anthropic’s “Building Effective Agents” guidance, which remains the canonical taxonomy in 2026. The practical lesson hidden in the distinction is the most important piece of advice in this whole series: most business problems do not need a fully autonomous agent.

A predefined workflow with one or two LLM calls is cheaper, faster, more predictable, and infinitely easier to audit. You should reach for genuine agency only when the task has so many branches that you genuinely cannot enumerate them ahead of time. Building a “fully autonomous multi-agent system” for a problem that a routing workflow would solve is the most common and expensive mistake teams make.

Diagram contrasting a workflow (predefined code paths) with an AI agent (LLM dynamically directing its own process and tool use)

So the first design question is never “which agent framework?” It is: does this even need an agent, or is it a workflow?

The test I’d apply: can you draw the decision tree for the task on a whiteboard? If you can enumerate the branches — even twenty of them — it’s a workflow, and you’ll be happier with hard-coded paths. If the branches depend on information you won’t have until runtime, and you genuinely can’t draw them in advance, that’s when agency earns its cost.

Decision flowchart for determining whether a problem needs a fully autonomous AI agent or a simpler predefined workflow
1.3

Every production agent decomposes into the same six concerns

01

Model

The reasoning engine — increasingly several models at different price and capability tiers, not one.

02

Context

Everything the model can see when it decides. The discipline that defines the field.

03

Memory

What persists across turns, sessions, and the agent’s whole operational lifetime.

04

Tools

How the agent touches the outside world, now standardised largely through MCP.

05

Orchestration

The loop, the branching, and coordination between multiple agents.

06

Production envelope

Durability, observability, guardrails, governance — where most projects live or die.

Hold those six in your head. Everything that follows hangs off them.

Look back at the fifteen-line loop with those six in mind and you can already point to four of them: the model, the messages list is proto-context and proto-memory, the tools list, and the while loop is orchestration in its simplest form. The next four articles are the story of what each becomes under production pressure.

Found this useful?

Libraries and frameworks referenced on this page

  • anthropic (Anthropic Python SDK) — used for the raw agent loop and the tool_runner helper. The loop keys on stop_reason == “tool_use” and returns tool_result blocks on the following turn. Model string shown: claude-sonnet-4-5-20250929.