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

# Structured Output

> Generate validated, structured data from your agents for seamless integration with databases, APIs, and downstream systems

Structured output enables your agents to return data in a predefined schema instead of free-form text. This is essential for integrating agents with databases, APIs, or any system that requires consistent data formats.

## Overview

When you enable structured output, your agent will:

1. Process the input normally
2. Extract information according to your schema
3. Return validated, typed data matching your specification
4. Ensure type safety and consistency

<Info>
  Structured output uses runtime schema generation and validation to ensure your agents return properly formatted data.
</Info>

<Warning>
  **Important**: Structured output is **NOT** included in the conversation history array. This means structured output from previous agents is only accessible through template variables in prompts (e.g., `{{ agent_name.output.field }}`) and will not appear in the `{{ history }}` or `{{ history[N] }}` variables.
</Warning>

## When to Use Structured Output

<CardGroup cols={2}>
  <Card title="Data Extraction" icon="database">
    Extract structured information from unstructured text (resumes, invoices, documents)
  </Card>

  <Card title="API Integration" icon="plug">
    Generate responses that match your API schema requirements
  </Card>

  <Card title="Database Inserts" icon="table">
    Create records with validated fields for database operations
  </Card>

  <Card title="Multi-Agent Pipelines" icon="diagram-project">
    Pass typed data between agents in complex workflows
  </Card>
</CardGroup>

## Basic Configuration

Add the `structured_output` field to your agent configuration:

```yaml theme={null}
agents:
  - name: "data_extractor"
    agent_type: "llm_agent"
    prompt_config:
      system_prompt: "Extract contact information from the provided text."
    
    structured_output:
      enabled: true
      schema:
        name:
          type: "str"
          description: "Full name of the person"
        email:
          type: "str"
          description: "Email address"
        phone:
          type: "str"
          description: "Phone number"
```

## Type Notation

Define field types using our type notation syntax:

### Basic Types

<ParamField path="string" type="type">
  Text data

  ```yaml theme={null}
  name:
    type: "str"
    description: "Person's full name"
  ```
</ParamField>

<ParamField path="int" type="type">
  Integer numbers

  ```yaml theme={null}
  age:
    type: "int"
    description: "Age in years"
  ```
</ParamField>

<ParamField path="float" type="type">
  Decimal numbers

  ```yaml theme={null}
  confidence:
    type: "float"
    description: "Confidence score between 0.0 and 1.0"
  ```
</ParamField>

<ParamField path="bool" type="type">
  Boolean values (true/false)

  ```yaml theme={null}
  is_verified:
    type: "bool"
    description: "Whether the information is verified"
  ```
</ParamField>

### Collection Types

<ParamField path="list[T]" type="type">
  List of items of type T

  ```yaml theme={null}
  skills:
    type: "list[str]"
    description: "List of technical skills"

  scores:
    type: "list[float]"
    description: "List of test scores"
  ```
</ParamField>

<ParamField path="dict[K, V]" type="type">
  Dictionary mapping keys of type K to values of type V

  ```yaml theme={null}
  metadata:
    type: "dict[str, str]"
    description: "Additional metadata fields"

  scores_by_subject:
    type: "dict[str, float]"
    description: "Subject name to score mapping"
  ```
</ParamField>

### Nullable Types

<ParamField path="T | None" type="type">
  Optional/nullable value of type T

  ```yaml theme={null}
  middle_name:
    type: "str | None"
    description: "Middle name if available, null otherwise"

  score:
    type: "float | None"
    description: "Score if calculable, null otherwise"
  ```
</ParamField>

You can also use `Optional[T]` syntax:

```yaml theme={null}
notes:
  type: "Optional[str]"
  description: "Optional notes"
```

<Note>
  **Enum types are not currently supported.** Use `str` type with clear descriptions for fields that should have restricted values. Guide the LLM via your system prompt to output specific allowed values.
</Note>

## Quick Start Example

Extract contact information from text:

```yaml theme={null}
agents:
  - name: "contact_extractor"
    agent_type: "llm_agent"
    prompt_config:
      system_prompt: "Extract contact information from the provided text."
    
    structured_output:
      enabled: true
      schema:
        name:
          type: "str"
          description: "Person's full name"
        
        email:
          type: "str"
          description: "Email address"
        
        phone:
          type: "str"
          description: "Phone number"
        
        company:
          type: "str"
          description: "Company name"
```

