This example demonstrates how to use named steps with custom function executors.
This example demonstrates Workflows 2.0 using named Step objects with custom function
executors. This pattern combines the benefits of named steps with the flexibility of
custom functions, allowing for sophisticated data processing within structured workflow steps.When to use: When you need named step organization but want custom logic that goes
beyond what agents/teams provide. Ideal for complex data processing, multi-step operations,
or when you need to orchestrate multiple agents within a single step.
step_with_function.py
Copy
Ask AI
from agno.agent import Agentfrom agno.models.openai import OpenAIChatfrom agno.storage.sqlite import SqliteStoragefrom agno.team import Teamfrom agno.tools.duckduckgo import DuckDuckGoToolsfrom agno.tools.hackernews import HackerNewsToolsfrom agno.workflow.v2.step import Step, StepInput, StepOutputfrom agno.workflow.v2.workflow import Workflow# Define agentshackernews_agent = Agent( name="Hackernews Agent", model=OpenAIChat(id="gpt-4o"), tools=[HackerNewsTools()], instructions="Extract key insights and content from Hackernews posts",)web_agent = Agent( name="Web Agent", model=OpenAIChat(id="gpt-4o"), tools=[DuckDuckGoTools()], instructions="Search the web for the latest news and trends",)# Define research team for complex analysisresearch_team = Team( name="Research Team", mode="coordinate", members=[hackernews_agent, web_agent], instructions="Analyze content and create comprehensive social media strategy",)content_planner = Agent( name="Content Planner", model=OpenAIChat(id="gpt-4o"), instructions=[ "Plan a content schedule over 4 weeks for the provided topic and research content", "Ensure that I have posts for 3 posts per week", ],)def custom_content_planning_function(step_input: StepInput) -> StepOutput: """ Custom function that does intelligent content planning with context awareness """ message = step_input.message previous_step_content = step_input.previous_step_content # Create intelligent planning prompt planning_prompt = f""" STRATEGIC CONTENT PLANNING REQUEST: Core Topic: {message} Research Results: {previous_step_content[:500] if previous_step_content else "No research results"} Planning Requirements: 1. Create a comprehensive content strategy based on the research 2. Leverage the research findings effectively 3. Identify content formats and channels 4. Provide timeline and priority recommendations 5. Include engagement and distribution strategies Please create a detailed, actionable content plan. """ try: response = content_planner.run(planning_prompt) enhanced_content = f""" ## Strategic Content Plan **Planning Topic:** {message} **Research Integration:** {"✓ Research-based" if previous_step_content else "✗ No research foundation"} **Content Strategy:** {response.content} **Custom Planning Enhancements:** - Research Integration: {"High" if previous_step_content else "Baseline"} - Strategic Alignment: Optimized for multi-channel distribution - Execution Ready: Detailed action items included """.strip() return StepOutput(content=enhanced_content, response=response) except Exception as e: return StepOutput( content=f"Custom content planning failed: {str(e)}", success=False, )# Define steps using different executor typesresearch_step = Step( name="Research Step", team=research_team,)content_planning_step = Step( name="Content Planning Step", executor=custom_content_planning_function,)# Define and use examplesif __name__ == "__main__": content_creation_workflow = Workflow( name="Content Creation Workflow", description="Automated content creation with custom execution options", storage=SqliteStorage( table_name="workflow_v2", db_file="tmp/workflow_v2.db", mode="workflow_v2", ), steps=[research_step, content_planning_step], ) content_creation_workflow.print_response( message="AI trends in 2024", markdown=True, ) print("\n" + "=" * 60 + "\n")
This was a synchronous non-streaming example of this pattern. To checkout async and streaming versions, see the cookbooks-