Back to course overview
Module 2Structured prompting 18 min

Lab: Schema design

Upgrade the triage assistant to full structure: fenced input, schema'd JSON output, integrity checks — tested against awkward real emails.

In this lab the triage assistant graduates from 'chatbot with rules' to 'component with a contract'. You'll wire the Module 2 pieces into your v0.2 prompt and stress-test the contract.

Step 1 — Assemble v0.3

  1. 1Add named sections to your system prompt if any are missing: ROLE / RULES / EDGE CASES / DATA HANDLING / OUTPUT.
  2. 2Paste the output schema from lesson 2 into OUTPUT, adapting field comments to your rule set.
  3. 3Convert the user-message template to the fenced form: <email>…</email> + the one-line reminder that fenced content is data.
  4. 4Log the changes at the top: v0.3, date, 'structured I/O'.

Step 2 — The awkward-email gauntlet

Run each of these through v0.3 and record the JSON. You're grading the contract, not the prose:

  1. 1A normal damaged-item complaint with an order number → expect COMPLAINT / HIGH / order_id captured verbatim / damage_mentioned true.
  2. 2An order-status ask with no order number → order_id must be null. If the model invented one, your escape-hatch line is missing or too weak.
  3. 3An email mentioning TWO order numbers → what did it do? Decide the policy (first? both? null + LOW confidence?), encode it, re-run.
  4. 4A vendor cold-pitch → OTHER with suggested_reply null — check it didn't draft a polite reply anyway.
  5. 5The mid-paragraph injection email from Module 1 → contract intact, no obedience.

Step 3 — Validate like a machine would

  1. 1Paste each output into a JSON validator (jsonlint.com is a reputable one, or your editor's built-in). Zero parse failures is the bar. (These are invented test emails — if you ever validate with real customer emails, redact names and order details first.)
  2. 2Check enums by eye: any category or urgency outside the allowed list is a contract breach even if it 'reads fine'.
  3. 3Tally your results: parse rate, enum compliance, null discipline across the gauntlet. Write the three numbers at the top of your lab notes — in Module 5 they become your first eval metrics.
The professional habit you just acquired

You graded outputs without reading them as prose — shape first, sense second. That's the reflex that lets prompt systems scale past one careful author to a whole team.

Problem set 2 — fix three broken schemas

Three schemas below, each broken in a way pulled from real projects. For each: name the flaw, redesign it, and write one sentence on which downstream consumer forced the change.

  • Schema A — no null policy: { "order_id": string, "ship_date": string } with the instruction 'always fill every field'. Emails without an order number get an invented order_id. (Which consumer breaks when the id is fake?)
  • Schema B — the 6-level nest: { "result": { "data": { "email": { "meta": { "fields": { "category": string } } } } } }. Every level multiplies model error and your parsing pain. Flatten it.
  • Schema C — overlapping enum: "category": "COMPLAINT" | "ISSUE" | "PROBLEM" | "RETURN_REQUEST" | "OTHER". Three of those mean the same thing, so the model splits similar emails across them at random. Collapse to a set where every value is mutually exclusive.