A friendly paragraph is great for a person to read, but hard for your app to use. If your code needs to read the answer — to show a category, fill a form, or decide what to do next — ask for structured output: usually JSON with fields you define.
Prose versus data
Asking "What category is this support ticket?" might return:
This looks like it's probably a billing issue, since the user mentions being charged twice.
Asking for structured output returns something your code can use directly:
{"category": "billing", "needs_human": false}
Many model APIs let you pass a schema — a description of exactly which fields and types you expect — and the model is constrained to follow it. This makes valid JSON far more reliable than just asking politely in the prompt.
Always check what comes back
Even with a schema, treat the model's output as a suggestion until your code has checked it. The JSON can be perfectly formed and still be wrong — the wrong category, a made-up value, or something your app does not support.
# academy-check
import json
ALLOWED = {"billing", "login", "bug", "other"}
def read_category(raw_text):
try:
data = json.loads(raw_text)
except json.JSONDecodeError:
return "other", "could not read the model's answer"
category = data.get("category") if isinstance(data, dict) else None
if category not in ALLOWED:
return "other", f"unexpected category: {category!r}"
return category, "ok"
assert read_category('{"category": "billing"}') == ("billing", "ok")
assert read_category('{"category": "refunds"}')[0] == "other"
assert read_category("Sure! It's billing.")[0] == "other"
The pattern — ask for a structure, then validate it, with a safe fallback — is one of the most important habits in AI engineering. It appears in almost every real AI feature.
Try it: design the JSON you would want back for "extract the date, amount, and shop name from a receipt". Which fields could the model get wrong, and how would your code notice?
Quick check: the model returns valid JSON with "category": "refunds", but your app only supports four categories. What should happen? (Your code rejects it and uses a safe fallback, such as "other" or a human review.)