Build your first agent
Your first working agent with the Claude API.
Goal: run a working agent that performs a real business task. We build up from a
single prompt to a simple agent.
Associated code: code/agent_mvp.py.
First: a single prompt (the building block)
Everything starts with one API call. This is the core you'll use hundreds of times:
import os
from dotenv import load_dotenv
import anthropic
load_dotenv("code/.env")
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1000,
system="You are an experienced e-commerce copywriter. Write compelling, honest copy.",
messages=[
{"role": "user", "content": "Write a product description for an oak dining table."}
],
)
for block in response.content:
if block.type == "text":
print(block.text)
Three things to remember:
system= who the agent is and what the rules are (your most important control lever).messages= the conversation; always starts with ausermessage.response.content= a list of blocks; extract thetextblocks.
This is not an agent โ it's one question, one answer. But it is the engine behind everything.
Turning on adaptive thinking & effort
For more serious work, you let the model think before it responds. With Opus 4.8 you do this with adaptive thinking (the model decides how deeply to think) and the effort level:
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=2000,
thinking={"type": "adaptive"}, # model thinks where needed
output_config={"effort": "high"}, # depth/cost level: low|medium|high|xhigh|max
system="...",
messages=[...],
)
Note (Opus 4.8/4.7): do NOT use
temperature,top_p, orbudget_tokensโ these have been
removed and will produce an error. You steer the model through your prompt and theeffortlevel.
From prompt to agent: structured output
An agent often needs to return a reliable, machine-readable result, not just free-form text. For that you use messages.parse() with a schema (via Pydantic). This gives you guaranteed valid, structured data back:
from pydantic import BaseModel
class ProductListing(BaseModel):
title: str
description: str
bullets: list[str]
seo_keywords: list[str]
response = client.messages.parse(
model="claude-opus-4-8",
max_tokens=2000,
messages=[{"role": "user", "content": "Create a listing for an oak dining table."}],
output_format=ProductListing,
)
result = response.parsed_output # a validated ProductListing object
print(result.title)
print(result.bullets)
This is enormously powerful for a business: you can feed the output directly into a database, webshop, or email without wrestling with text parsing.
What makes an agent different: handling multiple tasks autonomously
agent_mvp.py shows a first form of autonomy: you give the agent a task list and a role, and it processes them one by one, with logging and a cost counter. It's not yet a full tool-using loop (that's modules 05 and 06), but it shows the pattern:
for each task in the work list:
let the agent execute the task
validate and store the result
add up the cost
stop if the daily budget limit is reached
Run it:
python code/agent_mvp.py
You'll see the agent generate a set of product descriptions, neatly structured, with a cost summary at the end. Adjust the WORK_LIST at the top of the file to match your own business task.
How a single prompt becomes an agent
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ agent_mvp.py โ
โ โ
โ WORK_LIST โ
โ โ โ
โ โโโโบ Task 1 โโโบ API call โโโบ Result 1 โโโบ log โ
โ โโโโบ Task 2 โโโบ API call โโโบ Result 2 โโโบ log โ
โ โโโโบ Task 3 โโโบ API call โโโบ Result 3 โโโบ log โ
โ โ โ
โ Cost counter โ
โ (stop at budget) ๐ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Each task runs through the same API call. The model doesn't yet decide what to do next on its own โ that's the agentic loop in modules 05 and 06. But it's already doing real, automated work.
๐ก In Claude.ai: The system prompt is the perfect thing to design and refine in the
claude.ai web chat. Paste your draft system prompt, then test it with sample user messages.
Once the output looks right, copy the prompt into your Python script. Running the full
automated task list requires the Python API โ claude.ai handles one conversation at a time.
The system prompt: your most important tool
90% of your agent's quality lives in the system prompt. A good system prompt contains:
- Role โ "You are an experienced e-commerce copywriter specializing in furniture."
- Goal โ "Write copy that converts and is honest."
- Style & rules โ "Tone: warm and knowledgeable. Never exaggerate. Always 3โ5 bullets."
- Boundaries โ "Don't invent specs you don't know. When in doubt: leave it out."
- Output format โ "Provide a title, description, bullets, and keywords."
Use the template as a starting point. Iterate: run, review the output, improve the prompt, repeat. This "prompt tuning" is a core skill.
Tip for Opus 4.8: the model follows instructions very literally and is cautious about
overstating things. Write your instructions as clear facts and guidelines, not as shouty
"YOU MUST ALWAYS..."-commands โ that tends to backfire.
Common beginner mistakes
max_tokenstoo low โ response gets cut off. Set it generously (1,000โ4,000 for text).- No
.envfile โ API key hardcoded in your script. Never do this. - Everything on Opus โ expensive. Use Haiku for simple tasks (module 03).
- No logging โ you don't know what your agent did or what it cost. Always log (module 10).
Your assignment
- Run
agent_mvp.pyunchanged. - Replace the
WORK_LISTand the system prompt with your own business task from module 02. - Iterate on the system prompt until the output is good enough to show a client.
- Deliver the output once "by hand" to a real (potential) client โ feedback is gold.