---
title: Using Structured Output | Developer Documentation
---

Most of the time you need results from an agent in a specific format. Agents results can return structured json in two ways:

1. `output_cls` – a Pydantic model to use as a schema for the output
2. `structured_output_fn` – For more advanced use cases, supply a custom function that validates or rewrites the agent’s conversation into any model you want.

Both single-agents like `FunctionAgent` and `ReActAgent`, as well as multi-agent `AgentWorkflow` workflows, support these options - let’s explore the possibilities:

### Use `output_cls`

```
from llama_index.core.agent.workflow import FunctionAgent, AgentWorkflow
from llama_index.llms.openai import OpenAI
from pydantic import BaseModel, Field


llm = OpenAI(model="gpt-4.1")




## define structured output format  and tools
class MathResult(BaseModel):
    operation: str = Field(description="the performed operation")
    result: int = Field(description="the result of the operation")




def multiply(x: int, y: int):
    """Multiply two numbers"""
    return x * y




## define agent
agent = FunctionAgent(
    tools=[multiply],
    name="calculator",
    system_prompt="You are a calculator agent who can multiply two numbers using the `multiply` tool.",
    output_cls=MathResult,
    llm=llm,
)


response = await agent.run("What is 3415 * 43144?")
print(response.structured_response)
print(response.get_pydantic_model(MathResult))
```

This also works with mutl-agent workflows:

```
## define structured output format  and tools
class Weather(BaseModel):
    location: str = Field(description="The location")
    weather: str = Field(description="The weather")




def get_weather(location: str):
    """Get the weather for a given location"""
    return f"The weather in {location} is sunny"




## define single agents
agent = FunctionAgent(
    llm=llm,
    tools=[get_weather],
    system_prompt="You are a weather agent that can get the weather for a given location",
    name="WeatherAgent",
    description="The weather forecaster agent.",
)
main_agent = FunctionAgent(
    name="MainAgent",
    tools=[],
    description="The main agent",
    system_prompt="You are the main agent, your task is to dispatch tasks to secondary agents, specifically to WeatherAgent",
    can_handoff_to=["WeatherAgent"],
    llm=llm,
)


## define multi-agent workflow
workflow = AgentWorkflow(
    agents=[main_agent, agent],
    root_agent=main_agent.name,
    output_cls=Weather,
)


response = await workflow.run("What is the weather in Tokyo?")
print(response.structured_response)
print(response.get_pydantic_model(Weather))
```

### Use `structured_output_fn`

The custom function should take as input a sequence of `ChatMessage` objects produced by the agent workflow and returns a dictionary (that can be turned into a `BaseModel` subclass):

```
import json
from llama_index.core.llms import ChatMessage
from typing import List, Dict, Any




class Flavor(BaseModel):
    flavor: str
    with_sugar: bool




async def structured_output_parsing(
    messages: List[ChatMessage],
) -> Dict[str, Any]:
    sllm = llm.as_structured_llm(Flavor)
    messages.append(
        ChatMessage(
            role="user",
            content="Given the previous message history, structure the output based on the provided format.",
        )
    )
    response = await sllm.achat(messages)
    return json.loads(response.message.content)




def get_flavor(ice_cream_shop: str):
    return "Strawberry with no extra sugar"




agent = FunctionAgent(
    tools=[get_flavor],
    name="ice_cream_shopper",
    system_prompt="You are an agent that knows the ice cream flavors in various shops.",
    structured_output_fn=structured_output_parsing,
    llm=llm,
)


response = await agent.run(
    "What strawberry flavor is available at Gelato Italia?"
)
print(response.structured_response)
print(response.get_pydantic_model(Flavor))
```

### Streaming the Structured Output

You can get the structured output while the workflow is running by using the `AgentStreamStructuredOutput` event:

```
from llama_index.core.agent.workflow import (
    AgentInput,
    AgentOutput,
    ToolCall,
    ToolCallResult,
    AgentStreamStructuredOutput,
)


handler = agent.run("What strawberry flavor is available at Gelato Italia?")


async for event in handler.stream_events():
    if isinstance(event, AgentInput):
        print(event)
    elif isinstance(event, AgentStreamStructuredOutput):
        print(event.output)
        print(event.get_pydantic_model(Weather))
    elif isinstance(event, ToolCallResult):
        print(event)
    elif isinstance(event, ToolCall):
        print(event)
    elif isinstance(event, AgentOutput):
        print(event)
    else:
        pass


response = await handler
```

And you can parse the structured output in the agent’s response accessing it directly as a dictionary or loading it as a `BaseModel` subclass by using the `get_pydantic_model` method:

```
print(response.structured_response)
print(response.get_pydantic_model(Flavor))
```
