Skip to content
bits
Give your model tools · Lesson 6 of 10

Strict schemas

Tutor:

A schema tells Claude what shape you want. By default it's guidance, not a guarantee. Claude follows it very well, but now and then a flight-booking tool that needs passengers: 2 gets "2" or "two", or a required field goes missing. One bad call in a thousand is still a crash in production.

Add strict: true to a tool and the guidance becomes a rule. Claude's output is limited, token by token, to text that fits your schema, so the input you get always matches it. The technique is called grammar- constrained sampling.

import type Anthropic from "@anthropic-ai/sdk";
export const bookFlight: Anthropic.Tool = {
name: "book_flight",
description: "Book seats on a flight. Use it only after the user has confirmed the flight and the number of passengers.",
strict: true,
input_schema: {
type: "object",
properties: {
flight_number: { type: "string", description: "Airline code and number, e.g. TP1351" },
date: { type: "string", description: "Departure date, YYYY-MM-DD" },
passengers: { type: "integer", description: "Number of seats, 1 to 9" },
},
required: ["flight_number", "date", "passengers"],
additionalProperties: false,
},
};
TypeScriptUTF-8● lines 6–15: strict: true
Tutor:

Two things change in the schema. strict sits at the top level, next to name. And every object says additionalProperties: false, meaning “no fields except the ones listed”. Strict mode needs that.

It isn't free. The first request with a new schema waits a little while the API compiles it (the result is cached for 24 hours). There are limits per request: at most 20 strict tools, and 24 optional parameters across all of them. So save strict mode for the tools where a malformed call would really hurt.

quick check+20 neurons
Tutor:

What does strict: true guarantee?

    Type your answer or tap an option · Enter checks

    Tutor:

    Sometimes you don't want a tool call at all. You want Claude's answer as JSON: a list of extracted fields, a label, a summary in a fixed shape. That's structured outputs, and it uses the same machinery. Pass a schema in output_config.format and the reply's text is guaranteed to parse and match it.

    import Anthropic from "@anthropic-ai/sdk";
    const client = new Anthropic();
    const reply = await client.messages.create({
    model: "claude-haiku-5-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Table for two at Nonna's, Friday 7:30pm" }],
    output_config: {
    format: {
    type: "json_schema",
    schema: {
    type: "object",
    properties: {
    restaurant: { type: "string" },
    day: { type: "string" },
    party_size: { type: "integer" },
    },
    required: ["restaurant", "day", "party_size"],
    additionalProperties: false,
    },
    },
    },
    });
    const text = reply.content.find((block) => block.type === "text");
    if (text) console.log(JSON.parse(text.text)); // { restaurant: "Nonna's", day: "Friday", party_size: 2 }
    TypeScriptUTF-8
    Tutor:

    The rule of thumb: strict tools control how Claude calls your code; structured outputs control what Claude says back. You can use both in one request. And the guarantee has edges: if a reply is cut off by max_tokens, or Claude declines, the JSON can still be incomplete. Check stop_reason before you parse.

    quick check+20 neurons
    Tutor:

    You want Claude to read support emails and return { category, urgency } for your dashboard. Nothing needs to run. Which fits?

      Type your answer or tap an option · Enter checks

      Tutor:

      Your turn. Without any of this, you're relying on the prompt. Ask Claude to turn “two adults, Friday, Lisbon” into JSON with passengers as a number, plus day and city. Run it a few times and check the type of passengers each time.

      Your turn

      Run your prompt and the replies land here.

        • Includes the booking, not yet
        • Names the fields, not yet
        • Says passengers is a number, not yet
        • Asks for JSON only, not yet
        • Ran at 1.0, not yet
        run at
        ~0 tokens

        Turn on JavaScript to run prompts.