Schemas make LLM output trustworthy. Prompts do not.
Instead of asking for JSON, make anything that is not JSON fail to pass.
Contents
Asking politely has a ceiling
A common approach is to write this in the prompt:
Reply only with JSON in the format below. Do not add anything else.It works. About 99% of the time. The remaining 1% grows with your traffic.
Enforce it with structure
Making the model follow a format and refusing output that does not follow it are different things. The second one is code, not prose.
record ExtractedInvoice(String vendor, LocalDate issuedOn, long totalAmount) {}
ExtractedInvoice result = client.structured(prompt, ExtractedInvoice.class);Now a format violation is a parse failure, and a parse failure takes a defined path: retry, or human review. That is a different kind of guarantee than one more "must" in the prompt.
A narrower schema shortens the prompt
Field names and types already carry intent. totalAmount: long says
"digits only, no currency symbol" without a sentence saying so.