Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Principle:Anthropics Anthropic sdk python Parsed Output Access

From Leeroopedia
Knowledge Sources
Domains Structured_Output, LLM, Data_Extraction
Last Updated 2026-02-15 00:00 GMT

Overview

The Parsed Output Access principle describes how the SDK provides type-safe access to deserialized structured data through generic typed response containers. Rather than requiring developers to manually extract and parse JSON from response content blocks, the SDK introduces extended message and content block types that carry validated Pydantic model instances directly, accessible via a simple parsed_output property.

Generic Typed Response Containers for Structured Data

The Anthropic API returns responses as Message objects containing a list of content blocks (text, tool use, thinking, etc.). When structured output is requested, the model's JSON response appears as the text field within a TextBlock. Without typed containers, the developer must:

  1. Iterate through content blocks to find the text block.
  2. Extract the raw JSON string.
  3. Parse it manually.
  4. Validate it against their expected type.

The SDK eliminates this boilerplate by introducing generic container types that are parameterized by the developer's output type (ResponseFormatT). These containers extend the standard API response types with an additional parsed_output attribute that holds the already-validated Pydantic model instance.

The generic type parameter ResponseFormatT serves dual purposes:

  • At runtime: It determines which Pydantic model class is used to validate the JSON text via TypeAdapter(ResponseFormatT).validate_json(text).
  • At type-check time: It provides IDE autocompletion and static type checking for the parsed_output property, so message.parsed_output is known to be of type ResponseFormatT (or None).

ParsedMessage Extending Message with parsed_output Property

The SDK uses class inheritance to extend the standard response types without breaking API compatibility:

ParsedTextBlock

ParsedTextBlock extends TextBlock with a single additional attribute: parsed_output: Optional[ResponseFormatT]. This attribute defaults to None and is populated by the parsing logic when structured output is successfully validated. It is excluded from API serialization via __api_exclude__, ensuring it never appears in wire-format data.

ParsedMessage

ParsedMessage extends Message by overriding the content field to use ParsedContentBlock[ResponseFormatT] (a union that includes ParsedTextBlock alongside the standard block types). It adds a convenience parsed_output property that automatically finds and returns the first parsed output from its content blocks.

This design has several important properties:

  • Backward compatibility: Since ParsedMessage extends Message, it can be used anywhere a Message is expected. All existing Message attributes (id, model, stop_reason, usage, etc.) remain accessible.
  • Transparent augmentation: The parsed output is added alongside the original data, not instead of it. The raw text field is still available on the ParsedTextBlock for inspection or logging.
  • Discriminated unions: The ParsedContentBlock union uses the type field as a discriminator, so Pydantic can efficiently determine which block type to instantiate during deserialization.

Type-Safe Access to Deserialized Pydantic Model Instances

The parsed_output property on ParsedMessage provides a zero-ceremony access pattern for retrieving the validated output:

review = message.parsed_output  # Returns Optional[MovieReview]

This property iterates through the message's content blocks and returns the parsed_output from the first TextBlock that has a truthy (non-None) parsed output. This design handles the common case where the model produces a single text block containing the structured output.

The type safety guarantee flows through the entire chain:

  1. The developer specifies output_format=MovieReview at the call site.
  2. The return type becomes ParsedMessage[MovieReview].
  3. The parsed_output property returns Optional[MovieReview].
  4. The developer gets full IDE autocompletion on the resulting object's fields.

If the model's response does not contain any valid structured output (e.g., the stop reason is max_tokens before completing the JSON), parsed_output returns None, which the developer can check gracefully.

Validation via TypeAdapter

The actual deserialization and validation is performed by the parse_text() function, which uses Pydantic's TypeAdapter.validate_json():

adapted_type = TypeAdapter(output_format)
return adapted_type.validate_json(text)

validate_json() is used rather than model_validate_json() because TypeAdapter supports arbitrary types beyond just BaseModel subclasses. This means developers could theoretically use simple types like list[str] or dict[str, int] as their output format, though BaseModel subclasses are the primary use case.

If validation fails (the JSON does not conform to the expected type), Pydantic raises a ValidationError, which propagates to the caller. This ensures that the parsed_output attribute, when non-None, is guaranteed to be a valid instance of the declared type.

Related Pages

Implemented By

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment