Skip to main content
Workflows give you explicit control over execution order and data flow. Unlike teams (where the leader decides dynamically), workflows follow a defined structure.

Sequential Workflow

Steps execute in order, each building on the previous.
sequential_workflow.py
from agno.agent import Agent
from agno.workflow.step import Step
from agno.workflow.workflow import Workflow
from agno.models.openai import OpenAIChat
from agno.tools.websearch import WebSearchTools
from agno.team import Team

# Step 1: Research agent
research_agent = Agent(
    name="Researcher",
    model=OpenAIChat(id="gpt-4o-mini"),
    tools=[WebSearchTools()],
    role="Search the web for the latest news and trends",
)

# Step 2: Content planner
content_planner = Agent(
    name="Content Planner",
    model=OpenAIChat(id="gpt-4o"),
    instructions=[
        "Plan a content schedule over 4 weeks for the provided topic",
        "Ensure 3 posts per week",
    ],
)

# Step 3: Writer
writer = Agent(
    name="Writer",
    model=OpenAIChat(id="gpt-4o-mini"),
    instructions="Write a blog post on the topic",
)

# Create workflow
content_workflow = Workflow(
    name="Content Creation Workflow",
    description="Research → Plan → Write",
    steps=[
        Step(name="Research", agent=research_agent),
        Step(name="Planning", agent=content_planner),
        Step(name="Writing", agent=writer),
    ],
)

if __name__ == "__main__":
    # Sync
    content_workflow.print_response(
        input="AI trends in 2024",
        markdown=True,
    )
    
    # Async
    import asyncio
    asyncio.run(
        content_workflow.aprint_response(
            input="AI agent frameworks 2025",
            markdown=True,
            stream=True,
        )
    )
Workflow vs Team:
  • Workflow: Explicit step order, predictable execution
  • Team: Dynamic collaboration, leader decides

Workflow with Function Steps

Steps can be Python functions that transform data.
function_steps.py
from agno.workflow.step import Step
from agno.workflow.types import StepInput, StepOutput
from agno.workflow.workflow import Workflow
from typing import AsyncIterator
from textwrap import dedent

# Function step: Prepare input
async def prepare_research_input(
    step_input: StepInput,
) -> AsyncIterator[StepOutput]:
    topic = step_input.input
    content = dedent(
        f"""
        Research the following topic:
        <topic>
        {topic}
        </topic>
        
        Find at least 10 credible sources.
        """
    )
    yield StepOutput(content=content)

# Function step: Format output
async def format_output(
    step_input: StepInput,
) -> AsyncIterator[StepOutput]:
    research = step_input.previous_step_content
    formatted = dedent(
        f"""
        # Research Summary
        
        {research}
        
        ---
        Generated by Research Workflow
        """
    )
    yield StepOutput(content=formatted)

# Workflow mixing agents and functions
workflow = Workflow(
    name="Research Workflow",
    steps=[
        prepare_research_input,  # Function step
        research_agent,          # Agent step
        format_output,           # Function step
    ],
)
Use function steps for data transformation, validation, or formatting between agent steps.

Conditional Workflow

Steps execute only if conditions are met.
conditional_workflow.py
from agno.agent import Agent
from agno.tools.websearch import WebSearchTools
from agno.workflow.condition import Condition
from agno.workflow.step import Step
from agno.workflow.types import StepInput
from agno.workflow.workflow import Workflow

# Create agents
researcher = Agent(
    name="Researcher",
    instructions="Research the given topic and provide detailed findings.",
    tools=[WebSearchTools()],
)

summarizer = Agent(
    name="Summarizer",
    instructions="Create a clear summary of the research findings.",
)

fact_checker = Agent(
    name="Fact Checker",
    instructions="Verify facts and check for accuracy in the research.",
    tools=[WebSearchTools()],
)

writer = Agent(
    name="Writer",
    instructions="Write a comprehensive article based on research and verification.",
)

# Define condition evaluator
def needs_fact_checking(step_input: StepInput) -> bool:
    """Check if content needs fact-checking."""
    summary = step_input.previous_step_content or ""
    fact_indicators = [
        "study shows",
        "research indicates",
        "statistics",
        "data shows",
        "percent",
        "million",
        "billion",
    ]
    return any(indicator in summary.lower() for indicator in fact_indicators)

# Create workflow with condition
workflow = Workflow(
    name="Research Workflow",
    description="Research → Summarize → Condition(Fact Check) → Write",
    steps=[
        Step(name="research", agent=researcher),
        Step(name="summarize", agent=summarizer),
        Condition(
            name="fact_check_gate",
            description="Check if fact-checking is needed",
            evaluator=needs_fact_checking,
            steps=[Step(name="fact_check", agent=fact_checker)],
        ),
        Step(name="write_article", agent=writer),
    ],
)

if __name__ == "__main__":
    workflow.print_response(
        input="Recent breakthroughs in quantum computing",
        stream=True,
    )
Use conditional steps for:
  • Quality gates (fact-checking, validation)
  • Optional processing (enrichment, expansion)
  • Routing based on content type
  • Error handling and retries

Conditional with Else Branch

Execute different steps based on the condition.
condition_else.py
from agno.workflow.condition import Condition

