Lesson 11 · Domain 4 — Prompt Engineering & Structured Output (20% of exam)
Explicit criteria and few-shot examples shape what Claude decides. This lesson is about guaranteeing the shape of what comes back — and knowing exactly where that guarantee stops.
Defining an extraction tool with an input_schema and reading the result out of the tool_use block is the reliable way to get schema-compliant structured output. It eliminates an entire class of failure — malformed JSON, missing quotes, trailing commas — that used to require regex cleanup on free-text output.
It does not eliminate semantic errors. Line items that don't sum to the stated total, a value landing in the wrong field, a category that's technically valid JSON but factually wrong — none of that is caught by schema validation. The schema checks shape, not truth.
const invoiceSchema = {
name: "extract_invoice",
input_schema: {
type: "object",
properties: {
total: { type: "number" },
lineItems: {
type: "array",
items: {
type: "object",
properties: {
description: { type: "string" },
amount: { type: "number" },
},
},
},
vendorTaxId: { type: ["string", "null"] }, // nullable — don't fabricate
category: {
type: "string",
enum: ["utilities", "supplies", "travel", "other"],
},
},
required: ["total", "lineItems", "category"],
},
};
Two schema-design habits worth internalizing: make a field nullable/optional rather than required when the source document genuinely might not contain that information — a required field the model can't fill honestly gets fabricated to satisfy the schema instead. And give enum fields an "other" escape valve (paired with a free-text detail field) plus an "unclear" value for genuinely ambiguous cases, so the model isn't forced into a wrong bucket just because none of the fixed options fit.
When a semantic validation error is caught downstream (totals don't reconcile, a required relationship is violated), appending the specific error back into a follow-up request — original document, the failed extraction, and the exact validation error — reliably guides the model to self-correct. This is retry-with-error-feedback.
It has one hard limit: retrying cannot produce information that was never in the source document to begin with. If a required field is simply absent from what you gave the model, no amount of retrying fixes that — the fix there is making the field nullable, not looping harder.
A useful diagnostic habit: have extractions include a detected_pattern field describing what in the text triggered a given finding. When developers start dismissing findings, this field lets you analyze why systematically instead of guessing.
Primary source: Anthropic's Claude API docs cover tool use and JSON schema enforcement directly — this lesson compresses Task Statements 4.3 and 4.4.
Want to design a schema for a real extraction task you have in mind? Describe the source documents and I'll help you think through required vs. nullable fields.