Submit

How to Build an AI Agent: A Developer's Step-by-Step Tutorial

A code-first tutorial on how to build an AI agent: the three core components, MCP tools, orchestration patterns, and when to skip agents entirely.

Written by AiAgentsListing Team

9 min read
How to Build an AI Agent: A Developer's Step-by-Step Tutorial

Most tutorials on how to build an AI agent either skip the code entirely or hand you a framework and hope you figure out the rest. This one does neither. It walks through a working build: what actually counts as an agent, the three pieces every agent needs, how to give it real tools through MCP, and which orchestration pattern and framework fit which job.

How to build an AI agent comes down to three parts: a model that decides what to do, tools it can call to act, and instructions that bound its behavior. Add an orchestration pattern - single agent, routing, orchestrator-workers, or evaluator-optimizer - only once you need one, and skip the agent entirely if a fixed workflow already does the job.

Prerequisites

  • Python 3.10 or higher, and the Python MCP SDK at version 2.0.0 or higher if you plan to build a tool server.
  • The uv package manager, used in the MCP build step below.
  • Familiarity with calling an LLM API and defining function-calling tools. This tutorial does not re-explain what an LLM is.
  • Either an OpenAI account for the Agents SDK examples, or any LLM API key if you're following the plain-code path.

Step 1: Decide if you're building an agent at all

OpenAI's guide to building agents draws a hard line: applications that integrate an LLM but don't let it control workflow execution - simple chatbots, single-turn LLMs, sentiment classifiers - are not agents. An agent is a system that uses an LLM to manage workflow execution, recognize when the workflow is done, correct its own actions, and hand control back to a human on failure. It also has tools it selects dynamically, within guardrails, based on the current state of the task.

Anthropic draws the same line from a different angle: a workflow is a system where LLMs and tools are orchestrated through code paths written in advance. An agent is a system where the LLM directs its own process and tool use, keeping control over how it gets the job done. If you already know every step your system will take, you're building a workflow, not an agent, and that's often the right call. Anthropic's own advice is to find the simplest solution that works, and to accept that this might mean no agentic system at all.

Step 2: How to build an AI agent's three components

Every agent, regardless of framework, is a model, a set of tools, and a set of instructions. Here is the pattern from OpenAI's Agents SDK, reproduced from OpenAI's guide to building agents:

weather_agent = Agent(
name=\"Weather agent\",
instructions=\"You are a helpful agent who can talk to users about the weather\",
tools=[get_weather],
)

name and instructions set the model's behavior and boundaries. tools is a list of functions the model can call. The OpenAI Agents SDK is one concrete implementation of this three-part pattern; OpenAI's guide notes you can implement the same shape in any library, or from scratch against a raw LLM API.

On model choice, OpenAI's guide gives three rules: set up evals first to get a performance baseline, pick the most capable model to hit your accuracy target, then try swapping in smaller models to cut cost and latency once accuracy holds up.

On tools, OpenAI groups them into three types: data tools that retrieve context (query a database, read a PDF, search the web), action tools that change something (send an email, update a CRM record, hand a ticket to a human), and orchestration tools, where one agent calls another agent as a tool. OpenAI calls this the Manager Pattern - a refund agent, a research agent and a writing agent, each callable by a manager agent.

Step 3: Give the agent real tools with MCP

A tool defined in code only helps if it can reach the outside world. MCP is an open standard for connecting AI applications to external systems: data sources like files and databases, tools like search engines and calculators, and prompt templates, the same way USB-C connects hardware regardless of the device on either end. Claude, ChatGPT, and editors including Visual Studio Code, Cursor and MCPJam all support it, so a server built once works across clients.

MCP servers can expose three kinds of capability: resources (file-like data a client can read), tools (functions the LLM can call, with user approval), and prompts (templates for common tasks). Here's the build from the official MCP server tutorial: a weather server exposing get_alerts and get_forecast, connected to Claude for Desktop.

Set up the project with uv:

uv init weather
uv venv
source .venv/bin/activate
uv add \"mcp[cli]\"
touch weather.py

Then start weather.py:

from typing import Any
import httpx2
from mcp.server import MCPServer

