Agno Agents supports various forms of input and output. The most standard pattern is to use str input and str output.
from agno.agent import Agent
from agno.models.openai import OpenAIChat

agent = Agent(
    model=OpenAIChat(id="gpt-5-mini"),
    description="You write movie scripts.",
)

response = agent.run("Write movie script about a girl living in New York")
print(response.content)

Structured Output

One of our favorite features is using Agents to generate structured data (i.e. a pydantic model). This is generally called “Structured Output”. Use this feature to extract features, classify data, produce fake data etc. The best part is that they work with function calls, knowledge bases and all other features. Let’s create an Movie Agent to write a MovieScript for us.
1

Structured Output example

movie_agent.py
from typing import List
from rich.pretty import pprint
from pydantic import BaseModel, Field
from agno.agent import Agent
from agno.models.openai import OpenAIChat

class MovieScript(BaseModel):
    setting: str = Field(..., description="Provide a nice setting for a blockbuster movie.")
    ending: str = Field(..., description="Ending of the movie. If not available, provide a happy ending.")
    genre: str = Field(
        ..., description="Genre of the movie. If not available, select action, thriller or romantic comedy."
    )
    name: str = Field(..., description="Give a name to this movie")
    characters: List[str] = Field(..., description="Name of characters for this movie.")
    storyline: str = Field(..., description="3 sentence storyline for the movie. Make it exciting!")

# Agent that uses structured outputs
structured_output_agent = Agent(
    model=OpenAIChat(id="gpt-5-mini"),
    description="You write movie scripts.",
    output_schema=MovieScript,
)

structured_output_agent.print_response("New York")
2

Run the example

Install libraries
pip install openai agno
Export your key
export OPENAI_API_KEY=xxx
Run the example
python movie_agent.py
The output is an object of the MovieScript class, here’s how it looks:
MovieScript(
setting='In the bustling streets and iconic skyline of New York City.',
ending='Isabella and Alex, having narrowly escaped the clutches of the Syndicate, find themselves standing at the top of the Empire State Building. As the glow of the setting sun bathes the city, they share a victorious kiss. Newly emboldened and as an unstoppable duo, they vow to keep NYC safe from any future threats.',
genre='Action Thriller',
name='The NYC Chronicles',
characters=['Isabella Grant', 'Alex Chen', 'Marcus Kane', 'Detective Ellie Monroe', 'Victor Sinclair'],
storyline='Isabella Grant, a fearless investigative journalist, uncovers a massive conspiracy involving a powerful syndicate plotting to control New York City. Teaming up with renegade cop Alex Chen, they must race against time to expose the culprits before the city descends into chaos. Dodging danger at every turn, they fight to protect the city they love from imminent destruction.'
)
Some LLMs are not able to generate structured output. Agno has an option to tell the model to respond as JSON. Although this is typically not as accurate as structured output, it can be useful in some cases.If you want to use JSON mode, you can set use_json_mode=True on the Agent.
agent = Agent(
  model=OpenAIChat(id="gpt-5-mini"),
  description="You write movie scripts.",
  output_schema=MovieScript,
  use_json_mode=True,
)

Streaming Structured Output

Streaming can be used in combination with output_schema. This returns the structured output as a single RunContent event in the stream of events.
1

Streaming Structured Output example

streaming_agent.py
import asyncio
from typing import Dict, List

from agno.agent import Agent
from agno.models.openai.chat import OpenAIChat
from pydantic import BaseModel, Field


class MovieScript(BaseModel):
    setting: str = Field(
        ..., description="Provide a nice setting for a blockbuster movie."
    )
    ending: str = Field(
        ...,
        description="Ending of the movie. If not available, provide a happy ending.",
    )
    genre: str = Field(
        ...,
        description="Genre of the movie. If not available, select action, thriller or romantic comedy.",
    )
    name: str = Field(..., description="Give a name to this movie")
    characters: List[str] = Field(..., description="Name of characters for this movie.")
    storyline: str = Field(
        ..., description="3 sentence storyline for the movie. Make it exciting!"
    )
    rating: Dict[str, int] = Field(
        ...,
        description="Your own rating of the movie. 1-10. Return a dictionary with the keys 'story' and 'acting'.",
    )


