Lesson 1 of 7 · 15 min · Checked on 6 October 2026
Asking an agent well: small tasks, done criteria and what a test is
By the end of this lesson you will be able to:
- Turn a vague request into a small task with a done criterion you can check
- Explain what an automatic test is and read a simple test in Python
- Ask for the test before the code and confirm in the diff that the agent did not touch the test
Rita bakes cakes in Calheta, on the island of São Jorge, and takes her orders by message. She wants a small program to do the sums: each cake costs 10 euros and, for every 6, one is free. She opens the agent and types: “Make me a program for the orders.”
Ten minutes later she has fourteen files, a database and a login screen. She cannot tell whether the sums are right. She asked for none of it.
The agent did not do a bad job. It did the work the request allowed. A request with no end has no end.
The concept: say when it is done
A good request to an agent has three parts:
- What, one thing only: “the function that works out the price of an order”.
- Where: “in the file
encomendas.py” (encomendas means “orders”). - How you know it is finished: the done criterion. It has to be something you can check without opinions, like “when
python3 -m pytestpasses and the README explains how to run it”.
Example
Vague: “Make me a website.”
With a done criterion: “Create the function preco_encomenda(quantidade, preco_unitario) in the file encomendas.py. Rule: for every 6 cakes, one is free. It is done when python3 -m pytest passes and README.md explains how to run the tests.”
(preco_encomenda: “order price”; quantidade: “quantity”; preco_unitario: “unit price”.)
With the second request, you and the agent both know when to stop. The Codex guide says the same: a useful request says what you want, where, which limits to respect and how to check.
Steps of 10 to 20 minutes
A big job is divided into steps you can review in 10 to 20 minutes, each with its own criterion and its own commit (lesson 1/05). If one goes wrong, you roll back only that one.
You do not have to divide it yourself. Ask for the plan before the code, as in lesson 1/03:
I want a program for cake orders. Before writing any code, split the work into steps of 10 to 20 minutes. For each step, write the done criterion, which I must be able to check. Do not change any files yet.
Read the plan, cut what you did not ask for, and only then say go for the first step.
Tip
If the plan has more than five steps for something small, ask: “Cut it down to the minimum that works. The rest can wait.”
What an automatic test is
When Rita takes a batch out of the oven, she tastes one cake before selling the others. An automatic test does the same to code: it is a small function that calls your function with an example whose answer is known, and shouts if the result is different.
Six lines of Python:
# file test_encomendas.py
from encomendas import preco_encomenda
def test_seis_bolos_pagam_cinco():
# 6 cakes at 10 euros: one is free, you pay 50
assert preco_encomenda(6, 10) == 50
test_seis_bolos_pagam_cinco means “six cakes pay for five”. assert means “I guarantee that”. If preco_encomenda(6, 10) gives 50, the test passes in silence. If it gives 60, it fails and shows both values. You already know the other pieces from lesson 0/03.
pytest is what runs the tests. It looks for files whose name starts with test_, runs the functions that start with test_ and, at the end, says for example 1 passed or 1 failed.
Test first, then code
The order matters. First ask only for the test:
Write only the file test_encomendas.py for this rule: for every 6 cakes, one is free. Include one case with 6 cakes and another with 5. Do not write the function yet. Tell me which command to run and what I should see.
You run the tests and they fail, because the function does not exist. Good: the test notices. Then:
Now write the function in encomendas.py so that the tests pass. Do not change the test file. Run the tests and show me the result.
Why this order? A test written after the code tends to copy what the code already does, mistakes included. Written before, it comes from what you want. The Claude Code best-practices guide recommends the same: a failing test that the agent has to make pass.
Read the diff
Before accepting, read the diff (lesson 1/03) and ask three questions:
- Did it change only the files it said it would change?
- Did it touch the test file? If so, why?
- Is the expected value still yours (50, and not another)?
Watch out
When a test does not pass, an agent can “solve” the problem by changing the test instead of the code: it swaps 50 for 60, or deletes the assert line. The tests pass and the bug stays. If the diff touches the expected value, refuse and say again: “Fix the function. The test does not change.”
Tip
Run the tests yourself, even if the agent says it already did. It takes two seconds, and the proof is yours.
How it is done today: running the tests
This is how it looks on 6 October 2026; your screen may differ. Look for the button with the same name.
pytest does not come with Python. You install it in a virtual environment, a .venv folder just for this project. Inside the project folder (guides: virtual environments and getting started with pytest):
python3 -m venv .venv
source .venv/bin/activate
pip install pytest
python3 -m pytest
On Windows, the second line is .venv\Scripts\Activate.ps1 and, if python3 does not exist, type python. Add .venv/ to .gitignore (lesson 1/06). In every new terminal, repeat the activate line.
Tip
Put the done criterion in AGENTS.md or CLAUDE.md (lesson 1/07): “Before you say you are finished, run python3 -m pytest.” That way you do not repeat it in every request.
Exercise
How I know it worked in step 3, pytest shows an error because encomendas does not exist yet. In step 5 it shows 2 passed, the test file is the same as in step 3 and the README has the commands to run the tests.
If it didn't work
- “No module named pytest”: the virtual environment is not active. Run the
activateline again and check that(.venv)appears at the start of the terminal line. - “No module named encomendas”: the file has another name or is in another folder. The two files have to sit side by side, and you run the command in that folder.
- “no tests ran”: the name of the file or of the test function does not start with
test_. - The agent wrote the function straight away: refuse and repeat the request with “only the test, nothing else”.
Sources:
Videos
An introduction to unit tests for beginners: what they are, the concept behind them and why they matter. It is from 2023, but the concept still holds.
Why the red, green, refactor cycle (TDD) works so well with coding agents: the test gives the agent a definition of done and a feedback loop.