mcp = MCPServer(\"weather\")
NWS_API_BASE = \"https://api.weather.gov\"
USER_AGENT = \"weather-app/1.0\"

MCPServer reads your Python type hints and docstrings to generate tool definitions automatically, so functions decorated with @mcp.tool() become callable tools without a separate schema file. One rule matters more than it looks: if the server runs over STDIO, never write to stdout. print() will corrupt the JSON-RPC messages and break the connection. Use the standard logging module instead, which writes to stderr, with one logger per module via logging.getLogger(name). HTTP-based servers don't have this restriction.

Cursor and Claude Code both connect to MCP servers built this way, and both appear in the MCP servers directory on AI Agents Listing.

Step 4: Pick an orchestration pattern

Anthropic's engineering team, after working with dozens of teams building production agents, found the most successful builds use simple, composable patterns rather than heavy frameworks. Four patterns cover most of what you'll need:

Single agent. One model, its tools and its instructions, running its own loop until the task is done or it needs to hand back to a human. No orchestration layer needed.

Routing. Classify the input, then send it to a specialized followup task. Anthropic's examples: sending customer service queries down different downstream paths, or routing easy questions to a cheaper model and hard ones to a more capable one.

Orchestrator-workers. A central LLM breaks a task into pieces it can't predict in advance, delegates each piece to a worker LLM, then synthesizes the results. Anthropic's example is coding, where the number of files a change touches isn't known upfront.

Evaluator-optimizer. One LLM call produces a response; a second evaluates it and feeds back criticism in a loop. This works when there are clear evaluation criteria and iterative refinement is worth the extra calls - Anthropic compares it to the iterative writing process.

On which framework to reach for, Anthropic's own recommendation is to start with LLM APIs directly. Many of the four patterns above are a few lines of code without any framework. If you do reach for one, Anthropic names the Claude Agent SDK, AWS's Strands Agents SDK, the drag-and-drop tool Rivet, and Vellum. Anthropic's warning: frameworks add abstraction layers that can hide the actual prompts and responses, which makes debugging harder, and incorrect assumptions about what's happening under the hood are a common source of error. If you use a framework, read its source.

For OpenAI-based builds, the OpenAI Agents SDK gives you the Agent object and tool wiring shown in Step 2 without writing the loop yourself.

LangGraph is a different kind of tool: a low-level orchestration runtime, not a starter template. It's built for mixing deterministic, hand-coded steps with LLM-driven agentic steps inside the same graph, and it adds durable execution, persistence across failures, human-in-the-loop state inspection, and both short- and long-term memory. LangGraph is used by companies including Klarna, Uber and J.P. Morgan. Install it and run a minimal graph:

pip install -U langgraph
from langgraph.graph import StateGraph, MessagesState, START, END

def mock_llm(state: MessagesState):
return {\"messages\": [{\"role\": \"ai\", \"content\": \"hello world\"}]}

graph = StateGraph(MessagesState)
graph.add_node(mock_llm)
graph.add_edge(START, \"mock_llm\")
graph.add_edge(\"mock_llm\", END)
graph = graph.compile()
graph.invoke({\"messages\": [{\"role\": \"user\", \"content\": \"hi!\"}]})

Reach for LangGraph when you need that state control in production: long-running agents, checkpoints a human can inspect, or a graph mixing fixed steps with agentic ones. Reach for plain LLM API code, or the Agents SDK if you're already on OpenAI's stack, when a single pattern from the list above covers your case.

Step 5: Add guardrails, and decide if the agent should ship

An agent should operate within guardrails that define what it's allowed to do, and it should select tools dynamically based on the state of the task rather than run a fixed script. Anthropic's example of a guardrail pattern is parallelization: one model instance handles the user's query while a second model instance screens it for inappropriate content at the same time.

During execution, Anthropic says agents need to gain ground truth from the environment at each step, a tool call result or a code execution result, to judge their own progress, and they should pause for human feedback at checkpoints or when they hit a blocker. OpenAI's version of the same idea: an agent should recognize when a workflow is complete, correct its own actions, and halt and hand control back to a human on failure rather than continue guessing.

On whether to build the agent at all, OpenAI's guide says agents suit workflows that have resisted automation: complex decisions with nuance and exceptions, rulesets too intricate to maintain, or heavy reliance on unstructured natural language. If a task doesn't clearly fit one of those, a deterministic solution may be enough. Anthropic makes the cost concrete: agentic systems trade latency and cost for task performance, and for many applications, optimizing a single LLM call with retrieval and good in-context examples already does the job.

Common mistakes

  • Reaching for a framework before understanding what it does under the hood. Anthropic calls incorrect assumptions about the underlying code a common source of error.
  • Adding orchestration complexity, such as routing, multiple workers or an evaluator loop, when a single agent or a single LLM call would clear the bar.
  • Writing to stdout with print() inside a STDIO-based MCP server, which corrupts the JSON-RPC stream and breaks the connection.
  • Skipping evals before swapping in a smaller, cheaper model, which makes it impossible to tell whether the accuracy drop is acceptable.
  • Building an agent for a task with fixed, known steps, where a workflow with predefined code paths is more predictable and easier to debug.

What's new (as of 21 August 2026)

The MCP specification is now at version 2026-07-28, the latest release, and the official server tutorial requires Python 3.10 or higher plus Python MCP SDK 2.0.0 or higher to build against it. On the no-code side, Microsoft published a guide to building an AI agent through Microsoft 365 Copilot on 10 August 2026, with some examples updated on 21 August 2026. It covers the same define-the-problem, add-knowledge, test-and-share arc as this tutorial, but for business users clicking through Copilot Chat rather than developers writing code.

Key takeaways

  • An agent is defined by the LLM controlling workflow execution and tool selection itself, not by having an LLM somewhere in the pipeline; a chatbot or a fixed pipeline of LLM calls is a workflow, not an agent.
  • Every agent, in any framework, reduces to three parts: a model, a set of tools, and instructions that bound its behavior.
  • MCP, currently at spec version 2026-07-28, lets one server built once expose tools to Claude, ChatGPT, Cursor, MCPJam and other clients without a separate integration per client.
  • Anthropic's advice, drawn from working with dozens of production teams, is to start with plain LLM API code and only add a framework like LangGraph or the Claude Agent SDK once you know what the simpler version can't do.
  • Agents cost more latency and money than a single optimized LLM call or a deterministic pipeline, so both the OpenAI and Anthropic guides say to check the task actually needs one before building it.

FAQ

What is the difference between an AI agent and a chatbot?

A chatbot answers questions; it doesn't control a workflow or decide what action to take next. An agent uses the LLM to manage the execution of a task: deciding what to do, calling tools, checking its own progress, and stopping or handing off to a human when something goes wrong. OpenAI's guide is explicit that single-turn LLMs and sentiment classifiers are not agents for the same reason.

Should I use LangGraph or the OpenAI Agents SDK?

Use the OpenAI Agents SDK when building on OpenAI's model stack and wanting the Agent, instructions, tools pattern without writing the loop yourself. Use LangGraph when the build needs durable execution, persistence across failures, human-in-the-loop state inspection, or a graph mixing fixed, deterministic steps with LLM-driven ones. LangGraph is a low-level orchestration runtime, not a starter template, and companies including Klarna, Uber and J.P. Morgan run it in production.

Do I need MCP to build an AI agent?

No. MCP is one way to connect an agent's tools to real external systems, such as files, databases and search engines, without writing a custom integration for every client that uses the agent. Tools can also be wired directly through function calling in the model's own API. MCP is worth adopting once the same tool server needs to work across multiple clients, such as Claude, ChatGPT, Cursor and Visual Studio Code, without rebuilding the integration each time.

When should I not build an agent?

When the task has a small, fixed set of steps that are already known, or when a single, well-prompted LLM call with retrieval already meets the accuracy bar. Anthropic's guidance is to find the simplest solution first, since agentic systems trade latency and cost for task performance. OpenAI's guidance is to check that the task involves genuinely complex decisions, unwieldy rules, or unstructured data before committing to an agent.

Browse the agents directory on AI Agents Listing to see which of these patterns current coding, research and support agents actually ship with.

Share:

Subscribe to our newsletter

One email a week. New agents, MCP servers and skills, and what is actually getting traction.

Read next