> ## Documentation Index
> Fetch the complete documentation index at: https://docs.duraton.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Structured output

> Have an agent answer in a declared shape: a JSON schema the final answer must satisfy, validated and recorded as a durable step.

## Answering in a shape

By default an agent's answer is the model's text. Pass `output` - a JSON Schema, the same raw-schema
form `step.ai.generate` takes - and two things change: the model is constrained to that shape, and
the answer comes back **parsed**, so `final` is the object rather than a string you have to parse
yourself.

```ts theme={null}
interface Invoice {
  total: number;
  currency: string;
}

const result = await agent<Invoice>(ctx, "billing", {
  model: "claude-opus-4-8",
  prompt: "Total this invoice and give me the currency.",
  maxIterations: 4,
  tools: [lineItems],
  output: {
    type: "object",
    properties: { total: { type: "number" }, currency: { type: "string" } },
    required: ["total", "currency"],
    additionalProperties: false,
  },
});

result.final?.total; // a number, not a substring
```

The type parameter on `agent<Invoice>` is your assertion about the schema you passed - nothing
checks the parsed value against the schema, exactly as with `step.ai.generate`. What `output`
guarantees is that the answer is valid JSON and that the model was constrained while producing it.

Two ways this fails, both loudly rather than by handing you the wrong thing:

| Situation                                    | What happens                                                                                                                                                                                                                        |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The provider cannot constrain the model      | The agent refuses before calling it, naming the provider. Only adapters declaring the `structured-output` capability are accepted - the Anthropic adapter does, the AI SDK adapter does not, because `generateText` takes no schema |
| The model answers with text that is not JSON | The run fails. Returning the raw string would hand back a value typed as your shape that is not one                                                                                                                                 |

<Note>
  Without `output`, `agent()` behaves exactly as it always has and `final` is the model's text. The
  option changes nothing for an agent that does not use it.
</Note>
