Structured outputs are API contracts, act like it
Schema-enforced output killed the regex parser. It did not kill the need to version, validate and monitor what your model returns.
There is a museum in my heart for the code we all wrote in 2023: regexes fishing JSON out of markdown fences, retry loops begging the model to "respond ONLY with valid JSON", the try/except around json.loads with a fallback prompt. Gone, mostly. Schema-enforced generation like OpenAI's structured outputs constrains decoding so the shape is guaranteed.

The shape. Not the contents. And here is where teams built a new generation of bugs on top of a solved problem.
valid JSON, wrong universe
Structured output guarantees "refund_amount": number. It does not
guarantee the number is not 45000 on a $45 order. A schema-valid
hallucination is still a hallucination; it just parses on the first
try now. Faster wrongness, delivered with confidence.
So treat model output like input from a partner API you do not fully trust, because that is what it is:
- Schema for shape, then semantic validation for sanity: ranges, enum cross-checks, "does this order id exist".
- Version the schema like any contract. Adding a field is cheap. Renaming one silently changes what the model attends to, and your downstream consumers deserve a changelog.
- Log validation failures as their own metric. A rising rejection rate is your earliest signal that a model update moved under you.
enums are load-bearing
One field design carries most of the safety: closed enums over free
strings wherever a value drives behavior. "action": "refund" | "escalate" | "none"
cannot invent a fourth action. "action": string absolutely will, at
2 a.m., during the on-call shift of whoever trusted it.
The parser war is over. The contract work is the same as it always was with any system that talks to yours: trust, but validate, and keep the receipts.