Knowledge & actions · Explore this field ↗ · Implementation · 4 min read
Structured output validation: a schema is not a decision
Use typed output as a boundary between a model and a service, then apply the business checks that a well-formed object cannot know.
Output acceptance boundary
- 01Parse proposal
- 02Check contract
- 03Check live rules
- 04Confirm or reject
Conceptual flow; live rule checks remain outside the model.
Original conceptual diagram · not a live trace or measured result.Put a boundary around the model
Structured output is valuable because it replaces a prose guess with a declared handoff. Define an operation object with a version, a narrow action name, values, confidence only where it has a real use, and a reference to the user turn that produced it. Parse it once at the service boundary. A downstream worker should receive typed data, not a paragraph that it must reinterpret. JSON Schema describes constraints on a JSON instance; it does not know whether an account is active or a requested appointment still exists.
Start with the smallest contract that makes an action inspectable. An address-change proposal might require customerRef, newAddress, confirmationToken, and intentVersion. It should not carry an unbounded note field just because a model can write one. Give every field an owner: user-supplied, system-derived, or tool-derived. That simple distinction stops a generated value from impersonating an authoritative lookup.
Separate three kinds of validity
First check transport and parsing: the object is present, within size limits, and decodes once. Next check schema: required fields, allowed enum values, types, and rejected extra properties. Finally check business validity: the referenced customer is the authenticated customer, the confirmation is current, the serviceable area accepts the address, and a pending shipment has not locked the change. These are different failures and deserve different logs.
Worked example, hypothetical: {action:"refund", amount:0, currency:"USD", orderId:"o-19"} can be structurally valid if zero is allowed by a loose schema. The business validator should reject it with a non-executing result such as amount_must_be_positive, rather than silently converting it or asking a model to repair it. The user-facing reply can ask for the missing choice; the audit record should retain the machine-readable reason.
Make rejection a designed outcome
A rejection is not an exception path to hide. Return an outcome object with accepted, reasonCode, field errors where safe, and an allowed next action. Avoid exposing internal authorization rules or raw database errors. For a stale price quote, say it needs a refresh, preserve the user draft, and require a new confirmation. For an unauthorized order reference, do not reveal whether that order exists.
Do not let a model retry unchanged invalid output in a loop. The validator should identify whether the system needs a fresh lookup, a user clarification, a human review, or an outright refusal. Schema validation output can locate a failing instance value, which is useful for an operator; it is not a license to show an implementation trace to a customer.
Bind values to their source and time
A typed object can still contain a value copied from old conversation context. Store provenance beside consequential fields: where the value came from, when it was checked, which policy or tool version validated it, and whether the user explicitly confirmed it. If the product permits corrections, invalidate dependent fields rather than retaining a green check forever. A new delivery country can invalidate tax, inventory, and delivery estimates.
This also makes a useful review record. An operator should be able to distinguish “the user entered this account number” from “the model inferred it from a previous message.” The latter may be acceptable for a suggested draft but should not be accepted as an authenticated identity claim.
Test rejection as carefully as success
Build cases for malformed JSON, valid-but-unknown identifiers, extra properties, stale confirmation, changed authorization, conflicting currencies, and a tool response that disagrees with the proposal. Include a counterexample where the model chooses a valid enum that is inappropriate for the user’s country. The test asserts that no mutation occurs and that the visible result is truthful.
Success criteria are concrete: every action input has a current contract version; all schema failures produce a bounded code; all business failures avoid mutation; and replaying a rejected request does not turn it into an action. These are service properties, not a claim that the model understands the business.
Keep contracts versioned and small
Publish a compatibility policy for each operation. A worker receiving version 2 should know whether it can reject version 1, translate it, or require a new conversation turn. Review enum expansion, optional-field defaults, and deprecated fields as behavior changes, not harmless serialization edits. A permissive parser may ease migration while making it impossible to spot a model using an obsolete action.
The practical limit is that schemas express structure and some local constraints, not ethics, authorization, inventory truth, or user intent. OWASP identifies insecure output handling as an application risk; JSON Schema supplies a vocabulary for structural assertions. The business rules in between remain your product’s responsibility.
Take it into the review
Action validation ledger
| Operation | Schema rule | Business check | Safe rejection |
|---|---|---|---|
| change_address | country enum; postal text | customer owns order; shipment unlocked | refresh required |
| refund | positive money object | amount available; agent authorized | review required |
| book_slot | ISO time; service code | slot still free; location eligible | choose another slot |
| upload_note | known document reference | tenant access; retention allowed | not available |
A starting artifact to adapt to your service—not a ready-made policy, compliance certificate or test result.
Primary reading
Sources and limits
These links support the architecture, policy, or product behavior discussed above. Vendor documentation describes vendor features; it is not independent proof of performance. Current details should be rechecked before a production decision.
What the sources establish
JSON Schema: A Media Type for Describing JSON Documents
JSON Schema defines structural assertions and annotations for JSON instances, including validation output concepts; it does not define an application’s authorization or business policy.
Limits: This source is a schema specification, not guidance on model behavior or domain validation.
Checked 2026-09-19 · JSON Schema / IETF draft publication · source publication date not established.
Open original source ↗OWASP Top 10 for Large Language Model Applications
OWASP identifies application-layer risks around model inputs and outputs that need application controls.
Limits: The project is risk guidance, not a prescribed output-contract design.
Checked 2026-09-19 · OWASP · source publication date not established.
Open original source ↗Procedures and worked examples are editorial synthesis. Preparation/review dates are not claimed historical publication dates.