Skip to main content
How-to Building AI agents

Build your first agent

An agent is a model wired to a tool and a loop. This walks through the smallest version that actually works: one goal, one tool, a loop that requests, executes, and returns, and the guardrails that keep it from running away from you.

6 steps13 min readLast verified August 2026

What you’ll learn

  • Pick a goal narrow enough to need exactly one tool, and state both the goal and the tool in a single sentence each.
  • Write a tool definition, name, description, input schema, that gives the model enough signal to decide when to use it.
  • Build the request, execute, return loop that turns a single tool call into a working agent.
  • Add a stop condition and a hard step cap so the loop cannot spin forever on a broken tool or an underspecified goal.
  • Add a human approval checkpoint before any tool call that sends, spends, deletes, or otherwise touches something real.

An agent is not a special kind of model. It is a model wired to two things: a tool it can call, and a loop that keeps talking to it until the job is done. This walks through building the smallest version of that, one goal, one tool, and a loop tight enough to see exactly what happens at every step. Skip everything else for now, memory, planning, multiple tools, until this one works end to end.

Before you start: any model that supports tool use, sometimes called function calling, from a hosted API to a local model that exposes the same interface; a place to run code, a short script is enough, no framework required; and one real tool you can call from that code, a function, an API, a file read. Nothing here needs more than whatever the model call itself costs.

1. Pick a small goal and the one tool it needs

Start narrower than feels useful. A good first goal has one clear tool need and an obvious way to tell whether it succeeded: "check whether a website is up and report its status code," not "monitor my infrastructure." "Look up an exchange rate and convert an amount," not "manage my budget." If the goal needs three tools, you are building three agents worth of complexity, not testing the loop.

Name the one tool the goal needs before writing any code. For "is this site up," the tool is a function that takes a URL and returns a status code. That is the entire surface area the model gets for this exercise. Everything else, it has to answer from its own knowledge, or say it does not know.

Check: you can state the goal and the one tool it needs in a single sentence each. If you cannot, the goal is still too big.
New to this? Tool use, sometimes called function calling, is a feature the model API itself supports, not something you build from scratch. You describe a function in plain terms and the model asks for it by name; your code is what actually runs it.

2. Define the tool: name, what it does, its inputs

A tool definition is not the function itself, it is the description of the function that you hand to the model. The model never sees your code. It sees three things: a name, a description of what the tool does and when to use it, and a schema for the inputs it needs to make the call. The description does most of the work, it is the only signal the model has for deciding whether this tool is relevant to the current turn.

A minimal tool definition
tool = {
  name: "check_url",
  description:
    "Checks whether a URL is reachable and returns its HTTP status code. Use this when the user asks whether a site or endpoint is up, down, or reachable.",
  inputs: {
    url: {
      type: "string",
      required: true,
      description: "The full URL to check, including https://"
    }
  }
}
Check: read the description out loud as if you knew nothing about the tool. If it does not say when to use it, tighten it before moving on.

3. Call the model and let it decide

Send the model the goal and the tool definition together, then give it a request that tool could plausibly answer. Do not force the tool call. The model should read the description and decide on its own whether the request needs it. This is also the test that the description from step 2 actually works: give it a request the tool cannot help with, and a well-described tool leads to a plain answer, or an honest "I do not know," not a forced, irrelevant call.

One call, tool available, decision left to the model
response = model.call(
  system: "You have access to tools. Use one only when it helps answer the request.",
  tools: [tool],
  messages: [{ role: "user", content: "Is https://example.com up right now?" }]
)
Check: the response is either a normal text answer, or a structured request naming the tool and the input it wants to call it with, never both mixed into one blob of text.

4. Run the loop: request, execute, return, repeat

This is the part that turns a single tool call into an agent. The model never runs your code, it requests a call by name and arguments, your code executes it, and you hand the result back as part of the conversation so the model can use it in its next reply.1 Then you check whether it is done. If not, you go around again.

  1. 1Send goal + tool listyour code, to the model
  2. 2Model respondsplain text, or a tool call request
  3. 3Execute the toolyour code runs it, never the model
  4. 4Return the resultappended back into the conversation
  5. 5Check for donefinal answer, stop signal, or step cap
The agent loop, one pass
The loop: request, execute, return, repeat
messages = [{ role: "user", content: goal }]
steps = 0

while steps < MAX_STEPS:
    reply = model.call(messages, tools=[tool])
    messages.append(reply)

    if reply.type == "final_answer":
        break

    if reply.type == "tool_call":
        result = run_tool(reply.tool_name, reply.tool_input)
        messages.append({ role: "tool_result", content: result })

    steps += 1
Check: run it with logging on every iteration. You should see the tool name and input on the way in, and the raw result on the way back, before the model produces its final answer.

5. Add a stop condition and a step cap

Two separate guards, not one. A stop condition is the agent's own signal that it is done: a final answer, a specific tool result that means the goal is reached, or a deliberate "give up" response you define. A step cap is a hard number, MAX_STEPS above, and it is not a scenario you expect to hit, it is a circuit breaker. A tool that never resolves, a model that keeps re-requesting the same call, or a goal that was underspecified would otherwise loop forever, burning tokens on every pass with nothing to show for it.

Set the cap low at first, five or ten iterations, and only raise it once you have watched the loop run a few times and understand why it needs more. A loop that needs fifty steps to check a URL is not a bigger version of the same agent. It is a bug.

Check: force a failure, unplug the tool or make it always error, and confirm the loop still exits at the step cap instead of running until you kill the process.

6. Keep a human in the loop for anything real

Everything above is safe to let run unattended because nothing in it touches the outside world. The moment a tool can send a message, spend money, delete something, or write to a system another person depends on, the loop needs a checkpoint, not a log line after the fact.

  • Add an approval step between "model requests the call" and "your code executes it" for anything irreversible: sending an email, making a purchase, deleting a record, pushing to production.
  • Show the exact call and its inputs at that checkpoint, not a summary. "Send an email" is not enough, show the recipient, subject, and body.
  • Log every tool call and its result regardless of stakes. Low-risk actions still need a trail for when something goes wrong.
  • Treat a tool's own output as untrusted on the next loop. A scraped page or an API response can carry text aimed at steering the model, not just data for it to use.
Check: pick the single most consequential tool call your agent can make, and confirm a human sees it, with the real inputs, before it runs, not after.
Key idea
A tool definition, a loop that requests, executes, and returns, a stop condition backed by a hard step cap, and a human checkpoint on anything real. That is the whole shape of an agent. Everything past this is scale, not a different idea.
Going further: Once the loop works, two upgrades matter most: a second tool, which mostly means another entry in the tool list and tighter descriptions so the model does not confuse the two, and retries with backoff for a tool call that fails for a transient reason, a timeout or a rate limit, separate from the step cap, which exists to stop a loop that is not failing, just spinning.

This is the shortest path from a model that talks to one that acts. Once the loop works for a single tool, adding a second is mostly repetition: another entry in the tool list, a name-based dispatch in the executor, and tighter descriptions so the model does not confuse the two. For the concepts underneath all of this, models, tools, memory, and where the loop sits, see What an AI agent actually is. For a fuller build with real code across multiple lessons, the Building with AI course covers this same loop plus what comes after it: memory, planning, and agents with more than one tool.

Sources

Verified against primary sources: August 2026.

  1. Tool use with Claude. Anthropic (official docs). https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview
Read nextWhat an AI agent actually is