Skip to lesson

AnthropicClaude Certified Architect – Foundations2026-104.3 Enforce structured output using tool use and JSON schemas

Read extracted records from tool inputs

Completed by the knowledge check

Learning objective

Define extraction tools with JSON Schema input contracts and read structured tool_use blocks instead of parsing free-form answers.

Core idea

For a document-extraction pipeline, the output record can be the input to a client tool. Define extract_invoice so its input_schema describes invoice fields. Claude returns a tool_use block whose input contains those fields. Your application reads that object rather than searching an assistant’s prose for something that resembles JSON.

This changes the integration boundary. A tool’s name identifies the contract, its schema describes the record, and the content-block type identifies where to read it. A sentence such as “Here is the invoice” is no longer the payload your downstream consumer parses.

A schema declaration alone is not an enforcement guarantee. Add strict: true when you require schema-constrained tool inputs. See 4.3.2 for the choice between this mechanism and native JSON outputs, and 4.3.3 for requiring an extraction call on supported models.

How it works

Define the record as the tool contract

Pass client-tool definitions in the Messages API request’s tools array. Each definition has a name, a description, and an input_schema. For extraction, describe when the tool applies and what each field means in the source document. You are asking Claude to propose the record as arguments, rather than asking it to execute a parser that exists on Anthropic’s infrastructure.

The following tool definition illustrates the boundary with two fields:

{
  "name": "extract_invoice",
  "description": "Record the invoice identifier and stated total from one supplier invoice. Use the field labelled invoice number, not an order reference. Record the stated total without recomputing it. Use null when the corresponding evidence is absent.",
  "strict": true,
  "input_schema": {
    "type": "object",
    "properties": {
      "invoice_number": { "type": ["string", "null"] },
      "total": { "type": ["number", "null"] }
    },
    "required": ["invoice_number", "total"],
    "additionalProperties": false
  }
}

The tool and field names in this example are application-defined. tools, input_schema, and strict are API identifiers. The required keys give consumers a stable record shape; the nullable types let the document lack a value. See 4.3.4 for designing that distinction deliberately.

Tool descriptions matter to interpretation and selection. A schema that accepts two strings cannot distinguish an invoice identifier from a purchase-order identifier on its own. Put that distinction in description, including field-level descriptions where useful. See 2.1.1 for the broader description contract; here the specific responsibility is choosing evidence for extracted fields.

Read blocks by type and name

A client-tool response has stop_reason: "tool_use" and one or more tool_use blocks in content. Each block carries id, name, and input. The id identifies this particular call, while name identifies which contract its arguments use.

Do not assume content[0] is the extraction record. A response can contain text and tool blocks, or multiple calls. Iterate through content, select blocks whose type is tool_use, and dispatch by name. Then read input as the object to validate and consume. For a single-record endpoint, reject a response that lacks the expected extraction call or supplies a call count the endpoint does not accept.

The response fragment your consumer needs looks like this:

{
  "type": "tool_use",
  "id": "toolu_EXAMPLE",
  "name": "extract_invoice",
  "input": { "invoice_number": "INV-42", "total": 1240 }
}

toolu_EXAMPLE is an illustrative call identifier. The consumer reads input.invoice_number and input.total; it does not parse the assistant’s text block. The API response itself is serialized JSON, but that transport parsing is different from extracting JSON out of generated prose.

Decide whether the conversation continues

Client-tool execution belongs to your application. For a one-shot extraction, you can treat receiving and checking input as the terminal result of your endpoint. This is an application design: it does not mean client tools universally have no implementation or never execute.

If you continue the conversation, preserve the assistant’s content and return a user-message tool_result whose tool_use_id matches the call’s id. Its content can acknowledge acceptance or explain a validation failure. Do not continue as though the call never happened. See 1.1.2 for the full history contract rather than rebuilding that protocol here.

Keep extraction acceptance separate from posting a payment or changing a business record. The fact that Claude requested extract_invoice does not authorize downstream effects. Your consumer first decides whether the proposed record meets the application’s evidence and value checks.

Key distinctions and trade-offs

Structured block versus schema enforcement: Reading tool_use.input removes the need to locate a record inside prose. strict: true adds grammar-constrained schema compliance. A tool without strict mode can still supply incompatible types or omit required fields.

Extracted arguments versus tool results: The extracted fields are in the assistant’s tool_use.input. A later tool_result carries what your application did with those arguments. Reading the latter as the original extraction loses the interface distinction.

Shape versus evidence: A numeric total can have the right type and the wrong value. A string can be copied from the wrong part of the document. Strict mode enforces the supported schema, not the relationship between the proposed record and the invoice. See 4.3.5 for semantic validation.

This pattern fits a workflow already organized around tools and named record types. When the only requirement is a final JSON record, native JSON outputs can avoid introducing a synthetic extraction call; see 4.3.2.

Architecture / decision scenario

An accounts-payable service receives an invoice containing an invoice number, an order reference, and a stated total. Its first implementation asks for JSON, removes Markdown fences from the answer, and passes the resulting string to a JSON parser. Some responses include an explanation before the record, so the pipeline fails before it can examine values.

Replace that boundary with extract_invoice in tools, a precise input_schema, and strict: true. The consumer inspects the response outcome, selects the expected tool_use block by type and name, and reads input. An explanatory text block is harmless because it is not the payload.

The service checks that the selected identifier matches the invoice-number evidence rather than the order reference. It accepts one record for the one-document request and holds anything outside that contract. For the endpoint that ends at extraction, it returns the accepted record directly. For an enrichment conversation, it preserves the call and sends a correlated tool_result before the next inference. Both designs consume the same structured input; neither depends on extracting a JSON substring from prose.

Common exam traps

  • Parsing a text answer when the extracted record is already in tool_use.input.
  • Assuming the first content block always contains the record.
  • Confusing a tool name with a particular call’s id.
  • Treating an ordinary input_schema as equivalent to strict: true.
  • Leaving tool_choice on auto and parsing the text answer when no tool_use block arrives.
  • Continuing the conversation without a matching tool_result.

Where the exam guide differs

Note:

The exam guide describes tool use with JSON schemas as guaranteeing schema-compliant output. Anthropic distinguishes ordinary tool schemas from strict tool use: strict: true supplies the enforcement guarantee. Read an exam option favoring schema-based extraction over parsing prose as the interface choice, and distinguish it from the separate requirement to enable strict mode.

What to remember

Define the extracted record in input_schema, describe its evidence semantics, and read tool_use.input by block type and tool name. Strict mode enforces shape; your application accepts the values. If the conversation continues, preserve the call and its correlated result.

Knowledge check

References