What's new in v2.3?
This might be our longest changelog yet! At the core, it's the same blazing-fast, truly agnostic framework you know and love. But v2.3 brings some seriously exciting features that make building multi-agent systems even more powerful.
What's changed?
With Agno v2.3, you'll find:
Nano Banana image generation
Key improvement: Generate images with Google's Gemini 2.5 Flash Image model. And yes, Google actually named it Nano Banana.
We couldn't resist adding support for this one. The name alone is worth the upgrade.
Setup:
# Install dependencies
pip install agno google-genai Pillow
# Set your Google API key
export GOOGLE_API_KEY="your_api_key"from agno.agent import Agent
from agno.tools.nano_banana import NanoBananaTools
agent = Agent(
tools=[NanoBananaTools()],
name="NanoBanana Image Generator"
)
agent.run(
"Generate an image of a futuristic city with flying cars",
markdown=True,
)
Watch your images come to life
Images appear in real-time in the AgentOS chat interface. No more waiting around wondering if your generation worked, you'll see it streaming in.
# Want a specific aspect ratio? We've got you covered
portrait_agent = Agent(
tools=[NanoBananaTools(aspect_ratio="2:3")], # Portrait
name="Portrait Generator",
)
widescreen_agent = Agent(
tools=[NanoBananaTools(aspect_ratio="16:9")], # Cinematic
name="Widescreen Generator",
)Supported aspect ratios: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9. Pick your canvas.
Claude structured outputs
Key improvement: Get guaranteed structured responses from Claude. No more JSON parsing headaches. Remember the days of writing 47 lines of parsing code for every Claude response? Yeah, those days are over.
from typing import List
from agno.agent import Agent
from agno.models.anthropic import Claude
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!")
movie_agent = Agent(
model=Claude(id="claude-sonnet-4-5"),
description="You help people write movie scripts.",
output_schema=MovieScript, # Guaranteed structured output
)
movie_agent.print_response("New York")
Type-safe responses every time
# Get the response in a variable
run = movie_agent.run("New York")
# Returns validated MovieScript object
print(run.content.name) # Movie title
print(run.content.genre) # "Action Thriller"
print(run.content.characters) # ["John McClane", "Hans Gruber", ...]Works with any Pydantic model. Define your schema once, get clean data every time.
Check out the full example
RedisCluster support for production scale
Key improvement: Scale your agent infrastructure with Redis Cluster for high-availability deployments. Your agents can now handle millions of sessions.
Single Redis getting crushed by your agent's popularity? RedisCluster gives you automatic sharding, failover, and the kind of reliability that lets you sleep at night
from redis import RedisCluster
from agno.agent import Agent
from agno.db.redis import RedisDb
from agno.models.openai import OpenAIChat
from agno.tools.duckduckgo import DuckDuckGoTools
# Connect to Redis Cluster with startup nodes
redis_client = RedisCluster(
startup_nodes=[
{"host": "node1.redis.example.com", "port": 6379},
{"host": "node2.redis.example.com", "port": 6379},
{"host": "node3.redis.example.com", "port": 6379},
],
decode_responses=True,
skip_full_coverage_check=True,
)
# Use RedisCluster with Agno
db = RedisDb(redis_client=redis_client)
agent = Agent(
model=OpenAIChat(id="gpt-4"),
db=db, # Automatic sharding and failover
tools=[DuckDuckGoTools()],
add_history_to_context=True, # Auto-loads chat history
)
agent.print_response("How many people live in Canada?")
agent.print_response("What is their national anthem called?")
Perfect for production deployments requiring high availability, multi-region systems, and applications with millions of sessions.
Check out the Redis database documentation →
Seamless database migrations
Key improvement: MigrationManager handles schema updates automatically. No more manual database changes.
from agno.db.migrations.manager import MigrationManager
from agno.db.postgres import PostgresDb
db = PostgresDb(db_url="postgresql://localhost/agno")
migration_manager = MigrationManager(db=db)
# Your database is now future-proof
await migration_manager.up()
Migrate specific tables or versions
# Update just one table
await migration_manager.up(table_type="session")
# Or target a specific version
await migration_manager.up(target_version="2.3.0")Check out the migrations documentation →
Context compression (Beta)
Key improvement: Keep your agents running smoothly within their context window. Context compression automatically compresses tool call results in a running context, helping you avoid rate limits and maintain response quality during long conversations.
This is especially useful for agents that make many tool calls or work with large responses.
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.duckduckgo import DuckDuckGoTools
agent = Agent(
model=OpenAIChat(id="gpt-4o"),
tools=[DuckDuckGoTools()],
compress_tool_results=True,
)
agent.print_response("Research each of the following topics: AI, Crypto, Web3, and Blockchain")Check out the context compression docs →
Memory optimization (Beta)
Key improvement: Smarter memory management with automatic summarization. The new optimize_memories and aoptimize_memories methods on MemoryManager let you summarize user memories outside of agent runs.
from agno.db.sqlite import SqliteDb
from agno.memory import MemoryManager
from agno.memory.strategies.types import MemoryOptimizationStrategyType
from agno.models.openai import OpenAIChat
db = SqliteDb(db_file="tmp/agno.db")
memory_manager = MemoryManager(
model=OpenAIChat(id="gpt-4o-mini"),
db=db,
)
# Optimize memories for a user
memory_manager.optimize_memories(
user_id="user_123",
strategy=MemoryOptimizationStrategyType.SUMMARIZE,
apply=True, # Apply changes to database
)Currently supports one summarization strategy, with more coming soon.
Check out the memory optimization docs →
Gemini file search support
Key improvement: Full-featured document search powered by Gemini. Build RAG pipelines with native Google infrastructure.
What's included:
- File Search Store Management: Create, list, get, and delete document stores
- File Upload & Import: Direct upload with custom chunking configuration and metadata
- Document Management: List, get, delete, and update documents with metadata filtering
- Citation Extraction: Helper methods to extract and format source citations from responses
- Async Support: Full async/await support for production workloads
Check out these cookbooks to get started:
- cookbook/models/google/gemini/file_search_basic.py
- cookbook/models/google/gemini/file_search_advanced.py
- cookbook/models/google/gemini/file_search_rag_pipeline.py
And a whole lot more...
Beyond the headline features, v2.3 includes:
- Enhanced error handling across all model providers
- Optimized memory management for multi-turn conversations
- Better async support throughout the framework
- Expanded toolkit integrations
We're already working on v2.4 with even more exciting features. Stay tuned! 🚀
See the Changelog for more details on v2.3. Or check out this guide for help upgrading your Agno applications.
🧡 Team Agno
Install the latest version:
pip install -U agno

