---
title: "Structured output"
description: "Get JSON that matches a schema from Workers AI. Use strict mode and automatic re-ask."
---

> Documentation Index
> Fetch the complete documentation index at: https://laravel-cf-workersai-docs.mdick85.workers.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Structured output

Implement `Laravel\Ai\Contracts\HasStructuredOutput` on the agent. Return a schema from `schema()`.

```php
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Attributes\Strict;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Promptable;

#[Strict]
class TaskAgent implements Agent, HasStructuredOutput
{
    use Promptable;

    public function instructions(): string
    {
        return 'Extract the task from the message.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'title' => $schema->string()->required(),
            'priority' => $schema->string()->enum(['low', 'high'])->required(),
        ];
    }
}

$task = (new TaskAgent)->prompt('Fix the login bug, it is urgent.', provider: 'workers-ai');
$task->toArray();
```

The package sends the schema as `response_format` with type `json_schema`.

## Strict mode

Add `#[Strict]` to the agent. The request then sends `strict: true`, and the schema requires all properties. Without `#[Strict]`, the request sends `strict: false`.

Some models ignore the strict flag. The re-ask below catches those cases.

## Automatic re-ask

Workers AI JSON mode is best-effort. A model can omit a required field or return a value outside an enum.

The package checks each structured response for required fields and enum values. If the check fails, it adds the error to the conversation and asks again. It asks up to `structured_output_retries` times. The default is 2.

```php
'workers-ai' => [
    // ...
    'structured_output_retries' => 0, // turn re-ask off
],
```

The package does not re-ask after a finish reason of `length`. The output was cut off, so raise the token cap. A re-ask runs inside one step and does not count against `#[MaxSteps]`.

## Give structured calls enough budget

Reasoning and the answer share one token cap. A reasoning model can spend the whole cap on thinking and leave no room for the JSON. For schema work:

- Set `#[ReasoningEffort(ReasoningEffort::LOW)]`. See [Reasoning models](/docs/guides/reasoning/).
- Raise `#[Timeout]`. Structured calls run longer.
- Turn on `throw_on_truncation`, so a cut-off JSON object throws instead of returning bad JSON. See [Errors and retries](/docs/guides/errors-and-retries/).

Source: https://laravel-cf-workersai-docs.mdick85.workers.dev/docs/guides/structured-output/index.mdx
