JSON and structured data
Working fluently in both directions: getting clean JSON out, feeding tables and records in, and the handful of pitfalls that break pipelines.
JSON is the lingua franca between models and software — in both directions. You'll request it as output (last lesson) and provide it as input (records, tables, config). Fluency means knowing the handful of places where it goes wrong.
Getting clean JSON out
- Say 'ONLY JSON' and mean it — the classic failure is a helpful preamble ('Here's your JSON!') that breaks the parser. Your schema block already forbids it; your validator (Module 6) will catch the survivors.
- Watch the two killer characters: trailing commas and unescaped quotes inside strings ('The customer said "broken" twice'). Models handle escaping well but not perfectly — another validator job.
- Keep nesting shallow. Two levels is fine; five levels of nested objects multiplies both model errors and your debugging time. Flatten unless structure earns its keep.
- For lists of records, ask for an array of objects —
[{...}, {...}]— one object per email/product/row. Never a prose list you'll have to re-parse.
Feeding structured data in
The reverse direction matters just as much. When your input is inherently tabular — order rows, a product list — format matters for both accuracy and cost:
- CSV/TSV beats JSON for big flat tables — no repeated keys, roughly half the tokens for the same rows. Keep the header row; the model uses it.
- JSON beats CSV for records with structure — optional fields, nesting, mixed types.
- Always state the count: 'The table below has 42 rows.' You learned this in Foundations as truncation defense; in pipelines it becomes an automatic check — ask the model to echo
rows_receivedin its output and compare in code. - Fence it —
<orders>…</orders>— like any other data.
<orders> order_id,date,item,qty,status HL-1041,2026-06-28,Alder Bench,1,delivered HL-1042,2026-06-30,Juniper Throw,2,in_transit HL-1055,2026-07-01,Cast-Iron Trivet,1,delayed </orders> The table above has 3 rows. Return ONLY JSON: {"rows_received": number, "delayed_orders": [{"order_id": string, "item": string}], "summary": string (max 15 words)}.
Small but complete: fenced CSV in, counted rows, schema'd JSON out. Run it, then delete the count line and paste 60 rows — check whether rows_received still matches. You've just built your first automatic integrity check.
Input fencing + output schema + integrity fields is the exact anatomy of every tool call in an AI agent. When you reach the Agentic AI Systems course (or read the analytics agent course's tool design module), you'll recognize this lesson wearing a different hat.