def is_technical_topic(step_input: StepInput) -> bool:
    """Determine if topic is technical."""
    topic = step_input.input.lower()
    technical_keywords = [
        "api", "code", "algorithm", "database",
        "programming", "software", "technical"
    ]
    return any(keyword in topic for keyword in technical_keywords)

# Technical writer for code topics
technical_writer = Agent(
    name="Technical Writer",
    instructions="Write technical documentation with code examples.",
)

# General writer for other topics
general_writer = Agent(
    name="General Writer",
    instructions="Write engaging content for general audiences.",
)

workflow = Workflow(
    name="Smart Writing Workflow",
    steps=[
        research_step,
        Condition(
            name="topic_type_router",
            evaluator=is_technical_topic,
            steps=[Step(name="technical_write", agent=technical_writer)],  # If true
            else_steps=[Step(name="general_write", agent=general_writer)],  # If false
        ),
    ],
)

Parallel Execution

Run multiple steps concurrently.
parallel_workflow.py
from agno.workflow.step import Step
from agno.workflow.workflow import Workflow
from agno.workflow.parallel import Parallel

# Create specialists
market_analyst = Agent(
    name="Market Analyst",
    tools=[YFinanceTools(all=True)],
)

news_analyst = Agent(
    name="News Analyst",
    tools=[WebSearchTools()],
)

technical_analyst = Agent(
    name="Technical Analyst",
    tools=[YFinanceTools(all=True)],
)

# Synthesizer combines all analysis
synthesizer = Agent(
    name="Synthesizer",
    instructions="Combine market, news, and technical analysis into a report.",
)

workflow = Workflow(
    name="Parallel Analysis Workflow",
    steps=[
        Parallel(
            name="gather_analysis",
            description="Run all analyses in parallel",
            steps=[
                Step(name="market", agent=market_analyst),
                Step(name="news", agent=news_analyst),
                Step(name="technical", agent=technical_analyst),
            ],
        ),
        Step(name="synthesize", agent=synthesizer),
    ],
)

if __name__ == "__main__":
    workflow.print_response(
        input="Analyze Tesla (TSLA) stock",
        stream=True,
    )
Parallel execution is perfect for:
  • Independent analysis from multiple specialists
  • Gathering data from multiple sources
  • Any steps that don’t depend on each other

Loop Execution

Repeat steps until a condition is met.
loop_workflow.py
from agno.workflow.loop import Loop
from agno.workflow.step import Step
from agno.workflow.types import StepInput

def quality_check(step_input: StepInput) -> bool:
    """Check if content meets quality standards."""
    content = step_input.previous_step_content or ""
    
    # Simple quality checks
    min_length = len(content) > 500
    has_structure = "##" in content  # Has headings
    has_conclusion = "conclusion" in content.lower()
    
    return min_length and has_structure and has_conclusion

writer = Agent(
    name="Writer",
    instructions="Write a comprehensive article. Include structure and conclusion.",
)

reviewer = Agent(
    name="Reviewer",
    instructions="Review the article and suggest improvements.",
)

workflow = Workflow(
    name="Iterative Writing Workflow",
    steps=[
        Loop(
            name="write_review_loop",
            description="Write and review until quality check passes",
            steps=[
                Step(name="write", agent=writer),
                Step(name="review", agent=reviewer),
            ],
            max_iterations=3,
            exit_condition=quality_check,
        ),
    ],
)
Always set max_iterations to prevent infinite loops.

Workflow with Events

Monitor workflow execution with events.
workflow_events.py
import asyncio
from typing import AsyncIterator
from agno.run.workflow import WorkflowRunEvent, WorkflowRunOutputEvent

async def stream_workflow_events():
    events: AsyncIterator[WorkflowRunOutputEvent] = workflow.arun(
        input="AI trends in 2024",
        markdown=True,
        stream=True,
        stream_events=True,
    )
    
    async for event in events:
        if event.event == WorkflowRunEvent.workflow_started.value:
            print(f"Workflow started: {event.workflow_name}")
        
        elif event.event == WorkflowRunEvent.step_started.value:
            print(f"Step started: {event.step_name}")
        
        elif event.event == WorkflowRunEvent.step_completed.value:
            print(f"Step completed: {event.step_name}")
        
        elif event.event == WorkflowRunEvent.condition_execution_started.value:
            print(f"Evaluating condition: {event.condition_name}")
        
        elif event.event == WorkflowRunEvent.workflow_completed.value:
            print(f"Workflow completed: {event.content}")

if __name__ == "__main__":
    asyncio.run(stream_workflow_events())

CEL Expressions

Use Common Expression Language (CEL) for advanced conditions.
cel_workflow.py
from agno.workflow.condition import Condition

# CEL expression for condition
workflow = Workflow(
    name="CEL Workflow",
    steps=[
        research_step,
        Condition(
            name="length_check",
            # CEL expression: check content length
            evaluator="len(step_input.previous_step_content) > 1000",
            steps=[Step(name="summarize", agent=summarizer)],
        ),
    ],
)
# Check content length
"len(step_input.previous_step_content) > 1000"

# Check for keywords
"'important' in step_input.previous_step_content.lower()"

# Combine conditions
"len(content) > 500 && 'conclusion' in content.lower()"

# Access custom metadata
"step_input.metadata.confidence_score > 0.8"

Next Steps

Learn how to deploy workflows in production:
For the complete collection of workflow examples, see the source code.

Build docs developers (and LLMs) love