Curriculum › Prompt Engineering & Structured Output · 19% of the exam

Structured output and schema enforcement

What you'll be able to do

  • Choose between tool-use-as-structured-output and prompted JSON for a given requirement
  • Design a schema that constrains the model without starving it of room to reason
  • Decide when to repair a malformed response versus reject and retry
  • Account for truncation cutting structured output off mid-object

What you’ll be able to do

  • Choose between tool-use-as-structured-output and prompted JSON for a given requirement
  • Design a schema that constrains the model without starving it of room to reason
  • Decide when to repair a malformed response versus reject and retry

What you need to know

Two ways to ask for structure, and they fail differently

Asking Claude to "respond in JSON" inside a prompt is a request, not an enforcement mechanism. The model can wrap it in a markdown code fence, add a sentence of commentary before or after it, or produce a value that's syntactically valid JSON but doesn't match the shape you needed.

Defining a tool whose input schema is the structure you want, and having Claude call that tool, is a stronger contract: the platform validates the call against the schema before it ever reaches your code as a tool_use block. This is the standard architecture for reliable structured output, not a workaround.

  • Tool-use as structured output — define a tool (e.g. submit_classification) purely to receive the payload; no side effect required. The schema is enforced at the point of generation.
  • Prompted JSON — asking in plain text for a JSON object. Cheaper to set up, meaningfully more fragile in production. Reserve it for low-stakes, human-reviewed output.

Schema strictness is a tradeoff, not a pure win

A schema with every field required and tightly typed reduces malformed output, but an overly rigid schema can also box the model into a corner — for example, requiring a single category enum for input that genuinely spans two categories forces a wrong answer instead of surfacing the ambiguity.

Architect the schema to make ambiguity representable: an optional secondary_category field, or a confidence field, gives the model a place to put uncertainty instead of forcing a false-precise single answer.

Repair, reject, or retry — pick deliberately

When output fails schema validation, three responses are available, and picking the wrong one by default is the actual exam trap:

  • Repair — send the validation error back to the model in a short follow-up turn and ask it to correct just the invalid field. Cheap, fast, appropriate for low-stakes formatting slips.
  • Reject and retry from scratch — appropriate when the failure suggests the model misunderstood the task, not just the format. A retry with the same prompt that already failed rarely helps; add the specific validation error to the retry.
  • Reject and escalate — for compliance-sensitive fields, treat repeated validation failure as a signal to hand off to a human rather than keep coercing the model toward a shape it isn't producing.

Every one of these first requires checking stop_reason. A response truncated by max_tokens mid-object isn't a schema violation to repair — it's an incomplete generation that needs a larger budget or a continuation, not a correction turn.

Key concept

Tool-use enforces a schema at generation time; prompted JSON only asks for one. Pick tool-use whenever the output must reliably parse, and check stop_reason before deciding a response is even complete enough to validate.

When a scenario complains that "the model sometimes doesn't return valid JSON," the answer is almost always to switch from prompted JSON to tool-use, not to write a more forceful prompt.

Practice scenario

ScenarioA document-classification pipeline prompts Claude to "return a JSON object with category and confidence." Roughly 1 in 20 responses fails to parse — sometimes wrapped in a code fence, sometimes with a trailing sentence of explanation.
Work it through, then open this

This is the textbook case for switching to tool-use as structured output. Define a tool like submit_classification(category, confidence) with no real side effect, and have the model call it instead of writing prose. The schema is enforced before the payload ever reaches application code, eliminating the code-fence and stray-commentary failure modes entirely — not by writing a stricter prompt, but by changing the mechanism.

Build exercise — Convert prompted JSON to tool-use

Intermediate · 25 min

What you’ll learn

  • Recognizing when prompted JSON is the wrong mechanism
  • Designing a schema that leaves room for genuine ambiguity
  • Choosing repair vs reject for a validation failure
  1. Take a prompt that asks the model to “respond in JSON” and define an equivalent tool whose input schema matches the same shape.

    • Why: This moves enforcement from a request to a platform-validated constraint.
    • You should see: A tool definition that would have rejected any of your pipeline’s past malformed responses at generation time.
  2. Add a field to the schema that represents genuine ambiguity your current rigid schema forces the model to resolve incorrectly.

    • Why: An overly strict schema doesn’t prevent ambiguity, it just hides it behind a falsely confident answer.
    • You should see: A schema with somewhere for uncertainty to go, like an optional secondary field or a confidence score.
  3. Write the repair-turn logic for a validation failure, and separately decide which failures should escalate instead.

    • Why: Not every malformed response deserves the same response; treating all of them identically wastes retries on cases that need a human.
    • You should see: A clear rule, not a single catch-all retry loop.

Exam traps

Prompting for JSON and hoping the model complies exactly

A prompt is a request. Tool-use enforces the schema at generation time; prompted JSON only asks for it.

Treating any schema violation as a reason to surface a raw error to the user

Most validation failures are recoverable with a short repair turn, not a dead end.

Writing a schema so permissive the model has no real constraint to work against

A schema that accepts almost anything doesn’t actually enforce structure — it just moves the validation problem downstream.

Not checking stop_reason before parsing output as complete

A max_tokens truncation mid-object looks like a schema violation but is actually an incomplete generation. It needs a bigger budget, not a repair turn.

Retrying a malformed response with the identical prompt

The same prompt that already failed rarely succeeds differently. Include the specific validation error in the retry.

Assuming tool-use output never needs validation because it’s “structured”

Tool-use enforces shape, not business logic. A schema-valid response can still be wrong; validation and repair aren’t purely a prompted-JSON problem.

Sources

Quick check

A team adds chain-of-thought reasoning to every prompt in their application, including simple lookups with no real multi-step logic. What's the most likely outcome?