Output Formats: JSON, Tables & More
An answer is only useful if you can use it. A wall of text is hard to paste into a spreadsheet, and a chatty paragraph cannot be read by a program. Telling the model the exact output format is one of the simplest ways to make its answers practical, whether you want a neat table for your manager or JSON for your code.
In this lesson you will learn how to ask for common formats, how to describe a JSON structure precisely, and how to check and parse JSON replies in Python without crashing on the usual mistakes.
Formats for people
For answers that people will read, name the shape and its details:
| You want | Ask for |
|---|---|
| A quick overview | "5 bullet points, each under 15 words" |
| A comparison | "A table with columns: Option, Cost, Pros, Cons" |
| Something to fill in | "Use this template exactly: Name: / Date: / Summary: / Next step:" |
| Steps to follow | "A numbered list of steps, one action per step" |
| A document | "A heading, then 3 short paragraphs, then a one-line conclusion" |
Tables are especially handy. Most assistants show them neatly, and you can copy them into Excel or Google Sheets. If a table will go into a spreadsheet, you can ask for CSV (comma-separated values) instead, which spreadsheets import directly.
Compare these three phone plans for a college student in Kochi.
Return a table with the columns: Plan, Monthly price, Data per day, Best for.
Use only the details I give you below, and write "not given" for missing values.The last sentence matters: it stops the model from filling empty cells with invented numbers.
JSON for programs
JSON (JavaScript Object Notation) is a text format for structured data that every programming language can read. When a program will use the answer, ask for JSON and describe every key:
Read the customer review below and return only JSON, with no other text,
in exactly this shape:
{"sentiment": "positive" | "negative" | "mixed",
"rating_guess": an integer from 1 to 5,
"topics": a list of short strings,
"needs_reply": true or false}Writing the exact shape, the allowed values and the types (integer, list, true or false) gives the model a precise target. You can also describe the structure formally with a JSON Schema, a standard way to describe JSON data:
{
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "mixed"]},
"rating_guess": {"type": "integer", "minimum": 1, "maximum": 5},
"topics": {"type": "array", "items": {"type": "string"}},
"needs_reply": {"type": "boolean"}
},
"required": ["sentiment", "rating_guess", "topics", "needs_reply"],
"additionalProperties": false
}Parsing JSON replies safely
Even with clear instructions, replies sometimes arrive wrapped in a Markdown code fence, with a polite sentence before them, or with a missing key. Never assume the reply is perfect. This function cleans up the common problems and validates the result:
import json
import re
REQUIRED = {"sentiment": str, "rating_guess": int, "topics": list, "needs_reply": bool}
def parse_reply(reply):
match = re.search(r"\{.*\}", reply, re.DOTALL) # the part from the first { to the last }
if not match:
return None, "no JSON object found"
try:
data = json.loads(match.group())
except json.JSONDecodeError as err:
return None, f"invalid JSON: {err.msg}"
for key, kind in REQUIRED.items():
if not isinstance(data.get(key), kind):
return None, f"missing or wrong type: {key}"
if not 1 <= data["rating_guess"] <= 5:
return None, "rating_guess out of range"
return data, "ok"
replies = [
'{"sentiment": "positive", "rating_guess": 5, "topics": ["taste", "service"], "needs_reply": false}',
'Sure! Here is the JSON:\n```json\n{"sentiment": "mixed", "rating_guess": 3, '
'"topics": ["delivery"], "needs_reply": true}\n```',
'{"sentiment": "negative", "rating_guess": "two", "topics": [], "needs_reply": true}',
"{'sentiment': 'positive'}",
]
for reply in replies:
data, status = parse_reply(reply)
print(status, "->", data)ok -> {'sentiment': 'positive', 'rating_guess': 5, 'topics': ['taste', 'service'], 'needs_reply': False}
ok -> {'sentiment': 'mixed', 'rating_guess': 3, 'topics': ['delivery'], 'needs_reply': True}
missing or wrong type: rating_guess -> None
invalid JSON: Expecting property name enclosed in double quotes -> NoneThe first two replies are accepted, even though the second one is wrapped in chatty text and a code fence. The third has the wrong type for rating_guess, and the fourth uses single quotes, which are not valid JSON. In a real app, a failed reply can be retried once with a message such as "Your reply was not valid JSON. Return only the JSON object."
Templates and fixed layouts
Sometimes you need the same layout every time, for example a daily report. Give the template and ask the model to fill it, then check that every heading is present:
template_headings = ["Date:", "Summary:", "Issues:", "Next steps:"]
reply = """Date: 14 Nov 2026
Summary: 46 orders delivered in Pune, 3 delayed by rain.
Next steps: Call the 3 customers and offer free delivery next time."""
missing = [h for h in template_headings if h not in reply]
print("All headings present" if not missing else f"Missing: {missing}")Missing: ['Issues:']
The model skipped the "Issues:" heading, perhaps because there were no issues to report. The check catches it, and your follow-up prompt can say "Keep every heading; write 'None' if a section is empty."
Common mistakes
- Saying "give me JSON" without the shape. You will get different keys every time. Spell out keys, types and allowed values.
- Assuming the reply is always valid. Parse it with error handling, validate it, and retry or flag failures.
- Letting the model fill gaps. Say what to write for missing data ("not given",
null) so it does not invent values. - Over-formatting for people. Five bullet points of three words each can lose the meaning. Choose the format that fits the reader.
Key points
- Name the exact format: bullet count, table columns, template headings or JSON shape.
- Tables and CSV are great for spreadsheets; JSON is the standard for programs.
- Describe JSON with keys, types and allowed values, or with a JSON Schema.
- APIs offer structured output modes that enforce a schema; use them in apps.
- Always parse and validate replies in code, and handle code fences, extra text and wrong types.
Exercise
Add one more rule to parse_reply: topics must contain at most 3 items, and every item must be a non-empty string. Test it with a reply that has 4 topics and with one that has an empty string as a topic.
Show solution
import json
import re
REQUIRED = {"sentiment": str, "rating_guess": int, "topics": list, "needs_reply": bool}
def parse_reply(reply):
match = re.search(r"\{.*\}", reply, re.DOTALL)
if not match:
return None, "no JSON object found"
try:
data = json.loads(match.group())
except json.JSONDecodeError as err:
return None, f"invalid JSON: {err.msg}"
for key, kind in REQUIRED.items():
if not isinstance(data.get(key), kind):
return None, f"missing or wrong type: {key}"
if not 1 <= data["rating_guess"] <= 5:
return None, "rating_guess out of range"
topics = data["topics"]
if len(topics) > 3 or not all(isinstance(t, str) and t.strip() for t in topics):
return None, "topics must be at most 3 non-empty strings"
return data, "ok"
tests = [
'{"sentiment": "mixed", "rating_guess": 3, "topics": ["a", "b", "c", "d"], "needs_reply": true}',
'{"sentiment": "mixed", "rating_guess": 3, "topics": ["price", ""], "needs_reply": true}',
]
for reply in tests:
print(parse_reply(reply)[1])topics must be at most 3 non-empty strings topics must be at most 3 non-empty strings
The new check runs after the type checks, so by then topics is known to be a list and can safely be measured and looped over.
Quick Quiz
1. You want to paste the AI's comparison into a spreadsheet. Which format should you ask for?
Tables and CSV map directly onto spreadsheet rows and columns.
2. Why is {'sentiment': 'positive'} not valid JSON?
JSON requires double quotes; single quotes are a common error.
3. What does an API's structured output mode do?
Structured outputs constrain the reply to your schema, so your code can rely on its shape.
4. What should a prompt say about missing data?
Without guidance, models often fill gaps with invented values.
Learn Generative AI with a mentor
Free lessons get you started. Our AI Training & Workshops training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
