ailiteracynepal 🇳🇵
Text size

Chapter 02 · Section III · 11 min read

2.3 Asking for structured output: JSON, tables, checklists

How to get the model to return something a machine — or a hurried human — can parse. JSON schemas, Markdown tables, and the pitfalls of both.

“Give me a few thoughts” produces a blob of prose that a human has to read carefully and a machine cannot read at all. “Return a JSON array with these three fields” produces something you can pipe into the next step. Structured output is the difference between a prompt you demo and a prompt you ship.

When to reach for structure

  • You’ll parse the output with code. Non-negotiable — you need a strict format.
  • You’ll paste the output into a spreadsheet, doc, or ticket. A table is faster to review than a paragraph.
  • You want multiple items with the same shape. “Extract every deadline from this contract” is a list, not a story.
  • You’re comparing options. A table makes trade-offs visible; a paragraph hides them.

JSON — the workhorse

The strongest pattern:

Extract the following fields from the receipt text and return valid JSON only.

Fields:
- vendor: string
- date: ISO 8601 date (YYYY-MM-DD)
- total_npr: number (in Nepali rupees, no currency symbol)
- items: array of { name: string, qty: number, price_npr: number }

If a field is missing, use null. Do not invent values.

Return only the JSON. No preamble, no code fences.

<receipt>
Bhat Bhateni Supermarket
2081-03-14
Rice 5kg     650
Cooking oil  340
TOTAL:       990
</receipt>

Notes on what makes this work:

  • The schema is explicit. Types (string, number, ISO 8601) close off ambiguity.
  • “Return only the JSON. No preamble, no code fences.” Without this line, half of models wrap the JSON in ```json ... ``` or add “Here’s the JSON you asked for:” — both break JSON.parse.
  • “If a field is missing, use null. Do not invent values.” Without this line, models will make up plausible-looking dates and totals.

If the platform supports structured outputs or JSON mode natively (OpenAI, Anthropic, Google all do), turn it on. It enforces valid JSON at the sampler level, which is stricter than any prompt instruction.

Markdown tables — for humans

Compare the three phones below in a Markdown table with columns:
Model | Battery (mAh) | Price (NPR) | Best for

<phones>
...
</phones>

Tables force the model into a fixed shape and make comparison visible. They’re the right choice when the reader is a person, not a script.

Checklists — for actions

Return a Markdown checklist of the steps needed to open a bank account in
Nepal as a first-time customer. One step per line, starting with "- [ ]".

Checklists are underused. They read as actionable, they force the model to think in discrete steps, and they render in most doc tools.

The escape-hatch problem

Even a well-instructed model sometimes decides to be helpful and add “Sure, here’s the JSON:” before the JSON. Three lines of defense:

  1. Say it explicitly. “Return only valid JSON. No preamble, no explanation, no code fences.”
  2. Say it twice. Once at the top of the prompt, once at the bottom.
  3. Post-process defensively. In code, strip leading/trailing whitespace and code-fence markers before parsing.

Structured output is a constraint on the model, not the data

Structured output makes the model easier to consume, but it does not make the answer correct. A well-formatted JSON blob with a wrong vendor field is worse than a paragraph with the right vendor — you’re now confidently piping wrong data into the next step. Chapter 3 covers reliability separately from format.

Check your understanding

Quick check

Your prompt asks for JSON, but the model keeps wrapping its response in a triple-backtick code fence, which crashes your JSON.parse. Which of the following is the LEAST effective fix?