# Agent that uses structured outputs with streaming
structured_output_agent = Agent(
    model=OpenAIChat(id="gpt-5-mini"),
    description="You write movie scripts.",
    output_schema=MovieScript,
)

structured_output_agent.print_response(
    "New York", stream=True, stream_intermediate_steps=True
)
2

Run the example

Install libraries
pip install openai agno
Export your key
export OPENAI_API_KEY=xxx
Run the example
python streaming_agent.py

Structured Input

An agent can be provided with structured input (i.e a pydantic model) by passing it in the Agent.run() or Agent.print_response() as the input parameter.
1

Structured Input example

from typing import List

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.hackernews import HackerNewsTools
from pydantic import BaseModel, Field


class ResearchTopic(BaseModel):
    """Structured research topic with specific requirements"""

    topic: str
    focus_areas: List[str] = Field(description="Specific areas to focus on")
    target_audience: str = Field(description="Who this research is for")
    sources_required: int = Field(description="Number of sources needed", default=5)

hackernews_agent = Agent(
    name="Hackernews Agent",
    model=OpenAIChat(id="gpt-5-mini"),
    tools=[HackerNewsTools()],
    role="Extract key insights and content from Hackernews posts",
)

hackernews_agent.print_response(
    input=ResearchTopic(
        topic="AI",
        focus_areas=["AI", "Machine Learning"],
        target_audience="Developers",
        sources_required=5,
    )
)
2

Run the example

Install libraries
pip install openai agno
Export your key
export OPENAI_API_KEY=xxx
Run the example
python structured_input_agent.py

Validating the input

You can set input_schema on the Agent to validate the input. If you then pass the input as a dictionary, it will be automatically validated against the schema.
1

Validating the input example

validating_input_agent.py
from typing import List

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.hackernews import HackerNewsTools
from pydantic import BaseModel, Field


class ResearchTopic(BaseModel):
    """Structured research topic with specific requirements"""

    topic: str
    focus_areas: List[str] = Field(description="Specific areas to focus on")
    target_audience: str = Field(description="Who this research is for")
    sources_required: int = Field(description="Number of sources needed", default=5)


# Define agents
hackernews_agent = Agent(
    name="Hackernews Agent",
    model=OpenAIChat(id="gpt-5-mini"),
    tools=[HackerNewsTools()],
    role="Extract key insights and content from Hackernews posts",
    input_schema=ResearchTopic,
)

# Pass a dict that matches the input schema
hackernews_agent.print_response(
    input={
        "topic": "AI",
        "focus_areas": ["AI", "Machine Learning"],
        "target_audience": "Developers",
        "sources_required": "5",
    }
)
2

Run the example

Install libraries
pip install openai agno
Export your key
export OPENAI_API_KEY=xxx
Run the example
python validating_input_agent.py

Using a Parser Model

You can use a different model to parse and structure the output from your primary model. This approach is particularly effective when the primary model is optimized for reasoning tasks, as such models may not consistently produce detailed structured responses.
agent = Agent(
    model=Claude(id="claude-sonnet-4-20250514"),  # The main processing model
    description="You write movie scripts.",
    output_schema=MovieScript,
    parser_model=OpenAIChat(id="gpt-5-mini"),  # Only used to parse the output
)
You can also provide a custom parser_model_prompt to your Parser Model to customize the model’s instructions.

Using an Output Model

You can use a different model to produce the run output of the agent. This is useful when the primary model is optimized for image analysis, for example, but you want a different model to produce a structured output response.
agent = Agent(
    model=Claude(id="claude-sonnet-4-20250514"),  # The main processing model
    description="You write movie scripts.",
    output_schema=MovieScript,
    output_model=OpenAIChat(id="gpt-5-mini"),  # Only used to parse the output
)
You can also provide a custom output_model_prompt to your Output Model to customize the model’s instructions.
Gemini models often reject requests to use tools and produce structured output at the same time. Using an Output Model is an effective workaround for this.

Developer Resources