**Input:**

```
John Smith from Acme Corp can be reached at john@acme.com or 555-1234
```

**Output:**

```json theme={null}
{
  "name": "John Smith",
  "email": "john@acme.com",
  "phone": "555-1234",
  "company": "Acme Corp"
}
```

## Multi-Agent Data Passing

Use structured output to pass typed data between agents in workflows. Downstream agents can access structured outputs from previous agents using template variables in their system prompts.

### Accessing Structured Output in Prompts

Use the `{{ agent_name.output.field }}` syntax to inject structured output into agent prompts:

```yaml theme={null}
agents:
  - name: "data_extractor"
    agent_type: "llm_agent"
    structured_output:
      enabled: true
      schema:
        company_name:
          type: "str"
          description: "Company name"
        revenue:
          type: "float"
          description: "Annual revenue in millions"
  
  - name: "analyzer"
    agent_type: "llm_agent"
    prompt_config:
      system_prompt: |
        Analyze the company data:
        - Company: {{ data_extractor.output.company_name }}
        - Revenue: ${{ data_extractor.output.revenue }}M
        
        Provide insights on market position and growth potential.
```

**Supported template variables:**

* `{{ agent_name.output.field }}` — Access specific field from structured output
* `{{ agent_name.output.nested.field }}` — Access nested fields (dot-separated path)
* `{{ agent_name.output }}` — Access entire structured output as JSON string
* `{{ variables.name }}` — Access custom variables (see [Variables System](/documentation/advanced/variables-system))
* `{{ user_input }}` — Latest user message
* `{{ history[N] }}` — Last N messages from conversation (structured output NOT included)

<Warning>
  **Critical**: Structured output is excluded from history variables. Use the specific `{{ agent_name.output.field }}` template variables to access structured data from previous agents.
</Warning>

<Tip>
  **Complex data types** (lists, dicts) are automatically serialized to JSON when injected into prompts.
</Tip>

### Multi-Agent Example

Pass structured data between agents:

```yaml theme={null}
name: "Data Pipeline"
architecture: "workflow"

agents:
  - name: "extractor"
    agent_type: "llm_agent"
    prompt_config:
      system_prompt: "Extract key metrics from the report."
    
    structured_output:
      enabled: true
      schema:
        revenue:
          type: "float"
          description: "Annual revenue in millions"
        growth_rate:
          type: "float"
          description: "Year-over-year growth percentage"
  
  - name: "analyzer"
    agent_type: "llm_agent"
    prompt_config:
      system_prompt: |
        Analyze the company metrics:
        Revenue: ${{ extractor.output.revenue }}M
        Growth: {{ extractor.output.growth_rate }}%
        
        Provide insights on performance and recommendations.

edges:
  - from: "__start__"
    to: "extractor"
  - from: "extractor"
    to: "analyzer"
  - from: "analyzer"
    to: "__end__"

entry_point: "extractor"
```

<Tip>
  **Template variables**: Use `{{ agent_name.output.field }}` to access structured output from previous agents
</Tip>

## Best Practices

<Tip>
  **Clear Descriptions**: Always provide detailed descriptions for each field. The agent uses these to understand what to extract.
</Tip>

<Tip>
  **Appropriate Types**: Choose the most specific type possible. For fields with restricted values, use `str` type and specify allowed values in the description and system prompt.
</Tip>

<Tip>
  **System Prompt Alignment**: Ensure your system prompt explicitly mentions the structured output requirements.
</Tip>

<Warning>
  **Type Validation**: All output is validated against your schema. Invalid data will cause errors. Test your schemas thoroughly.
</Warning>

<Tip>
  **Nested Structures**: For complex nested objects, consider breaking them into multiple agents or using `dict` types with clear descriptions.
</Tip>

## Configuration Reference

### Schema Structure

The `structured_output` field has the following structure:

