DEV Community

Daniel Marin
Daniel Marin

Posted on

How to Build an AI Agent from Scratch: A Step-by-Step Guide

A step-by-step guide to going from a blank folder to a working agent, without the hype.

"AI agent" has become one of the most overloaded words in tech. Depending on who you ask, it's either a ChatGPT wrapper, a multi-step workflow, or a fully autonomous system that replaces an employee.

Here's the definition I actually use when I sit down to build one: an AI agent is an LLM in a loop that can use tools, read from and write to memory, and make decisions about what to do next.

That definition is small enough to build in an afternoon, and powerful enough to automate real work. This is the guide I wish someone had handed me before I started.

Step 1: Define the Agent's Job (Narrowly)

The single biggest predictor of whether your agent will work is how clearly you can describe its job. Vague goals produce vague agents.

The rule of thumb: if you can't describe the success criteria in one sentence, the scope is too broad.

Too broad: "An agent that helps me manage my business."

Good: "An agent that reads incoming invoice emails, extracts vendor, amount, and due date, then appends a row to a Google Sheet."

Before writing any code, write down three things: the input the agent receives, the output it produces, and the boundary, meaning what it is explicitly not allowed to do (send email, spend money, delete files). That boundary is what keeps an autonomous loop safe.

Step 2: Pick the Model and the Loop

Every agent has two core pieces: a model that makes decisions, and a loop that feeds those decisions back into the next step.

For most projects in 2026, the default model choice is Claude Sonnet 4.6. It's fast, cheap enough to run in a loop, and strong at tool use. Reach for Opus when the task requires deep reasoning over long context.

The loop itself is deceptively simple:

while not done:
    response = model.run(messages, tools=available_tools)
    if response.has_tool_call:
        result = execute_tool(response.tool_call)
        messages.append(result)
    else:
        done = True
        return response.text
Enter fullscreen mode Exit fullscreen mode

That's it. Everything else (memory, planning, multi-agent orchestration) is a variation on this pattern. If you're using Claude Code as your runtime, the loop is already implemented for you. You just supply the tools and the instructions.

Step 3: Give the Agent Tools (This Is Where It Gets Real)

An LLM without tools can only produce text. An LLM with tools can read files, call APIs, query databases, and trigger side effects in the world. Tools are what turn a chatbot into an agent.

There are roughly three ways to give your agent tools, in increasing order of power:

1. Built-in tools. Filesystem, bash, web fetch. Claude Code ships with these out of the box. If your agent's job involves reading code, running tests, or pulling data from URLs, you already have everything you need.

2. Custom functions. Write a function, describe its inputs and outputs in JSON schema, and hand it to the model. Good for private APIs, internal databases, and anything specific to your project.

3. MCP servers. The Model Context Protocol is the standard for exposing tools to AI agents. Instead of re-implementing Gmail, Slack, or Postgres integrations for every project, you run (or build) an MCP server once and plug it into any agent. This is the path that scales.

Step 4: Write the System Prompt (aka CLAUDE.md)

The system prompt is the agent's job description. It tells the model who it is, what tools it has, what the success criteria are, and critically, what it should refuse to do.

A good system prompt has four sections:

  • Role: "You are an agent that..."
  • Inputs and outputs: what you'll receive and what you should produce
  • How to use your tools: when to reach for each one, in what order
  • Guardrails: explicit limits, things to escalate, never-do actions

In Claude Code, this prompt lives in a file called CLAUDE.md at the root of your project. The agent reads it on every invocation. If you find yourself re-explaining the same thing across runs, that's a signal the information belongs in CLAUDE.md instead.

Step 5: Add Memory (When the Agent Needs to Remember)

A single-shot agent is stateless. Each run starts fresh. That's fine for "parse this invoice" but useless for "keep track of which customers have been contacted."

You give agents memory the same way you give yourself memory: by writing things down.

Two patterns cover most use cases:

Scratchpad memory. A single Markdown file the agent reads at the start of each run and appends to at the end. Simple, inspectable, easy to debug. Good for personal agents and small teams.

Structured memory. A database or vector store the agent queries through tools. Necessary when memory grows past what fits comfortably in context, or when multiple agents share state.

Start with scratchpad memory. Upgrade only when you hit a concrete limit. Most agents never do.

Step 6: Run Agents in Parallel (When One Isn't Enough)

Once a single agent is working, the natural next step is to run several at once. Parallel agents are how you scale from "automate one task" to "process a queue of tasks," or "explore several solutions simultaneously and pick the best."

The common patterns:

  • Fan-out / fan-in: split a big task into independent subtasks, run them in parallel, merge the results. Great for research, code review, and batch processing.
  • Specialist agents: a planner delegates to specialists (tester, writer, reviewer), each with its own system prompt and tools.
  • Critic loops: one agent proposes, another critiques, the first revises. Useful when quality matters more than speed.

Step 7: Test, Observe, Iterate

Agents fail in ways that deterministic programs don't. They hallucinate tool arguments, loop on the same action, or misread the system prompt. The cure is observability.

Three things to put in place before you trust an agent with anything real:

Log every tool call. Inputs, outputs, and the model's stated reasoning. When something goes wrong, this is your black box recorder.

Run on a fixed eval set. A folder of sample inputs and expected outputs. Every prompt change gets re-run against it. You'd be surprised how often a "small tweak" regresses an edge case.

Put irreversible actions behind confirmations. Sending email, deleting data, spending money. These should either require human approval or be locked behind a hard-coded allowlist until the agent has earned trust.

The Lesson I Keep Relearning

The agents that end up valuable aren't usually the most ambitious ones. They're the ones with a narrow job, clear boundaries, and a prompt that's been refined through a hundred real runs.

Treat the CLAUDE.md like a living document. Every bug you hit is a line you should add so the agent doesn't hit it again. Start small, ship it, and let the scope grow from there.

Getting Started

You can absolutely build all of this from first principles, and you should, at least once, to understand the moving parts. But for real projects, starting from a battle-tested template is faster and less error-prone.

I publish a collection of free, copy-paste Claude Code playbooks at claudecodehq.com, including an AI Agent Builder that scaffolds a custom agent from a plain-English description, an MCP Server Builder for exposing your own tools, and a Parallel Task Agents template for running multiple sub-agents concurrently. Worth a look if you want to skip the boilerplate and get to the interesting parts.

Originally published on claudecodehq.com

Top comments (0)