Get data back, not prose
Turn messy customer emails into validated records your code can trust.
You build: extract.py: reads an email, returns a checked Claim record, and retries once when the model gets the shape wrong.
- Python 3.11 or newer and uv
- An OpenRouter key (free models are enough)
-
01Write ten short customer emails about parcels: lost, damaged, late
This is Parcel Desk, the small courier the rest of the course works for. Its customers email in claims for refunds.
ls samples | wc -lYou pass when: Ten files. Make two of them awkward: one with no parcel number, one with two amounts.
-
02Define a Claim: parcel id, reason (lost, damaged or late), amount, currency
uv run --with pydantic python -c "from extract import Claim; print(Claim.model_json_schema()['required'])"You pass when: The required fields print. Reason only accepts the three values.
-
03Ask the model for JSON in that shape and validate it
uv run --with openai --with pydantic extract.py samples/You pass when: Ten lines of valid JSON, one per email. The email with no parcel number has a null id, not an invented one.
-
04On a validation error, send the error back to the model once, then give up loudly
uv run --with openai --with pydantic extract.py samples/; echo "exit $?"You pass when: Exit 0 when all ten validate. Break one on purpose (ask for a fourth reason value) and the exit code is not 0.
The check runs on the computer, not on your word: a step passes when its command exits with 0 there.
Computers are not set up on this site yet. Run each command on your own machine and compare with "You pass when".
Commands run in labs/14-structured-output and may take up to 60 seconds each. Every command starts a new shell: put keys and settings in a .env file there, it is loaded each time.