Skip to content

pydantic_ai.output

ToolOutput

Bases: Generic[OutputDataT]

Marker class to use a tool for output and optionally customize the tool.

Example:

tool_output.py
from pydantic import BaseModel

from pydantic_ai import Agent, ToolOutput


class Fruit(BaseModel):
    name: str
    color: str


class Vehicle(BaseModel):
    name: str
    wheels: int


agent = Agent(
    'openai:gpt-5.2',
    output_type=[
        ToolOutput(Fruit, name='return_fruit'),
        ToolOutput(Vehicle, name='return_vehicle'),
    ],
)
result = agent.run_sync('What is a banana?')
print(repr(result.output))
#> Fruit(name='banana', color='yellow')

Attributes

output

An output type or function.

Type: OutputTypeOrFunction[OutputDataT] Default: cast(OutputTypeOrFunction[OutputDataT], type_)

name

The name of the tool that will be passed to the model. If not specified and only one output is provided, final_result will be used. If multiple outputs are provided, the name of the output type or function will be added to the tool name.

Type: str | None Default: name

description

The description of the tool that will be passed to the model. If not specified, the docstring of the output type or function will be used.

Type: str | None Default: description

max_retries

Per-tool retry limit for this output tool.

Overrides the output side of the agent’s retry budget, which itself acts as the per-tool default for output tools that do not specify their own limit. If not set, the agent-level value is used.

Type: int | None Default: max_retries

strict

Whether to use strict mode for the tool.

Type: bool | None Default: strict

sequential

Whether this output tool must run as a barrier, not overlapping with other tool calls.

Only meaningful under end_strategy='exhaustive', where tools otherwise run in parallel: a sequential=True output tool runs alone, so function tools the model emitted before it complete first. Under 'early'/'graceful' output tools already run sequentially, so this has no effect.

Type: bool Default: sequential

NativeOutput

Bases: Generic[OutputDataT]

Marker class to use the model’s native structured outputs functionality for outputs and optionally customize the name and description.

Example:

native_output.py
from pydantic_ai import Agent, NativeOutput

from tool_output import Fruit, Vehicle

agent = Agent(
    'openai:gpt-5.2',
    output_type=NativeOutput(
        [Fruit, Vehicle],
        name='Fruit or vehicle',
        description='Return a fruit or vehicle.'
    ),
)
result = agent.run_sync('What is a Ford Explorer?')
print(repr(result.output))
#> Vehicle(name='Ford Explorer', wheels=4)

Attributes

outputs

The output types or functions.

Type: OutputTypeOrFunction[OutputDataT] | Sequence[OutputTypeOrFunction[OutputDataT]] Default: cast(OutputTypeOrFunction[OutputDataT] | Sequence[OutputTypeOrFunction[OutputDataT]], outputs)

name

The name of the structured output that will be passed to the model. If not specified and only one output is provided, the name of the output type or function will be used.

Type: str | None Default: name

description

The description of the structured output that will be passed to the model. If not specified and only one output is provided, the docstring of the output type or function will be used.

Type: str | None Default: description

strict

Whether to use strict mode for the output, if the model supports it.

Type: bool | None Default: strict

template

Template for the prompt passed to the model. The ‘{schema}’ placeholder will be replaced with the output JSON schema. If no template is specified but the model’s profile indicates that it requires the schema to be sent as a prompt, the default template specified on the profile will be used. Set to False to disable the schema prompt entirely.

Type: str | Literal[False] | None Default: template

PromptedOutput

Bases: Generic[OutputDataT]

Marker class to use a prompt to tell the model what to output and optionally customize the prompt.

Example:

prompted_output.py
from pydantic import BaseModel

from pydantic_ai import Agent, PromptedOutput

from tool_output import Vehicle


class Device(BaseModel):
    name: str
    kind: str


agent = Agent(
    'openai:gpt-5.2',
    output_type=PromptedOutput(
        [Vehicle, Device],
        name='Vehicle or device',
        description='Return a vehicle or device.'
    ),
)
result = agent.run_sync('What is a MacBook?')
print(repr(result.output))
#> Device(name='MacBook', kind='laptop')

agent = Agent(
    'openai:gpt-5.2',
    output_type=PromptedOutput(
        [Vehicle, Device],
        template='Gimme some JSON: {schema}'
    ),
)
result = agent.run_sync('What is a Ford Explorer?')
print(repr(result.output))
#> Vehicle(name='Ford Explorer', wheels=4)

Attributes

outputs

The output types or functions.

Type: OutputTypeOrFunction[OutputDataT] | Sequence[OutputTypeOrFunction[OutputDataT]] Default: cast(OutputTypeOrFunction[OutputDataT] | Sequence[OutputTypeOrFunction[OutputDataT]], outputs)

name

The name of the structured output that will be passed to the model. If not specified and only one output is provided, the name of the output type or function will be used.

Type: str | None Default: name

description

The description that will be passed to the model. If not specified and only one output is provided, the docstring of the output type or function will be used.

Type: str | None Default: description

template

Template for the prompt passed to the model. The ‘{schema}’ placeholder will be replaced with the output JSON schema. If not specified, the default template specified on the model’s profile will be used. Set to False to disable the schema prompt entirely.

Type: str | Literal[False] | None Default: template

TextOutput

Bases: Generic[OutputDataT]

Marker class to use text output for an output function taking a string argument.

Example:

from pydantic_ai import Agent, TextOutput


def split_into_words(text: str) -> list[str]:
    return text.split()


