Skip to content

Productivity · Guide

Get Reliable JSON from a Local LLM: Schema, Validation and Retries

Use structured outputs to constrain shape, then validate types and business rules. Valid JSON is a starting point, not evidence that the extracted facts are right.

Metarix Editorial · Nov 5, 2026 · 4 min read

Share

Documentation-based research

Editorial illustration: Get Reliable JSON from a Local LLM: Schema, Validation and Retries
AI-generated editorial illustration created for Metarix. Conceptual artwork, not a product screenshot or a measured result.
On this page

Three checks that are often confused

An automation needs more than a response that resembles JSON. First, the text must parse. Second, the object must match the expected schema. Third, the values must satisfy the application’s meaning and the source evidence. Those are separate checks, and each can fail.

Ollama documents passing JSON Schema through the format field and validating responses with tools such as Pydantic or Zod. This article describes that workflow and a locally verified validation example. It does not claim that a particular local model achieved an extraction accuracy score.

Scroll the table horizontally on smaller screens.

Three different validation layers
LayerExample failureWhat to check
ParsingIncomplete JSONResponse can be parsed
SchemaAmount is a stringRequired fields, types and extra properties
MeaningTotal does not match componentsDomain rules and original source evidence
Metarix editorial worksheet based on the linked sources; not a measured product benchmark.

Define the contract before writing the prompt

Imagine extracting an invoice with invoice_id, currency, subtotal_cents, tax_cents and total_cents. Decide whether fields can be missing, what currencies you support and how ambiguous source text should be represented. Use integer minor units for this example to avoid binary floating-point surprises in arithmetic. Real payment systems must also handle currency-specific units and rounding policies.

Reject unexpected properties where appropriate. Otherwise a model can add a field that an unsuspecting downstream consumer starts treating as an instruction. Never use a generated vendor name, URL or account number as an authorization decision without independent checks.

The schema is not the business rule

A schema can require that total_cents is an integer. It does not by itself prove total_cents equals subtotal_cents plus tax_cents, nor that the amount matches the document. Add semantic validation after parsing. Also check invoice identity and currency against the intended transaction.

For example, subtotal_cents=10000, tax_cents=2000 and total_cents=12000 pass the arithmetic check. Changing total_cents to 11999 should fail. A negative subtotal or a string containing “12000” should fail if the contract requires nonnegative integers. Decide explicitly whether zero values are allowed.

A minimal Python check you can adapt

The example expects a parsed object named data. Each line is valid top-level Python; applications should place this logic in their validation layer.

required = {"invoice_id", "currency", "subtotal_cents", "tax_cents", "total_cents"}

if not isinstance(data, dict) or set(data) != required: raise ValueError("Unexpected fields")

if not isinstance(data["invoice_id"], str) or not data["invoice_id"].strip(): raise ValueError("Missing identity")

if data["currency"] not in {"USD", "EUR", "GBP"}: raise ValueError("Unsupported currency")

amounts = ("subtotal_cents", "tax_cents", "total_cents")

if not all(type(data[k]) is int and data[k] >= 0 for k in amounts): raise ValueError("Invalid amount")

if data["subtotal_cents"] + data["tax_cents"] != data["total_cents"]: raise ValueError("Amounts do not reconcile")

A bounded generation workflow

  • Prepare a narrow schema and a source document that is allowed to be processed on this machine.
  • Request structured output using the documented runtime interface. Keep the schema in the application, not only in a natural-language instruction.
  • Parse and validate the returned object with your chosen schema library, then apply domain checks such as the example above.
  • If validation fails, allow a small bounded retry with specific validation feedback. Do not keep paying or looping indefinitely.
  • Escalate ambiguous or repeated failures to a review queue. Never silently replace missing values with invented defaults.

What we tested and what remains unproven

We ran the validation example on a matching example and negative cases for wrong totals, booleans, strings, negative amounts, missing fields and unexpected fields. Those are deterministic code tests; they are not tests of a model’s understanding.

Even a passing object can describe the wrong invoice. Check against the source and keep provenance, such as a document identifier and reviewer status, outside the model-controlled fields. If OCR is involved, distinguish OCR errors from extraction errors. Lower temperature may improve consistency but is not a guarantee of semantic correctness.

Keep failure visible

Store a clear failure category: parsing, schema, business rule, source mismatch or processing failure. Monitor those categories rather than reporting only a single “JSON success” percentage. A workflow that visibly asks for review is safer than one that produces clean-looking but unverified data.

Before adopting any runtime example, check its current SDK syntax and model support. Ollama’s documentation also identifies feature limitations; do not assume that a local structured-output feature is available through every cloud endpoint.

Official documentation checked 5 November 2026. Documentation-based research; illustrative scenarios are labeled. Product availability and pricing can change.

Ollama structured outputs and validation examples

Evaluate extraction quality

Troubleshoot local model memory

Frequently asked questions

Does JSON Schema guarantee factual accuracy?
No. It constrains structure. Validate business rules and compare the values with the source evidence.
Should failed extraction retry forever?
No. Use a bounded retry policy and an explicit review or failure state.

Share

Keep Reading