<ParamField path="structured_output" type="object">
  Configuration for structured output generation

  <Expandable title="Properties">
    <ParamField path="enabled" type="boolean">
      Enable or disable structured output for this agent

      When `true`, the agent will return data matching the defined schema instead of free-form text.

      **Default**: `true`
    </ParamField>

    <ParamField path="schema" type="object" required>
      Schema definition mapping field names to field specifications

      Each key is a field name, and each value is an object with `type` and optional `description`.

      **Required when** `enabled: true`
    </ParamField>
  </Expandable>
</ParamField>

### Field Specification

Each field in the schema must have:

<ParamField path="type" type="string" required>
  Type notation for the field

  See [Type Notation Reference](/documentation/advanced/reference/type-notation) for all supported types.

  **Supported types**: `str`, `int`, `float`, `bool`, `list[T]`, `dict[K, V]`, `T | None`, `Optional[T]`, `Any`
</ParamField>

<ParamField path="description" type="string">
  Human-readable description of what this field represents (optional but strongly recommended).

  The agent uses this description to understand what data to extract. Be specific and clear. Fields without descriptions may produce less accurate results.
</ParamField>

### Agent Type Support

<Check>
  **llm\_agent**: ✅ Fully supported - LLM agents can generate structured output for any schema
</Check>

<Check>
  **react\_agent**: ✅ Fully supported - ReAct agents generate structured output after completing their tool-calling iterations
</Check>

<Warning>
  **supervisor**: ❌ Not supported - Supervisor agents focus on coordination and do not produce structured output
</Warning>

## Validation and Error Handling

The system automatically validates structured output:

<Check>
  **Type Checking**: Values must match the declared type
</Check>

<Check>
  **Required Fields**: All fields in the schema must be present in the output
</Check>

<Check>
  **Format Validation**: Basic format checking for strings, numbers, etc.
</Check>

### Common Errors

| Error                    | Cause                             | Solution                                                                         |
| ------------------------ | --------------------------------- | -------------------------------------------------------------------------------- |
| `Invalid type notation`  | Unsupported type syntax           | Check [Type Notation Reference](/documentation/advanced/reference/type-notation) |
| `Missing required field` | Agent didn't provide all fields   | Improve system prompt to mention all fields                                      |
| `Type validation failed` | Value doesn't match expected type | Ensure agent outputs correct type for the field                                  |
| `Type mismatch`          | Wrong data type                   | Ensure agent outputs correct type (e.g., number not string)                      |

### Example Error Response

If validation fails, you'll receive a detailed error:

```json theme={null}
{
  "error": {
    "type": "StructuredOutputValidationError",
    "message": "Field 'age' has invalid value 'thirty'. Expected type: int",
    "field": "age",
    "expected": "int",
    "received": "thirty"
  }
}
```

## Variable Assignments

Structured output fields can be automatically mapped to system variables using `variable_assignments`. This creates a data pipeline: structured output → variables → downstream prompt substitution.

```yaml theme={null}
variables:
  customer_name:
    type: "str"
    description: "Extracted customer name"
  priority:
    type: "str"
    default: "medium"

agents:
  - name: "extractor"
    agent_type: "llm_agent"
    structured_output:
      enabled: true
      schema:
        name:
          type: "str"
          description: "Customer name"
        urgency:
          type: "str"
          description: "Priority level"
    variable_assignments:
      customer_name: "extractor.output.name"
      priority: "extractor.output.urgency"
  
  - name: "responder"
    agent_type: "llm_agent"
    prompt_config:
      system_prompt: |
        Customer: {{ variables.customer_name }}
        Priority: {{ variables.priority }}
        Respond appropriately.
```

Variable assignments also support static values and non-structured output. The system applies **automatic type coercion** during variable assignment, converting strings to types like integers, booleans, or JSON arrays to ensure they match the variable's defined `type`. See [Variables System](/documentation/advanced/variables-system) for details.

## Limitations

<Note>
  * Structured output is currently supported for `llm_agent` and `react_agent` types
  * Complex nested objects may require careful prompt engineering
  * Very large schemas (>20 fields) may impact performance
  * Use `str | None` or `Optional[str]` for optional fields
  * Output must be valid JSON
  * Enum types are not supported
</Note>

## Next Steps

<Card title="Conditional Edges" icon="code-branch" href="/documentation/advanced/conditional-edges">
  Learn how to route agents based on structured output values
</Card>
