CertSafari
    Anthropic Claude Certified Architect – Foundations (CCAR-F)· Lessons

    Domain 4 · Lesson 21/30

    Extraction Tools and tool_choice: Forcing Structured Output

    Enforce structured output using tool use and JSON schemas

    10 min read
    3.33% of exam
    5 sources
    Published 4 Oct 2026
    Docs as of 30 Sep 2026

    What you will be able to do

    • Explain why defining an extraction tool with a JSON schema, especially with strict: true, gives schema-compliant output that never has JSON syntax errors
    • Read the extracted data out of the input field of a tool_use block
    • Pick tool_choice auto, any, or a forced tool for a given extraction pipeline
    • Recognise when forced tool choice is rejected (manual extended thinking, the newest models) and what to use instead

    Key concept

    Extraction tool — An extraction tool is defined only so that Claude will fill in its JSON-schema input. The structured data you want is the tool call's input object. You are not asking Claude to run an operation. With strict mode on, that input is guaranteed to match the schema.

    1.Why a tool schema beats asking for JSON

    If you ask Claude in plain prose to 'reply in JSON', the result depends on how well it follows instructions. You can get a stray preamble, a missing brace, or a number written as a string. Tool use takes a different approach. Anthropic describes it as a contract: your application states which operations exist and what shape their inputs take, and Claude decides when to call them. Claude never runs anything itself. It produces a structured request that matches your schema.

    For extraction, that structured request is the output you want. The Anthropic cookbook describes a print_sentiment_scores tool whose only job is to get Claude to produce well-structured JSON. The tool does nothing. Its schema defines the shape of the answer.

    On its own, a schema guides Claude but does not guarantee anything. The strict tool use docs say that without strict mode Claude can still return the wrong types or leave out required fields. Setting strict: true closes that gap with grammar-constrained sampling: Claude can only generate tokens that keep the output valid for the schema. Malformed JSON can't be produced at all.

    Checkpoint 1 of 6· Check yourself

    A booking tool needs passengers as an integer. Without strict mode, what does the documentation say can happen?

    Sources123

    2.Defining the tool and reading the tool_use block

    Setup takes three steps. First, write a JSON schema as the tool's input_schema. Second, add strict: true at the top level of the tool definition, next to name, description and input_schema. Third, handle the call. When Claude uses the tool, the response has stop_reason set to tool_use and contains one or more tool_use content blocks. Each block has an id, the tool name, and an input object that follows your schema.

    A strict tool's response: the extracted data is the input objectjson
    {
      "type": "tool_use",
      "name": "get_weather",
      "input": {
        "location": "San Francisco, CA"
      }
    }

    Your code finds this block in response.content and reads input. That object is your structured record. For an extraction tool, input is already the result, so there's no real work to run on it. In an agentic loop, your code would run the operation and send the output back in a tool_result block. Strict mode also guarantees the tool name is always valid, so your dispatch code can trust it.

    Checkpoint 2 of 6· Put it in order

    Put the steps for enabling strict tool use in order

    1. 1.Set "strict": true as a top-level property of the tool definition
    2. 2.Define a JSON schema for the tool's input_schema
    3. 3.Read the input field of the returned tool_use block, which follows the schema

    Sources42

    3.tool_choice: auto, any, or a named tool

    Defining a tool doesn't make Claude use it. The tool_choice field controls whether a call happens. In the cookbook's deliberately weak example, Claude got a sentiment tool and a calculator under auto. For an excited tweet about a meal it replied with friendly chat and called no tool. For a tweet about cats it called the calculator. Strict mode doesn't help here: it controls the shape of a tool call, not whether one is made.

    The four tool_choice options and the extraction scenario each fits
    tool_choiceBehaviourExtraction use
    {"type": "auto"} (default with tools)Claude decides whether to call any tool, and may reply with textConversational flows; pipelines that need every input extracted must not rely on it
    {"type": "any"}Claude must call one of the provided tools but picks whichSeveral extraction schemas (invoice, contract, receipt) and an unknown document type
    {"type": "tool", "name": "..."}Claude must call that specific toolMake sure a particular metadata extraction step runs before any enrichment
    {"type": "none"}Claude cannot use tools (default when no tools are provided)Turns where you want prose only

    any fits a document classifier that has several extraction schemas. The cookbook describes it as telling Claude "you must call a tool, but you can pick which one". A text-free response is ruled out, but Claude still chooses the schema that fits the document. Forcing a named tool is stricter. Use it when one particular extraction has to happen, for example pulling metadata before later steps depend on it.

    Checkpoint 3 of 6· Fill the gap

    Complete the request so Claude must call get_weather specifically

    response = client.messages.create(
        model="claude-opus-5",
        max_tokens=1024,
        tools=tools,
        tool_choice={"type": " ? ", "name": "get_weather"},
        messages=[{"role": "user", "content": "What's the weather like in San Francisco?"}],
    )

    Sources53

    4.What forcing costs, and where it is rejected

    With any or a named tool, the API prefills the assistant turn so that a tool call is required. As a result, Claude writes no natural-language explanation before the tool_use block, even if your prompt asks for one. Anthropic says its testing shows this should not reduce performance. If you need commentary as well as the tool call, the documented approach is to keep tool_choice at auto and add an explicit instruction in the user message, for example telling Claude to use the get_weather tool.

    Checkpoint 4 of 6· Exam question

    A team is building a pipeline that asks Claude to read free-form support tickets and return a JSON object with fields like priority, category, and summary. Early prototypes used a prompt asking Claude to "reply with only JSON", but downstream parsing occasionally failed on malformed brackets and stray commentary text. Which approach most reliably eliminates these JSON syntax failures?

    Forced tool use also isn't supported everywhere. In those cases any and named-tool choices fail, while auto and none still work. Two situations matter. The first is manual extended thinking, thinking: {type: "enabled"}. The second is the newest models: Claude Opus 5.5, Claude Sonnet 5.5, Claude Fable 5.1 and Claude Mythos 5.1, which return a 400 error whatever the thinking settings.

    When forced tool choice fails, and the documented replacement
    Settingany / toolWhat to use instead
    Manual extended thinking (thinking: {type: "enabled"})Not supported; request errorsauto or none. Adaptive thinking does not block forced tool use (Claude Opus 5 supports it with thinking on)
    Claude Opus 5.5, Claude Sonnet 5.5, Claude Fable 5.1, Claude Mythos 5.1400 errorauto with strict tool use for schema-valid inputs, or structured outputs for a fixed JSON response shape

    On those models, auto plus strict: true still guarantees that any tool call is schema-valid. The documentation notes that your prompt still influences which tool Claude picks under auto, so it's the prompt, not the API, that makes Claude call the extraction tool.

    Checkpoint 5 of 6· Exam question

    A document-processing service receives files that could be invoices, resumes, or contracts, but the type is not known ahead of time. The service defines three separate extraction tools (extract_invoice, extract_resume, extract_contract) and needs Claude to always call exactly one of them so the pipeline never falls back to plain text. Which tool_choice configuration should be used?

    Checkpoint 6 of 6· Check yourself

    An extraction pipeline moves to Claude Opus 5.5 and keeps tool_choice: {"type": "tool", "name": "extract_metadata"}. What happens, and what does the documentation recommend?

    Sources5

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.With a forced tool choice, you can still ask Claude to explain its reasoning in text before the tool call.Why is that wrong?

      With any or a named tool, the API prefills the assistant turn, so Claude writes no natural-language text before the tool_use block. To get commentary, use auto and ask for the tool in the user message.

      Covered in What forcing costs, and where it is rejected

    2. 2.tool_choice any or a named tool works with every model and every thinking mode.Why is that wrong?

      Manual extended thinking rejects both, and Claude Opus 5.5, Sonnet 5.5, Fable 5.1 and Mythos 5.1 return a 400 error. Adaptive thinking does not block forced tool use on models that support it.

      Covered in What forcing costs, and where it is rejected

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 2.
      “Setting strict: true on a tool definition guarantees Claude's tool inputs match your JSON Schema”
      ↩︎ Why a tool schema beats asking for JSON
      “Tool name is always valid (from provided tools or server tools)”
      ↩︎ Defining the tool and reading the tool_use block
      “Setting strict: true on a tool definition guarantees Claude's tool inputs match your JSON Schema”
      ↩︎ Key concept
      “Without strict mode, Claude might return incompatible types ("2" instead of 2) or omit required fields, breaking your functions and causing runtime errors.”
      ↩︎ Checkpoint
      “Set "strict": true as a top-level property in your tool definition, alongside name, description, and input_schema.”
      ↩︎ Checkpoint
    2. 3.
      “a tool that "tricks" Claude into generating well-structured JSON output containing sentiment analysis data”
      ↩︎ Why a tool schema beats asking for JSON
      “Claude does not call our sentiment analysis tool”
      ↩︎ tool_choice: auto, any, or a named tool
      “you must call a tool, but you can pick which one”
      ↩︎ tool_choice: auto, any, or a named tool
    3. 4.
      “input: An object containing the input being passed to the tool, conforming to the tool's input_schema.”
      ↩︎ Defining the tool and reading the tool_use block
    4. 5.
      “any tells Claude that it must use one of the provided tools, but doesn't force a particular tool.”
      ↩︎ tool_choice: auto, any, or a named tool
      “you can use {"type": "auto"} for tool_choice (the default) and add explicit instructions in a user message.”
      ↩︎ What forcing costs, and where it is rejected
      “any and tool return a 400 error”
      ↩︎ What forcing costs, and where it is rejected
      “Adaptive thinking itself doesn't block forced tool use (Claude Opus 5 supports it with thinking on)”
      ↩︎ What forcing costs, and where it is rejected
      “the models will not emit a natural language response or explanation before tool_use content blocks, even if explicitly asked to do so.”
      ↩︎ Exam trap 1
      “any and tool are not supported and result in an error”
      ↩︎ Exam trap 2
      “auto allows Claude to decide whether to call any provided tools or not. This is the default value when tools are provided.”
      ↩︎ Prediction
      “auto with strict tool use to guarantee schema-valid tool inputs”
      ↩︎ Checkpoint

    Continue to page 2 of 2

    Designing Extraction Schemas: Nullable Fields, Enums and Validation

    Spotted a mistake, or was something unclear? Tell us.