Skip to the content.

Context

An LLM is asked for output in a fixed shape (JSON, a delimited record), and the parsed result feeds code on the critical path. Some providers can enforce a schema and some cannot, and even an enforced schema does not guarantee a response the code can consume.

Example

Multi-word-expression detection asks the LLM for a JSON array (groups of word positions in a sentence) but refuses to blindly trust that it will get one.

The same layered try / extract / validate / fall-back appears in the translation validator, the simplification service, and the example generators.

Problem

How can a malformed response, one that code cannot safely consume, be kept from turning into a failed request?

Forces

Solution

Do not trust the raw output’s shape.

Where the provider can enforce a schema (structured output), request it: syntax slips then disappear at the source. Where it cannot, repair the syntax in code: strip known wrappers, attempt a plain parse, and if the model wrapped the output in prose, find the expected structure inside the text and parse that.

In both cases, check in code what the schema cannot guarantee: that the response is complete, that it is not a refusal, and that it satisfies the structural constraints the code relies on (types, ranges, required fields, references into the input). On failure, degrade gracefully (a default, a skip, a retry, or the next provider in a fallback chain of LLM vendors) instead of raising.

Keep the strictness in code, where it is deterministic and testable, rather than in ever-longer prompt instructions. The question here is only whether code can consume the output; whether consumable output is correct is the concern of Reject and Reprompt and LLM-Checking-LLM.

A provider that enforces a schema sends JSON straight to the check; output from one that does not has its syntax repaired in code first. Either way, code checks what no schema guarantees (the response is complete, not a refusal, and its indices point into the input), and a response that fails degrades to a fallback instead of raising.
A provider that enforces a schema sends JSON straight to the check; output from one that does not has its syntax repaired in code first. Either way, code checks what no schema guarantees (the response is complete, not a refusal, and its indices point into the input), and a response that fails degrades to a fallback instead of raising.

Consequences

Known Uses

Notes


💬 Open an issue about this pattern