Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/phpaisdk/core/llms.txt

Use this file to discover all available pages before exploring further.

Structured output instructs the model to respond with a machine-readable value — a JSON object, an array, or an enum string — instead of free prose. aisdk/core validates the response against your schema and surfaces the decoded PHP value in $result->output, so you never need to manually parse or guard the model’s reply.
Structured output requires the model to advertise Capability::StructuredOutput. The SDK checks this before making any HTTP call and raises a CapabilityNotSupportedException for models that do not support it. Not every provider or model tier supports structured output — verify the capability list for your model before deploying.

Basic object extraction

Pass a Schema::object() to ->output(). After ->run(), $result->output is a PHP array keyed by your property names:
use AiSdk\Generate;
use AiSdk\OpenAI;
use AiSdk\Schema;

$result = Generate::text()
    ->model(OpenAI::model('gpt-4o'))
    ->prompt('Extract the city and country from: Lahore, Pakistan.')
    ->output(Schema::object(
        name: 'address',
        description: 'The city and country extracted from the prompt.',
        properties: [
            Schema::string(name: 'city',    description: 'City name')->required(),
            Schema::string(name: 'country', description: 'Country name')->required(),
        ],
    ))
    ->run();

echo $result->output['city'];    // "Lahore"
echo $result->output['country']; // "Pakistan"

Schema types

Schema is a single fluent class that covers every JSON Schema primitive. All factory methods accept an optional name and description:
Schema::string(name: 'title', description: 'The article title')
Maps to { "type": "string" }. Use for textual values.
Schema::integer(name: 'year', description: 'Publication year')
Maps to { "type": "integer" }. Use for whole numbers.
Schema::number(name: 'score', description: 'Confidence score between 0 and 1')
Maps to { "type": "number" }. Use for floats and decimals.
Schema::boolean(name: 'is_published', description: 'Whether the article is live')
Maps to { "type": "boolean" }.
Schema::array(
    items: Schema::string(),
    name: 'tags',
    description: 'Comma-separated content tags'
)
Maps to { "type": "array", "items": { "type": "string" } }. The $items argument is a nested Schema instance.
Schema::object(
    name: 'author',
    description: 'Author details',
    properties: [
        Schema::string(name: 'name')->required(),
        Schema::string(name: 'email'),
    ]
)
Maps to a JSON Schema object with properties and an optional required array.
Schema::enum(['low', 'medium', 'high'], name: 'priority')
Maps to { "type": "string", "enum": ["low", "medium", "high"] }. Also accepted by ->output() directly.

Property modifiers

Chain ->required() and ->nullable() to any schema. Both return a new Schema instance (schemas are immutable):
Schema::string(name: 'nickname')->required()   // included in JSON Schema "required" array
Schema::string(name: 'nickname')->nullable()   // type becomes ["string", "null"]
Schema::string(name: 'nickname')->required()->nullable()

Nested objects

Properties can be objects themselves. The SDK recursively serialises and validates the whole tree:
$result = Generate::text()
    ->model(OpenAI::model('gpt-4o'))
    ->prompt('Parse this: "The Pragmatic Programmer by David Thomas and Andrew Hunt, 1999".')
    ->output(Schema::object(
        name: 'book',
        properties: [
            Schema::string(name: 'title')->required(),
            Schema::integer(name: 'year')->required(),
            Schema::object(
                name: 'authors',
                description: 'Primary and secondary authors',
                properties: [
                    Schema::string(name: 'primary')->required(),
                    Schema::string(name: 'secondary')->nullable(),
                ]
            )->required(),
        ],
    ))
    ->run();

echo $result->output['title'];                    // "The Pragmatic Programmer"
echo $result->output['authors']['primary'];       // "David Thomas"
echo $result->output['year'];                     // 1999

Enum output

Use Output::enum() when you want to constrain the model to one of a fixed set of string values. $result->output is then the chosen string:
use AiSdk\Generate;
use AiSdk\OpenAI;
use AiSdk\Outputs\Output;

$result = Generate::text()
    ->model(OpenAI::model('gpt-4o'))
    ->prompt('Classify the urgency of this support ticket: "My production server is down."')
    ->output(Output::enum(['low', 'medium', 'high', 'critical']))
    ->run();

echo $result->output; // "critical"
You can achieve the same result by passing a Schema::enum() to ->output():
->output(Schema::enum(['low', 'medium', 'high', 'critical']))
Output::enum() is the canonical approach when you only need the enum value. Use Schema::enum() inside Schema::object() properties when the enum is a field within a larger structure.

Output validation

The SDK runs SchemaValidator::validate() against the decoded JSON before returning TextResult. If the model’s response does not conform to the schema — a required property is missing, a type is wrong — a validation exception is thrown. This means $result->output is always either a fully validated value or absent (when no ->output() schema was given). You do not need to guard against partial data.

Schema with array items

Extract a list of structured objects from a single prompt:
$result = Generate::text()
    ->model(OpenAI::model('gpt-4o'))
    ->prompt('List the top 3 PHP frameworks with a short description of each.')
    ->output(Schema::object(
        name: 'frameworks',
        properties: [
            Schema::array(
                items: Schema::object(
                    name: 'framework',
                    properties: [
                        Schema::string(name: 'name')->required(),
                        Schema::string(name: 'description')->required(),
                    ]
                ),
                name: 'items',
            )->required(),
        ],
    ))
    ->run();

foreach ($result->output['items'] as $framework) {
    echo "{$framework['name']}: {$framework['description']}\n";
}

Full reference: Output methods

MethodReturnsDescription
->output(Schema $schema)PendingTextRequestAttaches a schema for structured JSON extraction. Objects and arrays use $result->output as a PHP array.
->output(Output::enum([...]))PendingTextRequestConstrains output to one of the given string values. $result->output is the chosen string.
$result->outputmixednull when no ->output() was set. Array for object/array schemas. String for enum schemas.
Structured output is not available on all models or provider tiers. If you register a custom model with OpenAI::registerModel(), include Capability::StructuredOutput in its capability list only if the underlying model actually supports it.

Build docs developers (and LLMs) love