agent = Agent(
    'openai:gpt-5.2',
    output_type=TextOutput(split_into_words),
)
result = agent.run_sync('Who was Albert Einstein?')
print(result.output)
#> ['Albert', 'Einstein', 'was', 'a', 'German-born', 'theoretical', 'physicist.']

Attributes

output_function

The function that will be called to process the model’s plain text output. The function must take a single string argument.

Type: TextOutputFunc[OutputDataT]

Choice

Bases: Generic[T_co]

One choice in a Choices set: what it means, and what it stands for.

Building a set from descriptions alone yields the key the model picked, so Choice is only reached for when a choice stands for something other than its key:

choice.py
from pydantic_ai import Agent, Choice, Choices

Card = Choices(
    {
        'visa': Choice('Any card starting with a 4.', value=4),
        'amex': Choice('Any card starting with a 3.', value=3),
    }
)

agent = Agent('openai:gpt-5.2', output_type=Card)
result = agent.run_sync('4111 1111 1111 1111')
print(result.output)
#> 4

Attributes

description

What this choice means, shown to the model beside the choice itself.

Type: str | None Default: description

value

What the picked choice resolves to. Defaults to the choice’s own key.

A callable value is called when the model picks this choice, the way an output function is, so the run’s output is what the action returned. It is called with no arguments, so bind what it needs with functools.partial or a closure, and it can be async. A Choices set with a callable value can only be used as an agent’s output_type.

Type: T_co Default: value

BoolCriteria

What a yes and what a no would each mean, for a bool field or parameter to carry in Annotated.

A bool field’s description says what is being asked; these two say what either answer amounts to, which is what a set of options gets from Choices() and an Enum gets from UseEnumMemberDocstrings. Both descriptions reach the model in the schema, as a description on each of the two constants a boolean can be.

It is a marker rather than a type, so the field stays a plain bool to every type checker, and the value you get back is a plain True or False:

bool_criteria.py
from typing import Annotated

from pydantic import BaseModel, Field

from pydantic_ai import Agent, BoolCriteria


class Settled(BaseModel):
    refunded: Annotated[
        bool,
        BoolCriteria(true='Money was returned to the customer.', false='No refund was issued.'),
    ] = Field(description='Was a refund issued?')


agent = Agent('openai:gpt-5.2', output_type=Settled)
result = agent.run_sync('We have sent the 40 pounds back to your card.')
print(result.output.refunded)
#> True

On TypeSafe’s Jev, which asks a yes/no as its own primitive, the two land in that question’s criteria as true and false, sent verbatim.

Attributes

true

What it means for the answer to be True.

Type: str

false

What it means for the answer to be False.

Type: str

OutputObjectDefinition

Definition of an output object used for structured output generation.

StructuredDict

def StructuredDict(
    json_schema: JsonSchemaValue,
    name: str | None = None,
    description: str | None = None,
) -> type[JsonSchemaValue]

Returns a dict[str, Any] subclass with a JSON schema attached that will be used for structured output.

Example:

structured_dict.py
from pydantic_ai import Agent, StructuredDict

schema = {
    'type': 'object',
    'properties': {
        'name': {'type': 'string'},
        'age': {'type': 'integer'}
    },
    'required': ['name', 'age']
}

agent = Agent('openai:gpt-5.2', output_type=StructuredDict(schema))
result = agent.run_sync('Create a person')
print(result.output)
#> {'name': 'John Doe', 'age': 30}

Returns

type[JsonSchemaValue]

Parameters

json_schema : JsonSchemaValue

A JSON schema of type object defining the structure of the dictionary content.

name : str | None Default: None

Optional name of the structured output. If not provided, the title field of the JSON schema will be used if it’s present.

description : str | None Default: None

Optional description of the structured output. If not provided, the description field of the JSON schema will be used if it’s present.

Choices

def Choices(
    choices: Sequence[str] | Mapping[str, str],
    *,
    name: str | None = None,
    description: str | None = None,
) -> type[str]
def Choices(
    choices: Mapping[str, Choice[T_co]],
    *,
    name: str | None = None,
    description: str | None = None,
) -> type[T_co]
def Choices(
    choices: Mapping[str, str | Choice[T_co]],
    *,
    name: str | None = None,
    description: str | None = None,
) -> type[str | T_co]

Returns a type the model can only fill with one of choices, each described where it is built.

Use it when the set is only known once the run is under way — the actions available on the screen in front of an agent, the records a search returned. For a set you know when you write the code, use a Literal or an Enum (with UseEnumMemberDocstrings to describe its members), which give you exhaustiveness checking that a run-time set cannot.

Like StructuredDict it returns a type, so it works as an output_type, as a field of a Pydantic model, and as a tool parameter.

Example:

choices.py
from pydantic_ai import Agent, Choices

Intent = Choices(
    {
        'refund': 'The customer wants their money back.',
        'replace': 'The customer wants a working unit instead.',
        'escalate': 'Nobody on this tier can resolve it.',
    },
    name='customer_intent',
    description='What the customer is asking for.',
)

agent = Agent('openai:gpt-5.2', output_type=Intent)
result = agent.run_sync('The blender arrived smashed. Just send me another one.')
print(result.output)
#> replace

Returns

type[Any]

Parameters

choices : Sequence[str] | Mapping[str, str | Choice[Any]]

The choices, as a sequence of keys, a mapping from key to its description, or a mapping from key to a Choice carrying both a description and what the key stands for.

name : str | None Default: None

Name of the output tool or structured output. Defaults to 'Choices'.

description : str | None Default: None

What the model is being asked to pick, e.g. 'Which action to take next.'.

OutputDataT

Covariant type variable for the output data type of a run.

Default: TypeVar('OutputDataT', default=str, covariant=True)